This repository has been archived by the owner on Jun 22, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtrack_pyteam_email_addresses.py
137 lines (110 loc) · 4.37 KB
/
track_pyteam_email_addresses.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python3
#
# Keep track of the Python Team email address harmonization to tracker
#
# Copyright (c) 2021 Sandro Tosi <[email protected]>
# License: MIT
import datetime
import email.utils
import json
from collections import defaultdict
import dateutil
import matplotlib.dates as mdates
import matplotlib.patches as mpatches
import psycopg2
from matplotlib import pyplot as plt
DATAFILE = 'data/pyteam_email_addresses.json'
TODAY = datetime.date.today().isoformat()
DATA = json.loads(open(DATAFILE).read())
MAINT_QUERY = """
SELECT maintainer_email, source, version
FROM sources
WHERE release = 'sid'
AND maintainer_email LIKE '%python%'
AND maintainer_email NOT IN ('[email protected]', '[email protected]')
AND source != 'sphinx';
"""
UPLDR_QUERY = """
SELECT uploaders, source, version
FROM sources
WHERE release = 'sid'
AND uploaders LIKE '%python%';
"""
conn = psycopg2.connect("postgresql://udd-mirror:[email protected]/udd")
conn.set_client_encoding('UTF-8')
cursor = conn.cursor()
# process Maintainers
cursor.execute(MAINT_QUERY)
todaydata = cursor.fetchall()
data = defaultdict(list)
for emailaddr, source, version in todaydata:
data[emailaddr].append((source, version))
# process Uploaders
cursor.execute(UPLDR_QUERY)
todaydata = cursor.fetchall()
# the field can contain multiple address, so we need to parse it further
for emailaddrs, source, version in todaydata:
for emailaddr in emailaddrs.split(', '):
name, addr = email.utils.parseaddr(emailaddr)
if 'python' in addr and addr not in ('[email protected]', '[email protected]'):
data[addr].append((source, version))
for emailaddr, pkgs in data.items():
if emailaddr in DATA:
DATA[emailaddr][TODAY] = len(pkgs)
else:
DATA[emailaddr] = {TODAY: len(pkgs)}
with open(DATAFILE, 'w') as f:
json.dump(DATA, f, indent=2)
# Generate the progress image
plt_locator = mdates.AutoDateLocator()
plt_formatter = mdates.AutoDateFormatter(plt_locator)
fig, ax = plt.subplots()
fig.set_size_inches(16, 10)
ax.xaxis.set_major_locator(plt_locator)
ax.xaxis.set_major_formatter(plt_formatter)
# sort by "today" value
for k, v in dict(sorted(DATA.items(), key=lambda kv: kv[1].get(TODAY, 0), reverse=True)).items():
if k == "[email protected]":
continue
ax.plot(list(map(dateutil.parser.parse, DATA[k].keys())), DATA[k].values(), label=f"{k} ({v.get(TODAY, 0)})", linewidth=1.5)
ax.axvline(datetime.date(2021, 9, 5), ymin=0, ymax=1, color='red', linestyle='dashed')
ax.annotate('Added uploaders data', xy=(datetime.date(2021, 9, 5), 300), xytext=(datetime.date(2021, 9, 1), 200), arrowprops=dict(facecolor='red'), xycoords='data', color='red')
plt.xticks(rotation=18, ha='right')
plt.grid()
fig.tight_layout()
# dont draw the line for an every increasing "proper" team, just add an entry to the legend with the current value
handles, labels = ax.get_legend_handles_labels()
right_team = mpatches.Patch(alpha=0, label=f'[email protected] ({DATA["[email protected]"].get(TODAY)})')
handles.insert(0, right_team)
ax.legend(handles=handles, loc='center left')
plt.savefig('images/python_team_emails.svg')
# Generate the updated README.md page
with open('README.md.top') as f:
mdpage = f.readlines()
mdpage.extend(['', '# Packages with outdated email address', ''])
for addr in sorted(data.keys()):
if addr == '[email protected]':
continue
pkgs = data[addr]
mdpage.append(f"## `{addr}`")
mdpage.append(f"Total packages: {len(pkgs)}")
pkgs.sort(key=lambda x: x[0])
start = 1
stop = 1
_l = ['', '| # | Package | Version |', '| --- | --- | --- |']
for i, pkg in enumerate(pkgs):
stop = i + 1
_l.append(f"| {stop} | [{pkg[0]}](https://tracker.debian.org/{pkg[0]}) | {pkg[1]} |")
if stop % 50 == 0:
mdpage.extend(['<details>', f'<summary><b>{start}..{stop}</b></summary>', ''])
mdpage.extend(_l)
mdpage.append('</details>')
start = stop + 1
stop = 0
_l = ['| # | Package | Version |', '| --- | --- | --- |']
mdpage.extend(['<details>', f'<summary><b>{start}..{stop}</b></summary>', ''])
mdpage.extend(_l)
mdpage.append('</details>')
mdpage.append('')
with open('README.md', 'w') as f:
f.write('\n'.join(mdpage))