import re import sys import json import logging from logging import config import yaml from flask import Flask, render_template, redirect, request, url_for from flask_minify import minify from thsf.backend import Backend from thsf.schedule import Schedule from thsf.navbar import Navbar # ------------------------------------------------------------------------------ # -- Configuration # ------------------------------------------------------------------------------ class AppConfig: """ Flask application config """ CONFIG_FILENAME = "config.yml" # ------------------------------------------------------------------------------ # -- Application # ------------------------------------------------------------------------------ logger = logging.getLogger('wsgi') app = Flask(__name__) # ------------------------------------------------------------------------------ # -- Local configuration # ------------------------------------------------------------------------------ app.config.from_object(__name__ + '.AppConfig') try: with open(app.config["CONFIG_FILENAME"], mode="r", encoding="utf-8") as local_config_file: app.local_config = yaml.load(local_config_file, Loader=yaml.SafeLoader) app.config["SECRET_KEY"] = app.local_config["app"]["secret_key"] app.config["LANGUAGES"] = app.local_config["app"]["languages"] config.dictConfig(app.local_config["log"]) backend = Backend(url=app.local_config["pretalx"]["url"], apiprefix=app.local_config["pretalx"]["apiprefix"], apikey=app.local_config["pretalx"]["apikey"]) schedule = Schedule() navbar = Navbar(config=app.local_config["navbar"]) except Exception as err: logger.critical("[{}] {}".format(err.__class__, str(err))) sys.exit(1) if app.local_config["log"]["root"]["level"] != "DEBUG": minify(app=app, html=True, js=True, cssless=True) # ------------------------------------------------------------------------------ # -- Tools # ------------------------------------------------------------------------------ @app.errorhandler(404) def page_not_found(err): return redirect(url_for('index')) def get_slots(): return backend.get(endpoint=f"events/{app.local_config['pretalx']['event']}/schedules/{app.local_config['pretalx']['schedule']}/").json() def get_speaker_biography(name): try: speaker_info = backend.get(endpoint=f"events/{app.local_config['pretalx']['event']}/speakers/", params={"q": name}).json() logging.info(speaker_info) return speaker_info["results"][0]["biography"].strip() except Exception as err: logging.error(f"UnknownSpeakerError: {name}") return None # ------------------------------------------------------------------------------ # -- Custom filters # ------------------------------------------------------------------------------ @app.template_filter('date2dmyhm') def date2dmyhm(date): splitted_date = date.split("-") splitted_time = splitted_date[2].split("T")[1].split(":") year, month, day = (splitted_date[0], splitted_date[1], splitted_date[2].split("T")[0]) hour, minutes = (splitted_time[0], splitted_time[1].split("+")[0]) return f"{day}/{month} {hour}:{minutes}" @app.template_filter('date2dayclass') def date2dayclass(date): classes = {"26/05": "bg1", "27/05": "bg2", "28/05": "bg3",} splitted_date = date.split("-") month, day = (splitted_date[1], splitted_date[2].split("T")[0]) return classes[f"{day}/{month}"] @app.template_filter('toicon') def date2dmyhm(slot_type): slot_types = {"Projection": "fa-solid fa-film", "Presentation Courte": "fa-solid fa-person-chalkboard", "DJ Set": "fa-solid fa-guitar", "Concert": "fa-solid fa-guitar", "Présentation": "fa-solid fa-person-chalkboard", "Table Ronde": "fa-solid fa-users-line", "Atelier": "fa-solid fa-screwdriver-wrench", "Exposition": "fa-solid fa-palette"} return slot_types[slot_type] # ------------------------------------------------------------------------------ # -- Routes # ------------------------------------------------------------------------------ @app.route('/favicon.ico', methods=['GET']) def favicon(): return redirect(url_for('static', filename='images/favicon.png')) @app.route('/', methods=['GET']) def index(): return render_template("index.html", navbar=navbar.get_from_page(page="/")) @app.route('/planning', methods=['GET']) def planning(): slots = get_slots() for slot in slots.get("slots"): for speaker in slot.get("speakers"): speaker["biography"] = get_speaker_biography(speaker.get("name")) return render_template("planning.html", slots=sorted(slots.get("slots"), key=lambda slot: slot.get("slot").get("start")), navbar=navbar.get_from_page(page="/planning")) @app.route('/place', methods=['GET']) def place(): return render_template("index.html", navbar=navbar.get_from_page(page="/place")) @app.route('/food', methods=['GET']) def food(): return render_template("index.html", navbar=navbar.get_from_page(page="/food")) @app.route('/goodies', methods=['GET']) def goodies(): return render_template("goodies.html", navbar=navbar.get_from_page(page="/goodies")) @app.route('/concerts', methods=['GET']) def concerts(): slots = get_slots() return render_template("planning.html", slots=sorted(slots.get("slots"), key=lambda slot: slot.get("slot").get("start")), navbar=navbar.get_from_page(page="/concerts"), filter=["concert", "dj set"]) @app.route('/workshops', methods=['GET']) def workshops(): slots = get_slots() return render_template("planning.html", slots=sorted(slots.get("slots"), key=lambda slot: slot.get("slot").get("start")), navbar=navbar.get_from_page(page="/workshops"), filter=["workshop"]) @app.route('/screenings', methods=['GET']) def screenings(): slots = get_slots() return render_template("planning.html", slots=sorted(slots.get("slots"), key=lambda slot: slot.get("slot").get("start")), navbar=navbar.get_from_page(page="/screenings"), filter=["screening"]) @app.route('/discussions', methods=['GET']) def discussions(): slots = get_slots() return render_template("planning.html", slots=sorted(slots.get("slots"), key=lambda slot: slot.get("slot").get("start")), navbar=navbar.get_from_page(page="/discussions"), filter=["panel discussion"]) @app.route('/exhibitions', methods=['GET']) def exhibitions(): slots = get_slots() return render_template("planning.html", slots=sorted(slots.get("slots"), key=lambda slot: slot.get("slot").get("start")), navbar=navbar.get_from_page(page="/exhibitions"), filter=["exhibition"]) @app.route('/talks', methods=['GET']) def talks(): slots = get_slots() return render_template("planning.html", slots=sorted(slots.get("slots"), key=lambda slot: slot.get("slot").get("start")), navbar=navbar.get_from_page(page="/talks"), filter=["talk", "light talk"]) # ------------------------------------------------------------------------------ # -- Main # ------------------------------------------------------------------------------ if __name__ == '__main__': app.run(host='127.0.0.1', port=5000, debug=True)