-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathjnosy.py
100 lines (88 loc) · 3.29 KB
/
jnosy.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
"""
This module provides two helper functions used by the Javascript autocomplete
of the nosy list:
1) a simple state machine to parse the tables of the
experts index and turn them in a JSON object;
2) a function to get the list of developers as a JSON object;
"""
import urllib
try:
import json
except ImportError:
import simplejson as json
url = 'https://raw.githubusercontent.com/python/devguide/main/experts.rst'
# possible states
no_table = 0 # not parsing a table
table_header = 1 # parsing the header
table_content = 2 # parsing the content
table_end = 3 # reached the end of the table
def experts_as_json():
"""
Parse the tables of the experts index and turn them into a JSON object.
"""
data = {}
table_state = no_table
try:
page = urllib.urlopen(url)
except Exception:
# if something goes wrong just return an empty JSON object
return '{}'
for line in page:
columns = [column.strip() for column in line.split(' ', 1)]
# all the tables have 2 columns (some entries might not have experts,
# so we just skip them)
if len(columns) != 2:
continue
first, second = columns
# check if we found a table separator
if set(first) == set(second) == set('='):
table_state += 1
if table_state == table_end:
table_state = no_table
continue
if table_state == table_header:
# create a dict for the category (e.g. 'Modules', 'Interest areas')
category = first
data[category] = {}
if table_state == table_content:
# add to the category dict the entries for that category
# (e.g.module names) and the list of experts
# if the entry is empty the names belong to the previous entry
entry = first or entry
names = (name.strip(' *') for name in second.split(','))
names = ','.join(name for name in names if '(inactive)' not in name)
if not first:
data[category][entry] += names
else:
data[category][entry] = names
return json.dumps(data, separators=(',',':'))
def committers_as_json(cls):
"""
Generate a JSON object that contains the username and realname of all
the committers.
"""
users = []
for user in cls.filter(None, {'iscommitter': 1}):
username = user.username.plain()
realname = user.realname.plain()
if not realname:
continue
users.append([username, realname])
return json.dumps(users, separators=(',',':'))
def devs_as_json(cls):
"""
Generate a JSON object that contains the username and realname of all
the user with the Developer role that are not committers.
"""
users = []
for user in cls.filter(None, {'roles': 'Developer', 'iscommitter': 0}):
username = user.username.plain()
realname = user.realname.plain()
if not realname:
continue
users.append([username, realname])
return json.dumps(users, separators=(',',':'))
def init(instance):
instance.registerUtil('experts_as_json', experts_as_json)
instance.registerUtil('committers_as_json', committers_as_json)
instance.registerUtil('devs_as_json', devs_as_json)