Compare commits

29 Commits

Author SHA1 Message Date
mco-system
3dab312a74 feat: add ssl_verify parameter 2024-11-24 14:42:20 +11:00
mco-system
364c6391c9 chore: new tvbruits link 2023-05-28 07:33:38 +11:00
mco-system
439e637a86 feat: Lien vers TVBruits 2023-05-27 22:05:07 +11:00
mco-system
d9808cc66e feat: status page + maintenance 2023-05-27 19:23:09 +11:00
mco-system
f139fa4bc4 feat: status page + maintenance 2023-05-27 19:16:46 +11:00
mco-system
1af0e1f834 feat: status page + maintenance 2023-05-27 19:02:16 +11:00
mco-system
b0a88b1916 feat: status page + maintenance 2023-05-27 18:58:03 +11:00
mco-system
cf95503954 feat: status page + maintenance 2023-05-27 18:53:06 +11:00
mco-system
6cdf83b6d0 feat: status page + maintenance 2023-05-27 18:46:33 +11:00
mco-system
21a747e097 feat: status page + maintenance 2023-05-27 18:28:56 +11:00
mco-system
05faf28c26 feat: status page + maintenance 2023-05-27 18:22:38 +11:00
mco-system
154ab9089d feat: status page + maintenance 2023-05-27 18:07:59 +11:00
mco-system
429e2d221e feat: status page + maintenance 2023-05-27 18:05:19 +11:00
mco-system
f3d697699d feat: status page + maintenance 2023-05-27 17:58:14 +11:00
mco-system
02645b7ef7 feat: status page + maintenance 2023-05-27 17:45:07 +11:00
mco-system
9112763234 feat: status page + maintenance 2023-05-27 17:36:03 +11:00
mco-system
7a2fdec8d4 feat: status page + maintenance 2023-05-27 17:29:21 +11:00
mco-system
674edf2bf2 feat: status page + maintenance 2023-05-27 17:23:53 +11:00
mco-system
e76d9815c9 feat: status page + maintenance 2023-05-27 17:19:40 +11:00
mco-system
204269b849 feat: status page + maintenance 2023-05-27 17:05:30 +11:00
mco-system
c969dc0e2d feat: status page + maintenance 2023-05-27 16:55:00 +11:00
mco-system
b183059f85 feat: status page + maintenance 2023-05-27 16:46:59 +11:00
mco-system
b1e05e8e4d feat: status page + maintenance 2023-05-27 16:37:28 +11:00
mco-system
10bea4b46b feat: status page + maintenance 2023-05-27 16:31:50 +11:00
mco-system
0ede5055e2 feat: status page + maintenance 2023-05-27 14:47:39 +11:00
mco-system
d17c6f6142 feat: status page + maintenance 2023-05-27 14:42:56 +11:00
mco-system
fe7b0a9e41 feat: status page + maintenance 2023-05-27 14:38:00 +11:00
mco-system
3b659ab076 feat: status page + maintenance 2023-05-27 14:31:24 +11:00
mco-system
1819826151 feat: status page + maintenance 2023-05-27 14:28:33 +11:00
11 changed files with 79 additions and 54 deletions

View File

@@ -23,7 +23,8 @@ app:
name: THSF name: THSF
real_url: https://www.thsf.net real_url: https://www.thsf.net
pretalx: pretalx:
url: https://23.thsf.net url: https://thsf.tetaneutral.net
ssl_verify: False
apiprefix: api apiprefix: api
apikey: bb770a53b15467dfb67c03d178004aca9e4819d6 apikey: bb770a53b15467dfb67c03d178004aca9e4819d6
event: thsf-2023 event: thsf-2023

4
maintenance/reboot.py Normal file → Executable file
View File

@@ -4,10 +4,10 @@ import docker
client = docker.from_env() client = docker.from_env()
for container in client.containers.list(): for container in client.containers.list():
if container.name == "thsf": if container.name == "thsf":
print("Content-type: text/html\n\n")
print("[+] Rebooting container<br>") print("[+] Rebooting container<br>")
print(" '-> Stopping container<br>") print(" '-> Stopping container<br>")
container.stop() container.stop()
print(" '-> Starting container<br>") print(" '-> Starting container<br>")
container.start() container.start()
print("[\o/] Container restarted<br>") print("[+] Container restarted<br>")

File diff suppressed because one or more lines are too long

View File

@@ -1,13 +1,7 @@
function reboot() { $("#reboot").on("click", function(){
var xhttp = new XMLHttpRequest(); $.get("https://www.thsf.net/thsf.net/maintenance/reboot.py", function(data, status){
xhttp.onreadystatechange = function() { console.log(status);
if (this.readyState == 4 && this.status == 200) { $("#logs").html = data;
document.getElementById("logs").innerHTML = this.responseText; setTimeout(function () {document.location.reload()}, 5000);
} });
}; });
xhttp.open("GET", "https://www.thsf.net/maintenance/reboot.py", true);
xhttp.send();
setTimeout(function () {
document.location="https://www.thsf.net/maintenance/status.py"}, 5000
);
}

4
maintenance/status.py Normal file → Executable file
View File

@@ -15,5 +15,5 @@ for container in client.containers.list():
cont = dict() cont = dict()
cont["name"] = container.name cont["name"] = container.name
cont["status"] = container.status cont["status"] = container.status
cont["log"] = container.logs().decode('utf-8').replace('\n', '<br>') cont["logs"] = container.logs().decode('utf-8').replace('\n', '<br>')
print(template.render(containers=[container])) print(template.render(containers=[cont]))

View File

@@ -1,5 +1,6 @@
.body { body {
font-size: 1.2em;
font-family: Arial, Helvetica, sans-serif;
} }
.page_wrapper { .page_wrapper {
display: flex; display: flex;
@@ -8,8 +9,6 @@
align-items: center; align-items: center;
align-content: center; align-content: center;
text-align: center; text-align: center;
padding-bottom: 5em;
background-color: red;
} }
.center_wrapper { .center_wrapper {
display: flex; display: flex;
@@ -17,7 +16,6 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
text-align: center; text-align: center;
background-color: blue;
} }
.container_list { .container_list {
display: flex; display: flex;
@@ -25,20 +23,25 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
text-align: center; text-align: center;
background-color: yellow; width: 48em;
}
.title {
font-size: 3em;
font-weight: bold;
margin: 0.5em;
} }
.table_headers, .line { .table_headers, .line {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-color: green;
} }
.header, .status { .header, .status {
font-weight: bold; font-weight: bold;
border-width: 1px; border-width: 1px;
border-style: solid; border-style: solid;
background-color: violet; width: 16em;
padding: 0.2em;
} }
.table_content { .table_content {
display: flex; display: flex;
@@ -46,14 +49,18 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
text-align: center; text-align: center;
background-color: cyan;
} }
.status { .status {
font-weight: normal; font-weight: normal;
} }
.container_log { .container_log {
text-align: left;
width: 49em;
padding: 0.2em;
border-width: 1px;
border-style: solid;
} }
.button { .button {
font-weight: bold; font-weight: bold;
cursor: pointer;
} }

View File

@@ -1,19 +1,24 @@
Content-type: text/html
<!DOCTYPE html> <!DOCTYPE html>
<html lang='zxx'> <html lang='zxx'>
<head> <head>
<title>THSF 2023: Status page</title> <title>THSF 2023: Status page</title>
<meta name="viewport" content="initial-scale=1.0"> <meta name="viewport" content="initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="/maintenance/scripts/maintenance.js"></script>
<link rel="stylesheet" <link rel="stylesheet"
href="/maintenance/style/maintenance.css"> href="/thsf.net/maintenance/style/maintenance.css">
<link rel="stylesheet" <link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="/thsf.net/maintenance/scripts/jquery-3.7.0.min.js"></script>
</head> </head>
<body> <body>
<div class="page_wrapper"> <div class="page_wrapper">
<div class="center_wrapper"> <div class="center_wrapper">
<div class="container_list"> <div class="container_list">
<div class="line">
<span class="title">THSF Status</span>
</div>
<div class="table_headers"> <div class="table_headers">
<div class="header">Name</div> <div class="header">Name</div>
<div class="header">Status</div> <div class="header">Status</div>
@@ -25,16 +30,17 @@
<div class="status">{{ container.name }}</div> <div class="status">{{ container.name }}</div>
<div class="status">{{ container.status }}</div> <div class="status">{{ container.status }}</div>
<div class="status"> <div class="status">
<i class="button fa-regular fa-recycle" onclick=""></i> <i id="reboot" class="button fa-solid fa-recycle" title="Reboot container" alt="Reboot container"></i>
</div> </div>
</div> </div>
<div class="container_log" id="logs"> <div class="container_log" id="logs">
{{ container.logs }} {{ container.logs | safe }}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<script src="/thsf.net/maintenance/scripts/maintenance.js"></script>
</body> </body>
</html> </html>

View File

@@ -1,10 +1,8 @@
import re
import sys import sys
import json
import logging import logging
from logging import config from logging import config
import yaml import yaml
from flask import Flask, render_template, redirect, request, url_for from flask import Flask, render_template, redirect, url_for
from flask_minify import minify from flask_minify import minify
from thsf.backend import Backend from thsf.backend import Backend
from thsf.schedule import Schedule from thsf.schedule import Schedule
@@ -37,7 +35,8 @@ try:
config.dictConfig(app.local_config["log"]) config.dictConfig(app.local_config["log"])
backend = Backend(url=app.local_config["pretalx"]["url"], backend = Backend(url=app.local_config["pretalx"]["url"],
apiprefix=app.local_config["pretalx"]["apiprefix"], apiprefix=app.local_config["pretalx"]["apiprefix"],
apikey=app.local_config["pretalx"]["apikey"]) apikey=app.local_config["pretalx"]["apikey"],
ssl_verify=app.local_config["pretalx"]["ssl_verify"])
schedule = Schedule() schedule = Schedule()
navbar = Navbar(config=app.local_config["navbar"]) navbar = Navbar(config=app.local_config["navbar"])
except Exception as err: except Exception as err:
@@ -47,6 +46,7 @@ except Exception as err:
if app.local_config["log"]["root"]["level"] != "DEBUG": if app.local_config["log"]["root"]["level"] != "DEBUG":
minify(app=app, html=True, js=True, cssless=True) minify(app=app, html=True, js=True, cssless=True)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# -- Tools # -- Tools
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@@ -63,7 +63,7 @@ def get_speaker_biography(code):
try: try:
speaker_info = backend.get(endpoint=f"events/{app.local_config['pretalx']['event']}/speakers/{code}/").json() speaker_info = backend.get(endpoint=f"events/{app.local_config['pretalx']['event']}/speakers/{code}/").json()
return speaker_info.get("biography").strip() return speaker_info.get("biography").strip()
except Exception as err: except Exception:
return None return None
@@ -125,9 +125,10 @@ def planning():
for slot in slots.get("slots"): for slot in slots.get("slots"):
for speaker in slot.get("speakers"): for speaker in slot.get("speakers"):
speaker["biography"] = get_speaker_biography(speaker.get("code")) speaker["biography"] = get_speaker_biography(speaker.get("code"))
return render_template("planning.html",
slots = sorted(slots.get("slots"), slots = sorted(slots.get("slots"),
key=lambda slot: slot.get("slot").get("start")), key=lambda slot: slot.get("slot").get("start"))
return render_template("planning.html",
slots=slots,
navbar=navbar.get_from_page(page="/planning"), navbar=navbar.get_from_page(page="/planning"),
filter=["concert", "dj set", "panel discussion", "talk", "screening"]) filter=["concert", "dj set", "panel discussion", "talk", "screening"])
@@ -153,9 +154,10 @@ def goodies():
@app.route('/concerts', methods=['GET']) @app.route('/concerts', methods=['GET'])
def concerts(): def concerts():
slots = get_slots() slots = get_slots()
return render_template("planning.html",
slots = sorted(slots.get("slots"), slots = sorted(slots.get("slots"),
key=lambda slot: slot.get("slot").get("start")), key=lambda slot: slot.get("slot").get("start"))
return render_template("planning.html",
slots=slots,
navbar=navbar.get_from_page(page="/concerts"), navbar=navbar.get_from_page(page="/concerts"),
filter=["concert", "dj set"]) filter=["concert", "dj set"])
@@ -163,9 +165,10 @@ def concerts():
@app.route('/workshops', methods=['GET']) @app.route('/workshops', methods=['GET'])
def workshops(): def workshops():
slots = get_slots() slots = get_slots()
return render_template("planning.html",
slots = sorted(slots.get("slots"), slots = sorted(slots.get("slots"),
key=lambda slot: slot.get("slot").get("start")), key=lambda slot: slot.get("slot").get("start"))
return render_template("planning.html",
slots=slots,
navbar=navbar.get_from_page(page="/workshops"), navbar=navbar.get_from_page(page="/workshops"),
filter=["workshop"]) filter=["workshop"])
@@ -173,9 +176,10 @@ def workshops():
@app.route('/screenings', methods=['GET']) @app.route('/screenings', methods=['GET'])
def screenings(): def screenings():
slots = get_slots() slots = get_slots()
return render_template("planning.html",
slots = sorted(slots.get("slots"), slots = sorted(slots.get("slots"),
key=lambda slot: slot.get("slot").get("start")), key=lambda slot: slot.get("slot").get("start"))
return render_template("planning.html",
slots=slots,
navbar=navbar.get_from_page(page="/screenings"), navbar=navbar.get_from_page(page="/screenings"),
filter=["screening"]) filter=["screening"])
@@ -183,9 +187,10 @@ def screenings():
@app.route('/discussions', methods=['GET']) @app.route('/discussions', methods=['GET'])
def discussions(): def discussions():
slots = get_slots() slots = get_slots()
return render_template("planning.html",
slots = sorted(slots.get("slots"), slots = sorted(slots.get("slots"),
key=lambda slot: slot.get("slot").get("start")), key=lambda slot: slot.get("slot").get("start"))
return render_template("planning.html",
slots=slots,
navbar=navbar.get_from_page(page="/discussions"), navbar=navbar.get_from_page(page="/discussions"),
filter=["panel discussion"]) filter=["panel discussion"])
@@ -193,9 +198,10 @@ def discussions():
@app.route('/exhibitions', methods=['GET']) @app.route('/exhibitions', methods=['GET'])
def exhibitions(): def exhibitions():
slots = get_slots() slots = get_slots()
return render_template("planning.html",
slots = sorted(slots.get("slots"), slots = sorted(slots.get("slots"),
key=lambda slot: slot.get("slot").get("start")), key=lambda slot: slot.get("slot").get("start"))
return render_template("planning.html",
slots=slots,
navbar=navbar.get_from_page(page="/exhibitions"), navbar=navbar.get_from_page(page="/exhibitions"),
filter=["installation"]) filter=["installation"])
@@ -203,9 +209,10 @@ def exhibitions():
@app.route('/talks', methods=['GET']) @app.route('/talks', methods=['GET'])
def talks(): def talks():
slots = get_slots() slots = get_slots()
return render_template("planning.html",
slots = sorted(slots.get("slots"), slots = sorted(slots.get("slots"),
key=lambda slot: slot.get("slot").get("start")), key=lambda slot: slot.get("slot").get("start"))
return render_template("planning.html",
slots=slots,
navbar=navbar.get_from_page(page="/talks"), navbar=navbar.get_from_page(page="/talks"),
filter=["talk", "light talk"]) filter=["talk", "light talk"])

View File

@@ -1,15 +1,19 @@
import requests import requests
import logging
class Backend: class Backend:
def __init__(self, url, apiprefix, apikey): def __init__(self, url, apiprefix, apikey, ssl_verify):
self.url = url self.url = url
self.apiprefix = apiprefix self.apiprefix = apiprefix
self.apikey = apikey self.apikey = apikey
self.ssl_verify = ssl_verify
self.session = requests.Session() self.session = requests.Session()
def get(self, endpoint, params=None): def get(self, endpoint, params=None):
url = f"{self.url}/{self.apiprefix}/{endpoint}" url = f"{self.url}/{self.apiprefix}/{endpoint}"
headers = {"Authorization": f"Token {self.apikey}", headers = {"Authorization": f"Token {self.apikey}",
"Accept": "application/json"} "Accept": "application/json"}
return self.session.get(url, params=params, headers=headers) return self.session.get(url,
params=params,
headers=headers,
verify=self.ssl_verify)

View File

@@ -23,5 +23,7 @@
<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> <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>
<p>Retrouvez <a href="/planning">le programme du THSF</a> avec ses <a href="/workshops">ateliers</a>, ses <a href="/exhibitions">expositions et installations</a> mais également ses <a href="/concerts">concerts</a>, ses <a href="/projections">projections</a>, ses <a href="/talks">présentations</a> et ses <a href="/discussions">tables rondes</a>.</p> <p>Retrouvez <a href="/planning">le programme du THSF</a> avec ses <a href="/workshops">ateliers</a>, ses <a href="/exhibitions">expositions et installations</a> mais également ses <a href="/concerts">concerts</a>, ses <a href="/projections">projections</a>, ses <a href="/talks">présentations</a> et ses <a href="/discussions">tables rondes</a>.</p>
<p>Accéder aux conférences, tables rondes et reportages grâce à nos amis de TVBruits: <a href="https://tvbruits.org/spip.php?mot87">https://tvbruits.org/spip.php?mot87</a>
</p>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -1,6 +1,8 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %} {% block content %}
<div class="content"> <div class="content">
<p>Accéder aux conférences, tables rondes et reportages grâce à nos amis de TVBruits: <a href="https://tvbruits.org/spip.php?mot87">https://tvbruits.org/spip.php?mot87</a>
</p>
{% for slot in slots %} {% for slot in slots %}
{% set loop_index = loop.index %} {% set loop_index = loop.index %}
{% if filter %} {% if filter %}