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

1import requests 

2from django.http import HttpResponse, HttpResponseRedirect 

3from django.core.cache import cache 

4 

5 

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) 

14 

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 

21 

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. 

25 

26 # Fetch from libravatar 

27 url = f"https://cdn.libravatar.org/avatar/{email_hash}?s={size}&d=mm" 

28 

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 ) 

37 

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 

45 

46 return HttpResponseRedirect(url)