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:
+25
-3
@@ -9,9 +9,10 @@ from datetime import datetime, timedelta, timezone
|
||||
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
|
||||
|
||||
from flask import (Flask, Response, abort, flash, redirect, render_template,
|
||||
request, url_for)
|
||||
request, send_file, url_for)
|
||||
|
||||
from . import analytics, charts, config, conversation, db, export, poller, uploads
|
||||
from . import (analytics, charts, config, conversation, db, downloads, epirent,
|
||||
export, poller, uploads)
|
||||
from .zammad import ZammadClient, ZammadError
|
||||
|
||||
log = logging.getLogger("episupport.web")
|
||||
@@ -201,7 +202,8 @@ def create_app() -> Flask:
|
||||
stats=stats, recent=recent, last_run=last_run,
|
||||
active_state=state, sort=sort, dir=direction,
|
||||
unseen_map=unseen_map, show_archived=show_archived,
|
||||
archived_count=archived_count)
|
||||
archived_count=archived_count,
|
||||
epirent_version=epirent.current())
|
||||
|
||||
@app.route("/ticket/<int:ticket_id>")
|
||||
def ticket_detail(ticket_id):
|
||||
@@ -447,6 +449,26 @@ def create_app() -> Flask:
|
||||
headers={"Content-Disposition": f'attachment; filename="{fname}"'},
|
||||
)
|
||||
|
||||
@app.route("/downloads")
|
||||
def downloads_view():
|
||||
return render_template("downloads.html",
|
||||
versions=downloads.history(),
|
||||
human=downloads.human_size,
|
||||
keep=config.EPIRENT_DOWNLOAD_KEEP,
|
||||
current=epirent.current())
|
||||
|
||||
@app.route("/downloads/<version>/<path:filename>")
|
||||
def download_file(version, filename):
|
||||
# nur bekannte, in der DB verzeichnete Dateien ausliefern
|
||||
entry = next((r for r in downloads.archived(version)
|
||||
if r["filename"] == filename), None)
|
||||
if not entry:
|
||||
abort(404)
|
||||
path = downloads.version_dir(version) / filename
|
||||
if not path.exists():
|
||||
abort(404)
|
||||
return send_file(path, as_attachment=True, download_name=filename)
|
||||
|
||||
@app.route("/health")
|
||||
def health():
|
||||
with db.get_conn() as conn:
|
||||
|
||||
Reference in New Issue
Block a user