#!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="pretalx_import", default=False, help="import events from pretalx") 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 = json.load(json_file) app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + config['pretalx-conference'] + '-' + config['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) config['pretalx-conf-url'] = config['pretalx-url'] + 'orga/event/' + config['pretalx-conference'] config['pretalx-api-url'] = config['pretalx-url'] + 'api/events/' + config['pretalx-conference'] + '/submissions?track_id' + str(config['track-id']) class Event(db.Model): """An event as dumped from pretalx""" pretalx_id = db.Column(db.String(64), 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()) duration = db.Column(db.Integer()) 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)) pretalx_id = db.Column(db.String(64), db.ForeignKey('event.pretalx_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) @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 = db.session.get(Event, 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 = db.session.get(Event, eventid) dbevent.coordinator = content['coordinator'] db.session.commit() return jsonify({"result":"ok"}) @app.route('/api/remove_event/', methods=['POST']) def remove_event(eventid): dbevent = db.session.get(Event, 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(pretalx_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(pretalx_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'), pretalx_id = eventid, comment = content['comment'], rating_dict = rd)) db.session.commit() return jsonify({"result":"ok"}) def fetch_talks(): sess = requests.Session() response = sess.get(config['pretalx-api-url'] + '&format=json&limit=20000' , verify=False, stream=True, headers={'Authorization': "Token " + config['pretalx-token']}) talks_json = json.loads(response.text) # with open('dump.txt', mode='wb') as localfile: # localfile.write(response.content) submissions = [s for s in talks_json['results'] if s['track_id'] == config['track-id'] ] imported = 0 for json_event in submissions: # print (json_event) dbevent = db.session.get(Event, json_event['code']) speakers = { speaker['code']: speaker['name'] for speaker in json_event['speakers'] } submission_type = json_event['submission_type'].get('de') or json_event['submission_type'].get('en') if dbevent: dbevent.title = json_event['title'] dbevent.abstract = json_event['abstract'] dbevent.description = json_event['description'] dbevent.event_type = submission_type dbevent.notes = json_event.get('notes') dbevent.duration = int(json_event['duration']) if 'state' in json_event: if json_event['state'] != 'submitted' or dbevent.state == 'gone': dbevent.state = json_event['state'] dbevent.speakers = json.dumps(speakers) else: db.session.add( Event( pretalx_id = json_event['code'], title = json_event['title'], abstract = json_event['abstract'], description = json_event['description'], speakers = json.dumps(speakers), state = json_event.get('state', 'submitted'), event_type = submission_type, notes = json_event.get('notes'), duration = int(json_event['duration'])) ) imported += 1 for goner in Event.query.filter( Event.pretalx_id.notin_([ ev['code'] for ev in submissions ])).all(): goner.state = 'gone' db.session.commit() print ('Conference: ' + config['track'] + ', track: ' + config['track'] + ', imported ' + str(len(submissions)) + ' events, ' + str(imported) + ' new.') if __name__ == "__main__": with app.app_context(): db.create_all() if args.pretalx_import: fetch_talks() else: app.run(host=config.get('host', '127.0.0.1'), port=int(config.get('port', '8080')))