wip: programme
@ -1,188 +0,0 @@
|
|||||||
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 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)
|
|
||||||
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# -- 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()
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
|
||||||
# -- 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()
|
|
||||||
return render_template("planning.html",
|
|
||||||
slots=sorted(slots["slots"],
|
|
||||||
key=lambda slot: slot["slot"]["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["slots"],
|
|
||||||
key=lambda slot: slot["slot"]["start"]),
|
|
||||||
navbar=navbar.get_from_page(page="/concerts"),
|
|
||||||
filter=["concerts", "dj set"])
|
|
||||||
|
|
||||||
@app.route('/workshops', methods=['GET'])
|
|
||||||
def workshops():
|
|
||||||
slots = get_slots()
|
|
||||||
return render_template("planning.html",
|
|
||||||
slots=sorted(slots["slots"],
|
|
||||||
key=lambda slot: slot["slot"]["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["slots"],
|
|
||||||
key=lambda slot: slot["slot"]["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["slots"],
|
|
||||||
key=lambda slot: slot["slot"]["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["slots"],
|
|
||||||
key=lambda slot: slot["slot"]["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["slots"],
|
|
||||||
key=lambda slot: slot["slot"]["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)
|
|
@ -1,15 +0,0 @@
|
|||||||
import requests
|
|
||||||
import logging
|
|
||||||
|
|
||||||
class Backend:
|
|
||||||
def __init__(self, url, apiprefix, apikey):
|
|
||||||
self.url = url
|
|
||||||
self.apiprefix = apiprefix
|
|
||||||
self.apikey = apikey
|
|
||||||
self.session = requests.Session()
|
|
||||||
|
|
||||||
def get(self, endpoint, params=None):
|
|
||||||
url = f"{self.url}/{self.apiprefix}/{endpoint}"
|
|
||||||
headers = {"Authorization": f"Token {self.apikey}",
|
|
||||||
"Accept": "application/json"}
|
|
||||||
return self.session.get(url, params=params, headers=headers)
|
|
@ -1,6 +0,0 @@
|
|||||||
class Navbar:
|
|
||||||
def __init__(self, config):
|
|
||||||
self.config = config
|
|
||||||
|
|
||||||
def get_from_page(self, page):
|
|
||||||
return [item for item in self.config["items"] if item["url"] != page]
|
|
@ -1,6 +0,0 @@
|
|||||||
class Schedule:
|
|
||||||
def __init__(self):
|
|
||||||
self.slots = list()
|
|
||||||
|
|
||||||
def set_slots(self, slots):
|
|
||||||
self.slots = slots
|
|
@ -1,197 +0,0 @@
|
|||||||
#schedule {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: start;
|
|
||||||
align-items: flex-start;
|
|
||||||
align-content: flex-start;
|
|
||||||
margin-bottom: 5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
justify-content: center;
|
|
||||||
text-align: center;
|
|
||||||
flex-direction: row;
|
|
||||||
margin: 0.3em;
|
|
||||||
font-size: 2em;
|
|
||||||
width: 22em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info,
|
|
||||||
.slot_info_buttons {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-content: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metadata, .data {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: start;
|
|
||||||
align-content: flex-start;
|
|
||||||
padding: 0.5em;
|
|
||||||
border-style: solid;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metadata {
|
|
||||||
width: 7.333em;
|
|
||||||
border-radius: 10px 0 0 10px;
|
|
||||||
color: var(--main-color);
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
border-width: 1px 0 0px 1px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data {
|
|
||||||
width: 14.666em;
|
|
||||||
background-color: var(--main-color);
|
|
||||||
color: var(--alt-main-color);
|
|
||||||
border-color: var(--main-color);
|
|
||||||
border-width: 1px 1px 1px 0;
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.metadata > .slot_info_buttons > .button,
|
|
||||||
.metadata > .slot_info_buttons > .slot_info > .button {
|
|
||||||
font-size: 1em;
|
|
||||||
margin-right: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speakers {
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speaker {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speaker .details {
|
|
||||||
visibility: hidden;
|
|
||||||
background-color: var(--main-color);
|
|
||||||
color: var(--alt-main-color);
|
|
||||||
text-align: left;
|
|
||||||
padding: 1em;
|
|
||||||
border-radius: 6px;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 1s;
|
|
||||||
transform: translateY(102%);
|
|
||||||
overflow-y: auto;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: var(--alt-main-color);
|
|
||||||
border-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speaker .details::after {
|
|
||||||
content: "";
|
|
||||||
position: relative;
|
|
||||||
margin-left: -5px;
|
|
||||||
border-width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speaker:hover .details {
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
font-size: 0.7em;
|
|
||||||
padding: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speaker > .details > img,
|
|
||||||
.abstract > img {
|
|
||||||
max-width: 200px;
|
|
||||||
max-height: 200px;
|
|
||||||
float: left;
|
|
||||||
margin: 0 0.5em 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.speaker > .details > p {
|
|
||||||
text-align: justify;
|
|
||||||
font-size: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info .details {
|
|
||||||
visibility: hidden;
|
|
||||||
background-color: var(--main-color);
|
|
||||||
color: var(--alt-main-color);
|
|
||||||
text-align: left;
|
|
||||||
padding: 1em;
|
|
||||||
border-radius: 6px;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 1s;
|
|
||||||
transform: translateX(-2em) translateY(102%);
|
|
||||||
width: 30em;
|
|
||||||
overflow-y: auto;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: var(--alt-main-color);
|
|
||||||
border-width: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info .details > .description {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info .details::after {
|
|
||||||
content: "";
|
|
||||||
position: relative;
|
|
||||||
margin-left: -5px;
|
|
||||||
border-width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info:hover .details {
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
font-size: 0.7em;
|
|
||||||
padding: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info > .details > img,
|
|
||||||
.abstract > img {
|
|
||||||
max-width: 200px;
|
|
||||||
max-height: 200px;
|
|
||||||
float: left;
|
|
||||||
margin: 0 0.5em 0.5em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_info > .details > p {
|
|
||||||
text-align: justify;
|
|
||||||
font-size: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.abstract > p {
|
|
||||||
text-align: justify;
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data > .details {
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 0.2em;
|
|
||||||
font-size: 0.8em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.data > .resources > .resource > a {
|
|
||||||
color: var(--main-bg-color);
|
|
||||||
}
|
|
@ -1,183 +0,0 @@
|
|||||||
@font-face {
|
|
||||||
font-family: pfdintextcomppromedium;
|
|
||||||
src: url(../fonts/PFDinTextCompPro-Medium.ttf);
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
src: url(../fonts/PFDinTextCompPro-Thin.ttf);
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--main-bg-color: #e6007e;
|
|
||||||
--alt-bg-color: #E59730;
|
|
||||||
--alt2-bg-color: #9EBF43;
|
|
||||||
--alt3-bg-color: #3096E5;
|
|
||||||
--main-color: #ffffff;
|
|
||||||
--alt-main-color: #1A000D;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: var(--main-bg-color);
|
|
||||||
font-family: pfdintextcomppromedium;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.white {
|
|
||||||
color: var(--main-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.black {
|
|
||||||
color: var(--alt-main-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.thin {
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bold {
|
|
||||||
font-family: pfdintextcomppromedium;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
font-size: 2.5em;
|
|
||||||
transition-property: color;
|
|
||||||
transition-duration: 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button:hover {
|
|
||||||
color: var(--main-color);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
width: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg1 {
|
|
||||||
background-color: var(--alt-bg-color);
|
|
||||||
border-color: var(--alt-bg-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg2 {
|
|
||||||
background-color: var(--alt2-bg-color);
|
|
||||||
border-color: var(--alt2-bg-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg3 {
|
|
||||||
background-color: var(--alt3-bg-color);
|
|
||||||
border-color: var(--alt3-bg-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-family: pfdintextcomppromedium;
|
|
||||||
font-weight: 250;
|
|
||||||
color: var(--alt-main-color);
|
|
||||||
transition-property: color;
|
|
||||||
transition-duration: 1s;
|
|
||||||
text-decoration: wavy;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: var(--main-color);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#main_wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
margin-bottom: 5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#center_wrapper, #header_wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 0;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 9.75em;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header > span {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#subheader {
|
|
||||||
margin: -1em 0 0 0;
|
|
||||||
font-size: 3.47em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#place {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 2.145em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logo_wrapper {
|
|
||||||
margin-top: 1em;
|
|
||||||
width: 40em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#navbar_wrapper {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
padding: 1em 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
gap: 2em;
|
|
||||||
background-color: var(--main-bg-color);
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
#blah {
|
|
||||||
margin: 2em 0 2em;
|
|
||||||
font-size: 2em;
|
|
||||||
font-family: pfdintextcompprothin;
|
|
||||||
color: var(--main-color);
|
|
||||||
width: 20em;
|
|
||||||
text-align:justify;
|
|
||||||
text-justify:inter-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
#blah > p, #blah.h2 {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.important {
|
|
||||||
font-family: pfdintextcomppromedium;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
float: left;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
float: right;
|
|
||||||
margin-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo_partner {
|
|
||||||
max-width: 250px;
|
|
||||||
max-height: 250px;
|
|
||||||
margin: 1em;
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
.tooltip,
|
|
||||||
.slot_tooltip {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip .tooltiptext {
|
|
||||||
visibility: hidden;
|
|
||||||
background-color: var(--main-color);
|
|
||||||
color: var(--alt-main-color);
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 5px 0;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(-25%) translateY(-2em);
|
|
||||||
transition: opacity 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slot_tooltip .slot_tooltiptext {
|
|
||||||
visibility: hidden;
|
|
||||||
background-color: var(--main-color);
|
|
||||||
color: var(--alt-main-color);
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 5px 0;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateX(2em);
|
|
||||||
transition: opacity 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip .tooltiptext::after,
|
|
||||||
.slot_tooltip .slot_tooltiptext::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
left: 50%;
|
|
||||||
margin-left: -5px;
|
|
||||||
border-width: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip:hover .tooltiptext,
|
|
||||||
.slot_tooltip:hover .slot_tooltiptext {
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
font-size: 0.7em;
|
|
||||||
padding: 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 5.2 KiB |
@ -1,73 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang='zxx'>
|
|
||||||
<head>
|
|
||||||
<title>THSF 2023: S/Extraire</title>
|
|
||||||
<meta name="viewport" content="initial-scale=1.0">
|
|
||||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
|
||||||
<link rel="stylesheet"
|
|
||||||
href="{{ url_for('static', filename='css/style.css') }}">
|
|
||||||
<link rel="stylesheet"
|
|
||||||
href="{{ url_for('static', filename='css/tooltip.css') }}">
|
|
||||||
<link rel="stylesheet"
|
|
||||||
href="{{ url_for('static', filename='css/planning.css') }}">
|
|
||||||
<link rel="icon"
|
|
||||||
type="image/png"
|
|
||||||
href="{{ url_for('static', filename='images/favicon.png') }}">
|
|
||||||
<link rel="stylesheet"
|
|
||||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
||||||
{% block headers %}
|
|
||||||
{% endblock %}
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div id="main_wrapper">
|
|
||||||
<div id="center_wrapper">
|
|
||||||
<div id="header_wrapper">
|
|
||||||
<div id="header">
|
|
||||||
<span class="black bold">THSF</span>
|
|
||||||
<span class="white thin">2023</span>
|
|
||||||
</div>
|
|
||||||
<div id="subheader">
|
|
||||||
<span class="white thin">Toulouse Hacker Space Factory</span>
|
|
||||||
</div>
|
|
||||||
<div id="place">
|
|
||||||
<span class="black thin">26 28 mai 2023 - </span>
|
|
||||||
<span class="white bold">CINÉMA UTOPIA BORDEROUGE</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% block content %}
|
|
||||||
{% endblock %}
|
|
||||||
<div id="#partners">
|
|
||||||
<a href="https://www.tetalab.org/">
|
|
||||||
<img src="{{ url_for('static', filename='images/tetalab.png')}}"
|
|
||||||
alt="Tetalab"
|
|
||||||
title="Tetalab"
|
|
||||||
class="logo_partner">
|
|
||||||
</a>
|
|
||||||
<a href="https://www.tetaneutral.net/">
|
|
||||||
<img src="{{ url_for('static', filename='images/tetaneutral.png')}}"
|
|
||||||
alt="Tetaneutral"
|
|
||||||
title="Tetaneutral"
|
|
||||||
class="logo_partner">
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<a href="https://clutchmag.fr/">
|
|
||||||
<img src="{{ url_for('static', filename='images/clutch.png')}}"
|
|
||||||
alt="Clutch"
|
|
||||||
title="Clutch"
|
|
||||||
class="logo_partner">
|
|
||||||
</a>
|
|
||||||
<a href="https://www.antistatik.store/">
|
|
||||||
<img src="{{ url_for('static', filename='images/antistatik.png')}}"
|
|
||||||
alt="Antistatik"
|
|
||||||
title="Antistatik"
|
|
||||||
class="logo_partner">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% block navbar %}
|
|
||||||
{% include "navbar.html" %}
|
|
||||||
{% endblock %}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,52 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% block content %}
|
|
||||||
<div id="logo_wrapper">
|
|
||||||
<img class="logo"
|
|
||||||
src="{{ url_for('static', filename='images/logo.svg') }}"
|
|
||||||
alt="THSF 2023 - S/Extraire"
|
|
||||||
title="THSF 2023 - S/Extraire">
|
|
||||||
</div>
|
|
||||||
<div id="blah" class="goodies">
|
|
||||||
<h2>Nous avons besoin de votre soutien</h2>
|
|
||||||
<p>
|
|
||||||
Nous avons besoin de <a href="https://www.leetchi.com/c/thsf23">votre soutien financier</a> pour faire du <strong>Toulouse Hacker Space Factory</strong> un événement toujours différent des autres festivals. Ainsi, comme chaque année, nous faisons venir des artistes, des associations, des conférenciers, mais cela nécessite des frais importants pour leur transport et leur hébergement. C'est pourquoi nous sollicitons votre aide pour couvrir ces coûts et garantir le succès du <strong>THSF</strong>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
En contribuant financièrement au <strong>Toulouse Hacker Space Factory</strong>, vous soutenez non seulement notre événement, mais également cette communauté de passionnés qui conserve un regard différent sur la technologie. Chaque don compte, c'est pourquoi nous avons créé des lots de goodies en guise de remerciement pour votre contribution.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Pour faciliter la collecte des dons et vous remercier de votre participation, nous avons mis en place <a href="https://www.leetchi.com/c/thsf23">une cagnote Leetchi</a> qui nous permettra de recenser les dons et vous permettra de suivre l'évolution du financement de notre festival.
|
|
||||||
</p>
|
|
||||||
<p class="goodies">
|
|
||||||
<img class="left"
|
|
||||||
src="{{ url_for('static', filename='images/stickers.webp') }}"
|
|
||||||
alt="Stickers"
|
|
||||||
title="Stickers">
|
|
||||||
À partir de 10€, vous recevrez <span class="important">un lot de 4 stickers</span> au logo de l'édition 2023 du THSF.
|
|
||||||
</p>
|
|
||||||
<p class="goodies">
|
|
||||||
<img class="right"
|
|
||||||
src="{{ url_for('static', filename='images/tshirt.webp') }}"
|
|
||||||
alt="T-Shirt"
|
|
||||||
title="T-Shirt">
|
|
||||||
Pour un don de 20€ ou plus, vous recevrez <span class="important">un lot de 4 stickers et un T-Shirt</span> au logo de l'édition 2023 du THSF.
|
|
||||||
</p>
|
|
||||||
<p class="goodies">
|
|
||||||
<img class="left"
|
|
||||||
src="{{ url_for('static', filename='images/totebag.webp') }}"
|
|
||||||
alt="Tote Bag"
|
|
||||||
title="Tote Bag">
|
|
||||||
À partir de 30€, vous recevrez <span class="important">un lot de 4 stickers, un T-Shirt et un Tote bag</span> au logo de l'édition 2023 du THSF.
|
|
||||||
</p>
|
|
||||||
<p class="goodies">
|
|
||||||
<img class="right"
|
|
||||||
src="{{ url_for('static', filename='images/sweatshirt.webp') }}"
|
|
||||||
alt="Sweat shirt"
|
|
||||||
title="Sweat shirt">
|
|
||||||
Et pour plus de 40€, vous recevrez <span class="important">un lot de 4 stickers, un T-Shirt, un Tote bag et un sweat-shirt</span> estampillés du logo de l'édition 2023 du THSF.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Nous sommes également conscients que la situation actuelle est particulièrement difficile. C'est pourquoi nous nous engageons à ce que <span class="important">toutes les sommes qui dépasseront notre objectif de financement de 2 000 € seront reversées aux caisses des grévistes de la réforme des retraites</span>. Ainsi, votre contribution permettra également de soutenir une cause importante et de <span class="important">faire une différence dans la vie de ceux qui se battent pour nos droits</span>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -1,19 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% block content %}
|
|
||||||
<div id="logo_wrapper">
|
|
||||||
<img class="logo"
|
|
||||||
src="{{ url_for('static', filename='images/logo.svg') }}"
|
|
||||||
alt="THSF 2023 - S/Extraire"
|
|
||||||
title="THSF 2023 - S/Extraire">
|
|
||||||
</div>
|
|
||||||
<div id="blah">
|
|
||||||
<h2>Le T.H.S.F est enfin de retour !</h2>
|
|
||||||
<p>Nous vous invitons à passer un week-end de 3 jours à <a href="https://www.cinemas-utopia.org/toulouse/">Utopia Borderouge Toulouse</a> pour partager avec vous nos projets, nos réflexions, nos performances, nos poésies et nos doutes sur la technologie.</p>
|
|
||||||
|
|
||||||
<p>Après avoir été soutenu et accueilli pendant 10 ans par <a href="https://vive.mixart-myrys.org/">Mix'Art Myrys</a>, le <strong>Toulouse HackerSpace Factory (T.H.S.F)</strong> se tient désormais dans un autre lieu où l'utopie nécessaire est inscrite programme.</p>
|
|
||||||
|
|
||||||
<p>Cette année nous mettrons en avant des réflexions sur <a href="https://fr.wikipedia.org/wiki/Extractivisme" target="_new">l'extractivisme des ressources</a> planétaires, des données, de la valeur travail.</p>
|
|
||||||
|
|
||||||
<p>Comme toujours, notre objectif est de créer un festival qui poétise les bifurcations de nos idées communes et qui réinvente le sens de certains schémas imposés par notre époque. Rejoignez-nous pour une expérience enrichissante et pleine de surprises !</p>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -1,8 +0,0 @@
|
|||||||
<div id="navbar_wrapper">
|
|
||||||
{% for item in navbar %}
|
|
||||||
<i class="button tooltip black {{ item.classes }}"
|
|
||||||
onclick="document.location='{{item.url}}'">
|
|
||||||
<span class="tooltiptext thin">{{item.name}}</span>
|
|
||||||
</i>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
@ -1,14 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% block content %}
|
|
||||||
<div id="schedule">
|
|
||||||
{% for slot in slots %}
|
|
||||||
{% if filter %}
|
|
||||||
{% if slot.submission_type.en | lower in filter %}
|
|
||||||
{% include "slot.html" %}
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
{% include "slot.html" %}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
@ -1,53 +0,0 @@
|
|||||||
<div class="slot">
|
|
||||||
<div class="metadata {{ slot.slot.start | date2dayclass}}">
|
|
||||||
<div class="speakers">
|
|
||||||
{% for speaker in slot.speakers %}
|
|
||||||
<div class="speaker">
|
|
||||||
{{speaker.name | title}}
|
|
||||||
<i class="speaker_details fa-solid fa-user"></i>
|
|
||||||
{% if speaker.avatar or speaker.biography %}
|
|
||||||
<div class="details">
|
|
||||||
{% if speaker.avatar %}
|
|
||||||
<img src="{{speaker.avatar}}"
|
|
||||||
alt=""
|
|
||||||
title="">
|
|
||||||
{% endif %}
|
|
||||||
{% if speaker['biography'] %}
|
|
||||||
<p class="thin">{{speaker.biography}}</p>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div><br>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
<div class="slot_info_buttons">
|
|
||||||
<i class="button slot_tooltip black {{slot.submission_type.fr | toicon }}">
|
|
||||||
<span class="slot_tooltiptext thin">
|
|
||||||
{{slot.submission_type.fr}}
|
|
||||||
</span>
|
|
||||||
</i>
|
|
||||||
<div class="slot_info">
|
|
||||||
<i class="button slot_info_details black fa-solid fa-circle-info"></i>
|
|
||||||
<div class="details thin">
|
|
||||||
<div class="abstract">
|
|
||||||
{% if slot['image'] %}
|
|
||||||
<img class="data_img"
|
|
||||||
src="{{slot.image}}"
|
|
||||||
alt=""
|
|
||||||
title="">
|
|
||||||
{% endif %}
|
|
||||||
<p>{{slot.abstract}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="description">{{slot.description}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="data">
|
|
||||||
<div class="details">
|
|
||||||
<div class="title black">{{slot.title}}</div>
|
|
||||||
<div class="room"><i class="fa-solid fa-caret-right"></i> {{slot.slot.room.fr}}</div>
|
|
||||||
<div class="start"><i class="fa-solid fa-caret-right"></i> {{slot.slot.start | date2dmyhm}} - {{slot.duration}} minutes ({{slot.content_locale | capitalize}})</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,50 +0,0 @@
|
|||||||
Metadata-Version: 2.1
|
|
||||||
Name: thsf
|
|
||||||
Version: 0.0.1
|
|
||||||
Summary: "THSF website"
|
|
||||||
Home-page: https://git.tetalab.org/tetalab/thsf.net
|
|
||||||
Author: Doug Le Tough
|
|
||||||
Author-email: doug@redatomik.org
|
|
||||||
Classifier: Programming Language :: Python :: 3
|
|
||||||
Classifier: License :: OSI Approved :: MIT License
|
|
||||||
Classifier: Operating System :: OS Independent
|
|
||||||
Requires-Python: >=3.7
|
|
||||||
Description-Content-Type: text/markdown
|
|
||||||
Provides-Extra: dev
|
|
||||||
|
|
||||||
# THSF.NET
|
|
||||||
|
|
||||||
Le site du THSF
|
|
||||||
|
|
||||||
## Modifier le site
|
|
||||||
|
|
||||||
Il n'est **pas possible** de pousser directement des modifications sur la branche `master`.
|
|
||||||
|
|
||||||
Pour modifier le site, il est nécessaire de créer une branche spécifique et d'y pousser vos modifications.
|
|
||||||
|
|
||||||
## Publication du site
|
|
||||||
|
|
||||||
Lorsque vous êtes satisfaits de vos modifications, vous pouvez créer [une demande d'ajout](https://git.tetalab.org/tetalab/thsf.net/pulls) de votre branche sur la branche `master`.
|
|
||||||
|
|
||||||
Lorsque la demande de fusion sera acceptée (vous pouvez auto-accepter vos demandes de fusion), vos modifications seront automatiquement publiées sur [le site du THSF](https://www.thsf.net).
|
|
||||||
|
|
||||||
### Personnalisation de la publication
|
|
||||||
|
|
||||||
Afin de rendre le processus plus souple, il est possible de personnaliser la livraison en plaçant **à la racine du dépôt** un fichier `Makefile` contenant une cible `all` qui sera systématiquement exécutée.
|
|
||||||
|
|
||||||
C'est dans cette cible `all` que vous pourrez mettre toutes vos commandes personnalisées, typiquement l'installation de modules `python`, etc.
|
|
||||||
|
|
||||||
Le processus de publication est le suivant:
|
|
||||||
|
|
||||||
1. Le site actuellement en production est **supprimé**
|
|
||||||
|
|
||||||
2. La branche `master` du présent dépôt est cloné sur le serveur hébergeant le site du **THSF**
|
|
||||||
|
|
||||||
3. Si un fichier `Makefile` se trouve **à la racine du dépôt**, la cible `all` (i.e: `make all`) est automatiquement exécutée.
|
|
||||||
|
|
||||||
|
|
||||||
## Contrôle de qualité et tests
|
|
||||||
|
|
||||||
Aucun contrôle de qualité ou de tests n'est mis en place. Vous êtes seuls sur le coup.
|
|
||||||
|
|
||||||
Soyez responsable et **testez vos modifications sur votre machine locale avant de fusionner votre branche** sur la branche `master`.
|
|
@ -1,40 +0,0 @@
|
|||||||
MANIFEST.in
|
|
||||||
README.md
|
|
||||||
pyproject.toml
|
|
||||||
setup.cfg
|
|
||||||
setup.py
|
|
||||||
src/thsf/__init__.py
|
|
||||||
src/thsf.egg-info/PKG-INFO
|
|
||||||
src/thsf.egg-info/SOURCES.txt
|
|
||||||
src/thsf.egg-info/dependency_links.txt
|
|
||||||
src/thsf.egg-info/requires.txt
|
|
||||||
src/thsf.egg-info/top_level.txt
|
|
||||||
src/thsf/backend/__init__.py
|
|
||||||
src/thsf/navbar/__init__.py
|
|
||||||
src/thsf/schedule/__init__.py
|
|
||||||
src/thsf/static/css/planning.css
|
|
||||||
src/thsf/static/css/style.css
|
|
||||||
src/thsf/static/css/tooltip.css
|
|
||||||
src/thsf/static/fonts/PFDinTextCompPro-Medium.ttf
|
|
||||||
src/thsf/static/fonts/PFDinTextCompPro-Thin.ttf
|
|
||||||
src/thsf/static/fonts/Uni Sans Bold.otf
|
|
||||||
src/thsf/static/fonts/Uni Sans Book.otf
|
|
||||||
src/thsf/static/images/affiche_v1.png
|
|
||||||
src/thsf/static/images/antistatik.png
|
|
||||||
src/thsf/static/images/bg.png
|
|
||||||
src/thsf/static/images/clutch.png
|
|
||||||
src/thsf/static/images/favicon.png
|
|
||||||
src/thsf/static/images/logo.svg
|
|
||||||
src/thsf/static/images/pretalx-header.png
|
|
||||||
src/thsf/static/images/stickers.webp
|
|
||||||
src/thsf/static/images/sweatshirt.webp
|
|
||||||
src/thsf/static/images/tetalab.png
|
|
||||||
src/thsf/static/images/tetaneutral.png
|
|
||||||
src/thsf/static/images/totebag.webp
|
|
||||||
src/thsf/static/images/tshirt.webp
|
|
||||||
src/thsf/templates/base.html
|
|
||||||
src/thsf/templates/goodies.html
|
|
||||||
src/thsf/templates/index.html
|
|
||||||
src/thsf/templates/navbar.html
|
|
||||||
src/thsf/templates/planning.html
|
|
||||||
src/thsf/templates/slot.html
|
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -1,17 +0,0 @@
|
|||||||
flask
|
|
||||||
gunicorn
|
|
||||||
pyYAML
|
|
||||||
requests
|
|
||||||
|
|
||||||
[dev]
|
|
||||||
twine
|
|
||||||
build
|
|
||||||
wheel>=0.37.0
|
|
||||||
flake8>=4.0.1
|
|
||||||
flake8-breakpoint>=1.1.0
|
|
||||||
flake8-builtins>=1.5.3
|
|
||||||
flake8-print>=4.0.0
|
|
||||||
flake8-return>=1.1.3
|
|
||||||
pep8-naming>=0.8.2
|
|
||||||
setuptools>=60.9.2
|
|
||||||
pylint>=2.12.2
|
|
@ -1 +0,0 @@
|
|||||||
thsf
|
|