diff options
author | User Content <content@content.events.ccc.de> | 2019-10-30 01:11:47 +0000 |
---|---|---|
committer | User Content <content@content.events.ccc.de> | 2019-10-30 01:11:47 +0000 |
commit | e8b020e28ca377868ff8aad8418372debc910ae6 (patch) | |
tree | 53f318f05093e9cbde83e91f2c58035aedf2d7f0 /rater.py |
Initial commit
Diffstat (limited to 'rater.py')
-rwxr-xr-x | rater.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/rater.py b/rater.py new file mode 100755 index 0000000..e1ed9c5 --- /dev/null +++ b/rater.py | |||
@@ -0,0 +1,172 @@ | |||
1 | #!venv/bin/python | ||
2 | |||
3 | from flask import Flask, render_template, jsonify, request | ||
4 | from flask_sqlalchemy import SQLAlchemy | ||
5 | from lxml import etree | ||
6 | from argparse import ArgumentParser | ||
7 | import requests | ||
8 | import json | ||
9 | |||
10 | # Use this on FreeBSD when you've compiled pyopenssl with openssl from ports | ||
11 | # import urllib3.contrib.pyopenssl | ||
12 | # urllib3.contrib.pyopenssl.inject_into_urllib3() | ||
13 | |||
14 | parser = ArgumentParser(description="C3 rating helper") | ||
15 | parser.add_argument("-i", action="store_true", dest="frab_import", default=False, help="import events from frab") | ||
16 | parser.add_argument("-c", "--config", help="Config file location", default="./config.json") | ||
17 | args = parser.parse_args() | ||
18 | |||
19 | with open(args.config, mode="r", encoding="utf-8") as json_file: | ||
20 | config_data = json.load(json_file) | ||
21 | |||
22 | app = Flask(__name__) | ||
23 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+config_data.get('frab-conference')+'-'+config_data.get('track')+'.db' | ||
24 | app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | ||
25 | app.config['SECRET_KEY'] = 'Silence is golden. Gerd Eist.' | ||
26 | app.jinja_env.trim_blocks = True | ||
27 | app.jinja_env.lstrip_blocks = True | ||
28 | |||
29 | db = SQLAlchemy(app) | ||
30 | |||
31 | class Event(db.Model): | ||
32 | """An event as dumped from frab""" | ||
33 | frab_id = db.Column(db.Integer, primary_key=True) | ||
34 | title = db.Column(db.String(1024)) | ||
35 | subtitle = db.Column(db.String(1024)) | ||
36 | abstract = db.Column(db.Text()) | ||
37 | description = db.Column(db.Text()) | ||
38 | state = db.Column(db.String(64)) | ||
39 | event_type = db.Column(db.String(64)) | ||
40 | speakers = db.Column(db.String(1024)) | ||
41 | coordinator = db.Column(db.String(1024)) | ||
42 | notes = db.Column(db.Text()) | ||
43 | |||
44 | class EventRating(db.Model): | ||
45 | """A rating as given by a logged in user""" | ||
46 | id = db.Column(db.Integer, primary_key=True) | ||
47 | submitter = db.Column(db.String(1024)) | ||
48 | event_id = db.Column(db.Integer, db.ForeignKey('event.frab_id')) | ||
49 | event = db.relationship('Event', backref=db.backref('ratings', lazy='dynamic')) | ||
50 | comment = db.Column(db.Text()) | ||
51 | rating_dict = db.Column(db.String(1024), server_default="{}") | ||
52 | |||
53 | @app.route("/") | ||
54 | def root(): | ||
55 | events = Event.query.all() | ||
56 | return render_template('index.html', events=events, json=json, config=config_data, cat=config_data.get('categories')) | ||
57 | |||
58 | @app.route('/api/ratings') | ||
59 | def get_ratings(): | ||
60 | return jsonify(EventRating.query.all()) | ||
61 | |||
62 | @app.route('/api/set_event_state/<eventid>', methods=['POST']) | ||
63 | def set_sevent_state(eventid): | ||
64 | content = request.json | ||
65 | dbevent = Event.query.get(eventid) | ||
66 | dbevent.state = content.get('state', 'new') | ||
67 | db.session.commit() | ||
68 | return jsonify({"result":"ok"}) | ||
69 | |||
70 | @app.route('/api/set_event_coordinator/<eventid>', methods=['POST']) | ||
71 | def set_sevent_coordinator(eventid): | ||
72 | content = request.json | ||
73 | dbevent = Event.query.get(eventid) | ||
74 | dbevent.coordinator = content['coordinator'] | ||
75 | db.session.commit() | ||
76 | return jsonify({"result":"ok"}) | ||
77 | |||
78 | @app.route('/api/remove_event/<eventid>', methods=['POST']) | ||
79 | def remove_event(eventid): | ||
80 | dbevent = Event.query.get(eventid) | ||
81 | if dbevent.state == 'gone': | ||
82 | db.session.delete(dbevent) | ||
83 | db.session.commit() | ||
84 | return jsonify({"result":"ok"}) | ||
85 | |||
86 | @app.route('/api/remove_rating/<eventid>', methods=['POST']) | ||
87 | def remove_rating(eventid): | ||
88 | content = request.json | ||
89 | rating = EventRating.query.filter_by(event_id = eventid, submitter = content['author']).first() | ||
90 | if rating: | ||
91 | db.session.delete(rating) | ||
92 | db.session.commit() | ||
93 | return jsonify({"result":"ok"}) | ||
94 | |||
95 | @app.route('/api/add_rating/<eventid>', methods=['POST']) | ||
96 | def add_rating(eventid): | ||
97 | content = request.json | ||
98 | print ( str(eventid) + " " + str(content)) | ||
99 | r = content.get('ratings', '{}'); | ||
100 | |||
101 | rating = EventRating.query.filter_by(event_id = eventid, submitter = content['author']).first() | ||
102 | |||
103 | rd = json.dumps({ k: r.get(k,'0') for k in ['category1', 'category2', 'category3', 'category4'] }) | ||
104 | if rating: | ||
105 | if 'comment' in content: | ||
106 | rating.comment = content['comment'] | ||
107 | rating.rating_dict = rd | ||
108 | else: | ||
109 | db.session.add( EventRating( submitter = content.get('author','anonymous'), event_id = eventid, comment = content['comment'], rating_dict = rd)) | ||
110 | |||
111 | db.session.commit() | ||
112 | return jsonify({"result":"ok"}) | ||
113 | |||
114 | def fetch_talks(config): | ||
115 | sess = requests.Session() | ||
116 | new_session_page = sess.get(config.get('frab-url')) | ||
117 | tree = etree.HTML(new_session_page.text) | ||
118 | auth_token = tree.xpath("//meta[@name='csrf-token']")[0].get("content") | ||
119 | login_data = dict() | ||
120 | login_data['user[email]'] = config.get('frab-user') | ||
121 | login_data['user[password]'] = config.get('frab-password') | ||
122 | login_data['user[remember_me]'] = 1 | ||
123 | login_data['authenticity_token'] = auth_token | ||
124 | |||
125 | frab = config.get('frab-url') | ||
126 | conf = config.get('frab-conference') | ||
127 | track = config.get('track-name') | ||
128 | |||
129 | sess.post(frab + 'users/sign_in?conference_acronym=' + conf + '&locale=en', login_data, verify=False) | ||
130 | response = sess.get(frab + 'en/'+conf+'/events?track_name=' + track + '&format=json', verify=False, stream=True) | ||
131 | |||
132 | talks_json = json.loads(response.text) | ||
133 | |||
134 | # with open('dump.txt', mode='wb') as localfile: | ||
135 | # localfile.write(response.content) | ||
136 | |||
137 | imported = 0 | ||
138 | for json_event in talks_json['events']: | ||
139 | # print (json_event) | ||
140 | rawhtml = sess.get(frab + 'en/' + conf + '/events/'+ str(json_event['id']), verify=False, stream=True) | ||
141 | tree = etree.HTML(rawhtml.text) | ||
142 | submission_notes = tree.xpath('//b[text()="Submission Notes(user and admin):"]')[0].tail.strip() | ||
143 | |||
144 | dbevent = Event.query.get(json_event['id']) | ||
145 | speakers = { speaker['id']: speaker['full_public_name'] for speaker in json_event['speakers'] } | ||
146 | if dbevent: | ||
147 | dbevent.title = json_event['title'] | ||
148 | dbevent.subtitle = json_event['subtitle'] | ||
149 | dbevent.abstract = json_event['abstract'] | ||
150 | dbevent.description = json_event['description'] | ||
151 | dbevent.event_type = json_event['type'] | ||
152 | dbevent.notes = submission_notes | ||
153 | if 'state' in json_event: | ||
154 | if json_event['state'] != 'new' or dbevent.state == 'gone': | ||
155 | dbevent.state = json_event['state'] | ||
156 | dbevent.speakers = json.dumps(speakers) | ||
157 | else: | ||
158 | db.session.add( Event( frab_id = json_event['id'], title = json_event['title'], subtitle = json_event['subtitle'], abstract = json_event['abstract'], description = json_event['description'], speakers = json.dumps(speakers), state = json_event.get('state', 'new'), event_type = json_event['type'], notes = submission_notes) ) | ||
159 | imported += 1 | ||
160 | for goner in Event.query.filter( Event.frab_id.notin_([ ev['id'] for ev in talks_json['events'] ])).all(): | ||
161 | goner.state = 'gone' | ||
162 | db.session.commit() | ||
163 | print ('Conference: ' + conf + ', track: ' + track + ', imported ' + str(len(talks_json['events'])) + ' events, ' + str(imported) + ' new.') | ||
164 | |||
165 | |||
166 | if __name__ == "__main__": | ||
167 | db.create_all() | ||
168 | if args.frab_import: | ||
169 | fetch_talks(config_data) | ||
170 | else: | ||
171 | app.run(host=config_data.get('host'), port=int(config_data.get('port'))) | ||
172 | |||