Coverage for sm / views_avatars.py: 17%
23 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-24 12:43 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-24 12:43 +0000
1import requests
2from django.http import HttpResponse, HttpResponseRedirect
3from django.core.cache import cache
6def avatar_proxy(request, email_hash):
7 """
8 Proxies libravatar images to allow for aggressive browser caching.
9 """
10 size = request.GET.get("s", 80)
11 # Check cache first to avoid network hit
12 cache_key = f"avatar_{email_hash}_{size}"
13 cached_avatar = cache.get(cache_key)
15 if cached_avatar:
16 response = HttpResponse(
17 cached_avatar["content"], content_type=cached_avatar["content_type"]
18 )
19 response["Cache-Control"] = "public, max-age=604800, immutable"
20 return response
22 # Fetch from libravatar (using hash directly if possible, or we just pass through)
23 # For now, we'll just redirect to the real URL but with a script that fetches it
24 # OR we fetch it here. Fetching is better for "hiding" the slow load.
26 # Fetch from libravatar
27 url = f"https://cdn.libravatar.org/avatar/{email_hash}?s={size}&d=mm"
29 try:
30 res = requests.get(url, timeout=5)
31 if res.status_code == 200:
32 content_type = res.headers.get("Content-Type", "image/png")
33 # Cache for 1 day in Django cache
34 cache.set(
35 cache_key, {"content": res.content, "content_type": content_type}, 86400
36 )
38 response = HttpResponse(res.content, content_type=content_type)
39 response["Cache-Control"] = (
40 "public, max-age=604800, immutable" # 1 week browser cache
41 )
42 return response
43 except Exception:
44 pass
46 return HttpResponseRedirect(url)