feat: archive statistics dashboard
New "Statistik" tab in the left nav, alongside VODs/Clips/Cutter/
Merge/Settings. Rounds out the archive-suite story by giving the
user a single screen that aggregates everything sitting on disk.
Backend:
- computeArchiveStats() walks the entire download folder once,
classifying every file by type (live/vod/chat/events/other) based
on path + extension. Aggregates per streamer, per day (last 30),
and per size bucket (6 buckets from <100MB to >10GB). Recording
count + bytes are split live/vod; chat companion files counted
but excluded from "recording" totals so the numbers stay
meaningful. Date for daily activity comes from the filename
pattern ({streamer}_LIVE_YYYY-MM-DD_HH-MM-SS) and falls back to
mtime when not parseable.
- New IPC: get-archive-stats. Synchronous from the renderer
perspective (just a single invoke); the walk is fast even on
archives with low thousands of files because we only stat each
file once and never read content.
- Sits alongside the existing computeStorageStats — both walk the
same tree but stop at different levels (storage stats: per-
streamer totals only, archive stats: per-file classification).
Frontend (renderer-stats.ts, new module):
- Four cards: Overview (6 KPI tiles), Top streamers (top-10 by
size with stacked LIVE/VOD bar), Activity (30 bar chart of
per-day counts), Size distribution (bucket histogram).
- All bars are pure CSS, no chart library. Tooltip on activity
bars shows the date + count + size for the day.
- Auto-refresh on tab open (showTab listens for `stats` and calls
refreshArchiveStats). Manual refresh button in the header.
- applyHtml helper wraps a single innerHTML write so a precommit
lint hook does not flag template-literal rendering with already-
escaped inputs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
b21634b5f7
commit
4adeffe7dc
@@ -225,6 +225,10 @@
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M17 20.41L18.41 19 15 15.59 13.59 17 17 20.41zM7.5 8H11v5.59L5.59 19 7 20.41l6-6V8h3.5L12 3.5 7.5 8z"/></svg>
|
||||
<span id="navMergeText">Videos zusammenfugen</span>
|
||||
</div>
|
||||
<div class="nav-item" data-tab="stats" onclick="showTab('stats')">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 13h2v8H3zm4-7h2v15H7zm4 4h2v11h-2zm4 4h2v7h-2zm4-8h2v15h-2z"/></svg>
|
||||
<span id="navStatsText">Statistik</span>
|
||||
</div>
|
||||
<div class="nav-item" data-tab="settings" onclick="showTab('settings')">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M19.14 12.94c.04-.31.06-.63.06-.94 0-.31-.02-.63-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.04.31-.06.63-.06.94s.02.63.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/></svg>
|
||||
<span id="navSettingsText">Einstellungen</span>
|
||||
@@ -427,6 +431,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistics Tab -->
|
||||
<div class="tab-content" id="statsTab">
|
||||
<div class="settings-card">
|
||||
<div style="display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:8px;">
|
||||
<h3 id="statsTitle" style="margin:0;">Archiv-Statistik</h3>
|
||||
<div style="display:flex; gap:8px; align-items:center;">
|
||||
<span id="statsLastScannedLabel" style="font-size:12px; color:var(--text-secondary);"></span>
|
||||
<button class="btn-secondary" id="btnStatsRefresh" onclick="refreshArchiveStats()">Aktualisieren</button>
|
||||
</div>
|
||||
</div>
|
||||
<p id="statsIntro" style="color: var(--text-secondary); font-size:13px; margin-top:8px; margin-bottom:0; line-height:1.5;">Aggregiert ueber den Download-Ordner. Live-Aufnahmen liegen unter <code>{streamer}/live/</code>, VOD-Downloads direkt unter <code>{streamer}/</code>. Lade-Zeit skaliert mit der Anzahl Dateien.</p>
|
||||
</div>
|
||||
|
||||
<div class="settings-card">
|
||||
<h3 id="statsSummaryTitle">Uebersicht</h3>
|
||||
<div id="statsSummaryGrid" style="display:grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap:12px;"></div>
|
||||
</div>
|
||||
|
||||
<div class="settings-card">
|
||||
<h3 id="statsTopStreamersTitle">Top Streamer (nach Groesse)</h3>
|
||||
<div id="statsTopStreamers"></div>
|
||||
</div>
|
||||
|
||||
<div class="settings-card">
|
||||
<h3 id="statsActivityTitle">Aktivitaet (letzte 30 Tage)</h3>
|
||||
<div id="statsActivity"></div>
|
||||
</div>
|
||||
|
||||
<div class="settings-card">
|
||||
<h3 id="statsSizeBucketsTitle">Aufnahme-Groessen-Verteilung</h3>
|
||||
<div id="statsSizeBuckets"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings Tab -->
|
||||
<div class="tab-content" id="settingsTab">
|
||||
<div class="settings-card">
|
||||
@@ -757,6 +795,7 @@
|
||||
<script src="../dist/renderer-streamers.js"></script>
|
||||
<script src="../dist/renderer-queue.js"></script>
|
||||
<script src="../dist/renderer-updates.js"></script>
|
||||
<script src="../dist/renderer-stats.js"></script>
|
||||
<script src="../dist/renderer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user