Coverage for seedboxsync/front/views/settings/info.py: 100%
31 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-26 17:14 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-26 17:14 +0000
1#
2# Copyright (C) 2015-2026 Guillaume Kulakowski <guillaume@kulakowski.fr>
3#
4# For the full copyright and license information, please view the LICENSE
5# file that was distributed with this source code.
6#
7"""SeedboxSync Flask view for info."""
9from datetime import datetime
10from flask import render_template
11from humanize import filesize, precisedelta
12from peewee import fn
13from seedboxsync.__version__ import __version__ as version
14from seedboxsync.core import current_app
15from seedboxsync.core.database.models import Download, TaskStatus
16from seedboxsync.front.cache import cache
17from seedboxsync.front.login_manager import login_required
18from seedboxsync.front.views import bp_settings as bp
21@bp.route("/info")
22@bp.route("")
23@login_required # type: ignore[untyped-decorator]
24def info() -> str:
25 """
26 Render the system information view.
28 Gathers download metrics, system task statuses, database versioning,
29 and application runtime statistics (cached for 60 seconds).
31 Returns:
32 str: Rendered HTML template containing overall application information.
33 """
34 return render_template("settings/info.html", info=_get_info_data())
37@cache.memoize(timeout=60)
38def _get_info_data() -> dict[str, object]:
39 """
40 Fetch and calculate application system information.
42 Queries download metrics, background task statuses, application version,
43 and database migration metadata. Cached for 60 seconds.
45 Returns:
46 dict[str, object]: Dictionary containing gathered system statistics
47 and status flags.
48 """
49 # Download statistics
50 query_stats = Download.select().where(Download.finished != 0)
51 total_files = query_stats.count()
52 total_size = sum([d.seedbox_size for d in query_stats if d.seedbox_size])
53 sync_blackhole: TaskStatus | bool
54 sync_seedbox: TaskStatus | bool
56 # Get statues
57 keys = ["sync-blackhole", "sync-seedbox", "heartbeat"]
58 statuses = {ts.key: ts for ts in TaskStatus.select().where(TaskStatus.key.in_(keys))}
59 sync_blackhole = statuses.get("sync-blackhole", False)
60 sync_seedbox = statuses.get("sync-seedbox", False)
61 heartbeat = statuses.get("heartbeat", False)
63 # First download statistics
64 first_date = Download.select(fn.MIN(Download.finished)).where(Download.finished != 0).scalar()
65 first_delta = ""
66 if first_date is not None:
67 first_delta = datetime.now() - first_date
68 first_delta = precisedelta(first_delta, minimum_unit="days")
70 return {
71 "stats_total_files": total_files,
72 "stats_total_size": filesize.naturalsize(total_size, True),
73 "stats_first": first_date,
74 "stats_first_delta": first_delta,
75 "version": version,
76 "last_migration": current_app.config.get("LAST_MIGRATION"),
77 "sync_blackhole": sync_blackhole,
78 "sync_seedbox": sync_seedbox,
79 "heartbeat": heartbeat,
80 }