From e8b020e28ca377868ff8aad8418372debc910ae6 Mon Sep 17 00:00:00 2001 From: User Content Date: Wed, 30 Oct 2019 01:11:47 +0000 Subject: Initial commit --- rater.py | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100755 rater.py (limited to 'rater.py') diff --git a/rater.py b/rater.py new file mode 100755 index 0000000..e1ed9c5 --- /dev/null +++ b/rater.py @@ -0,0 +1,172 @@ +#!venv/bin/python + +from flask import Flask, render_template, jsonify, request +from flask_sqlalchemy import SQLAlchemy +from lxml import etree +from argparse import ArgumentParser +import requests +import json + +# Use this on FreeBSD when you've compiled pyopenssl with openssl from ports +# import urllib3.contrib.pyopenssl +# urllib3.contrib.pyopenssl.inject_into_urllib3() + +parser = ArgumentParser(description="C3 rating helper") +parser.add_argument("-i", action="store_true", dest="frab_import", default=False, help="import events from frab") +parser.add_argument("-c", "--config", help="Config file location", default="./config.json") +args = parser.parse_args() + +with open(args.config, mode="r", encoding="utf-8") as json_file: + config_data = json.load(json_file) + +app = Flask(__name__) +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///'+config_data.get('frab-conference')+'-'+config_data.get('track')+'.db' +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +app.config['SECRET_KEY'] = 'Silence is golden. Gerd Eist.' +app.jinja_env.trim_blocks = True +app.jinja_env.lstrip_blocks = True + +db = SQLAlchemy(app) + +class Event(db.Model): + """An event as dumped from frab""" + frab_id = db.Column(db.Integer, primary_key=True) + title = db.Column(db.String(1024)) + subtitle = db.Column(db.String(1024)) + abstract = db.Column(db.Text()) + description = db.Column(db.Text()) + state = db.Column(db.String(64)) + event_type = db.Column(db.String(64)) + speakers = db.Column(db.String(1024)) + coordinator = db.Column(db.String(1024)) + notes = db.Column(db.Text()) + +class EventRating(db.Model): + """A rating as given by a logged in user""" + id = db.Column(db.Integer, primary_key=True) + submitter = db.Column(db.String(1024)) + event_id = db.Column(db.Integer, db.ForeignKey('event.frab_id')) + event = db.relationship('Event', backref=db.backref('ratings', lazy='dynamic')) + comment = db.Column(db.Text()) + rating_dict = db.Column(db.String(1024), server_default="{}") + +@app.route("/") +def root(): + events = Event.query.all() + return render_template('index.html', events=events, json=json, config=config_data, cat=config_data.get('categories')) + +@app.route('/api/ratings') +def get_ratings(): + return jsonify(EventRating.query.all()) + +@app.route('/api/set_event_state/', methods=['POST']) +def set_sevent_state(eventid): + content = request.json + dbevent = Event.query.get(eventid) + dbevent.state = content.get('state', 'new') + db.session.commit() + return jsonify({"result":"ok"}) + +@app.route('/api/set_event_coordinator/', methods=['POST']) +def set_sevent_coordinator(eventid): + content = request.json + dbevent = Event.query.get(eventid) + dbevent.coordinator = content['coordinator'] + db.session.commit() + return jsonify({"result":"ok"}) + +@app.route('/api/remove_event/', methods=['POST']) +def remove_event(eventid): + dbevent = Event.query.get(eventid) + if dbevent.state == 'gone': + db.session.delete(dbevent) + db.session.commit() + return jsonify({"result":"ok"}) + +@app.route('/api/remove_rating/', methods=['POST']) +def remove_rating(eventid): + content = request.json + rating = EventRating.query.filter_by(event_id = eventid, submitter = content['author']).first() + if rating: + db.session.delete(rating) + db.session.commit() + return jsonify({"result":"ok"}) + +@app.route('/api/add_rating/', methods=['POST']) +def add_rating(eventid): + content = request.json + print ( str(eventid) + " " + str(content)) + r = content.get('ratings', '{}'); + + rating = EventRating.query.filter_by(event_id = eventid, submitter = content['author']).first() + + rd = json.dumps({ k: r.get(k,'0') for k in ['category1', 'category2', 'category3', 'category4'] }) + if rating: + if 'comment' in content: + rating.comment = content['comment'] + rating.rating_dict = rd + else: + db.session.add( EventRating( submitter = content.get('author','anonymous'), event_id = eventid, comment = content['comment'], rating_dict = rd)) + + db.session.commit() + return jsonify({"result":"ok"}) + +def fetch_talks(config): + sess = requests.Session() + new_session_page = sess.get(config.get('frab-url')) + tree = etree.HTML(new_session_page.text) + auth_token = tree.xpath("//meta[@name='csrf-token']")[0].get("content") + login_data = dict() + login_data['user[email]'] = config.get('frab-user') + login_data['user[password]'] = config.get('frab-password') + login_data['user[remember_me]'] = 1 + login_data['authenticity_token'] = auth_token + + frab = config.get('frab-url') + conf = config.get('frab-conference') + track = config.get('track-name') + + sess.post(frab + 'users/sign_in?conference_acronym=' + conf + '&locale=en', login_data, verify=False) + response = sess.get(frab + 'en/'+conf+'/events?track_name=' + track + '&format=json', verify=False, stream=True) + + talks_json = json.loads(response.text) + +# with open('dump.txt', mode='wb') as localfile: +# localfile.write(response.content) + + imported = 0 + for json_event in talks_json['events']: +# print (json_event) + rawhtml = sess.get(frab + 'en/' + conf + '/events/'+ str(json_event['id']), verify=False, stream=True) + tree = etree.HTML(rawhtml.text) + submission_notes = tree.xpath('//b[text()="Submission Notes(user and admin):"]')[0].tail.strip() + + dbevent = Event.query.get(json_event['id']) + speakers = { speaker['id']: speaker['full_public_name'] for speaker in json_event['speakers'] } + if dbevent: + dbevent.title = json_event['title'] + dbevent.subtitle = json_event['subtitle'] + dbevent.abstract = json_event['abstract'] + dbevent.description = json_event['description'] + dbevent.event_type = json_event['type'] + dbevent.notes = submission_notes + if 'state' in json_event: + if json_event['state'] != 'new' or dbevent.state == 'gone': + dbevent.state = json_event['state'] + dbevent.speakers = json.dumps(speakers) + else: + 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) ) + imported += 1 + for goner in Event.query.filter( Event.frab_id.notin_([ ev['id'] for ev in talks_json['events'] ])).all(): + goner.state = 'gone' + db.session.commit() + print ('Conference: ' + conf + ', track: ' + track + ', imported ' + str(len(talks_json['events'])) + ' events, ' + str(imported) + ' new.') + + +if __name__ == "__main__": + db.create_all() + if args.frab_import: + fetch_talks(config_data) + else: + app.run(host=config_data.get('host'), port=int(config_data.get('port'))) + -- cgit v1.2.3