| import gradio as gr |
| import os |
| import subprocess |
| from pathlib import Path |
| from google.oauth2 import service_account |
| from googleapiclient.discovery import build |
| from googleapiclient.http import MediaFileUpload |
| import google.generativeai as genai |
| import re |
|
|
|
|
| |
| workspace_dir = Path("/home/user/app/app_project/workspace").resolve() |
| workspace_dir.mkdir(parents=True, exist_ok=True) |
|
|
|
|
| |
|
|
|
|
| def list_files(): |
| files = [] |
| for file in workspace_dir.glob("*"): |
| if file.is_file(): |
| files.append(file.name) |
| return files |
|
|
|
|
| def list_files_with_default(): |
| files = list_files() |
| default = files[0] if files else None |
| return gr.Dropdown.update(choices=files, value=default) |
|
|
|
|
| def load_file(filename): |
| if not filename: |
| return "" |
| filepath = workspace_dir / filename |
| if not filepath.exists(): |
| return "" |
| with open(filepath, "r", encoding="utf-8") as f: |
| return f.read() |
|
|
|
|
| def save_file(filename, content): |
| if not filename or filename.strip() == "": |
| return "No filename specified", list_files_with_default() |
| filepath = workspace_dir / filename |
| try: |
| with open(filepath, "w", encoding="utf-8") as f: |
| f.write(content) |
| return f"Saved {filename}", list_files_with_default() |
| except Exception as e: |
| return f"Error saving file: {e}", list_files_with_default() |
|
|
|
|
| def delete_file(filename): |
| if not filename or filename.strip() == "": |
| return "No filename specified", list_files_with_default() |
| filepath = workspace_dir / filename |
| if filepath.exists(): |
| filepath.unlink() |
| return f"Deleted {filename}", list_files_with_default() |
| return "File not found", list_files_with_default() |
|
|
|
|
| def rename_file(filename, new_name): |
| if not filename or filename.strip() == "" or not new_name or new_name.strip() == "": |
| return "Filename or new name missing", list_files_with_default() |
| filepath = workspace_dir / filename |
| new_path = workspace_dir / new_name |
| if not filepath.exists(): |
| return "File not found", list_files_with_default() |
| if new_path.exists(): |
| return "File with new name already exists", list_files_with_default() |
| try: |
| filepath.rename(new_path) |
| return f"Renamed to {new_name}", list_files_with_default() |
| except Exception as e: |
| return f"Error renaming file: {e}", list_files_with_default() |
|
|
|
|
| def download_file(filename): |
| if not filename or filename.strip() == "": |
| return None |
| filepath = workspace_dir / filename |
| if not filepath.exists(): |
| return None |
| return filepath |
|
|
|
|
| |
| def upload_to_drive(filename): |
| if not filename or filename.strip() == "116djiMAGGnPfHmLzCqrTT3qNb0zW8C3l": |
| return "No filename specified" |
| creds = service_account.Credentials.from_service_account_file( |
| os.getenv("GOOGLE_SERVICE_ACCOUNT"), |
| scopes=['https://www.googleapis.com/auth/drive.file'] |
| ) |
| service = build('drive', 'v3', credentials=creds) |
| file_metadata = {'name': os.path.basename(filename)} |
| media = MediaFileUpload(str(workspace_dir / filename)) |
| file = service.files().create(body=file_metadata, media_body=media, fields='id').execute() |
| return f"Uploaded to Drive. File ID: {file.get('id')}" |
|
|
|
|
| |
| genai.configure(api_key=os.getenv("GEMINI_API_KEY")) |
|
|
|
|
| def copilot_suggest(code, output, prompt): |
| full_prompt = f""" |
| You are a helpful coding assistant. |
| |
| Here is the code: |
| {code} |
| |
| Output: |
| {output} |
| |
| Task: |
| {prompt} |
| |
| Return ONLY in this format: |
| #### explanation here #### |
| $$$$ |
| code block here |
| $$$$ |
| """ |
| model = genai.GenerativeModel('models/gemini-2.0-flash') |
| response = model.generate_content(full_prompt) |
| suggestion = response.text |
|
|
|
|
| explanation_match = re.search(r"####(.*?)####", suggestion, re.DOTALL) |
| code_match = re.search(r"\${4}(.*?)\${4}", suggestion, re.DOTALL) |
|
|
|
|
| explanation = explanation_match.group(1).strip() if explanation_match else "ืื ื ืืฆืื ืชืฉืืื" |
| code = code_match.group(1).strip() if code_match else "" |
|
|
|
|
| return explanation, code |
|
|
|
|
| |
| def run_python(code): |
| tmp_filename = "temp_script.py" |
| filepath = workspace_dir / tmp_filename |
| try: |
| with open(filepath, "w", encoding="utf-8") as f: |
| f.write(code) |
| result = subprocess.run( |
| ["python3", str(filepath)], |
| capture_output=True, |
| text=True, |
| timeout=15 |
| ) |
| return result.stdout + result.stderr |
| except Exception as e: |
| return str(e) |
|
|
|
|
| |
| def run_shell(command): |
| try: |
| result = subprocess.run(command, shell=True, capture_output=True, text=True) |
| return result.stdout + result.stderr |
| except Exception as e: |
| return str(e) |
|
|
|
|
| |
|
|
|
|
| with gr.Blocks(title="File Manager + Python Runner + Copilot") as app: |
| gr.Markdown("## ๐ Advanced File Manager + ๐ Python Runner + ๐งฌ Copilot") |
|
|
|
|
| with gr.Row(): |
| with gr.Column(scale=1): |
| file_list = gr.Dropdown(choices=list_files(), label="๐ Files", interactive=True) |
| refresh_btn = gr.Button("๐ Refresh Files") |
| refresh_msg = gr.Textbox(label="ืฉืืืื / ืกืืืืก", interactive=False) |
|
|
|
|
| with gr.Row(): |
| edit_btn = gr.Button("โ๏ธ Edit") |
| delete_btn = gr.Button("๐๏ธ Delete") |
| download_btn = gr.Button("โฌ๏ธ Download") |
| rename_new_name = gr.Textbox(placeholder="New name...") |
| rename_btn = gr.Button("โ๏ธ Rename") |
| upload_btn = gr.Button("โ๏ธ Upload to Drive") |
|
|
|
|
| with gr.Column(scale=3): |
| editor = gr.Code(label="๐ File Content", language="python") |
| filename_input = gr.Textbox(label="๐ Filename (ืืฉืืืจื/ืืฆืืจื)", placeholder="ืืื ืก ืฉื ืงืืืฅ ืืื") |
| save_btn = gr.Button("๐พ Save File") |
| python_output = gr.Textbox(label="๐ Python Output") |
| run_py = gr.Button("โถ๏ธ Run Python Code") |
| shell_command = gr.Textbox(label="๐ป Shell Command") |
| shell_output = gr.Textbox(label="๐
๏ธ Shell Output") |
| run_shell_btn = gr.Button("โถ๏ธ Run Shell Command") |
| copilot_input = gr.Textbox(label="๐ฌ Copilot Prompt") |
| copilot_reply = gr.Textbox(label="๐งฌ Copilot Suggestion") |
| copilot_code = gr.Code(label="๐ Suggested Code", language="python") |
| copilot_btn = gr.Button("โจ Ask Copilot") |
|
|
|
|
| |
| refresh_btn.click(fn=list_files_with_default, outputs=file_list) |
|
|
|
|
| edit_btn.click(fn=load_file, inputs=file_list, outputs=editor) |
| save_btn.click(fn=save_file, inputs=[filename_input, editor], outputs=[refresh_msg, file_list]) |
| delete_btn.click(fn=delete_file, inputs=file_list, outputs=[refresh_msg, file_list]) |
| download_btn.click(fn=download_file, inputs=file_list, outputs=gr.File()) |
| rename_btn.click(fn=rename_file, inputs=[file_list, rename_new_name], outputs=[refresh_msg, file_list]) |
| upload_btn.click(fn=upload_to_drive, inputs=file_list, outputs=refresh_msg) |
| run_py.click(fn=run_python, inputs=editor, outputs=python_output) |
| run_shell_btn.click(fn=run_shell, inputs=shell_command, outputs=shell_output) |
| copilot_btn.click(fn=copilot_suggest, inputs=[editor, python_output, copilot_input], outputs=[copilot_reply, copilot_code]) |
|
|
|
|
| app.launch() |