Админка: колонка «Сшивка» в таблице документов (+ в CSV)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
14
app/main.py
14
app/main.py
@@ -2735,7 +2735,7 @@ _ADMIN_HTML = """<!doctype html>
|
|||||||
<h2 style="margin:0">Обработанные документы <span class="muted" id="docs-totals"></span></h2>
|
<h2 style="margin:0">Обработанные документы <span class="muted" id="docs-totals"></span></h2>
|
||||||
<button class="ghost" onclick="downloadCsv()">Экспорт CSV</button>
|
<button class="ghost" onclick="downloadCsv()">Экспорт CSV</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="scroll"><table><thead><tr><th>Дата</th><th>Файл</th><th class="num">Стр.</th><th class="num">Исходник</th><th class="num">Результат</th><th>Кач-во</th><th>OCR</th><th>Источник</th></tr></thead>
|
<div class="scroll"><table><thead><tr><th>Дата</th><th>Файл</th><th class="num">Стр.</th><th class="num">Исходник</th><th class="num">Результат</th><th>Кач-во</th><th>Сшивка</th><th>OCR</th><th>Источник</th></tr></thead>
|
||||||
<tbody id="t-docs"></tbody></table></div>
|
<tbody id="t-docs"></tbody></table></div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
@@ -2816,8 +2816,8 @@ _ADMIN_HTML = """<!doctype html>
|
|||||||
var dd = (f.date||'') + (f.time ? ' '+String(f.time).slice(0,5) : '');
|
var dd = (f.date||'') + (f.time ? ' '+String(f.time).slice(0,5) : '');
|
||||||
return '<tr><td>'+esc(dd)+'</td><td class="fname" title="'+esc(f.name)+'">'+esc(f.name)+'</td><td class="num">'+(f.pages||'—')+
|
return '<tr><td>'+esc(dd)+'</td><td class="fname" title="'+esc(f.name)+'">'+esc(f.name)+'</td><td class="num">'+(f.pages||'—')+
|
||||||
'</td><td class="num">'+size(f.source_size_mb)+'</td><td class="num">'+size(f.result_size_mb)+
|
'</td><td class="num">'+size(f.source_size_mb)+'</td><td class="num">'+size(f.result_size_mb)+
|
||||||
'</td><td>'+esc(f.quality||'—')+'</td><td>'+(f.ocr?'✓':'')+'</td><td>'+srcPill+'</td></tr>';
|
'</td><td>'+esc(f.quality||'—')+'</td><td>'+esc(f.stitching||'—')+'</td><td>'+(f.ocr?'✓':'')+'</td><td>'+srcPill+'</td></tr>';
|
||||||
}).join('') : '<tr><td colspan="8" class="muted">Пока нет документов</td></tr>';
|
}).join('') : '<tr><td colspan="9" class="muted">Пока нет документов</td></tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
function showGate(err){
|
function showGate(err){
|
||||||
@@ -2934,7 +2934,7 @@ def _admin_collect_stats() -> dict:
|
|||||||
pages_expr = "COALESCE(NULLIF(pages_total,0), num_pages, 0)" if "pages_total" in cols else "COALESCE(num_pages,0)"
|
pages_expr = "COALESCE(NULLIF(pages_total,0), num_pages, 0)" if "pages_total" in cols else "COALESCE(num_pages,0)"
|
||||||
docs = [dict(r) for r in con.execute(
|
docs = [dict(r) for r in con.execute(
|
||||||
f"SELECT date, time, COALESCE(NULLIF(original_name,''), name_or_f) AS name, {pages_expr} AS pages, "
|
f"SELECT date, time, COALESCE(NULLIF(original_name,''), name_or_f) AS name, {pages_expr} AS pages, "
|
||||||
"source_size_mb, result_size_mb, quality, ocr, user_id, url_res_f "
|
"source_size_mb, result_size_mb, quality, stitching, ocr, user_id, url_res_f "
|
||||||
"FROM FILES ORDER BY rowid DESC LIMIT 150")]
|
"FROM FILES ORDER BY rowid DESC LIMIT 150")]
|
||||||
agg = con.execute(
|
agg = con.execute(
|
||||||
f"SELECT COUNT(*) c, COALESCE(SUM({pages_expr}),0) p, "
|
f"SELECT COUNT(*) c, COALESCE(SUM({pages_expr}),0) p, "
|
||||||
@@ -2956,7 +2956,7 @@ def _build_docs_csv() -> bytes:
|
|||||||
buf = io.StringIO()
|
buf = io.StringIO()
|
||||||
w = csv.writer(buf, delimiter=";")
|
w = csv.writer(buf, delimiter=";")
|
||||||
w.writerow(["Дата", "Время", "Файл", "Страниц", "Исходник, МБ",
|
w.writerow(["Дата", "Время", "Файл", "Страниц", "Исходник, МБ",
|
||||||
"Результат, МБ", "Качество", "OCR", "Источник", "Статус"])
|
"Результат, МБ", "Качество", "Сшивка", "OCR", "Источник", "Статус"])
|
||||||
def _mb(v):
|
def _mb(v):
|
||||||
return ("%.2f" % v) if v else ""
|
return ("%.2f" % v) if v else ""
|
||||||
with sqlite3.connect(DB_PATH, timeout=30) as con:
|
with sqlite3.connect(DB_PATH, timeout=30) as con:
|
||||||
@@ -2965,11 +2965,11 @@ def _build_docs_csv() -> bytes:
|
|||||||
pages_expr = "COALESCE(NULLIF(pages_total,0), num_pages, 0)" if "pages_total" in cols else "COALESCE(num_pages,0)"
|
pages_expr = "COALESCE(NULLIF(pages_total,0), num_pages, 0)" if "pages_total" in cols else "COALESCE(num_pages,0)"
|
||||||
for r in con.execute(
|
for r in con.execute(
|
||||||
f"SELECT date, time, COALESCE(NULLIF(original_name,''), name_or_f) AS name, {pages_expr} AS pages, "
|
f"SELECT date, time, COALESCE(NULLIF(original_name,''), name_or_f) AS name, {pages_expr} AS pages, "
|
||||||
"source_size_mb, result_size_mb, quality, ocr, user_id, url_res_f FROM FILES ORDER BY rowid DESC"):
|
"source_size_mb, result_size_mb, quality, stitching, ocr, user_id, url_res_f FROM FILES ORDER BY rowid DESC"):
|
||||||
src = "сайт" if (r["user_id"] == WEB_USER_ID) else "бот"
|
src = "сайт" if (r["user_id"] == WEB_USER_ID) else "бот"
|
||||||
w.writerow([r["date"] or "", (r["time"] or "")[:8], r["name"] or "", r["pages"] or "",
|
w.writerow([r["date"] or "", (r["time"] or "")[:8], r["name"] or "", r["pages"] or "",
|
||||||
_mb(r["source_size_mb"]), _mb(r["result_size_mb"]), r["quality"] or "",
|
_mb(r["source_size_mb"]), _mb(r["result_size_mb"]), r["quality"] or "",
|
||||||
"да" if r["ocr"] else "", src, r["url_res_f"] or ""])
|
r["stitching"] or "", "да" if r["ocr"] else "", src, r["url_res_f"] or ""])
|
||||||
return ("" + buf.getvalue()).encode("utf-8") # BOM → кириллица в Excel
|
return ("" + buf.getvalue()).encode("utf-8") # BOM → кириллица в Excel
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user