diff --git a/tahrir/__init__.py b/tahrir/__init__.py index 34eb84c..c4eeae6 100644 --- a/tahrir/__init__.py +++ b/tahrir/__init__.py @@ -1,9 +1,6 @@ import os from configparser import ConfigParser -import dogpile.cache -import dogpile.cache.util -import tahrir_api.model from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy from pyramid.config import Configurator @@ -15,20 +12,12 @@ from . import notifications from .app import get_root -from .utils import ( - make_avatar_method, - str_to_bytes, -) +from .utils import cache def main(global_config, **settings): """This function returns a Pyramid WSGI application.""" - cache = dogpile.cache.make_region( - key_mangler=lambda x: dogpile.cache.util.sha1_mangle_key(str_to_bytes(x)) - ) - tahrir_api.model.Person.avatar_url = make_avatar_method(cache) - session_cls = scoped_session( sessionmaker( bind=create_engine(settings["sqlalchemy.url"]), diff --git a/tahrir/templates/functions.mak b/tahrir/templates/functions.mak index 07a1674..a4a0dc7 100644 --- a/tahrir/templates/functions.mak +++ b/tahrir/templates/functions.mak @@ -1,3 +1,10 @@ +<%! + import functools + from tahrir.utils import get_avatar + def as_avatar(size): + return functools.partial(get_avatar, size=size) +%> + <%def name="avatar_thumbnail(person, size, cell_width, tooltip=True)">
@@ -5,7 +12,7 @@ % endif - + % if tooltip: diff --git a/tahrir/utils.py b/tahrir/utils.py index e69aef5..257253b 100644 --- a/tahrir/utils.py +++ b/tahrir/utils.py @@ -4,6 +4,8 @@ from hashlib import sha256 import dateutil.relativedelta +import dogpile.cache +import dogpile.cache.util import pyramid.threadlocal libravatar = None @@ -13,6 +15,11 @@ pass +cache = dogpile.cache.make_region( + key_mangler=lambda x: dogpile.cache.util.sha1_mangle_key(str_to_bytes(x)) +) + + def generate_badge_yaml(postdict): return ( "%YAML 1.2\n" @@ -45,55 +52,46 @@ def generate_badge_yaml(postdict): ) -def make_avatar_method(cache): - - @cache.cache_on_arguments() - def _avatar_function(email: bytes, size): - request = pyramid.threadlocal.get_current_request() - theme_name = request.registry.settings.get("tahrir.theme_name", "tahrir") - absolute_default = request.registry.settings.get( - "tahrir.default_avatar", - request.static_url(f"{theme_name}:static/img/badger_avatar.png"), - ) - - query = { - "s": size, - "d": absolute_default, - } - - if size == "responsive": - # Make it big so we can downscale it as we please - query["s"] = 312 +@cache.cache_on_arguments() +def get_avatar(email: str, size): + request = pyramid.threadlocal.get_current_request() + theme_name = request.registry.settings.get("tahrir.theme_name", "tahrir") + absolute_default = request.registry.settings.get( + "tahrir.default_avatar", + request.static_url(f"{theme_name}:static/img/badger_avatar.png"), + ) - query = urllib.parse.urlencode(query) + query = { + "s": size, + "d": absolute_default, + } - # Use md5 for emails, and sha256 for openids. - # We're really using openids, so... - # hash = md5(email).hexdigest() - hash = sha256(email).hexdigest() + if size == "responsive": + # Make it big so we can downscale it as we please + query["s"] = 312 - # TODO This next line is temporary and can be removed. We do - # libravatar ourselves here by hand to avoid pyDNS issues on epel6. - # Once those are resolved we can use pylibravatar again. - return f"https://seccdn.libravatar.org/avatar/{hash}?{query}" + query = urllib.parse.urlencode(query) - gravatar_url = f"https://secure.gravatar.com/avatar/{hash}?{query}" + # Use md5 for emails, and sha256 for openids. + # We're really using openids, so... + # hash = md5(email).hexdigest() + hash = sha256(email.encode("utf-8")).hexdigest() - if libravatar: - return libravatar.libravatar_url( - email=email, - size=size, - default=gravatar_url, - ) - else: - return gravatar_url + # TODO This next line is temporary and can be removed. We do + # libravatar ourselves here by hand to avoid pyDNS issues on epel6. + # Once those are resolved we can use pylibravatar again. + return f"https://seccdn.libravatar.org/avatar/{hash}?{query}" - def avatar_method(self, size): - # dogpile.cache can barf on unicode, so do this ourselves. - # Call the cached workhorse function - return _avatar_function(self.email.encode("utf-8"), size) + gravatar_url = f"https://secure.gravatar.com/avatar/{hash}?{query}" - return avatar_method + if libravatar: + return libravatar.libravatar_url( + email=email, + size=size, + default=gravatar_url, + ) + else: + return gravatar_url def singularize(term, value): diff --git a/tahrir/views.py b/tahrir/views.py index 785693e..48ba01a 100644 --- a/tahrir/views.py +++ b/tahrir/views.py @@ -23,7 +23,7 @@ from pyramid.view import view_config from tahrir_api.utils import convert_name_to_id -from tahrir.utils import generate_badge_yaml +from tahrir.utils import generate_badge_yaml, get_avatar def _get_user(request, id_or_nickname): @@ -915,7 +915,7 @@ def badge_rss(request): entry.description( description_template % ( - assertion.person.avatar_url(128), + get_avatar(assertion.person.email, 128), assertion.person.nickname, assertion.person.nickname, ) @@ -1070,7 +1070,7 @@ def _user_json_generator(request, user): return { "user": user.nickname, - "avatar": user.avatar_url(int(request.GET.get("size", 100))), + "avatar": get_avatar(user.email, int(request.GET.get("size", 100))), "percent_earned": user_info["percent_earned"], "assertions": assertions, "percentile": str(user_info["percentile"]),