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 # ☁️ העלאה לדרייב (דרך SECRET) 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')}" # 🧬 קופיילוט Gemini (Flash) 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) # 🖼️ ממשק Gradio 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()