qtutils: avoid None in add_items()
[git-cola.git] / cola / gravatar.py
blob5ab976da3eb075d09fcf1715a6e70636cbfe21bc
1 from __future__ import division, absolute_import, unicode_literals
3 import time
5 from PyQt4 import QtGui
6 from PyQt4 import QtCore
7 from PyQt4 import QtNetwork
8 from PyQt4.QtCore import SIGNAL
10 from cola import core
11 from cola import icons
12 from cola.compat import ustr, urllib
13 from cola.widgets import defs
14 import hashlib
17 class Gravatar(object):
19 @staticmethod
20 def url_for_email(email, imgsize):
21 email_hash = hashlib.md5(core.encode(email)).hexdigest()
22 default_url = b'https://git-cola.github.io/images/git-64x64.jpg'
23 encoded_url = urllib.quote(default_url, b'')
24 query = '?s=%d&d=%s' % (imgsize, encoded_url)
25 url = 'https://gravatar.com/avatar/' + email_hash + query
26 return url
29 class GravatarLabel(QtGui.QLabel):
31 def __init__(self, parent=None):
32 QtGui.QLabel.__init__(self, parent)
34 self.email = None
35 self.response = None
36 self.timeout = 0
37 self.imgsize = defs.medium_icon
38 self.pixmaps = {}
40 self.network = QtNetwork.QNetworkAccessManager()
41 self.connect(self.network,
42 SIGNAL('finished(QNetworkReply*)'),
43 self.network_finished)
45 def set_email(self, email):
46 if email in self.pixmaps:
47 self.setPixmap(self.pixmaps[email])
48 return
49 if (self.timeout > 0 and
50 (int(time.time()) - self.timeout) < (5 * 60)):
51 self.set_pixmap_from_response()
52 return
53 if email == self.email and self.response is not None:
54 self.set_pixmap_from_response()
55 return
56 self.email = email
57 self.request(email)
59 def request(self, email):
60 url = Gravatar.url_for_email(email, self.imgsize)
61 self.network.get(QtNetwork.QNetworkRequest(QtCore.QUrl(url)))
63 def default_pixmap_as_bytes(self):
64 xres = self.imgsize
65 pixmap = icons.cola().pixmap(xres)
66 byte_array = QtCore.QByteArray()
67 buf = QtCore.QBuffer(byte_array)
68 buf.open(QtCore.QIODevice.WriteOnly)
69 pixmap.save(buf, 'PNG')
70 buf.close()
71 return byte_array
73 def network_finished(self, reply):
74 email = self.email
76 header = QtCore.QByteArray('Location')
77 raw_header = reply.rawHeader(header)
78 if raw_header:
79 location = ustr(QtCore.QString(raw_header)).strip()
80 request_location = ustr(
81 Gravatar.url_for_email(self.email, self.imgsize))
82 relocated = location != request_location
83 else:
84 relocated = False
86 if reply.error() == QtNetwork.QNetworkReply.NoError:
87 if relocated:
88 # We could do get_url(urllib.unquote(location)) to
89 # download the default image.
90 # Save bandwidth by using a pixmap.
91 self.response = self.default_pixmap_as_bytes()
92 else:
93 self.response = reply.readAll()
94 self.timeout = 0
95 else:
96 self.response = self.default_pixmap_as_bytes()
97 self.timeout = int(time.time())
99 pixmap = self.set_pixmap_from_response()
101 # If the email has not changed (e.g. no other requests)
102 # then we know that this pixmap corresponds to this specific
103 # email address. We can't blindly trust self.email else
104 # we may add cache entries for thee wrong email address.
105 url = Gravatar.url_for_email(email, self.imgsize)
106 if url == ustr(reply.url().toString()):
107 self.pixmaps[email] = pixmap
109 def set_pixmap_from_response(self):
110 pixmap = QtGui.QPixmap()
111 pixmap.loadFromData(self.response)
112 self.setPixmap(pixmap)
113 return pixmap