Update app.py
Browse files
app.py
CHANGED
|
@@ -1,39 +1,36 @@
|
|
| 1 |
from flask import Flask, request, render_template_string
|
| 2 |
-
import subprocess, tempfile, os, shutil, time, json
|
| 3 |
|
| 4 |
app = Flask(__name__)
|
| 5 |
|
| 6 |
-
# تعريف الأدوات الأربعة المجانية مع أوامر التشغيل
|
| 7 |
TOOLS = [
|
| 8 |
{
|
| 9 |
"name": "PENgram",
|
| 10 |
"command": "pengram run {repo_path}",
|
| 11 |
-
"
|
| 12 |
-
"
|
| 13 |
},
|
| 14 |
{
|
| 15 |
"name": "Cartographer",
|
| 16 |
-
"command": "
|
| 17 |
-
"
|
| 18 |
-
"requires": "python"
|
| 19 |
},
|
| 20 |
{
|
| 21 |
"name": "llumsum",
|
| 22 |
-
"command": "
|
| 23 |
-
"
|
| 24 |
-
"
|
| 25 |
},
|
| 26 |
{
|
| 27 |
"name": "GitIngest",
|
| 28 |
"command": "gitingest {repo_path}",
|
| 29 |
-
"
|
| 30 |
-
"requires": "python"
|
| 31 |
},
|
| 32 |
{
|
| 33 |
"name": "Repomix",
|
| 34 |
-
"command": "
|
| 35 |
-
"
|
| 36 |
-
"
|
| 37 |
}
|
| 38 |
]
|
| 39 |
|
|
@@ -47,11 +44,13 @@ HTML_TEMPLATE = """
|
|
| 47 |
input[type=text] { width: 500px; padding: 10px; background: #333; border: 1px solid #555; color: white; border-radius: 5px; }
|
| 48 |
button { padding: 10px 20px; background: #007acc; border: none; color: white; border-radius: 5px; cursor: pointer; }
|
| 49 |
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
|
| 50 |
-
th, td { padding: 12px; border: 1px solid #555; text-align: left; }
|
| 51 |
th { background: #2d2d2d; }
|
| 52 |
.success { color: #4ec9b0; }
|
| 53 |
.fail { color: #f44747; }
|
| 54 |
-
|
|
|
|
|
|
|
| 55 |
</style>
|
| 56 |
</head>
|
| 57 |
<body>
|
|
@@ -62,7 +61,7 @@ HTML_TEMPLATE = """
|
|
| 62 |
</form>
|
| 63 |
|
| 64 |
{% if results %}
|
| 65 |
-
<h3>
|
| 66 |
<table>
|
| 67 |
<thead>
|
| 68 |
<tr>
|
|
@@ -70,7 +69,7 @@ HTML_TEMPLATE = """
|
|
| 70 |
<th>الحالة</th>
|
| 71 |
<th>الوقت (ث)</th>
|
| 72 |
<th>حجم المخرج (KB)</th>
|
| 73 |
-
<th>م
|
| 74 |
</tr>
|
| 75 |
</thead>
|
| 76 |
<tbody>
|
|
@@ -81,13 +80,15 @@ HTML_TEMPLATE = """
|
|
| 81 |
<td>{{ "%.2f"|format(r.time) if r.time else '-' }}</td>
|
| 82 |
<td>{{ r.size if r.size else '-' }}</td>
|
| 83 |
<td>
|
| 84 |
-
{% if r.
|
| 85 |
-
<details>
|
| 86 |
-
<summary>عرض
|
| 87 |
-
<pre
|
| 88 |
</details>
|
|
|
|
|
|
|
| 89 |
{% else %}
|
| 90 |
-
<span
|
| 91 |
{% endif %}
|
| 92 |
</td>
|
| 93 |
</tr>
|
|
@@ -104,34 +105,46 @@ def index():
|
|
| 104 |
repo_url = request.args.get("repo", "").strip()
|
| 105 |
results = []
|
| 106 |
if repo_url:
|
| 107 |
-
# استنساخ المستودع إلى مجلد مؤقت
|
| 108 |
tmpdir = tempfile.mkdtemp()
|
| 109 |
repo_name = repo_url.split("/")[-1].replace(".git", "")
|
| 110 |
repo_path = os.path.join(tmpdir, repo_name)
|
| 111 |
clone_cmd = f"git clone --depth 1 {repo_url} {repo_path}"
|
| 112 |
-
|
| 113 |
-
if
|
| 114 |
shutil.rmtree(tmpdir)
|
| 115 |
-
results.append({"name": "Clone", "ok": False, "time": 0, "size": 0, "
|
| 116 |
else:
|
| 117 |
-
# تشغيل كل أداة
|
| 118 |
for tool in TOOLS:
|
| 119 |
start = time.time()
|
| 120 |
cmd = tool["command"].format(repo_path=repo_path)
|
| 121 |
try:
|
| 122 |
proc = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=180)
|
| 123 |
elapsed = time.time() - start
|
| 124 |
-
output =
|
| 125 |
-
if
|
| 126 |
-
output = proc.
|
| 127 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
results.append({
|
| 129 |
"name": tool["name"],
|
| 130 |
-
"ok":
|
| 131 |
"time": elapsed,
|
| 132 |
-
"size": round(len(output) / 1024, 2),
|
| 133 |
-
"
|
| 134 |
-
"
|
|
|
|
| 135 |
})
|
| 136 |
except Exception as e:
|
| 137 |
elapsed = time.time() - start
|
|
@@ -140,8 +153,9 @@ def index():
|
|
| 140 |
"ok": False,
|
| 141 |
"time": elapsed,
|
| 142 |
"size": 0,
|
| 143 |
-
"
|
| 144 |
-
"
|
|
|
|
| 145 |
})
|
| 146 |
shutil.rmtree(tmpdir)
|
| 147 |
return render_template_string(HTML_TEMPLATE, repo_url=repo_url, results=results)
|
|
|
|
| 1 |
from flask import Flask, request, render_template_string
|
| 2 |
+
import subprocess, tempfile, os, shutil, time, json, glob
|
| 3 |
|
| 4 |
app = Flask(__name__)
|
| 5 |
|
|
|
|
| 6 |
TOOLS = [
|
| 7 |
{
|
| 8 |
"name": "PENgram",
|
| 9 |
"command": "pengram run {repo_path}",
|
| 10 |
+
"output_type": "file",
|
| 11 |
+
"output_glob": "**/*.md"
|
| 12 |
},
|
| 13 |
{
|
| 14 |
"name": "Cartographer",
|
| 15 |
+
"command": "cartographer {repo_path}",
|
| 16 |
+
"output_type": "stdout"
|
|
|
|
| 17 |
},
|
| 18 |
{
|
| 19 |
"name": "llumsum",
|
| 20 |
+
"command": "cd {repo_path} && npx llumsum",
|
| 21 |
+
"output_type": "file",
|
| 22 |
+
"output_glob": "*.summary"
|
| 23 |
},
|
| 24 |
{
|
| 25 |
"name": "GitIngest",
|
| 26 |
"command": "gitingest {repo_path}",
|
| 27 |
+
"output_type": "stdout"
|
|
|
|
| 28 |
},
|
| 29 |
{
|
| 30 |
"name": "Repomix",
|
| 31 |
+
"command": "cd {repo_path} && npx repomix",
|
| 32 |
+
"output_type": "file",
|
| 33 |
+
"output_glob": "repomix-output.xml"
|
| 34 |
}
|
| 35 |
]
|
| 36 |
|
|
|
|
| 44 |
input[type=text] { width: 500px; padding: 10px; background: #333; border: 1px solid #555; color: white; border-radius: 5px; }
|
| 45 |
button { padding: 10px 20px; background: #007acc; border: none; color: white; border-radius: 5px; cursor: pointer; }
|
| 46 |
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
|
| 47 |
+
th, td { padding: 12px; border: 1px solid #555; text-align: left; vertical-align: top; }
|
| 48 |
th { background: #2d2d2d; }
|
| 49 |
.success { color: #4ec9b0; }
|
| 50 |
.fail { color: #f44747; }
|
| 51 |
+
pre { background: #2d2d2d; padding: 10px; max-height: 400px; overflow-y: auto; font-size: 12px; white-space: pre-wrap; word-break: break-word; }
|
| 52 |
+
details { cursor: pointer; }
|
| 53 |
+
summary { color: #569cd6; }
|
| 54 |
</style>
|
| 55 |
</head>
|
| 56 |
<body>
|
|
|
|
| 61 |
</form>
|
| 62 |
|
| 63 |
{% if results %}
|
| 64 |
+
<h3>مستودع الاختبار: <a href="{{ repo_url }}">{{ repo_url }}</a></h3>
|
| 65 |
<table>
|
| 66 |
<thead>
|
| 67 |
<tr>
|
|
|
|
| 69 |
<th>الحالة</th>
|
| 70 |
<th>الوقت (ث)</th>
|
| 71 |
<th>حجم المخرج (KB)</th>
|
| 72 |
+
<th>المخرجات الكاملة</th>
|
| 73 |
</tr>
|
| 74 |
</thead>
|
| 75 |
<tbody>
|
|
|
|
| 80 |
<td>{{ "%.2f"|format(r.time) if r.time else '-' }}</td>
|
| 81 |
<td>{{ r.size if r.size else '-' }}</td>
|
| 82 |
<td>
|
| 83 |
+
{% if r.ok and r.output %}
|
| 84 |
+
<details open>
|
| 85 |
+
<summary>عرض كامل ({{ r.output_lines }} سطر)</summary>
|
| 86 |
+
<pre>{{ r.output }}</pre>
|
| 87 |
</details>
|
| 88 |
+
{% elif not r.ok %}
|
| 89 |
+
<span class="fail">{{ r.error }}</span>
|
| 90 |
{% else %}
|
| 91 |
+
<span>لم تنتج الأداة مخرجات</span>
|
| 92 |
{% endif %}
|
| 93 |
</td>
|
| 94 |
</tr>
|
|
|
|
| 105 |
repo_url = request.args.get("repo", "").strip()
|
| 106 |
results = []
|
| 107 |
if repo_url:
|
|
|
|
| 108 |
tmpdir = tempfile.mkdtemp()
|
| 109 |
repo_name = repo_url.split("/")[-1].replace(".git", "")
|
| 110 |
repo_path = os.path.join(tmpdir, repo_name)
|
| 111 |
clone_cmd = f"git clone --depth 1 {repo_url} {repo_path}"
|
| 112 |
+
clone_r = subprocess.run(clone_cmd, shell=True, capture_output=True)
|
| 113 |
+
if clone_r.returncode != 0:
|
| 114 |
shutil.rmtree(tmpdir)
|
| 115 |
+
results.append({"name": "Clone", "ok": False, "time": 0, "size": 0, "output": "", "error": "فشل استنساخ المستودع"})
|
| 116 |
else:
|
|
|
|
| 117 |
for tool in TOOLS:
|
| 118 |
start = time.time()
|
| 119 |
cmd = tool["command"].format(repo_path=repo_path)
|
| 120 |
try:
|
| 121 |
proc = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=180)
|
| 122 |
elapsed = time.time() - start
|
| 123 |
+
output = ""
|
| 124 |
+
if tool["output_type"] == "stdout":
|
| 125 |
+
output = proc.stdout.strip()
|
| 126 |
+
if proc.returncode != 0:
|
| 127 |
+
output = proc.stderr.strip()
|
| 128 |
+
elif tool["output_type"] == "file":
|
| 129 |
+
# ابحث عن الملفات المطابقة في المستودع وفي أي مكان
|
| 130 |
+
pattern = os.path.join(repo_path, tool["output_glob"])
|
| 131 |
+
files = glob.glob(pattern, recursive=True)
|
| 132 |
+
if not files:
|
| 133 |
+
# ربما الأداة تضعها في مجلد الإخراج الحالي
|
| 134 |
+
files = glob.glob(tool["output_glob"], recursive=True)
|
| 135 |
+
if files:
|
| 136 |
+
# خذ أول ملف مناسب
|
| 137 |
+
with open(files[0], "r", encoding="utf-8", errors="ignore") as f:
|
| 138 |
+
output = f.read()
|
| 139 |
+
ok = bool(output.strip()) and proc.returncode == 0
|
| 140 |
results.append({
|
| 141 |
"name": tool["name"],
|
| 142 |
+
"ok": ok,
|
| 143 |
"time": elapsed,
|
| 144 |
+
"size": round(len(output) / 1024, 2) if output else 0,
|
| 145 |
+
"output": output,
|
| 146 |
+
"output_lines": output.count('\n') + 1 if output else 0,
|
| 147 |
+
"error": "" if ok else (proc.stderr[:500] if proc.returncode != 0 else "No output")
|
| 148 |
})
|
| 149 |
except Exception as e:
|
| 150 |
elapsed = time.time() - start
|
|
|
|
| 153 |
"ok": False,
|
| 154 |
"time": elapsed,
|
| 155 |
"size": 0,
|
| 156 |
+
"output": "",
|
| 157 |
+
"output_lines": 0,
|
| 158 |
+
"error": str(e)[:500]
|
| 159 |
})
|
| 160 |
shutil.rmtree(tmpdir)
|
| 161 |
return render_template_string(HTML_TEMPLATE, repo_url=repo_url, results=results)
|