Skip to content

Commit 2343f76

Browse files
jontsaiJonathan Tsai
authored andcommitted
- Updates to use explicitly set Conduit API token, Phabricator base URL, etc
- Adds `/users` listing page and user profile page - Adds utils for fetching users: single user by user name, multiple users, all active users - Adds the ability to show metrics for specific users - Adds more colors from flatuicolors.com - Upgrades to Chart.js 3.8.0 and adds legend event hooks - cleanup: rename `*_pages` to `*_endpoints` for several view
1 parent 70a49d6 commit 2343f76

34 files changed

+477
-95
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# CHANGELOG
22

3+
## NEXT RELEASE (v3.2.0?) (2022-07-26)
4+
- Updates to use explicitly set Conduit API token, Phabricator base URL, etc
5+
- Adds `/users` listing page and user profile page
6+
- Adds utils for fetching users: single user by user name, multiple users, all active users
7+
- Adds the ability to show metrics for specific users
8+
- Adds more colors from flatuicolors.com
9+
- Upgrades to Chart.js 3.8.0 and adds legend event hooks
10+
- cleanup: rename `*_pages` to `*_endpoints` for several view
11+
312
## v3.1.2 (2022-05-21)
413
- Fixes breadcrumbs for report names by preserving case
514

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ Analytics, metrics, and reports for Phabricator (https://phacility.com/phabricat
2727
2828
# Authors and Maintainers
2929
30-
[Hacktoolkit](https://github.com/hacktoolkit) and [Jonathan Tsai](https://github.com/jontsai)
30+
- [Hacktoolkit](https://github.com/hacktoolkit)
31+
- [Jonathan Tsai](https://github.com/jontsai)
3132
3233
# License
3334

phablytics/classes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,10 @@ def customer_name(self):
246246

247247

248248
class Project(PhabricatorEntity):
249+
def __str__(self):
250+
value = f'{self.type_}: {self.name}'
251+
return value
252+
249253
@property
250254
def attachments(self):
251255
attachments = self.raw_data.get('attachments', {})

phablytics/constants/ui.py

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
# https://flatuicolors.com/palette/us
1+
# Possible sources of inspiration
2+
#
3+
# - https://flatuicolors.com/
4+
# - https://coolors.co/
5+
26
COLORS = [
7+
# https://flatuicolors.com/palette/us
38
'#55efc4',
49
'#81ecec',
510
'#74b9ff',
@@ -22,7 +27,7 @@
2227
'#d63031',
2328
'#e84393',
2429
'#2d3436',
25-
# regular flatui
30+
# https://flatuicolors.com/palette/defo
2631
'#1abc9c',
2732
'#16a085',
2833
'#f1c40f',
@@ -43,4 +48,109 @@
4348
'#2c3e50',
4449
'#95a5a6',
4550
'#7f8c8d',
51+
# https://flatuicolors.com/palette/fr
52+
'#fad390',
53+
'#f8c291',
54+
'#6a89cc',
55+
'#82ccdd',
56+
'#b8e994',
57+
'#f6b93b',
58+
'#e55039',
59+
'#4a69bd',
60+
'#60a3bc',
61+
'#78e08f',
62+
'#fa983a',
63+
'#eb2f06',
64+
'#1e3799',
65+
'#3c6382',
66+
'#38ada9',
67+
'#e58e26',
68+
'#b71540',
69+
'#0c2461',
70+
'#0a3d62',
71+
'#079992',
72+
# https://flatuicolors.com/palette/es
73+
'#40407a',
74+
'#706fd3',
75+
'#f7f1e3',
76+
'#34ace0',
77+
'#33d9b2',
78+
'#2c2c54',
79+
'#474787',
80+
'#aaa69d',
81+
'#227093',
82+
'#218c74',
83+
'#ff5252',
84+
'#ff793f',
85+
'#d1ccc0',
86+
'#ffb142',
87+
'#ffda79',
88+
'#b33939',
89+
'#cd6133',
90+
'#ccae62',
91+
'#cc8e35',
92+
'#ccae62',
93+
# https://flatuicolors.com/palette/gb
94+
'#00a8ff',
95+
'#9c88ff',
96+
'#fbc531',
97+
'#4cd137',
98+
'#487eb0',
99+
'#0097e6',
100+
'#8c7ae6',
101+
'#e1b12c',
102+
'#44bd32',
103+
'#40739e',
104+
'#e84118',
105+
'#f5f6fa',
106+
'#7f8fa6',
107+
'#273c75',
108+
'#353b48',
109+
'#c23616',
110+
'#dcdde1',
111+
'#718093',
112+
'#192a56',
113+
'#2f3640',
114+
# https://flatuicolors.com/palette/nl
115+
'#ffc312',
116+
'#c4e538',
117+
'#12cbc4',
118+
'#fda7df',
119+
'#ed4c67',
120+
'#f79f1f',
121+
'#a3cb38',
122+
'#1289a7',
123+
'#d980fa',
124+
'#b53471',
125+
'#ee5a24',
126+
'#009432',
127+
'#0652dd',
128+
'#9980fa',
129+
'#833471',
130+
'#ea2027',
131+
'#006266',
132+
'#1b1464',
133+
'#5758bb',
134+
'#6f1e51',
135+
# https://flatuicolors.com/palette/tr
136+
'#cd84f1',
137+
'#ffcccc',
138+
'#ff4d4d',
139+
'#ffaf40',
140+
'#fffa65',
141+
'#c56cf0',
142+
'#4b4b4b',
143+
'#ff3838',
144+
'#ff9f1a',
145+
'#fff200',
146+
'#32ff7e',
147+
'#7efff5',
148+
'#18dcff',
149+
'#7d5fff',
150+
'#4b4b4b',
151+
'#3ae374',
152+
'#4b4b4b',
153+
'#17c0eb',
154+
'#7158e2',
155+
'#3d3d3d',
46156
]

phablytics/metrics/metrics.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
get_project_by_name,
2424
get_tasks_closed_over_period,
2525
get_tasks_created_over_period,
26+
get_user_by_username,
2627
pluralize,
2728
)
2829

@@ -179,9 +180,14 @@ def _retrieve_task_metrics(
179180
team: str=None,
180181
customer: str=None,
181182
projects: list=None,
183+
username: str=None,
182184
*args,
183185
**kwargs
184186
):
187+
"""The params on this function should match the keys on the result of
188+
189+
`phablytics.web.metrics.forms.get_filter_params`
190+
"""
185191
now = datetime.datetime.now()
186192

187193
task_metrics = []
@@ -212,6 +218,10 @@ def _retrieve_task_metrics(
212218

213219
end = period_end
214220

221+
if username:
222+
user = get_user_by_username(username)
223+
team_member_phids = [user.phid]
224+
215225
# TODO: implement make_intervals(period_start, period_end, interval)
216226
while end > period_start:
217227
start = end - datetime.timedelta(days=interval_days)

phablytics/metrics/stats.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,15 +228,15 @@ def _build_customer_segment(self):
228228
'data': {
229229
'datasets': [
230230
{
231-
'label': 'Points completed',
232-
'name': 'Points completed',
231+
'label': 'Points Completed',
232+
'name': 'Points Completed',
233233
'data': [
234234
metric.points_completed for metric in metrics
235235
],
236236
'backgroundColor': colors,
237237
},
238238
{
239-
'label': 'Tickets Closed',
239+
'label': 'Tasks Closed',
240240
'data': [
241241
metric.num_closed for metric in metrics
242242
],
@@ -250,7 +250,7 @@ def _build_customer_segment(self):
250250
}
251251

252252
segment['metrics'] = metrics
253-
segment['chart_config_json'] = json.dumps(chart_config_json)
253+
segment['chart_config_json'] = json.dumps(chart_config_json, indent=4)
254254

255255
return segment
256256

@@ -290,20 +290,22 @@ def _build_user_segment(self):
290290
in range(len(metrics))
291291
]
292292

293-
# https://www.chartjs.org/samples/latest/charts/doughnut.html
293+
# https://www.chartjs.org/docs/latest/samples/other-charts/doughnut.html
294294
chart_config_json = {
295295
'type': 'doughnut',
296296
'data': {
297297
'datasets': [
298298
{
299-
'label': 'Points completed',
299+
'label': 'Points Completed',
300+
'name': 'Points Completed',
300301
'data': [
301302
metric.points_completed for metric in metrics
302303
],
303304
'backgroundColor': colors,
304305
},
305306
{
306-
'label': 'Tickets Closed',
307+
'label': 'Tasks Closed',
308+
'name': 'Tasks Closed',
307309
'data': [
308310
metric.num_closed for metric in metrics
309311
],
@@ -317,7 +319,7 @@ def _build_user_segment(self):
317319
}
318320

319321
segment['metrics'] = metrics
320-
segment['chart_config_json'] = json.dumps(chart_config_json)
322+
segment['chart_config_json'] = json.dumps(chart_config_json, indent=4)
321323

322324
return segment
323325

@@ -360,8 +362,8 @@ def _build_service_segment(self):
360362
'data': {
361363
'datasets': [
362364
{
363-
'label': 'Points completed',
364-
'name': 'Points completed',
365+
'label': 'Points Completed',
366+
'name': 'Points Completed',
365367
'data': [
366368
# TODO: fix this
367369
# random.randint(1, 100) for metric in metrics
@@ -370,7 +372,8 @@ def _build_service_segment(self):
370372
'backgroundColor': colors,
371373
},
372374
{
373-
'label': 'Tickets Closed',
375+
'label': 'Tasks Closed',
376+
'name': 'Tasks Closed',
374377
'data': [
375378
metric.num_closed for metric in metrics
376379
],
@@ -384,6 +387,6 @@ def _build_service_segment(self):
384387
}
385388

386389
segment['metrics'] = metrics
387-
segment['chart_config_json'] = json.dumps(chart_config_json)
390+
segment['chart_config_json'] = json.dumps(chart_config_json, indent=4)
388391

389392
return segment

phablytics/reports/group_review_status.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
)
2424

2525

26+
# isort: off
27+
28+
2629
class GroupReviewStatusReport(PhablyticsReport):
2730
"""The Group Review Status Report shows a list of Diffs with
2831
particular reviewers added.

phablytics/reports/revision_status.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
)
2222

2323

24+
# isort: off
25+
26+
2427
class RevisionStatusReport(PhablyticsReport):
2528
"""The Revision Status Report shows a list of Diffs being worked on by a team,
2629
and outputs them based on their acceptance/needs review status
@@ -38,7 +41,12 @@ def _add_users(self, phids):
3841
self.user_phids.extend(phids)
3942

4043
def _add_repo(self, phid):
41-
self.repo_phids.append(phid)
44+
if phid is not None:
45+
self.repo_phids.append(phid)
46+
else:
47+
# do nothing
48+
# likely/somehow, a diff or revision does not have an associated repository
49+
pass
4250

4351
def _lookup_phids(self):
4452
"""Build lookup tables for User and Repo phids in batch
@@ -120,11 +128,15 @@ def _format_user_phid(self, phid, slack=True):
120128
return formatted
121129

122130
def _format_and_append_revision_to_report(self, report, revision, count, slack=True):
123-
repo = self.repos_lookup[revision.repo_phid]
124-
if slack:
125-
repo_link = f'<{repo.repository_url}|{repo.slug}>'
131+
repo = self.repos_lookup.get(revision.repo_phid)
132+
133+
if repo is None:
134+
repo_link = 'N/A'
126135
else:
127-
repo_link = f'[{repo.slug}]({repo.repository_url})'
136+
if slack:
137+
repo_link = f'<{repo.repository_url}|{repo.slug}>'
138+
else:
139+
repo_link = f'[{repo.slug}]({repo.repository_url})'
128140

129141
acceptors = [f'{self._format_user_phid(phid, slack=slack)}' for phid in revision.acceptor_phids]
130142
blockers = [f'{self._format_user_phid(phid, slack=slack)}' for phid in revision.blocker_phids]

phablytics/settings.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@
1010
##
1111
# Various Settings and Configuration Variables
1212

13-
PHABLYTICS_BASE_URL = None
13+
PHABLYTICS_BASE_URL = 'configure_me'
1414
PHABRICATOR_INSTANCE_BASE_URL = 'configure_me'
15+
CONDUIT_API_TOKEN = 'configure_me'
1516

1617
ADMIN_USERNAME = 'configure_me'
1718

phablytics/utils/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# Phablytics Imports
2-
from phablytics.utils.dt import * # noqa
3-
from phablytics.utils.phab import * # noqa
4-
from phablytics.utils.strings import * # noqa
2+
from phablytics.utils.dt import *
3+
from phablytics.utils.phab import *
4+
from phablytics.utils.strings import *

0 commit comments

Comments
 (0)