git-cola v1.9.1
[git-cola.git] / cola / gravatar.py
blob3d38ef87557dffe10a657125a12f151b5a535e25
1 import time
2 import urllib
4 from PyQt4 import QtGui
5 from PyQt4 import QtCore
6 from PyQt4 import QtNetwork
7 from PyQt4.QtCore import Qt
8 from PyQt4.QtCore import SIGNAL
10 from cola import resources
11 from cola.compat import hashlib
14 class Gravatar(object):
15 @staticmethod
16 def url_for_email(email, imgsize):
17 email_hash = hashlib.md5(email).hexdigest()
18 default_url = 'http://git-cola.github.io/images/git-64x64.jpg'
19 encoded_url = urllib.quote(default_url, '')
20 query = '?s=%d&d=%s' % (imgsize, encoded_url)
21 url = 'http://gravatar.com/avatar/' + email_hash + query
22 return url
25 class GravatarLabel(QtGui.QLabel):
26 def __init__(self, parent=None):
27 QtGui.QLabel.__init__(self, parent)
29 self.email = None
30 self.response = None
31 self.timeout = 0
32 self.imgsize = 48
33 self.pixmaps = {}
35 self.network = QtNetwork.QNetworkAccessManager()
36 self.connect(self.network,
37 SIGNAL('finished(QNetworkReply*)'),
38 self.network_finished)
40 def set_email(self, email):
41 if email in self.pixmaps:
42 self.setPixmap(self.pixmaps[email])
43 return
44 if (self.timeout > 0 and
45 (int(time.time()) - self.timeout) < (5 * 60)):
46 self.set_pixmap_from_response()
47 return
48 if email == self.email and self.response is not None:
49 self.set_pixmap_from_response()
50 return
51 self.email = email
52 self.request(email)
54 def request(self, email):
55 url = Gravatar.url_for_email(email, self.imgsize)
56 self.network.get(QtNetwork.QNetworkRequest(QtCore.QUrl(url)))
58 def default_pixmap_as_bytes(self):
59 xres = self.imgsize
60 pixmap = QtGui.QPixmap(resources.icon('git.svg'))
61 pixmap = pixmap.scaledToHeight(xres, Qt.SmoothTransformation)
62 byte_array = QtCore.QByteArray()
63 buf = QtCore.QBuffer(byte_array)
64 buf.open(QtCore.QIODevice.WriteOnly)
65 pixmap.save(buf, 'PNG')
66 buf.close()
67 return byte_array
69 def network_finished(self, reply):
70 email = self.email
72 header = QtCore.QByteArray('Location')
73 raw_header = reply.rawHeader(header)
74 if raw_header:
75 location = unicode(QtCore.QString(raw_header)).strip()
76 request_location = unicode(
77 Gravatar.url_for_email(self.email, self.imgsize))
78 relocated = location != request_location
79 else:
80 relocated = False
82 if reply.error() == QtNetwork.QNetworkReply.NoError:
83 if relocated:
84 # We could do get_url(urllib.unquote(location)) to
85 # download the default image.
86 # Save bandwidth by using a pixmap.
87 self.response = self.default_pixmap_as_bytes()
88 else:
89 self.response = reply.readAll()
90 self.timeout = 0
91 else:
92 self.response = self.default_pixmap_as_bytes()
93 self.timeout = int(time.time())
95 pixmap = self.set_pixmap_from_response()
97 # If the email has not changed (e.g. no other requests)
98 # then we know that this pixmap corresponds to this specific
99 # email address. We can't blindly trust self.email else
100 # we may add cache entries for thee wrong email address.
101 url = Gravatar.url_for_email(email, self.imgsize)
102 if url == unicode(reply.url().toString()):
103 self.pixmaps[email] = pixmap
105 def set_pixmap_from_response(self):
106 pixmap = QtGui.QPixmap()
107 pixmap.loadFromData(self.response)
108 self.setPixmap(pixmap)
109 return pixmap