-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathavatar.py
121 lines (105 loc) · 3.37 KB
/
avatar.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import gi
gi.require_version ('Astroid', '0.2')
gi.require_version ('Gtk', '3.0')
try:
gi.require_version ('GMime', '3.0')
except ValueError:
gi.require_version ('GMime', '2.6')
from gi.repository import GObject
from gi.repository import Gtk
from gi.repository import Astroid
from gi.repository import GMime
from urllib.parse import urlencode
from hashlib import md5
from urllib.request import urlopen
from os.path import exists, expanduser, dirname
from os import unlink, makedirs
from base64 import b64encode
try:
from libravatar import libravatar_url as avatar_url
print('avatar: using libravatar')
except ImportError:
# fallback to home grown gravatar url
def avatar_url(email, https=True, size=48, default='404', ):
return 'https://www.gravatar.com/avatar/{}?{}'.format(
md5(email.encode('ascii', 'replace')).hexdigest(),
urlencode(dict(
d=default,
s=str(size),
)))
print('avatar: using gravatar')
class AvatarPlugin (GObject.Object, Astroid.ThreadViewActivatable):
object = GObject.property (type=GObject.Object)
thread_view = GObject.property (type = Gtk.Box)
def do_activate (self):
self.cache_dir = expanduser('~/.cache/astroid/avatar/')
self.config_dir = dirname(__file__)
if not exists(self.cache_dir):
makedirs(self.cache_dir)
print ('avatar: activated', __file__)
def do_deactivate (self):
print ('avatar: deactivated')
def _load(self, url, filename):
with urlopen(url, timeout=3) as response:
data = response.read()
with open(filename, 'wb') as f:
f.write(data)
return b64encode(data).decode()
def _load_preinstalled(self, name):
filename = '{}/avatar_{}.png'.format(self.config_dir, name)
if exists(filename):
print('avatar: filename=', filename)
with open(filename, 'rb') as f:
data = f.read()
return b64encode(data).decode()
def do_get_avatar_uri (self, email, type_, size, message):
# Check if message is from GitHub
github_user = message.get_header ('X-GitHub-Sender')
if github_user:
email = github_user
mime_type = 'image/png'
ext = 'png'
else:
email = email.lower()
mime_type = 'image/jpeg'
ext = 'jpg'
print('avatar:', email, type_, size)
data = self._load_preinstalled(email.split('@')[0])
if not data:
filename = '{}{}.{}'.format(self.cache_dir, email, ext)
print('avatar: filename=', filename)
if exists(filename):
# TODO check age
with open(filename, 'rb') as f:
data = f.read()
if not data: # has no avatar, give default
data = self._load_preinstalled('default')
mime_type = 'image/jpeg'
ext = 'jpg'
else:
data = b64encode(data).decode()
else:
try:
if github_user:
url = "https://github.com/%s.png" % github_user
print ('avatar: github url=', url)
data = self._load(url, filename)
else:
url = avatar_url(email, https=True, size=size, default='404', )
print('avatar: libravatar_url=', url)
data = self._load(url, filename)
except Exception as e:
print('_load: e=', e)
with open(filename, 'wb') as f: # we had an error, do neg cache (empty file)
pass
data = self._load_preinstalled('default')
else:
# pre-installed
mime_type = 'image/jpeg'
ext = 'jpg'
url = 'data:{};base64,{}'.format(mime_type, data)
return url
def do_get_allowed_uris (self):
print('do_get_allowed_uris:')
return [] # our uris are always allowed
print ('avatar: plugin loaded')