Translated ita -> eng and tidied for public release
This commit is contained in:
parent
fc864fce57
commit
294d30a464
19
api.py
19
api.py
|
@ -1,5 +1,5 @@
|
||||||
from sanic import response
|
from sanic import response
|
||||||
from sanic import Blueprint, exceptions
|
from sanic import Blueprint
|
||||||
from ext import *
|
from ext import *
|
||||||
from config import *
|
from config import *
|
||||||
import sqlite3
|
import sqlite3
|
||||||
|
@ -59,8 +59,8 @@ async def api_leaderboard(request):
|
||||||
async def send_feedback(request):
|
async def send_feedback(request):
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
r = await client.post("https://api.telegram.org/bot5648800229:AAGr5EJdyo4obXB7pftIcQGjYLAlQdpu1Iw/sendMessage",
|
r = await client.post(f"https://api.telegram.org/bot{TG_BOT_API}/sendMessage",
|
||||||
json = {'chat_id': -946677603, 'text': str(request.json)}
|
json = {'chat_id': TG_CHAT_ID, 'text': str(request.json)}
|
||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
return response.json({'ok': False, 'error': 'There has been an issue sending your feedback.'})
|
return response.json({'ok': False, 'error': 'There has been an issue sending your feedback.'})
|
||||||
|
@ -85,19 +85,6 @@ async def show_events(request):
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@bp.route("/achievements.json")
|
|
||||||
async def show_achievements(request):
|
|
||||||
|
|
||||||
if request.token:
|
|
||||||
user = await request.app.ctx.om.get_order(code=request.token[:5])
|
|
||||||
if not user or user.app_token != request.token[5:]:
|
|
||||||
return response.json({'ok': False, 'error': 'The token you have provided is not valid.'}, status=401)
|
|
||||||
|
|
||||||
with sqlite3.connect('data/boop.db') as db:
|
|
||||||
db.row_factory = sqlite3.Row
|
|
||||||
events = db.execute('SELECT * FROM achievement ORDER BY points DESC')
|
|
||||||
return response.json([{'won_at': '2023-05-05T21:00Z' if request.token and random.random() < 0.2 else None, **dict(x), 'about': 'This is instructions on how to win the field.'} for x in events])
|
|
||||||
|
|
||||||
@bp.get("/logout")
|
@bp.get("/logout")
|
||||||
async def logout(request):
|
async def logout(request):
|
||||||
if not request.token:
|
if not request.token:
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
from sanic.response import html, redirect, text
|
from sanic.response import html
|
||||||
from sanic import Blueprint, exceptions
|
from sanic import Blueprint, exceptions
|
||||||
from random import choice
|
|
||||||
from ext import *
|
from ext import *
|
||||||
from config import headers
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
bp = Blueprint("carpooling", url_prefix="/manage/carpooling")
|
bp = Blueprint("carpooling", url_prefix="/manage/carpooling")
|
||||||
|
|
|
@ -1,11 +1,41 @@
|
||||||
headers = {'Host': 'your-pretix-hostname', 'Authorization': 'Token XXXXXXXXXXXXXXXXXXXXXXXX'}
|
ORGANIZER = 'furizon'
|
||||||
base_url = "https://your-pretix-hostname/api/v1/organizers/organizer-name/events/your-event/"
|
EVENT_NAME = 'river-side-2023'
|
||||||
|
API_TOKEN = 'xxxxxxxxxxxxxxxxxxxxxx'
|
||||||
|
HOSTNAME = 'your-pretix-hostname'
|
||||||
|
|
||||||
|
headers = {'Host': HOSTNAME, 'Authorization': f'Token {API_TOKEN}'}
|
||||||
|
base_url = f"https://{HOSTNAME}/api/v1/organizers/{ORGANIZER}/events/{EVENT_NAME}/"
|
||||||
|
|
||||||
PROPIC_DEADLINE = 1683575684
|
PROPIC_DEADLINE = 1683575684
|
||||||
FILL_CACHE = True
|
FILL_CACHE = True
|
||||||
|
|
||||||
DEV_MODE = True
|
DEV_MODE = True
|
||||||
|
|
||||||
|
ITEM_IDS = {
|
||||||
|
'ticket': [90,],
|
||||||
|
'membership_card': [91,],
|
||||||
|
'sponsorship': [], # first one = normal, second = super
|
||||||
|
'early_arrival': [],
|
||||||
|
'late_departure': [],
|
||||||
|
'room': 98
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create a bunch of "room" items which will get added to the order once somebody gets a room.
|
||||||
|
ROOM_MAP = {
|
||||||
|
1: 16,
|
||||||
|
2: 17,
|
||||||
|
3: 18,
|
||||||
|
4: 19,
|
||||||
|
5: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
# This is used for feedback sending inside of the app. Feedbacks will be sent to the specified chat using the bot api id.
|
||||||
|
TG_BOT_API = '123456789:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
|
||||||
|
TG_CHAT_ID = -1234567
|
||||||
|
|
||||||
|
# These order codes have additional functions.
|
||||||
|
ADMINS = ['XXXXX', 'YYYYY']
|
||||||
|
|
||||||
SMTP_HOST = 'your-smtp-host.com'
|
SMTP_HOST = 'your-smtp-host.com'
|
||||||
SMTP_USER = 'username'
|
SMTP_USER = 'username'
|
||||||
SMTP_PASSWORD = 'password'
|
SMTP_PASSWORD = 'password'
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
from sanic.response import text
|
from sanic.response import text
|
||||||
from sanic import Blueprint, exceptions
|
from sanic import Blueprint, exceptions
|
||||||
from ext import *
|
from ext import *
|
||||||
from config import headers
|
from config import headers, ADMINS, ORGANIZER, EVENT_NAME
|
||||||
|
|
||||||
bp = Blueprint("export", url_prefix="/manage/export")
|
bp = Blueprint("export", url_prefix="/manage/export")
|
||||||
|
|
||||||
@bp.route("/export.csv")
|
@bp.route("/export.csv")
|
||||||
async def export_csv(request, order: Order):
|
async def export_csv(request, order: Order):
|
||||||
if not order: raise exceptions.Forbidden("You have been logged out. Please access the link in your E-Mail to login again!")
|
if not order: raise exceptions.Forbidden("You have been logged out. Please access the link in your E-Mail to login again!")
|
||||||
if order.code not in ['HWUC9','9YKGJ']: raise exceptions.Forbidden("Birichino :)")
|
if order.code not in ADMINS: raise exceptions.Forbidden("Birichino :)")
|
||||||
|
|
||||||
page = 0
|
page = 0
|
||||||
orders = {}
|
orders = {}
|
||||||
|
@ -18,7 +18,7 @@ async def export_csv(request, order: Order):
|
||||||
while 1:
|
while 1:
|
||||||
page += 1
|
page += 1
|
||||||
|
|
||||||
r = httpx.get(f'https://reg.furizon.net/api/v1/organizers/furizon/events/beyond/orders/?page={page}', headers=headers)
|
r = httpx.get(f'https://reg.furizon.net/api/v1/organizers/{ORGANIZER}/events/{EVENT_NAME}/orders/?page={page}', headers=headers)
|
||||||
if r.status_code == 404: break
|
if r.status_code == 404: break
|
||||||
|
|
||||||
for r in r.json()['results']:
|
for r in r.json()['results']:
|
||||||
|
@ -64,7 +64,7 @@ async def export_hotel_csv(request, order: Order):
|
||||||
while 1:
|
while 1:
|
||||||
page += 1
|
page += 1
|
||||||
|
|
||||||
r = httpx.get(f'https://reg.furizon.net/api/v1/organizers/furizon/events/beyond/orders/?page={page}', headers=headers)
|
r = httpx.get(f'https://reg.furizon.net/api/v1/organizers/{ORGANIZER}/events/{EVENT_NAME}/orders/?page={page}', headers=headers)
|
||||||
if r.status_code == 404: break
|
if r.status_code == 404: break
|
||||||
|
|
||||||
for r in r.json()['results']:
|
for r in r.json()['results']:
|
||||||
|
|
15
karaoke.py
15
karaoke.py
|
@ -1,15 +1,8 @@
|
||||||
from sanic.response import html, redirect, text
|
from sanic.response import html, redirect, text
|
||||||
from sanic import Blueprint, exceptions, response
|
from sanic import Blueprint, exceptions, response
|
||||||
from random import choice
|
|
||||||
from ext import *
|
from ext import *
|
||||||
from config import headers, PROPIC_DEADLINE
|
|
||||||
from PIL import Image
|
|
||||||
from os.path import isfile
|
|
||||||
from os import unlink
|
|
||||||
from io import BytesIO
|
|
||||||
from hashlib import sha224
|
|
||||||
from time import time
|
|
||||||
from urllib.parse import unquote
|
from urllib.parse import unquote
|
||||||
|
from config import ADMINS
|
||||||
import json
|
import json
|
||||||
|
|
||||||
bp = Blueprint("karaoke", url_prefix="/manage/karaoke")
|
bp = Blueprint("karaoke", url_prefix="/manage/karaoke")
|
||||||
|
@ -17,7 +10,7 @@ bp = Blueprint("karaoke", url_prefix="/manage/karaoke")
|
||||||
@bp.get("/admin")
|
@bp.get("/admin")
|
||||||
async def show_songs(request, order: Order):
|
async def show_songs(request, order: Order):
|
||||||
|
|
||||||
if order.code not in ['9YKGJ', 'CMPQG']:
|
if order.code not in ADMINS:
|
||||||
raise exceptions.Forbidden("Birichino")
|
raise exceptions.Forbidden("Birichino")
|
||||||
|
|
||||||
orders = [x for x in request.app.ctx.om.cache.values() if x.karaoke_songs]
|
orders = [x for x in request.app.ctx.om.cache.values() if x.karaoke_songs]
|
||||||
|
@ -35,7 +28,7 @@ async def show_songs(request, order: Order):
|
||||||
@bp.post("/approve")
|
@bp.post("/approve")
|
||||||
async def approve_songs(request, order: Order):
|
async def approve_songs(request, order: Order):
|
||||||
|
|
||||||
if order.code not in ['9YKGJ', 'CMPQG']:
|
if order.code not in ADMINS:
|
||||||
raise exceptions.Forbidden("Birichino")
|
raise exceptions.Forbidden("Birichino")
|
||||||
|
|
||||||
for song in request.form:
|
for song in request.form:
|
||||||
|
@ -51,7 +44,7 @@ async def sing_song(request, order: Order, songname):
|
||||||
|
|
||||||
if not order: raise exceptions.Forbidden("You have been logged out. Please access the link in your E-Mail to login again!")
|
if not order: raise exceptions.Forbidden("You have been logged out. Please access the link in your E-Mail to login again!")
|
||||||
|
|
||||||
if order.code not in ['9YKGJ', 'CMPQG']:
|
if order.code not in ADMINS:
|
||||||
raise exceptions.Forbidden("Birichino")
|
raise exceptions.Forbidden("Birichino")
|
||||||
|
|
||||||
songname = unquote(songname)
|
songname = unquote(songname)
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
from sanic.response import html, redirect, text
|
from sanic.response import html, redirect
|
||||||
from sanic import Blueprint, exceptions
|
from sanic import Blueprint, exceptions
|
||||||
from random import choice
|
|
||||||
from ext import *
|
from ext import *
|
||||||
from config import headers, PROPIC_DEADLINE
|
from config import PROPIC_DEADLINE
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from os.path import isfile
|
|
||||||
from os import unlink
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from hashlib import sha224
|
from hashlib import sha224
|
||||||
from time import time
|
from time import time
|
||||||
|
|
5
stats.py
5
stats.py
|
@ -1,9 +1,6 @@
|
||||||
from sanic.response import html
|
from sanic.response import html
|
||||||
from sanic import Blueprint, exceptions
|
from sanic import Blueprint
|
||||||
from ext import *
|
from ext import *
|
||||||
from config import headers
|
|
||||||
from time import time
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
bp = Blueprint("stats", url_prefix="/manage")
|
bp = Blueprint("stats", url_prefix="/manage")
|
||||||
|
|
||||||
|
|
|
@ -88,9 +88,6 @@
|
||||||
<a href="/manage/nosecount">Nose Count</a>
|
<a href="/manage/nosecount">Nose Count</a>
|
||||||
{% if order %}
|
{% if order %}
|
||||||
<a href="/manage/carpooling">Carpooling</a>
|
<a href="/manage/carpooling">Carpooling</a>
|
||||||
{% if not order.room_confirmed %}
|
|
||||||
<a href="/manage/roommate_search">Roommate Search</a>
|
|
||||||
{% endif %}
|
|
||||||
<a style="float:right;" href="/manage/logout">Logout</a>
|
<a style="float:right;" href="/manage/logout">Logout</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br clear="both" />
|
<br clear="both" />
|
||||||
|
@ -109,7 +106,7 @@
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<footer>
|
<footer>
|
||||||
Made in 🇮🇹 by <img src="/res/icons/silhouette.svg" class="icon" title="ACCBCAC" /> · <a href="/manage/privacy">Privacy</a>
|
Made in 🇮🇹 by <img src="/res/icons/silhouette.svg" class="icon" /> · <a href="/manage/privacy">Privacy</a>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<h1>Cerca ordine</h1>
|
<h1>Search order</h1>
|
||||||
<input id="search" type="text" onchange="updateSearch();" onclick="this.value = '';" />
|
<input id="search" type="text" onchange="updateSearch();" onclick="this.value = '';" />
|
||||||
<form method="get" id="actionform" style="font-family:monospace;" action="order">
|
<form method="get" id="actionform" style="font-family:monospace;" action="order">
|
||||||
<select id="badgelist" name="order" id="order" multiple>
|
<select id="badgelist" name="order" id="order" multiple>
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<h1><kbd>{{order.code}}</kbd> {{order.name}} ({{order.first_name}} {{order.last_name}})</h1>
|
<h1><kbd>{{order.code}}</kbd> {{order.name}} ({{order.first_name}} {{order.last_name}})</h1>
|
||||||
<p><strong>Commento:</strong> {{order.comment or '--'}}<br />
|
<p><strong>Comment:</strong> {{order.comment or '--'}}<br />
|
||||||
<strong>Note ordine:</strong> {{order.notes or '--'}}<br />
|
<strong>Order notes:</strong> {{order.notes or '--'}}<br />
|
||||||
<strong>Stato ordine: <span style="color: {{'#900' if order.status == 'unpaid' else '#090'}}">{{order.status}}</span></strong><br />
|
<strong>Status: <span style="color: {{'#900' if order.status == 'unpaid' else '#090'}}">{{order.status}}</span></strong><br />
|
||||||
<strong>Sponsor: <span style="color: {{'#fa0' if order.sponsorship == 'super' else ('#e8e' if order.sponsorship else 'initial')}}">{{order.sponsorship}}</span></strong><br />
|
<strong>Sponsor: <span style="color: {{'#fa0' if order.sponsorship == 'super' else ('#e8e' if order.sponsorship else 'initial')}}">{{order.sponsorship}}</span></strong><br />
|
||||||
<strong>Compagni di stanza:</strong> {% for code in room_owner.room_members %}<kbd><a href="order?order={{code}}">{{code}}</a></kbd> {% endfor %}<br />
|
<strong>Roommates:</strong> {% for code in room_owner.room_members %}<kbd><a href="order?order={{code}}">{{code}}</a></kbd> {% endfor %}<br />
|
||||||
<a target="_blank" href="https://reg.furizon.net/control/event/furizon/beyond/orders/{{order.code}}/">Apri su pretix</a><br /></p>
|
<a target="_blank" href="https://{config.HOSTNAME}/control/event/{config.ORGANIZER}/{config.EVENT_NAME}/orders/{{order.code}}/">Open on pretix</a><br /></p>
|
||||||
<form method="post" id="actionform" action="checkin">
|
<form method="post" id="actionform" action="checkin">
|
||||||
<input type="hidden" value="{{order.code}}" name="code" />
|
<input type="hidden" value="{{order.code}}" name="code" />
|
||||||
<label for="actual_room">Numero Stanza Reale</label>
|
<label for="actual_room">Real Room Number</label>
|
||||||
<input type="text" value="{{room_owner.actual_room or ''}}" name="actual_room" required />
|
<input type="text" value="{{room_owner.actual_room or ''}}" name="actual_room" required />
|
||||||
<label for="nfc_id">NFC Badge</label>
|
<label for="nfc_id">NFC Badge</label>
|
||||||
<input type="text" value="{{order.nfc_id or ''}}" name="nfc_id" pattern="[A-F0-9]{14}" title="NFC Tag id must be 14 chars" required />
|
<input type="text" value="{{order.nfc_id or ''}}" name="nfc_id" pattern="[A-F0-9]{14}" title="NFC Tag id must be 14 chars" required />
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block main %}
|
{% block main %}
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<h1>✅ Checkin effettuato!</h1>
|
<h1>✅ Checkin done!</h1>
|
||||||
<p><strong>Ricorda di apporre il numero sul badge! Numero: {{order.badge_id}}</strong></p>
|
<p><strong>Remember to stick the REG number to the badge! Number: {{order.badge_id}}</strong></p>
|
||||||
|
|
||||||
<h2>Altri membri della stessa stanza ({{room_owner.actual_room}})</h2>
|
<h2>Other members of the same room ({{room_owner.actual_room}})</h2>
|
||||||
<table>
|
<table>
|
||||||
{% for o in roommates %}
|
{% for o in roommates %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="order?order={{o.code}}">{{o.code}}</a></td>
|
<td><a href="order?order={{o.code}}">{{o.code}}</a></td>
|
||||||
<td>{{o.name}}</td>
|
<td>{{o.name}}</td>
|
||||||
<td><a href="order?order={{o.code}}">{{'Effettua Checkin' if not o.checked_in else '✅'}}</a></td>
|
<td><a href="order?order={{o.code}}">{{'Checkin' if not o.checked_in else '✅'}}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
<h3><a href="start">Effettua un altro checkin ➡️</a></h3>
|
<h3><a href="start">Checkin somebody else ➡️</a></h3>
|
||||||
</main>
|
</main>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<main class="container">
|
<main class="container">
|
||||||
<h1>Karaoke Admin</h1>
|
<h1>Karaoke Admin</h1>
|
||||||
|
|
||||||
<h2>Canzoni da cantare</h2>
|
<h2>Songs to sing</h2>
|
||||||
<table>
|
<table>
|
||||||
{% for s in songs if s.approved is not none and (not s.singed) %}
|
{% for s in songs if s.approved is not none and (not s.singed) %}
|
||||||
<tr {% if s.approved == false %}style="text-decoration: line-through"{% endif %}>
|
<tr {% if s.approved == false %}style="text-decoration: line-through"{% endif %}>
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
{% block title %}Furizon 2023 Stats{% endblock %}
|
|
||||||
{% block main %}
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
||||||
<main class="container">
|
|
||||||
<header>
|
|
||||||
<picture>
|
|
||||||
<source srcset="/res/furizon.png" media="(prefers-color-scheme:dark)">
|
|
||||||
<img src="/res/furizon-light.png" style="height:4rem;text-align:center;">
|
|
||||||
</picture>
|
|
||||||
</header>
|
|
||||||
<h2>Countries</h2>
|
|
||||||
<div style="margin: 0 auto;">
|
|
||||||
<canvas id="countries"></canvas>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
const ctx = document.getElementById('countries');
|
|
||||||
new Chart(ctx, {
|
|
||||||
type: 'bar',
|
|
||||||
data: {
|
|
||||||
labels: {{stats['countries'].keys()|list|safe}},
|
|
||||||
datasets: [{
|
|
||||||
label: '# of Attendees',
|
|
||||||
data: {{stats['countries'].values()|list|safe}},
|
|
||||||
borderWidth: 0
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: {
|
|
||||||
scales: {
|
|
||||||
y: {beginAtZero: true}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<h2>Sponsors</h2>
|
|
||||||
<div style="max-width:20em;margin: 0 auto;">
|
|
||||||
<canvas id="sponsors"></canvas>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
const ctx2 = document.getElementById('sponsors');
|
|
||||||
new Chart(ctx2, {
|
|
||||||
type: 'pie',
|
|
||||||
data: {
|
|
||||||
labels: {{stats['sponsors'].keys()|list|safe}},
|
|
||||||
datasets: [{
|
|
||||||
label: '# of Attendees',
|
|
||||||
data: {{stats['sponsors'].values()|list|safe}},
|
|
||||||
borderWidth: 0
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</main>
|
|
||||||
{% endblock %}
|
|
|
@ -24,7 +24,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>When{{' (convention)' if order.has_early or order.has_late else ''}}?</th>
|
<th>When{{' (convention)' if order.has_early or order.has_late else ''}}?</th>
|
||||||
<td>30 May → 3 June 2023</td></td>
|
<td>13 October → 15 October 2023</td></td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if order.has_early or order.has_late %}
|
{% if order.has_early or order.has_late %}
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
{% if order.status == 'paid' and order.room_confirmed %}
|
{% if order.status == 'paid' and order.room_confirmed %}
|
||||||
<br />
|
<br />
|
||||||
<img src="/res/icons/pdf.svg" class="icon" />
|
<img src="/res/icons/pdf.svg" class="icon" />
|
||||||
<a href="/manage/download_ticket?name=BEYOND-{{order.code}}.pdf" target="_blank">Download ticket PDF</a>
|
<a href="/manage/download_ticket?name=RIVERSIDE-{{order.code}}.pdf" target="_blank">Download ticket PDF</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
Loading…
Reference in New Issue