summaryrefslogtreecommitdiff
path: root/rater.py
diff options
context:
space:
mode:
Diffstat (limited to 'rater.py')
-rwxr-xr-xrater.py172
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
3from flask import Flask, render_template, jsonify, request
4from flask_sqlalchemy import SQLAlchemy
5from lxml import etree
6from argparse import ArgumentParser
7import requests
8import 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
14parser = ArgumentParser(description="C3 rating helper")
15parser.add_argument("-i", action="store_true", dest="frab_import", default=False, help="import events from frab")
16parser.add_argument("-c", "--config", help="Config file location", default="./config.json")
17args = parser.parse_args()
18
19with open(args.config, mode="r", encoding="utf-8") as json_file:
20 config_data = json.load(json_file)
21
22app = Flask(__name__)
23app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+config_data.get('frab-conference')+'-'+config_data.get('track')+'.db'
24app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
25app.config['SECRET_KEY'] = 'Silence is golden. Gerd Eist.'
26app.jinja_env.trim_blocks = True
27app.jinja_env.lstrip_blocks = True
28
29db = SQLAlchemy(app)
30
31class 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
44class 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("/")
54def 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')
59def get_ratings():
60 return jsonify(EventRating.query.all())
61
62@app.route('/api/set_event_state/<eventid>', methods=['POST'])
63def 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'])
71def 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'])
79def 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'])
87def 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'])
96def 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
114def 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
166if __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