Watch EPIRent version and archive its download packages

- Poll the public download page for "Aktuelle Version <nr> vom <date>",
  report changes through the normal change feed and notification mail,
  and show the current version as a card on the overview. Runs on its own
  interval (default 30 min); the first run only records a baseline.
- Archive epirentServer.zip / epirentClient.zip per version number so we
  keep a download cache and history: streamed to disk with SHA-256 and
  size, fetched in a background thread so ticket polling is unaffected,
  with a free-space check before downloading (~1.1 GB per version).
- Retention is configurable via EPIRENT_DOWNLOAD_KEEP, where 0 means
  unlimited; a successful archive is reported as a change and by mail.
- New Downloads page listing the archived versions with checksums and
  links to fetch the cached files.
- Notification lines now omit the arrow when there is no previous value
  and drop the "#" for entries without a ticket.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 15:12:48 +02:00
co-authored by Claude Opus 4.8
parent 528d66b2b0
commit bdcb17285c
13 changed files with 575 additions and 10 deletions
+41
View File
@@ -0,0 +1,41 @@
{% extends "base.html" %}
{% block title %}Downloads · EPI-Support{% endblock %}
{% block content %}
<section class="panel">
<div class="panel-head">
<h2>EPIRent Download-Archiv</h2>
{% if current %}
<span class="hint-inline">aktuelle Version: <b>{{ current.version }}</b> vom {{ current.released_at }}</span>
{% endif %}
</div>
{% if versions %}
{% for v in versions %}
<div class="dl-version">
<div class="dl-head">
<span class="dl-ver">Version {{ v.version }}</span>
<span class="dl-meta">{{ human(v.total) }} · gesichert am {{ v.downloaded_at|dt }}</span>
</div>
<ul class="dl-files">
{% for f in v.files %}
<li>
<a href="{{ url_for('download_file', version=v.version, filename=f.filename) }}">⬇ {{ f.filename }}</a>
<span class="dl-size">{{ human(f.size) }}</span>
{% if f.sha256 %}<code class="dl-hash" title="SHA-256">{{ f.sha256[:16] }}…</code>{% endif %}
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
{% if keep and keep > 0 %}
<p class="hint">Es werden die letzten <b>{{ keep }}</b> Versionsstände aufbewahrt; ältere werden automatisch gelöscht.</p>
{% else %}
<p class="hint">Aufbewahrung: <b>unbegrenzt</b> es wird nichts automatisch gelöscht (ca. 1,1 GB je Stand).</p>
{% endif %}
{% else %}
<p class="muted">Noch keine Pakete archiviert. Der Poller lädt sie im Hintergrund,
sobald eine Version bekannt ist (ca. 1,1 GB pro Stand das dauert einen Moment).</p>
{% endif %}
</section>
{% endblock %}