-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
98 lines (73 loc) · 2.56 KB
/
main.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
from flask import Flask, render_template, redirect, request, abort
from notion.client import NotionClient
from os import getenv
import json
app = Flask(__name__)
width = 380
height = 220
default_labels = ['Not Started', 'In Progress', 'Done']
client = NotionClient(token_v2=getenv('TOKEN_V2'))
URL_BASE = 'https://www.notion.so/businesstime/{}?v={}'
CHART_URL = f"https://quickchart.io/chart?w={width}&h={height}&bkg=white&c="
def remove_non_ascii(string):
return bytes(string, 'utf-8').decode('ascii', 'ignore')
def get_stats(collection, view, labels, prop):
try:
cv = client.get_collection_view(URL_BASE.format(collection, view))
except Exception as e:
if str(e) == 'Invalid collection view URL':
raise Exception('Bad view')
raise
elems = {label: 0 for label in labels}
rows = cv.default_query().execute()
if not rows or not prop in [x['slug'] for x in rows[0].schema]:
abort(404, f'No {prop} found in the response.')
for row in rows:
values = row.get_property(prop)
if not values:
continue
elif not isinstance(values, list):
values = values.split(',')
for value in values:
if value in elems:
elems[value] += 1
else:
elems[list(elems.keys())[-1]] += 1
return elems, cv.name
def get_labels(request):
labels = request.args.get('l')
if labels:
return labels.split('|')
return default_labels
@app.route('/chart-image/<collection>/<view>')
def get_chart_image(collection, view):
labels = get_labels(request)
selector = request.args.get('p', 'status')
elems, _ = get_stats(collection, view, labels, selector)
data = {
'type': 'pie',
'data': {
'labels': list(map(remove_non_ascii, elems.keys())),
'borderWidth': 0,
'datasets': [{'data': list(elems.values())}]
},
'options': {
'plugins': {'outlabels': {'text': ''}},
'rotation': 0,
}
}
return redirect(CHART_URL + json.dumps(data))
@app.route('/chart/<collection>/<view>')
def get_chart(collection, view):
dark_mode = 'dark' in request.args
labels = get_labels(request)
selector = request.args.get('p', 'status')
elems, title = get_stats(collection, view, labels, selector)
return render_template(
'chart.html',
datas=json.dumps(list(elems.items())),
dark_mode=dark_mode,
title=request.args.get('title', title),
)
if __name__ == "__main__":
app.run()