135 lines
5.2 KiB
Python
135 lines
5.2 KiB
Python
"""queries/documenti.py — sessione_documenti con join sessione"""
|
|
|
|
from .db import query, e, dt
|
|
|
|
|
|
_STATUS_BADGE = {
|
|
'trovato': '<span class="badge doc-trovato">trovato</span>',
|
|
'caricato': '<span class="badge doc-caricato">caricato</span>',
|
|
'errore': '<span class="badge doc-errore">errore</span>',
|
|
'warning': '<span class="badge doc-warning">warning</span>',
|
|
}
|
|
|
|
|
|
def get_documenti(db_path: str) -> list:
|
|
sql = """
|
|
SELECT
|
|
sd.sessione_id,
|
|
s.corso,
|
|
s.azienda,
|
|
sd.subfolder,
|
|
sd.doc_type,
|
|
sd.doc_status,
|
|
sd.filename,
|
|
sd.note,
|
|
sd.sp_web_url,
|
|
sd.uploaded_at
|
|
FROM sessione_documenti sd
|
|
LEFT JOIN sessione s ON s.id = sd.sessione_id
|
|
ORDER BY sd.sessione_id, sd.subfolder, sd.filename
|
|
"""
|
|
return query(db_path, sql)
|
|
|
|
|
|
def get_stats(db_path: str) -> dict:
|
|
rows = get_documenti(db_path)
|
|
return {
|
|
'doc_trovato': sum(1 for r in rows if r['doc_status'] == 'trovato'),
|
|
'doc_caricato': sum(1 for r in rows if r['doc_status'] == 'caricato'),
|
|
'doc_errore': sum(1 for r in rows if r['doc_status'] == 'errore'),
|
|
'doc_sessioni': len({r['sessione_id'] for r in rows}),
|
|
}
|
|
|
|
|
|
def render_page(rows: list) -> str:
|
|
if not rows:
|
|
return '<p class="empty-msg">Nessun documento registrato.</p>'
|
|
|
|
# Group by sessione_id
|
|
sessions: dict = {}
|
|
order: list = []
|
|
for r in rows:
|
|
sid = r['sessione_id']
|
|
if sid not in sessions:
|
|
sessions[sid] = {'corso': r['corso'], 'azienda': r['azienda'], 'docs': []}
|
|
order.append(sid)
|
|
sessions[sid]['docs'].append(r)
|
|
|
|
html_parts = []
|
|
for sid in order:
|
|
s = sessions[sid]
|
|
docs = s['docs']
|
|
n_trovato = sum(1 for d in docs if d['doc_status'] == 'trovato')
|
|
n_caricato = sum(1 for d in docs if d['doc_status'] == 'caricato')
|
|
n_errore = sum(1 for d in docs if d['doc_status'] == 'errore')
|
|
n_warning = sum(1 for d in docs if d['doc_status'] == 'warning')
|
|
|
|
counts_html = (
|
|
(f'<span class="cnt cnt-caricato">{n_caricato} caricati</span>' if n_caricato else '')
|
|
+ (f'<span class="cnt cnt-trovato">{n_trovato} trovati</span>' if n_trovato else '')
|
|
+ (f'<span class="cnt cnt-warning">{n_warning} warning</span>' if n_warning else '')
|
|
+ (f'<span class="cnt cnt-errore">{n_errore} errori</span>' if n_errore else '')
|
|
)
|
|
|
|
tbody_rows = ''
|
|
for d in docs:
|
|
status = d['doc_status'] or ''
|
|
badge_html = _STATUS_BADGE.get(status, f'<span class="badge">{e(status)}</span>')
|
|
if d['sp_web_url']:
|
|
sp_cell = (
|
|
f'<a href="{e(d["sp_web_url"])}" target="_blank" rel="noopener"'
|
|
f' class="sp-link" title="Apri su SharePoint">🔗</a>'
|
|
)
|
|
else:
|
|
sp_cell = '<span class="sp-missing" title="Non caricato su SharePoint">❌</span>'
|
|
fn = d["filename"]
|
|
if fn and fn.startswith("[") and fn.endswith("]"):
|
|
fn_cell = f'<span style=\'color:#f97316;\'>{e(fn)}</span>'
|
|
else:
|
|
fn_cell = e(fn)
|
|
tbody_rows += (
|
|
f'<tr class="doc-row doc-{e(status)}"'
|
|
f' data-filename="{e(d["filename"] or "")}"'
|
|
f' data-doctype="{e(d["doc_type"] or "")}"'
|
|
f' data-subfolder="{e(d["subfolder"] or "")}"'
|
|
f' data-status="{e(status)}"'
|
|
f' data-note="{e(d["note"] or "")}"'
|
|
f' data-uploaded="{e(dt(d["uploaded_at"]) if status == "caricato" else "")}">'
|
|
f'<td class="col-filename" title="{e(d["filename"] or "")}">{fn_cell}</td>'
|
|
f'<td class="col-doctype">{e(d["doc_type"])}</td>'
|
|
f'<td class="col-subfolder">{e(d["subfolder"])}</td>'
|
|
f'<td class="col-status">{badge_html}</td>'
|
|
f'<td class="col-sp">{sp_cell}</td>'
|
|
f'<td class="col-note">{e(d["note"])}</td>'
|
|
f'<td class="col-uploaded">{dt(d["uploaded_at"]) if status == "caricato" else "-"}</td>'
|
|
f'</tr>'
|
|
)
|
|
|
|
subtable = (
|
|
'<table class="doc-subtable">'
|
|
'<thead><tr>'
|
|
'<th>File</th><th>Tipo</th><th>Cartella</th>'
|
|
'<th>Stato</th><th>SP</th><th>Note</th><th>Caricato</th>'
|
|
'</tr></thead>'
|
|
f'<tbody>{tbody_rows}</tbody>'
|
|
'</table>'
|
|
)
|
|
|
|
open_attr = ' open' if (n_errore > 0 or n_warning > 0) else ''
|
|
html_parts.append(
|
|
f'<details class="sess-block"{open_attr}'
|
|
f' data-sessione="{e(sid)}"'
|
|
f' data-corso="{e(s["corso"])}"'
|
|
f' data-azienda="{e(s["azienda"])}">'
|
|
f'<summary class="sess-summary">'
|
|
f'<span class="sess-id">#{e(sid)}</span>'
|
|
f'<span class="sess-corso">{e(s["corso"])}</span>'
|
|
f'<span class="sess-azienda">{e(s["azienda"])}</span>'
|
|
f'<span class="sess-counts">{counts_html}</span>'
|
|
f'</summary>'
|
|
f'<div class="sess-docs">{subtable}</div>'
|
|
f'</details>'
|
|
)
|
|
|
|
return '\n'.join(html_parts)
|