]> git.ipfire.org Git - ipfire.org.git/commitdiff
accounts: Export the jpegPhoto LDAP attribute
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 17 Mar 2015 13:09:30 +0000 (14:09 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 17 Mar 2015 13:09:30 +0000 (14:09 +0100)
This adds the functionality to link to the avatar of a certain
user. The image is taken from the LDAP database and resized as
requested. If no image was found, the client will be redirected
to gravatar.

webapp/__init__.py
webapp/backend/accounts.py
webapp/backend/base.py
webapp/handlers.py
webapp/handlers_accounts.py [new file with mode: 0644]

index 87cebb2ad7fcb937000764b3265750c1d2772e0d..22e4e0d81d181137f93783e439b8b739ec70b642 100644 (file)
@@ -255,6 +255,11 @@ class Application(tornado.web.Application):
                        (r"/trunks", TalkTrunksHandler),
                ] + authentication_handlers + static_handlers)
 
+               # accounts.ipfire.org
+               self.add_handlers(r"accounts(\.dev)?\.ipfire\.org", [
+                       (r"/avatar/(\w+)\.jpg", AccountsAvatarHandler),
+               ] + static_handlers)
+
                # admin.ipfire.org
                self.add_handlers(r"admin(\.dev)?\.ipfire\.org", [
                        (r"/", AdminIndexHandler),
@@ -302,7 +307,8 @@ class Application(tornado.web.Application):
                        if not configfile:
                                raise RuntimeException("Could not find configuration file")
 
-                       self.__backend = backend.Backend(configfile=configfile)
+                       self.__backend = backend.Backend(configfile=configfile,
+                               debug=self.settings.get("debug", False))
 
                return self.__backend
 
index d67fc6176c32a91e0fa93be9fa94342455ea548f..e3b70f551cb032b959282e7e738563ede04da508 100644 (file)
@@ -1,6 +1,8 @@
 #!/usr/bin/python
 # encoding: utf-8
 
+import PIL
+import StringIO
 import hashlib
 import ldap
 import logging
@@ -236,20 +238,8 @@ class Account(Object):
                        if mail.startswith("%s@ipfire.org" % name):
                                return mail
 
-               raise Exception, "Cannot figure out email address"
-
-       def gravatar_icon(self, size=128):
-               try:
-                       gravatar_email = self.email.lower()
-               except:
-                       gravatar_email = "nobody@ipfire.org"
-
-               # construct the url
-               gravatar_url = "http://www.gravatar.com/avatar/" + \
-                       hashlib.md5(gravatar_email).hexdigest() + "?"
-               gravatar_url += urllib.urlencode({'d': "mm", 's': str(size)})
-
-               return gravatar_url
+               # If everything else fails, we will go with the UID
+               return "%s@ipfire.org" % self.uid
 
        @property
        def sip_id(self):
@@ -286,6 +276,62 @@ class Account(Object):
        def telephone_numbers(self):
                return self.attributes.get("telephoneNumber")
 
+       def avatar_url(self, size=None):
+               if self.backend.debug:
+                       hostname = "accounts.dev.ipfire.org"
+               else:
+                       hostname = "accounts.ipfire.org"
+
+               url = "http://%s/avatar/%s.jpg" % (hostname, self.uid)
+
+               if size:
+                       url += "?size=%s" % size
+
+               return url
+
+       gravatar_icon = avatar_url
+
+       def get_avatar(self, size=None):
+               avatar = self._get_first_attribute("jpegPhoto")
+               if not avatar:
+                       return
+
+               if not size:
+                       return avatar
+
+               return self._resize_avatar(avatar, size)
+
+       def _resize_avatar(self, image, size):
+               image = StringIO.StringIO(image)
+               image = PIL.Image.open(image)
+
+               # Resize the image to the desired resolution
+               image.thumbnail((size, size), PIL.Image.ANTIALIAS)
+
+               f = StringIO.StringIO()
+
+               # If writing out the image does not work with optimization,
+               # we try to write it out without any optimization.
+               try:
+                       image.save(f, "JPEG", optimize=True)
+               except:
+                       image.save(f, "JPEG")
+
+               return f.getvalue()
+
+       def get_gravatar_url(self, size=128):
+               try:
+                       gravatar_email = self.email.lower()
+               except:
+                       gravatar_email = "nobody@ipfire.org"
+
+               # construct the url
+               gravatar_url = "http://www.gravatar.com/avatar/" + \
+                       hashlib.md5(gravatar_email).hexdigest() + "?"
+               gravatar_url += urllib.urlencode({'d': "mm", 's': str(size)})
+
+               return gravatar_url
+
 
 if __name__ == "__main__":
        a = Accounts()
index 1878e836ce3d98b92ec5ceb3cfb2f09308753f88..6cdb5a457d06d2499b2b4d13b74ac00f2622c38e 100644 (file)
@@ -21,9 +21,10 @@ import tracker
 import wishlist
 
 class Backend(object):
-       def __init__(self, configfile):
+       def __init__(self, configfile, debug=False):
                # Read configuration file.
                self.config = self.read_config(configfile)
+               self.debug = debug
 
                # Setup database.
                self.setup_database()
index 7d662dd8cd137c988f0f8fb459fbe1fcab712db5..8a082b0f96baac1283593ee129fca4708b5a9995 100644 (file)
@@ -15,6 +15,7 @@ import tornado.web
 
 import backend
 
+from handlers_accounts import *
 from handlers_admin import *
 from handlers_base import *
 from handlers_boot import *
diff --git a/webapp/handlers_accounts.py b/webapp/handlers_accounts.py
new file mode 100644 (file)
index 0000000..bc419fd
--- /dev/null
@@ -0,0 +1,46 @@
+#!/usr/bin/python
+
+import logging
+import tornado.web
+
+from handlers_base import *
+
+class AccountsAvatarHandler(BaseHandler):
+       def get(self, who):
+               # Get the desired size of the avatar file
+               size = self.get_argument("size", 0)
+
+               try:
+                       size = int(size)
+               except (TypeError, ValueError):
+                       size = None
+
+               # Cache handle
+               cache_handle = "accounts-avatar-%s-%s" % (who, size or 0)
+               avatar = self.memcached.get(cache_handle)
+
+               if not avatar:
+                       logging.debug("Querying for avatar of %s" % who)
+
+                       account = self.backend.accounts.get_by_uid(who)
+                       if not account:
+                               raise tornado.web.HTTPError(404)
+
+                       avatar = account.get_avatar(size)
+
+                       # Save the avatar to cache for 6 hours
+                       if avatar:
+                               self.memcached.set(cache_handle, avatar, 6 * 3600)
+
+                       # Otherwise redirect to gravatar
+                       else:
+                               avatar = account.get_gravatar_url(size)
+
+               if avatar.startswith("http://"):
+                       return self.redirect(avatar)
+
+               self.set_header("Cache-Control", "public,max-age=300")
+               self.set_header("Content-Disposition", "inline; filename=\"%s.jpg\"" % who)
+               self.set_header("Content-Type", "image/jpeg")
+
+               self.finish(avatar)