| from flask import Flask, request, render_template_string |
| import subprocess, tempfile, os, shutil, time, json, glob |
|
|
| app = Flask(__name__) |
|
|
| TOOLS = [ |
| { |
| "name": "PENgram", |
| "command": "pengram run {repo_path}", |
| "output_type": "file", |
| "output_glob": "**/*.md" |
| }, |
| { |
| "name": "Cartographer", |
| "command": "cartographer {repo_path}", |
| "output_type": "stdout" |
| }, |
| { |
| "name": "llumsum", |
| "command": "cd {repo_path} && npx llumsum", |
| "output_type": "file", |
| "output_glob": "*.summary" |
| }, |
| { |
| "name": "GitIngest", |
| "command": "gitingest {repo_path}", |
| "output_type": "stdout" |
| }, |
| { |
| "name": "Repomix", |
| "command": "cd {repo_path} && npx repomix", |
| "output_type": "file", |
| "output_glob": "repomix-output.xml" |
| } |
| ] |
|
|
| HTML_TEMPLATE = """ |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <title>Uspoo - Summarizer Battle</title> |
| <style> |
| body { font-family: sans-serif; margin: 40px; background: #1e1e1e; color: #ccc; } |
| input[type=text] { width: 500px; padding: 10px; background: #333; border: 1px solid #555; color: white; border-radius: 5px; } |
| button { padding: 10px 20px; background: #007acc; border: none; color: white; border-radius: 5px; cursor: pointer; } |
| table { width: 100%; border-collapse: collapse; margin-top: 20px; } |
| th, td { padding: 12px; border: 1px solid #555; text-align: left; vertical-align: top; } |
| th { background: #2d2d2d; } |
| .success { color: #4ec9b0; } |
| .fail { color: #f44747; } |
| pre { background: #2d2d2d; padding: 10px; max-height: 400px; overflow-y: auto; font-size: 12px; white-space: pre-wrap; word-break: break-word; } |
| details { cursor: pointer; } |
| summary { color: #569cd6; } |
| </style> |
| </head> |
| <body> |
| <h1>🔬 Summarizer Test Bench</h1> |
| <form method="GET"> |
| <input type="text" name="repo" placeholder="أدخل رابط المستودع مثلاً: https://github.com/pallets/flask" value="{{ repo_url }}"> |
| <button type="submit">🔍 اختبر الآن</button> |
| </form> |
| |
| {% if results %} |
| <h3>مستودع الاختبار: <a href="{{ repo_url }}">{{ repo_url }}</a></h3> |
| <table> |
| <thead> |
| <tr> |
| <th>الأداة</th> |
| <th>الحالة</th> |
| <th>الوقت (ث)</th> |
| <th>حجم المخرج (KB)</th> |
| <th>المخرجات الكاملة</th> |
| </tr> |
| </thead> |
| <tbody> |
| {% for r in results %} |
| <tr> |
| <td>{{ r.name }}</td> |
| <td class="{{ 'success' if r.ok else 'fail' }}">{{ '✅ نجحت' if r.ok else '❌ فشلت' }}</td> |
| <td>{{ "%.2f"|format(r.time) if r.time else '-' }}</td> |
| <td>{{ r.size if r.size else '-' }}</td> |
| <td> |
| {% if r.ok and r.output %} |
| <details open> |
| <summary>عرض كامل ({{ r.output_lines }} سطر)</summary> |
| <pre>{{ r.output }}</pre> |
| </details> |
| {% elif not r.ok %} |
| <span class="fail">{{ r.error }}</span> |
| {% else %} |
| <span>لم تنتج الأداة مخرجات</span> |
| {% endif %} |
| </td> |
| </tr> |
| {% endfor %} |
| </tbody> |
| </table> |
| {% endif %} |
| </body> |
| </html> |
| """ |
|
|
| @app.route("/") |
| def index(): |
| repo_url = request.args.get("repo", "").strip() |
| results = [] |
| if repo_url: |
| tmpdir = tempfile.mkdtemp() |
| repo_name = repo_url.split("/")[-1].replace(".git", "") |
| repo_path = os.path.join(tmpdir, repo_name) |
| clone_cmd = f"git clone --depth 1 {repo_url} {repo_path}" |
| clone_r = subprocess.run(clone_cmd, shell=True, capture_output=True) |
| if clone_r.returncode != 0: |
| shutil.rmtree(tmpdir) |
| results.append({"name": "Clone", "ok": False, "time": 0, "size": 0, "output": "", "error": "فشل استنساخ المستودع"}) |
| else: |
| for tool in TOOLS: |
| start = time.time() |
| cmd = tool["command"].format(repo_path=repo_path) |
| try: |
| proc = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=180) |
| elapsed = time.time() - start |
| output = "" |
| if tool["output_type"] == "stdout": |
| output = proc.stdout.strip() |
| if proc.returncode != 0: |
| output = proc.stderr.strip() |
| elif tool["output_type"] == "file": |
| |
| pattern = os.path.join(repo_path, tool["output_glob"]) |
| files = glob.glob(pattern, recursive=True) |
| if not files: |
| |
| files = glob.glob(tool["output_glob"], recursive=True) |
| if files: |
| |
| with open(files[0], "r", encoding="utf-8", errors="ignore") as f: |
| output = f.read() |
| ok = bool(output.strip()) and proc.returncode == 0 |
| results.append({ |
| "name": tool["name"], |
| "ok": ok, |
| "time": elapsed, |
| "size": round(len(output) / 1024, 2) if output else 0, |
| "output": output, |
| "output_lines": output.count('\n') + 1 if output else 0, |
| "error": "" if ok else (proc.stderr[:500] if proc.returncode != 0 else "No output") |
| }) |
| except Exception as e: |
| elapsed = time.time() - start |
| results.append({ |
| "name": tool["name"], |
| "ok": False, |
| "time": elapsed, |
| "size": 0, |
| "output": "", |
| "output_lines": 0, |
| "error": str(e)[:500] |
| }) |
| shutil.rmtree(tmpdir) |
| return render_template_string(HTML_TEMPLATE, repo_url=repo_url, results=results) |
|
|
| if __name__ == "__main__": |
| app.run(host="0.0.0.0", port=7860) |