Aigg / app.py
Athspi's picture
Update app.py
8b2be7b verified
raw
history blame
5.14 kB
import os
import zipfile
import uuid
from flask import Flask, request, jsonify, render_template, session, send_from_directory
from flask_session import Session
from dotenv import load_dotenv
import google.generativeai as genai
# Load env
load_dotenv()
app = Flask(__name__)
app.config["SECRET_KEY"] = os.getenv("FLASK_SECRET_KEY", "insecure")
app.config["SESSION_TYPE"] = "filesystem"
app.config["SESSION_FILE_DIR"] = './flask_session'
app.config["SESSION_PERMANENT"] = False
Session(app)
UPLOAD_FOLDER = 'uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(app.config['SESSION_FILE_DIR'], exist_ok=True)
# Configure Gemini
gemini_api_key = os.getenv("GEMINI_API_KEY")
model = None
if gemini_api_key:
genai.configure(api_key=gemini_api_key)
model = genai.GenerativeModel('gemini-2.0-flash')
def get_project_files(project_path):
files = {}
for root, _, filenames in os.walk(project_path):
for file in filenames:
if file.startswith('.'): continue
rel_path = os.path.relpath(os.path.join(root, file), project_path)
try:
with open(os.path.join(root, file), 'r', encoding='utf-8', errors='ignore') as f:
files[rel_path] = f.read()
except Exception as e:
files[rel_path] = f"Error reading: {e}"
return files
@app.route('/')
def index():
if 'project_id' not in session:
session['project_id'] = str(uuid.uuid4())
session['chat_history'] = []
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload():
if 'project_zip' not in request.files:
return jsonify({'error': 'No file uploaded'}), 400
file = request.files['project_zip']
if not file.filename.endswith('.zip'):
return jsonify({'error': 'Only .zip supported'}), 400
project_id = session['project_id']
project_path = os.path.join(app.config['UPLOAD_FOLDER'], project_id)
if os.path.exists(project_path):
for root, dirs, files in os.walk(project_path, topdown=False):
for f in files:
os.remove(os.path.join(root, f))
for d in dirs:
os.rmdir(os.path.join(root, d))
os.makedirs(project_path, exist_ok=True)
zip_path = os.path.join(project_path, file.filename)
file.save(zip_path)
with zipfile.ZipFile(zip_path, 'r') as z:
z.extractall(project_path)
os.remove(zip_path)
files = get_project_files(project_path)
context = "User uploaded a project:\n"
for path, content in files.items():
context += f"**File:** `{path}`\n```\n{content[:2000]}\n```\n\n" # clip long content
session['chat_history'] = [
{"role": "user", "parts": [context]},
{"role": "model", "parts": ["Project loaded. Ready to help."]}
]
session.modified = True
return jsonify({
"message": "Project uploaded.",
"file_tree": list(files.keys()),
"chat_history": [
{"role": "user", "content": "Project context sent to AI."},
{"role": "assistant", "content": "Project loaded. Ready to help."}
]
})
@app.route('/chat', methods=['POST'])
def chat():
if not model:
return jsonify({"error": "Gemini API not configured"}), 500
msg = request.json.get("message")
if not msg:
return jsonify({"error": "Empty message"}), 400
session['chat_history'].append({"role": "user", "parts": [msg]})
try:
chat = model.start_chat(history=session['chat_history'])
reply = chat.send_message(msg).text
session['chat_history'].append({"role": "model", "parts": [reply]})
return jsonify({"reply": reply})
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route('/file_tree')
def file_tree():
pid = session.get('project_id')
if not pid:
return jsonify({"file_tree": []})
path = os.path.join(app.config['UPLOAD_FOLDER'], pid)
return jsonify({"file_tree": list(get_project_files(path).keys())})
@app.route('/file_content')
def file_content():
pid = session.get('project_id')
filepath = request.args.get('path')
full = os.path.join(app.config['UPLOAD_FOLDER'], pid, filepath)
try:
with open(full, 'r', encoding='utf-8', errors='ignore') as f:
return jsonify({"content": f.read()})
except Exception as e:
return jsonify({"error": str(e)})
@app.route('/download')
def download():
pid = session.get('project_id')
if not pid:
return "No project uploaded", 404
path = os.path.join(app.config['UPLOAD_FOLDER'], pid)
zpath = os.path.join(app.config['UPLOAD_FOLDER'], f"{pid}.zip")
with zipfile.ZipFile(zpath, 'w') as zipf:
for root, _, files in os.walk(path):
for file in files:
fpath = os.path.join(root, file)
zipf.write(fpath, os.path.relpath(fpath, path))
return send_from_directory(app.config['UPLOAD_FOLDER'], f"{pid}.zip", as_attachment=True)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=7860)