queue_stopped #3
@@ -508,7 +508,7 @@ def tracker_favicon(domain: str):
|
|||||||
enabled = bool(prefs and prefs.get("tracker_favicons_enabled"))
|
enabled = bool(prefs and prefs.get("tracker_favicons_enabled"))
|
||||||
static_url = tracker_cache.favicon_public_url(domain, enabled=enabled, create=True)
|
static_url = tracker_cache.favicon_public_url(domain, enabled=enabled, create=True)
|
||||||
if static_url:
|
if static_url:
|
||||||
# Note: The API only discovers/cache-warms the icon; the browser receives the file from /static/data/tracker_favicons/.
|
# Note: The API only discovers/cache-warms the icon; the browser receives the file from /static/tracker_favicons/.
|
||||||
return redirect(static_url, code=302)
|
return redirect(static_url, code=302)
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ TRACKER_CACHE_TTL_SECONDS = 7 * 24 * 60 * 60
|
|||||||
FAVICON_CACHE_TTL_SECONDS = 7 * 24 * 60 * 60
|
FAVICON_CACHE_TTL_SECONDS = 7 * 24 * 60 * 60
|
||||||
TRACKER_SCAN_LIMIT = 80
|
TRACKER_SCAN_LIMIT = 80
|
||||||
FAVICON_DIR = BASE_DIR / "data" / "tracker_favicons"
|
FAVICON_DIR = BASE_DIR / "data" / "tracker_favicons"
|
||||||
PUBLIC_FAVICON_BASE = "/static/data/tracker_favicons"
|
PUBLIC_FAVICON_BASE = "/static/tracker_favicons"
|
||||||
|
|
||||||
|
|
||||||
class _IconParser(HTMLParser):
|
class _IconParser(HTMLParser):
|
||||||
@@ -161,7 +161,7 @@ def summary(profile: dict, hashes: list[str], loader, scan_limit: int = TRACKER_
|
|||||||
|
|
||||||
def favicon_public_url(domain: str, enabled: bool = True, create: bool = False) -> str:
|
def favicon_public_url(domain: str, enabled: bool = True, create: bool = False) -> str:
|
||||||
"""Return the static URL for a cached tracker favicon, optionally creating it first."""
|
"""Return the static URL for a cached tracker favicon, optionally creating it first."""
|
||||||
# Note: Favicon files are stored under data/tracker_favicons and can be served by the static/data symlink.
|
# Note: Favicon files stay in data/tracker_favicons, but the browser loads them via the static/tracker_favicons symlink.
|
||||||
clean = tracker_domain(domain)
|
clean = tracker_domain(domain)
|
||||||
if not enabled or not clean:
|
if not enabled or not clean:
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -239,7 +239,7 @@
|
|||||||
function trackerFavicon(tracker){
|
function trackerFavicon(tracker){
|
||||||
const domain=typeof tracker==='string'?tracker:(tracker?.domain||'');
|
const domain=typeof tracker==='string'?tracker:(tracker?.domain||'');
|
||||||
if(!trackerFaviconsEnabled || !domain) return '<i class="fa-solid fa-bullseye"></i>';
|
if(!trackerFaviconsEnabled || !domain) return '<i class="fa-solid fa-bullseye"></i>';
|
||||||
// Note: Cached favicons are served from the static/data symlink; the API path is only a one-time cache warmer fallback.
|
// Note: Cached favicons are served from the static/tracker_favicons symlink; the API path is only a one-time cache warmer fallback.
|
||||||
const src=(typeof tracker==='object' && tracker?.favicon_url) ? tracker.favicon_url : `/api/trackers/favicon/${encodeURIComponent(domain)}`;
|
const src=(typeof tracker==='object' && tracker?.favicon_url) ? tracker.favicon_url : `/api/trackers/favicon/${encodeURIComponent(domain)}`;
|
||||||
return `<img class="tracker-favicon" src="${esc(src)}" alt="" loading="lazy" onerror="this.classList.add('d-none')"><i class="fa-solid fa-bullseye tracker-fallback-icon"></i>`;
|
return `<img class="tracker-favicon" src="${esc(src)}" alt="" loading="lazy" onerror="this.classList.add('d-none')"><i class="fa-solid fa-bullseye tracker-fallback-icon"></i>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
../../data/tracker_favicons
|
|
||||||
1
pytorrent/static/tracker_favicons
Executable file
1
pytorrent/static/tracker_favicons
Executable file
@@ -0,0 +1 @@
|
|||||||
|
../../data/tracker_favicons
|
||||||
Reference in New Issue
Block a user