submodules: address pylint warnings
[git-cola.git] / cola / gravatar.py
blob94d1b9cca43b798fdd3bba1ff5b418fb33a419d3
1 from __future__ import division, absolute_import, unicode_literals
2 import time
3 import hashlib
5 from qtpy import QtCore
6 from qtpy import QtGui
7 from qtpy import QtWidgets
8 from qtpy import QtNetwork
10 from . import core
11 from . import icons
12 from .compat import bstr
13 from .compat import ustr
14 from .compat import parse
15 from .widgets import defs
18 class Gravatar(object):
19 @staticmethod
20 def url_for_email(email, imgsize):
21 email_hash = core.decode(hashlib.md5(core.encode(email)).hexdigest())
22 # Python2.6 requires byte strings for urllib2.quote() so we have
23 # to force
24 default_url = 'https://git-cola.github.io/images/git-64x64.jpg'
25 encoded_url = parse.quote(core.encode(default_url), core.encode(''))
26 query = '?s=%d&d=%s' % (imgsize, core.decode(encoded_url))
27 url = 'https://gravatar.com/avatar/' + email_hash + query
28 return url
31 class GravatarLabel(QtWidgets.QLabel):
32 def __init__(self, parent=None):
33 QtWidgets.QLabel.__init__(self, parent)
35 self.email = None
36 self.response = None
37 self.timeout = 0
38 self.imgsize = defs.medium_icon
39 self.pixmaps = {}
40 self._default_pixmap_bytes = None
42 self.network = QtNetwork.QNetworkAccessManager()
43 # pylint: disable=no-member
44 self.network.finished.connect(self.network_finished)
46 def set_email(self, email):
47 if email in self.pixmaps:
48 self.setPixmap(self.pixmaps[email])
49 return
50 if self.timeout > 0 and (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 if self._default_pixmap_bytes is None:
65 xres = self.imgsize
66 pixmap = icons.cola().pixmap(xres)
67 byte_array = QtCore.QByteArray()
68 buf = QtCore.QBuffer(byte_array)
69 buf.open(QtCore.QIODevice.WriteOnly)
70 pixmap.save(buf, 'PNG')
71 buf.close()
72 self._default_pixmap_bytes = byte_array
73 else:
74 byte_array = self._default_pixmap_bytes
75 return byte_array
77 def network_finished(self, reply):
78 email = self.email
80 header = QtCore.QByteArray(bstr('Location'))
81 location = ustr(reply.rawHeader(header)).strip()
82 if location:
83 request_location = Gravatar.url_for_email(self.email, self.imgsize)
84 relocated = location != request_location
85 else:
86 relocated = False
88 if reply.error() == QtNetwork.QNetworkReply.NoError:
89 if relocated:
90 # We could do get_url(parse.unquote(location)) to
91 # download the default image.
92 # Save bandwidth by using a pixmap.
93 self.response = self.default_pixmap_as_bytes()
94 else:
95 self.response = reply.readAll()
96 self.timeout = 0
97 else:
98 self.response = self.default_pixmap_as_bytes()
99 self.timeout = int(time.time())
101 pixmap = self.set_pixmap_from_response()
103 # If the email has not changed (e.g. no other requests)
104 # then we know that this pixmap corresponds to this specific
105 # email address. We can't blindly trust self.email else
106 # we may add cache entries for thee wrong email address.
107 url = Gravatar.url_for_email(email, self.imgsize)
108 if url == reply.url().toString():
109 self.pixmaps[email] = pixmap
111 def set_pixmap_from_response(self):
112 if self.response is None:
113 self.response = self._default_pixmap_bytes()
114 pixmap = QtGui.QPixmap()
115 pixmap.loadFromData(self.response)
116 self.setPixmap(pixmap)
117 return pixmap