stranck-dev #31
48
admin.py
48
admin.py
|
@ -62,13 +62,14 @@ async def unconfirm_room(request, code, order:Order):
|
|||
return redirect(f'/manage/nosecount')
|
||||
|
||||
@bp.get('/room/autoconfirm')
|
||||
async def autoconfirm_room(request, code, order:Order):
|
||||
async def autoconfirm_room(request, order:Order):
|
||||
await clear_cache(request, order)
|
||||
orders = request.app.ctx.om.cache.values()
|
||||
for order in orders:
|
||||
if(order.code == order.room_id and not order.room_confirmed and len(order.room_members) == order.room_person_no):
|
||||
logger.info(f"Auto-Confirming room {order.room_id}")
|
||||
await confirm_room_by_order(order, request)
|
||||
await clear_cache(request, order)
|
||||
return redirect(f'/manage/admin')
|
||||
|
||||
@bp.get('/room/delete/<code>')
|
||||
|
@ -111,12 +112,12 @@ async def room_wizard(request, order:Order):
|
|||
await clear_cache(request, order)
|
||||
|
||||
#Separate orders which have incomplete rooms and which have no rooms
|
||||
all_orders = {key:value for key,value in sorted(request.app.ctx.om.cache.items(), key=lambda x: len(x[1].room_members), reverse=True) if value.status not in ['c', 'e'] and not value.daily}
|
||||
all_orders = {key:value for key,value in sorted(request.app.ctx.om.cache.items(), key=lambda x: (x[1].room_person_no, len(x[1].room_members)), reverse=True) if (value.status not in ['canceled', 'expired'] and not value.daily and value.bed_in_room != ITEM_VARIATIONS_MAP["bed_in_room"]["bed_in_room_no_room"])}
|
||||
orders = {key:value for key,value in sorted(all_orders.items(), key=lambda x: x[1].ans('fursona_name')) if not value.room_confirmed}
|
||||
# Orders with incomplete rooms
|
||||
incomplete_orders = {key:value for key,value in orders.items() if value.code == value.room_id and (value.room_person_no - len(value.room_members)) > 0}
|
||||
# Roomless furs
|
||||
roomless_orders = {key:value for key,value in orders.items() if not value.room_id and not value.daily}
|
||||
roomless_orders = {key:value for key,value in orders.items() if(not value.room_id and not value.daily and value.bed_in_room != ITEM_VARIATIONS_MAP["bed_in_room"]["bed_in_room_no_room"])}
|
||||
|
||||
# Result map
|
||||
result_map = {}
|
||||
|
@ -124,10 +125,13 @@ async def room_wizard(request, order:Order):
|
|||
# Check overflows
|
||||
room_quota_overflow = {}
|
||||
for key, value in ITEM_VARIATIONS_MAP['bed_in_room'].items():
|
||||
room_quota = get_quota(ITEMS_ID_MAP['bed_in_room'], value)
|
||||
capacity = ROOM_CAPACITY_MAP[key] if key in ROOM_CAPACITY_MAP else 1
|
||||
current_quota = len(list(filter(lambda y: y.bed_in_room == value and y.room_owner == True, orders.values())))
|
||||
room_quota_overflow[value] = current_quota - int(room_quota.size / capacity) if room_quota else 0
|
||||
if key != "bed_in_room_no_room":
|
||||
room_quota = get_quota(ITEMS_ID_MAP['bed_in_room'], value)
|
||||
capacity = ROOM_CAPACITY_MAP[key] if key in ROOM_CAPACITY_MAP else 1
|
||||
current_quota = len(list(filter(lambda y: y.bed_in_room == value and y.room_owner == True, all_orders.values())))
|
||||
room_quota_overflow[value] = current_quota - int(room_quota.size / capacity) if room_quota else 0
|
||||
if DEV_MODE and EXTRA_PRINTS:
|
||||
print(f"There are {current_quota} of room type {key} out of a total of ({room_quota.size} / {capacity})")
|
||||
|
||||
# Init rooms to remove
|
||||
result_map["void"] = []
|
||||
|
@ -135,6 +139,7 @@ async def room_wizard(request, order:Order):
|
|||
# Remove rooms that are over quota
|
||||
for room_type, overflow_qty in {key:value for key,value in room_quota_overflow.items() if value > 0}.items():
|
||||
sorted_rooms = sorted(incomplete_orders.values(), key=lambda r: len(r.room_members))
|
||||
sorted_rooms = [r for r in sorted_rooms if r.bed_in_room == room_type]
|
||||
for room_to_remove in sorted_rooms[:overflow_qty]:
|
||||
# Room codes to remove
|
||||
result_map["void"].append(room_to_remove.code)
|
||||
|
@ -147,8 +152,10 @@ async def room_wizard(request, order:Order):
|
|||
for room_order in incomplete_orders.items():
|
||||
room = room_order[1]
|
||||
to_add = []
|
||||
missing_slots = room.room_person_no - len(room.room_members)
|
||||
for i in range(missing_slots):
|
||||
count = room.room_person_no
|
||||
alreadyPresent = len(room.room_members)
|
||||
missing_slots = count - alreadyPresent
|
||||
for _ in range(missing_slots):
|
||||
compatible_roomates = {key:value for key,value in roomless_orders.items() if value.bed_in_room == room.bed_in_room}
|
||||
if len(compatible_roomates.items()) == 0: break
|
||||
# Try picking a roomate that's from the same country and room type
|
||||
|
@ -165,7 +172,9 @@ async def room_wizard(request, order:Order):
|
|||
del roomless_orders[code_to_add]
|
||||
result_map[room.code] = {
|
||||
'type': 'add_existing',
|
||||
'to_add': to_add
|
||||
'to_add': to_add,
|
||||
'count': count,
|
||||
'previouslyPresent': alreadyPresent
|
||||
}
|
||||
|
||||
generated_counter = 0
|
||||
|
@ -173,8 +182,10 @@ async def room_wizard(request, order:Order):
|
|||
while len(roomless_orders.items()) > 0:
|
||||
room = list(roomless_orders.items())[0][1]
|
||||
to_add = []
|
||||
missing_slots = room.room_person_no - len(room.room_members)
|
||||
for i in range(missing_slots):
|
||||
count = room.room_person_no
|
||||
alreadyPresent = len(room.room_members)
|
||||
missing_slots = count - alreadyPresent
|
||||
for _ in range(missing_slots):
|
||||
compatible_roomates = {key:value for key,value in roomless_orders.items() if value.bed_in_room == room.bed_in_room}
|
||||
if len(compatible_roomates.items()) == 0: break
|
||||
# Try picking a roomate that's from the same country and room type
|
||||
|
@ -194,17 +205,20 @@ async def room_wizard(request, order:Order):
|
|||
'type': 'new',
|
||||
'room_name': f'Generated Room {generated_counter}',
|
||||
'room_type': room.bed_in_room,
|
||||
'to_add': to_add
|
||||
'to_add': to_add,
|
||||
'count': count,
|
||||
'previouslyPresent': alreadyPresent
|
||||
}
|
||||
|
||||
result_map["infinite"] = { 'to_add': [] }
|
||||
result_map = {k: v for k, v in sorted(result_map.items(), key=lambda x: ((x[1]["count"], x[1]["previouslyPresent"]) if("count" in x[1] and "previouslyPresent" in x[1]) else (4316, 0) ))}
|
||||
tpl = request.app.ctx.tpl.get_template('wizard.html')
|
||||
return html(tpl.render(order=order, all_orders=all_orders, unconfirmed_orders=orders, data=result_map, jsondata=json.dumps(result_map, skipkeys=True, ensure_ascii=False)))
|
||||
|
||||
@bp.post('/room/wizard/submit')
|
||||
async def submit_from_room_wizard(request:Request, order:Order):
|
||||
'''Will apply changes to the rooms'''
|
||||
await request.app.ctx.om.fill_cache()
|
||||
await clear_cache(request, order)
|
||||
|
||||
data = json.loads(request.body)
|
||||
|
||||
|
@ -253,7 +267,7 @@ async def submit_from_room_wizard(request:Request, order:Order):
|
|||
pending_member = await request.app.ctx.om.get_order(code=new_member_code)
|
||||
# Preconditions
|
||||
if pending_member.daily == True: raise exceptions.BadRequest(f"Order {pending_member.code} is daily.")
|
||||
if pending_member.status != 'paid': raise exceptions.BadRequest(f"Order {new_member_code} hasn't paid.")
|
||||
#if pending_member.status != 'paid': raise exceptions.BadRequest(f"Order {new_member_code} hasn't paid.") # Since we don't confirm rooms anymore, we don't need to check if they're paid or not
|
||||
if pending_member.bed_in_room != room_order.bed_in_room: raise exceptions.BadRequest(f"Order {new_member_code} has a different room type than {room_code}.")
|
||||
if pending_member.room_owner: exceptions.BadRequest(f"Order {new_member_code} is already a room owner.")
|
||||
if pending_member.room_id and pending_member.room_id not in data['void']: exceptions.BadRequest(f"Order {new_member_code} is in another room.")
|
||||
|
@ -270,10 +284,10 @@ async def submit_from_room_wizard(request:Request, order:Order):
|
|||
else: raise exceptions.BadRequest(f"Unexpected type ({value['type']})")
|
||||
await room_order.edit_answer('pending_room', None)
|
||||
await room_order.edit_answer('pending_roommates', None)
|
||||
await room_order.edit_answer('room_confirmed', "True")
|
||||
# await room_order.edit_answer('room_confirmed', "True") Use the autoconfirm button in the admin panel
|
||||
await room_order.edit_answer('room_members', ','.join(list(set([*room_order.room_members, room_order.code, *value['to_add']]))))
|
||||
await room_order.send_answers()
|
||||
await request.app.ctx.om.fill_cache()
|
||||
await clear_cache(request, order)
|
||||
return text('done', status=200)
|
||||
|
||||
|
||||
|
|
15
api.py
15
api.py
|
@ -34,7 +34,8 @@ async def api_members(request):
|
|||
'propic_fursuiter': o.ans('propic_fursuiter'),
|
||||
'staff_role': o.ans('staff_role'),
|
||||
'country': o.country,
|
||||
'is_checked_in': False,
|
||||
'room_id': o.room_id,
|
||||
'is_checked_in': o.checked_in,
|
||||
'points': random.randint(0,50) if random.random() > 0.3 else 0
|
||||
})
|
||||
|
||||
|
@ -112,6 +113,10 @@ async def token_test(request):
|
|||
return response.json({'ok': False, 'error': 'The token you have provided is not correct.'}, status=401)
|
||||
|
||||
return response.json({'ok': True, 'message': 'This token is valid :)'})
|
||||
|
||||
@bp.get("/ping")
|
||||
async def ping(request):
|
||||
return response.text("pong")
|
||||
|
||||
@bp.get("/welcome")
|
||||
async def welcome_app(request):
|
||||
|
@ -139,15 +144,18 @@ async def welcome_app(request):
|
|||
'propic_fursuiter': o.ans('propic_fursuiter'),
|
||||
'staff_role': o.ans('staff_role'),
|
||||
'country': o.country,
|
||||
'is_checked_in': False,
|
||||
'is_checked_in': o.checked_in,
|
||||
'points': random.randint(0,50) if random.random() > 0.3 else 0,
|
||||
'can_scan_nfc': o.can_scan_nfc,
|
||||
'room_id': o.room_id,
|
||||
#'mail': o.email,
|
||||
'actual_room_id': o.actual_room,
|
||||
**ret
|
||||
})
|
||||
|
||||
@bp.get("/scan/<nfc_id>")
|
||||
async def nfc_scan(request, nfc_id):
|
||||
return response.text("Nope")
|
||||
if not request.token:
|
||||
return response.json({'ok': False, 'error': 'You need to provide a token.'}, status=401)
|
||||
|
||||
|
@ -174,11 +182,12 @@ async def nfc_scan(request, nfc_id):
|
|||
'propic_fursuiter': o.ans('propic_fursuiter'),
|
||||
'staff_role': o.ans('staff_role'),
|
||||
'country': o.country,
|
||||
'is_checked_in': False,
|
||||
'is_checked_in': o.checked_in,
|
||||
'points': random.randint(0,50) if random.random() > 0.3 else 0,
|
||||
'comment': o.comment,
|
||||
'actual_room_id': o.actual_room,
|
||||
'phone': o.phone,
|
||||
'room_id': o.room_id,
|
||||
'telegram_username': o.telegram_username,
|
||||
'roommates': {x: (await request.app.ctx.om.get_order(code=x, cached=True)).name for x in room_owner.room_members if x != o.code}
|
||||
})
|
||||
|
|
10
app.py
10
app.py
|
@ -16,10 +16,12 @@ import requests
|
|||
import sys
|
||||
from sanic.log import logger, logging, access_logger
|
||||
from metrics import *
|
||||
from utils import isSessionAdmin
|
||||
from email_util import killSmptClient
|
||||
import pretixClient
|
||||
import traceback
|
||||
|
||||
|
||||
app = Sanic(__name__)
|
||||
app.static("/res", "res/")
|
||||
|
||||
|
@ -80,6 +82,7 @@ async def main_start(*_):
|
|||
app.ctx.tpl = Environment(loader=FileSystemLoader("tpl"), autoescape=True)
|
||||
app.ctx.tpl.globals.update(time=time)
|
||||
app.ctx.tpl.globals.update(PROPIC_DEADLINE=PROPIC_DEADLINE)
|
||||
app.ctx.tpl.globals.update(ROOM_DEADLINE=ROOM_DEADLINE)
|
||||
app.ctx.tpl.globals.update(LOCALES=LOCALES)
|
||||
app.ctx.tpl.globals.update(ITEMS_ID_MAP=ITEMS_ID_MAP)
|
||||
app.ctx.tpl.globals.update(ITEM_VARIATIONS_MAP=ITEM_VARIATIONS_MAP)
|
||||
|
@ -98,11 +101,6 @@ async def gen_barcode(request, code):
|
|||
|
||||
return raw(img.getvalue(), content_type="image/png")
|
||||
|
||||
@app.route("/manage/lol")
|
||||
async def lol(request: Request):
|
||||
await get_quotas(request)
|
||||
return text('hi')
|
||||
|
||||
@app.route(f"/{ORGANIZER}/{EVENT_NAME}/order/<code>/<secret>/open/<secret2>")
|
||||
async def redirect_explore(request, code, secret, order: Order, secret2=None):
|
||||
|
||||
|
@ -161,7 +159,7 @@ async def welcome(request, order: Order, quota: Quotas):
|
|||
room_members.append(await app.ctx.om.get_order(code=member_id, cached=True))
|
||||
|
||||
tpl = app.ctx.tpl.get_template('welcome.html')
|
||||
return html(tpl.render(order=order, quota=quota, room_members=room_members, pending_roommates=pending_roommates, ROOM_ERROR_MESSAGES=ROOM_ERROR_TYPES))
|
||||
return html(tpl.render(order=order, quota=quota, room_members=room_members, pending_roommates=pending_roommates, ROOM_ERROR_MESSAGES=ROOM_ERROR_TYPES, isSessionAdmin=await isSessionAdmin(request, order)))
|
||||
|
||||
|
||||
@app.route("/manage/download_ticket")
|
||||
|
|
|
@ -17,6 +17,8 @@ PROPIC_MAX_FILE_SIZE = 5 * 1024 * 1024 # 5MB
|
|||
PROPIC_MAX_SIZE = (2048, 2048) # (Width, Height)
|
||||
PROPIC_MIN_SIZE = (125, 125) # (Width, Height)
|
||||
|
||||
ROOM_DEADLINE = 9999999999
|
||||
|
||||
# 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
|
||||
|
|
|
@ -15,30 +15,44 @@ def killSmptClient():
|
|||
global sslLock
|
||||
global sslTimer
|
||||
global smptSender
|
||||
logger.info(f"[SMPT] killSmptClient: Lock status: {sslLock.locked()}")
|
||||
sslTimer.cancel()
|
||||
sslLock.acquire()
|
||||
exp = None
|
||||
if(smptSender is not None):
|
||||
logger.debug('[SMPT] Closing smpt client')
|
||||
smptSender.quit() # it calls close() inside
|
||||
try:
|
||||
smptSender.quit() # it calls close() inside
|
||||
except Exception as e:
|
||||
exp = e
|
||||
smptSender = None
|
||||
sslLock.release()
|
||||
if(exp != None):
|
||||
raise exp
|
||||
|
||||
async def openSmptClient():
|
||||
global sslLock
|
||||
global sslTimer
|
||||
global sslContext
|
||||
global smptSender
|
||||
logger.info(f"[SMPT] openSmptClient: Lock status: {sslLock.locked()}")
|
||||
sslTimer.cancel()
|
||||
sslLock.acquire()
|
||||
if(smptSender is None):
|
||||
logger.debug('[SMPT] Opening smpt client')
|
||||
client : smtplib.SMTP = smtplib.SMTP(SMTP_HOST, SMTP_PORT)
|
||||
client.starttls(context=sslContext)
|
||||
client.login(SMTP_USER, SMTP_PASSWORD)
|
||||
smptSender = client
|
||||
exp = None
|
||||
try:
|
||||
if(smptSender is None):
|
||||
logger.debug('[SMPT] Opening smpt client')
|
||||
client : smtplib.SMTP = smtplib.SMTP(SMTP_HOST, SMTP_PORT)
|
||||
client.starttls(context=sslContext)
|
||||
client.login(SMTP_USER, SMTP_PASSWORD)
|
||||
smptSender = client
|
||||
except Exception as e:
|
||||
exp = e
|
||||
sslLock.release()
|
||||
sslTimer = createTimer()
|
||||
sslTimer.start()
|
||||
if(exp != None):
|
||||
raise exp
|
||||
|
||||
def createTimer():
|
||||
return Timer(SMPT_CLIENT_CLOSE_TIMEOUT, killSmptClient)
|
||||
|
@ -51,9 +65,16 @@ async def sendEmail(message : MIMEMultipart):
|
|||
message['From'] = f'{EMAIL_SENDER_NAME} <{EMAIL_SENDER_MAIL}>'
|
||||
await openSmptClient()
|
||||
logger.debug(f"[SMPT] Sending mail {message['From']} -> {message['to']} '{message['Subject']}'")
|
||||
logger.info(f"[SMPT] sendEmail: Lock status: {sslLock.locked()}")
|
||||
exp = None
|
||||
sslLock.acquire()
|
||||
smptSender.sendmail(message['From'], message['to'], message.as_string())
|
||||
try:
|
||||
smptSender.sendmail(message['From'], message['to'], message.as_string())
|
||||
except Exception as e:
|
||||
exp = e
|
||||
sslLock.release()
|
||||
if(exp != None):
|
||||
raise exp
|
||||
|
||||
def render_email_template(title = "", body = ""):
|
||||
tpl = Environment(loader=FileSystemLoader("tpl"), autoescape=False).get_template('email/comunication.html')
|
||||
|
|
24
ext.py
24
ext.py
|
@ -282,9 +282,12 @@ class Quota:
|
|||
return f'Quota [items={self.items}, variations={self.variations}] [{self.available_number}/{self.size}]'
|
||||
|
||||
def get_quota(item: int, variation: int = None) -> Quota:
|
||||
ret : Quota = None
|
||||
for q in QUOTA_LIST:
|
||||
if (q.has_item(item, variation)): return q
|
||||
return None
|
||||
if (q.has_item(item, variation)):
|
||||
if(ret == None or (q.size != None and q.size < ret.size)):
|
||||
ret = q
|
||||
return ret
|
||||
|
||||
@dataclass
|
||||
class Quotas:
|
||||
|
@ -364,9 +367,24 @@ class OrderManager:
|
|||
del cache[code]
|
||||
orderList.remove(code)
|
||||
|
||||
|
||||
async def fill_cache(self, check_itemsQuestions=False) -> bool:
|
||||
# Check cache lock
|
||||
logger.info(f"[CACHE] Lock status: {self.updating.locked()}")
|
||||
self.updating.acquire()
|
||||
ret = False
|
||||
exp = None
|
||||
try:
|
||||
ret = await self.fill_cache_INTERNAL(check_itemsQuestions=check_itemsQuestions)
|
||||
except Exception as e:
|
||||
exp = e
|
||||
self.updating.release()
|
||||
logger.info(f"[CACHE] Ret status: {ret}. Exp: {exp}")
|
||||
if(exp != None):
|
||||
raise exp
|
||||
return ret
|
||||
|
||||
async def fill_cache_INTERNAL(self, check_itemsQuestions=False) -> bool:
|
||||
start_time = time()
|
||||
logger.info("[CACHE] Filling cache...")
|
||||
# Index item's ids
|
||||
|
@ -409,8 +427,6 @@ class OrderManager:
|
|||
except Exception:
|
||||
logger.error(f"[CACHE] Error while refreshing cache.\n{traceback.format_exc()}")
|
||||
success = False
|
||||
finally:
|
||||
self.updating.release()
|
||||
|
||||
# Apply new cache if there were no errors
|
||||
if(success):
|
||||
|
|
|
@ -3,6 +3,7 @@ from sanic import Blueprint, exceptions, response
|
|||
from ext import *
|
||||
from urllib.parse import unquote
|
||||
from config import ADMINS
|
||||
from utils import isSessionAdmin
|
||||
import json
|
||||
|
||||
bp = Blueprint("karaoke", url_prefix="/manage/karaoke")
|
||||
|
@ -10,7 +11,7 @@ bp = Blueprint("karaoke", url_prefix="/manage/karaoke")
|
|||
@bp.get("/admin")
|
||||
async def show_songs(request, order: Order):
|
||||
|
||||
if not order.isAdmin():
|
||||
if not await isSessionAdmin(request, order):
|
||||
raise exceptions.Forbidden("Birichino")
|
||||
|
||||
orders = [x for x in request.app.ctx.om.cache.values() if x.karaoke_songs]
|
||||
|
@ -28,7 +29,7 @@ async def show_songs(request, order: Order):
|
|||
@bp.post("/approve")
|
||||
async def approve_songs(request, order: Order):
|
||||
|
||||
if not order.isAdmin():
|
||||
if not await isSessionAdmin(request, order):
|
||||
raise exceptions.Forbidden("Birichino")
|
||||
|
||||
for song in request.form:
|
||||
|
@ -44,7 +45,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.isAdmin():
|
||||
if not await isSessionAdmin(request, order):
|
||||
raise exceptions.Forbidden("Birichino")
|
||||
|
||||
songname = unquote(songname)
|
||||
|
|
|
@ -6,6 +6,7 @@ from PIL import Image
|
|||
from io import BytesIO
|
||||
from hashlib import sha224
|
||||
from time import time
|
||||
from utils import isSessionAdmin
|
||||
import os
|
||||
|
||||
bp = Blueprint("propic", url_prefix="/manage/propic")
|
||||
|
@ -38,7 +39,7 @@ async def upload_propic(request, order: Order):
|
|||
if order.propic_locked:
|
||||
raise exceptions.BadRequest("You have been limited from further editing the propic.")
|
||||
|
||||
if request.form.get('submit') != 'Upload' and time() > PROPIC_DEADLINE:
|
||||
if request.form.get('submit') != 'Upload' and (time() > PROPIC_DEADLINE and not await isSessionAdmin(request, order)):
|
||||
raise exceptions.BadRequest("The deadline has passed. You cannot modify the badges at this moment.")
|
||||
|
||||
if request.form.get('submit') == 'Delete main image':
|
||||
|
|
11
room.py
11
room.py
|
@ -6,9 +6,18 @@ from config import headers
|
|||
import os
|
||||
from image_util import generate_room_preview, get_room
|
||||
from utils import confirm_room_by_order
|
||||
from time import time
|
||||
|
||||
bp = Blueprint("room", url_prefix="/manage/room")
|
||||
|
||||
@bp.middleware
|
||||
async def deadline_check(request: Request):
|
||||
order = await get_order(request)
|
||||
if not order:
|
||||
raise exceptions.Forbidden("You have been logged out. Please access the link in your E-Mail to login again!")
|
||||
if time() > ROOM_DEADLINE and not await isSessionAdmin(request, order):
|
||||
raise exceptions.BadRequest("The deadline has passed. You cannot modify the room at this moment.")
|
||||
|
||||
@bp.post("/create")
|
||||
async def room_create_post(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!")
|
||||
|
@ -304,7 +313,7 @@ async def confirm_room(request, order: Order, quotas: Quotas):
|
|||
#if quotas.get_left(len(order.room_members)) == 0:
|
||||
# raise exceptions.BadRequest("There are no more rooms of this size to reserve.")
|
||||
|
||||
confirm_room_by_order(order, request)
|
||||
await confirm_room_by_order(order, request)
|
||||
|
||||
return redirect('/manage/welcome')
|
||||
|
||||
|
|
|
@ -1,21 +1,28 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from os import listdir, remove
|
||||
from os import listdir, remove, getenv
|
||||
from os.path import isfile, join
|
||||
import datetime
|
||||
import subprocess
|
||||
|
||||
PRETIX_BACKUP = False
|
||||
WEBINT_BACKUP = False
|
||||
WP_BACKUP = False
|
||||
STUFF_BACKUP = False
|
||||
|
||||
BACKUP_DIR_PRETIX = "/home/pretix/backups/"
|
||||
BACKUP_DIR_WEBINT = "/home/webint/backups/"
|
||||
BACKUP_DIR_WP = "/home/worcopio/backups/"
|
||||
BACKUP_DIR_STUFF = "/root/backups/"
|
||||
|
||||
MAX_FILE_NO = 14
|
||||
MAX_FILE_NO = 7
|
||||
|
||||
COMMAND_PRETIX_POSTGRES = "pg_dump -F p pretix | gzip > %s" # Restore with psql -f %s
|
||||
COMMAND_PRETIX_DATA = "tar -cf %s /var/pretix-data" # Restore with tar -xvf %s. To make .secret readable I used setfacl -m u:pretix:r /var/pretix-data/.secret
|
||||
COMMAND_WEBINT = "tar -cf %s /home/webint/furizon_webint" # Restore with tar -xvf %s
|
||||
COMMAND_PRETIX_DATA = "tar -czf %s /var/pretix-data" # Restore with tar -xvf %s. To make .secret readable I used setfacl -m u:pretix:r /var/pretix-data/.secret
|
||||
COMMAND_WEBINT = "tar -czf %s /home/webint/furizon_webint" # Restore with tar -xvf %s
|
||||
COMMAND_WP_MYSQL = "mysqldump -h 127.0.0.1 -P 5688 -u root --password=__PASSWORD__ --all-databases | gzip > %s" # Restore with zcat %s | mysql -h 127.0.0.1 -P 5688 -u root
|
||||
COMMAND_WP_DATA = "tar -czf %s /var/lib/docker/volumes/worcopio-docker_wordpress/_data" # Restore with tar -xvf %s
|
||||
COMMAND_STUFF = "tar -czf %s /etc/ /var/backups/ /var/log/ /var/mail/ /var/pretix-data/ /var/prometheus-data/ /var/spool/ /var/www/ /var/lib/grafana/ /var/lib/redis/" # Restore with tar -xvf %s
|
||||
|
||||
|
||||
def deleteOlder(path : str, prefix : str, postfix : str):
|
||||
|
@ -41,4 +48,19 @@ if(PRETIX_BACKUP):
|
|||
runBackup("pretix_data", "backup.tar.gz", join(BACKUP_DIR_PRETIX, "data"), COMMAND_PRETIX_DATA)
|
||||
|
||||
if(WEBINT_BACKUP):
|
||||
runBackup("webint_full", "backup.tar.gz", BACKUP_DIR_WEBINT, COMMAND_WEBINT)
|
||||
runBackup("webint_full", "backup.tar.gz", BACKUP_DIR_WEBINT, COMMAND_WEBINT)
|
||||
|
||||
if(WP_BACKUP):
|
||||
mysqlCmd = COMMAND_WP_MYSQL
|
||||
mysqlPwd = getenv("MYSQL_PWD")
|
||||
if(mysqlPwd != None and mysqlPwd.strip() != ""):
|
||||
mysqlPwd = mysqlPwd.strip()
|
||||
print(f"Running with password `{mysqlPwd}`")
|
||||
mysqlCmd = mysqlCmd.replace("__PASSWORD__", mysqlPwd)
|
||||
runBackup("wp_mysql", "backup.sql.gz", join(BACKUP_DIR_WP, "mysql"), mysqlCmd)
|
||||
else:
|
||||
print("Backup run without the $MYSQL_PWD env var set. Skipping wp_mysql backup")
|
||||
runBackup("wp_wp", "backup.tar.gz", join(BACKUP_DIR_WP, "wp"), COMMAND_WP_DATA)
|
||||
|
||||
if(STUFF_BACKUP):
|
||||
runBackup("stuff", "backup.tar.gz", BACKUP_DIR_STUFF, COMMAND_STUFF)
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# python merda
|
||||
import asyncio
|
||||
|
||||
async def a():
|
||||
print("a")
|
||||
|
||||
def b():
|
||||
loop = asyncio.get_event_loop()
|
||||
print(loop)
|
||||
|
||||
b()
|
|
@ -32,7 +32,7 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if time() > PROPIC_DEADLINE %}
|
||||
{% if time() > PROPIC_DEADLINE and not isSessionAdmin %}
|
||||
<p class="notice">⚠️ The deadline to upload pictures for the badge has expired. For last-minute changes, please contact the support over at <a href="mailto:info@furizon.net">info@furizon.net</a>. If your badge has been printed already, changing it will incur in a 2€ fee. You can also get extra badges at the reception for the same price. If you upload a propic now, it might not be printed on time.</p>
|
||||
{% else %}
|
||||
<p><em>
|
||||
|
@ -43,9 +43,9 @@
|
|||
{% endif %}
|
||||
|
||||
<div class="grid grid_2x2">
|
||||
<input style="grid-area: 1 / 1 / 2 / 3;" type="submit" name="submit" value="Upload" {{'disabled' if (order.ans('propic') and order.ans('propic_fursuiter')) else ''}} />
|
||||
<input style="grid-area: 2 / 1 / 3 / 2;" type="submit" name="submit" value="Delete main image" {{'disabled' if (time() > PROPIC_DEADLINE or not order.ans('propic')) else ''}} />
|
||||
<input style="grid-area: 2 / 2 / 3 / 3;" type="submit" name="submit" value="Delete fursuit image" {{'disabled' if (time() > PROPIC_DEADLINE or not order.ans('propic_fursuiter')) else ''}} />
|
||||
<input style="grid-area: 1 / 1 / 2 / 3;" type="submit" name="submit" value="Upload" {{'disabled' if ((order.ans('propic') and order.ans('propic_fursuiter'))) or (time() > PROPIC_DEADLINE and not isSessionAdmin) else ''}} />
|
||||
<input style="grid-area: 2 / 1 / 3 / 2;" type="submit" name="submit" value="Delete main image" {{'disabled' if ((time() > PROPIC_DEADLINE and not isSessionAdmin) or not order.ans('propic')) else ''}} />
|
||||
<input style="grid-area: 2 / 2 / 3 / 3;" type="submit" name="submit" value="Delete fursuit image" {{'disabled' if ((time() > PROPIC_DEADLINE and not isSessionAdmin) or not order.ans('propic_fursuiter')) else ''}} />
|
||||
</div>
|
||||
</form>
|
||||
</details>
|
||||
|
|
|
@ -8,17 +8,24 @@
|
|||
<p class="notice" style="background:#0881c0"><b><a href="/manage/nosecount?filter=capacity">Check here</a> for any fur who share your room type.</p>
|
||||
{% endif %}
|
||||
|
||||
{# Show alert if room owner has wrong people inside #}
|
||||
{% if time() > ROOM_DEADLINE %}
|
||||
<p class="notice">⚠️ The deadline to edit your room has passed. If your room is not full it will be subject to changes by the staff as we optimize for hotel capacity.</p>
|
||||
|
||||
{# {% if room_members and quota.get_left(len(room_members)) == 0 and (not order.room_confirmed) %} #}
|
||||
{# <p class="notice">⚠️ Your room contains {{len(room_members)}} people inside, but sadly there are no more {{[None,'single','double','triple','quadruple','quintuple'][len(room_members)]}} rooms. You need to add or remove people until you reach the size of an available room if you want to confirm it.</p> #}
|
||||
{# {% endif %} #}
|
||||
{% else %}
|
||||
|
||||
{# Show alert if room was not confirmed #}
|
||||
{% if order.room_id and not order.room_confirmed %}
|
||||
<p class="notice">⚠️ Your room hasn't been confirmed yet. Unconfirmed rooms are subject to changes by the staff as we optimize for hotel capacity.</p>
|
||||
{# Show alert if room owner has wrong people inside #}
|
||||
|
||||
{# {% if room_members and quota.get_left(len(room_members)) == 0 and (not order.room_confirmed) %} #}
|
||||
{# <p class="notice">⚠️ Your room contains {{len(room_members)}} people inside, but sadly there are no more {{[None,'single','double','triple','quadruple','quintuple'][len(room_members)]}} rooms. You need to add or remove people until you reach the size of an available room if you want to confirm it.</p> #}
|
||||
{# {% endif %} #}
|
||||
|
||||
{# Show alert if room was not confirmed #}
|
||||
{% if order.room_id and not order.room_confirmed %}
|
||||
<p class="notice">⚠️ Your room hasn't been confirmed yet. Unconfirmed rooms are subject to changes by the staff as we optimize for hotel capacity.</p>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
|
||||
{# Show notice if the room is confirmed #}
|
||||
{% if order.room_confirmed %}
|
||||
{# <p class="notice" style="background:#060">✅ Your <strong>{{[None,'single','double','triple','quadruple','quintuple'][len(room_members)]}}</strong> room has been confirmed</p> #}
|
||||
|
@ -40,7 +47,7 @@
|
|||
{% if person.status == 'pending' %}
|
||||
<p><strong style="color:red;">UNPAID</strong></p>
|
||||
{% endif %}
|
||||
{% if order.room_owner and person.code != order.code and (not order.room_confirmed) %}<a href="/manage/room/kick/{{person.code}}">KICK</a>{% endif %}
|
||||
{% if order.room_owner and person.code != order.code and (not order.room_confirmed) and (time() <= ROOM_DEADLINE or isSessionAdmin) %}<a href="/manage/room/kick/{{person.code}}">KICK</a>{% endif %}
|
||||
</div>
|
||||
|
||||
{% if person.status != 'paid' %}
|
||||
|
@ -51,7 +58,7 @@
|
|||
{# {% if order.room_id == order.code and not order.room_confirmed and len(room_members) < 5%} #}
|
||||
{% if order.room_id == order.code and not order.room_confirmed and len(room_members) < order.room_person_no %}
|
||||
<div>
|
||||
<a href="javascript:document.getElementById('modal-roominvite').setAttribute('open', 'true');">
|
||||
<a {% if time() <= ROOM_DEADLINE or isSessionAdmin %} href="javascript:document.getElementById('modal-roominvite').setAttribute('open', 'true');" {% else %} disabled {% endif %}>
|
||||
<div class="propic-container">
|
||||
<img class="propic" src="/res/new.png" />
|
||||
<h3>Invite</h3>
|
||||
|
@ -63,13 +70,13 @@
|
|||
</div>
|
||||
{% elif order.pending_room %}
|
||||
<p>You have have asked to join the room of another member. Wait for them to confirm or reject your request.</p>
|
||||
<a role="button" href="/manage/room/cancel_request">Cancel pending join request</a>
|
||||
<a role="button" href="/manage/room/cancel_request" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}}>Cancel pending join request</a>
|
||||
{% else %}
|
||||
<p class="notice">🎲 If you don't join a room or create your one within the room deadline, we will randomly put you into a room with free spots.</p>
|
||||
<p>To join a room, ask somebody to send you their room code.</p>
|
||||
<p class="grid">
|
||||
<a role="button" href="/manage/room/create">Create a room</a>
|
||||
<a role="button" href="javascript:document.getElementById('modal-joinroom').setAttribute('open', 'true');">Join a room</a>
|
||||
<a role="button" href="/manage/room/create" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}}>Create a room</a>
|
||||
<a role="button" href="javascript:document.getElementById('modal-joinroom').setAttribute('open', 'true');" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}}>Join a room</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
|
@ -83,17 +90,17 @@
|
|||
{% if order.room_owner %}
|
||||
|
||||
{% if not order.room_confirmed %}
|
||||
{# <a role="button" {% if not room.forbidden and quota.get_left(len(room_members)) > 0 %}href="javascript:document.getElementById('modal-roomconfirm').setAttribute('open', 'true');"{% endif %}>Confirm <strong>{{[None,'single','double','triple','quadruple','quintuple'][len(room_members)]}}</strong> room</a> #}
|
||||
{# <a role="button" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}} {% if not room.forbidden and quota.get_left(len(room_members)) > 0 %}href="javascript:document.getElementById('modal-roomconfirm').setAttribute('open', 'true');"{% endif %}>Confirm <strong>{{[None,'single','double','triple','quadruple','quintuple'][len(room_members)]}}</strong> room</a> #}
|
||||
|
||||
<a style="grid-area: 1 / 1 / 2 / 2;" role="button" href="javascript:document.getElementById('modal-roomrename').setAttribute('open', 'true');">Rename room</a>
|
||||
<a style="grid-area: 1 / 2 / 2 / 3;" href="/manage/room/delete" role="button" {{'disabled' if (len(room_members) > 1) else ''}} >Delete room</a>
|
||||
<a style="grid-area: 2 / 1 / 3 / 3; display:block;" role="button" {% if not room.forbidden and len(room_members) == order.room_person_no %}href="javascript:document.getElementById('modal-roomconfirm').setAttribute('open', 'true');"{% endif %}>Confirm <strong>{{[None,'single','double','triple','quadruple','quintuple'][order.room_person_no]}}</strong> room</a>
|
||||
<a style="grid-area: 1 / 1 / 2 / 2;" role="button" href="javascript:document.getElementById('modal-roomrename').setAttribute('open', 'true');" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}}>Rename room</a>
|
||||
<a style="grid-area: 1 / 2 / 2 / 3;" href="/manage/room/delete" role="button" {{'disabled' if (len(room_members) > 1) or (time() > ROOM_DEADLINE and not isSessionAdmin) else ''}} >Delete room</a>
|
||||
<a style="grid-area: 2 / 1 / 3 / 3; display:block;" role="button" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}} {% if not room.forbidden and len(room_members) == order.room_person_no %}href="javascript:document.getElementById('modal-roomconfirm').setAttribute('open', 'true');"{% endif %}>Confirm <strong>{{[None,'single','double','triple','quadruple','quintuple'][order.room_person_no]}}</strong> room</a>
|
||||
{% else %}
|
||||
{# <a style="grid-area: 1 / 1 / 2 / 2;" role="button" href="javascript:navigator.share({title: 'Furizon room', text:'Viewing room {{order.room_name}}', url: `${window.location.protocol}//${window.location.host}/manage/room/view/{{order.code}}}`});">Share</a> #}
|
||||
{# <a style="grid-area: 1 / 1 / 2 / 2;" role="button" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}} href="javascript:navigator.share({title: 'Furizon room', text:'Viewing room {{order.room_name}}', url: `${window.location.protocol}//${window.location.host}/manage/room/view/{{order.code}}}`});">Share</a> #}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if order.room_id and not order.room_confirmed %}
|
||||
<a href="/manage/room/leave" role="button">Leave room</a>
|
||||
<a href="/manage/room/leave" role="button" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}}>Leave room</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
@ -111,8 +118,8 @@
|
|||
<td><strong style="color:red;">UNPAID</strong></td>
|
||||
{% endif %}
|
||||
{% if order.room_owner %}
|
||||
<td style="width:1%;white-space: nowrap;"><a role="button" href="/manage/room/approve/{{person.code}}">Approve</a></td>
|
||||
<td style="width:1%;white-space: nowrap;"><a role="button" href="/manage/room/reject/{{person.code}}">Reject</a></td>
|
||||
<td style="width:1%;white-space: nowrap;"><a role="button" href="/manage/room/approve/{{person.code}}" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}}>Approve</a></td>
|
||||
<td style="width:1%;white-space: nowrap;"><a role="button" href="/manage/room/reject/{{person.code}}" {{'disabled' if time() > ROOM_DEADLINE and not isSessionAdmin else ''}}>Reject</a></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</div>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
{%with room_order = unconfirmed_orders[room[0]] %}
|
||||
<div class="room" id="room-{{room_order.code}}" room-type="{{room_order.bed_in_room}}" room-size="{{room_order.room_person_no - len(room_order.room_members)}}" current-size="{{len(room[1]['to_add'])}}">
|
||||
<h4 style="margin-top:1em;">
|
||||
<span>{{room_order.room_name if room_order.room_name else room[1]['room_name'] if room[1] and room[1]['room_name'] else ''}}</span>
|
||||
<span>{{room_order.room_name if room_order.room_name else room[1]['room_name'] if room[1] and room[1]['room_name'] else ''}} - {{room_order.room_person_no}} People max</span>
|
||||
</h4>
|
||||
<div class="grid people" style="padding-bottom:1em;">
|
||||
{% for m in room_order.room_members %}
|
||||
|
|
13
utils.py
13
utils.py
|
@ -287,6 +287,19 @@ async def validate_rooms(request, rooms, om):
|
|||
logger.info(f"[ROOM VALIDATION] Sent {sent_count} emails")
|
||||
|
||||
|
||||
# Returns true if the logged used is an admin OR if it's an admin logged as another user
|
||||
async def isSessionAdmin(request, order):
|
||||
if(order.isAdmin()): return True
|
||||
|
||||
orgCode = request.cookies.get("foxo_code_ORG")
|
||||
orgSecret = request.cookies.get("foxo_secret_ORG")
|
||||
if orgCode != None and orgSecret != None:
|
||||
|
||||
user = await request.app.ctx.om.get_order(code=orgCode)
|
||||
if(user == None): return False
|
||||
if(user.secret != orgSecret): raise exceptions.Forbidden("Birichino :)")
|
||||
return user.isAdmin()
|
||||
|
||||
async def check_room(request, order, om=None):
|
||||
room_errors = []
|
||||
room_members = []
|
||||
|
|
Loading…
Reference in New Issue