Makeroom wizard #27

Merged
stranck merged 15 commits from drew-dev into stranck-dev 2024-05-20 10:32:09 +00:00
8 changed files with 85 additions and 61 deletions
Showing only changes of commit 687eaf7317 - Show all commits

3
.gitignore vendored
View File

@ -168,4 +168,5 @@ diomerdas
furizon.net/site/* furizon.net/site/*
furizon.net.zip furizon.net.zip
stuff/secrets.py stuff/secrets.py
backups/* backups/*
log.txt

15
api.py
View File

@ -9,7 +9,9 @@ import random
import string import string
import httpx import httpx
import json import json
import traceback
from sanic.log import logger from sanic.log import logger
from email_util import send_app_login_attempt
bp = Blueprint("api", url_prefix="/manage/api") bp = Blueprint("api", url_prefix="/manage/api")
@ -221,16 +223,9 @@ async def get_token(request, code):
request.app.ctx.login_codes[code] = [''.join(random.choice(string.digits) for _ in range(6)), 3] request.app.ctx.login_codes[code] = [''.join(random.choice(string.digits) for _ in range(6)), 3]
try: try:
msg = MIMEText(f"Hello {user.name}!\n\nWe have received a request to login in the app. If you didn't do this, please ignore this email. Somebody is probably playing with you.\n\nYour login code is: {request.app.ctx.login_codes[code][0]}\n\nPlease do not tell this to anybody!") await send_app_login_attempt(user, request.app.ctx.login_codes[code][0])
msg['Subject'] = '[Furizon] Your login code' except Exception:
msg['From'] = 'Furizon <no-reply@furizon.net>' logger.error(f"[API] [GET_TOKEN] Error while sending email.\n{traceback.format_exc()}")
msg['To'] = f"{user.name} <{user.email}>"
s = smtplib.SMTP_SSL(SMTP_HOST)
s.login(SMTP_USER, SMTP_PASSWORD)
s.sendmail(msg['From'], msg['to'], msg.as_string())
s.quit()
except:
return response.json({'ok': False, 'error': 'There has been an issue sending your e-mail. Please try again later or report to an admin.'}, status=500) return response.json({'ok': False, 'error': 'There has been an issue sending your e-mail. Please try again later or report to an admin.'}, status=500)
return response.json({'ok': True, 'message': 'A login code has been sent to your email.'}) return response.json({'ok': True, 'message': 'A login code has been sent to your email.'})

View File

@ -46,6 +46,8 @@ DEV_MODE = True
ACCESS_LOG = True ACCESS_LOG = True
EXTRA_PRINTS = True EXTRA_PRINTS = True
UNCONFIRM_ROOMS_ENABLE = True
METRICS_PATH = "/welcome/metrics" METRICS_PATH = "/welcome/metrics"
# Additional configured locales. # Additional configured locales.
@ -65,51 +67,53 @@ SPONSORSHIP_COLOR_MAP = {
# Maps Products metadata name <--> ID # Maps Products metadata name <--> ID
ITEMS_ID_MAP = { ITEMS_ID_MAP = {
'early_bird_ticket': 126, 'early_bird_ticket': None,
'regular_ticket': 127, 'regular_ticket': None,
'staff_ticket': 155, 'staff_ticket': None,
'daily_ticket': 162, 'daily_ticket': None,
'sponsorship_item': 129, 'regular_bundle_sponsor_ticket': None,
'early_arrival_admission': 133, 'sponsorship_item': None,
'late_departure_admission': 134, 'early_arrival_admission': None,
'membership_card_item': 128, 'late_departure_admission': None,
'bed_in_room': 153, 'membership_card_item': None,
'room_type': 135, 'bed_in_room': None,
'room_guest': 136, 'room_type': None,
'daily_1': 163, 'room_guest': None,
'daily_2': 164, 'daily_1': None,
'daily_3': 165, 'daily_2': None,
'daily_4': 166, 'daily_3': None,
'daily_4': None,
'daily_5': None 'daily_5': None
} }
# Maps Products' variants metadata name <--> ID # Maps Products' variants metadata name <--> ID
ITEM_VARIATIONS_MAP = { ITEM_VARIATIONS_MAP = {
'sponsorship_item': { 'sponsorship_item': {
'sponsorship_item_normal': 55, 'sponsorship_item_normal': None,
'sponsorship_item_super': 56 'sponsorship_item_super': None
}, },
'bed_in_room': { 'bed_in_room': {
'bed_in_room_main_1': 83, 'bed_in_room_no_room': None,
'bed_in_room_main_2': 67, 'bed_in_room_main_1': None,
'bed_in_room_main_3': 68, 'bed_in_room_main_2': None,
'bed_in_room_main_4': 69, 'bed_in_room_main_3': None,
'bed_in_room_main_5': 70, 'bed_in_room_main_4': None,
'bed_in_room_overflow1_2': 75, 'bed_in_room_main_5': None,
'bed_in_room_overflow1_2': None,
}, },
'room_type': { 'room_type': {
'single': 57, 'single': None,
'double': 58, 'double': None,
'triple': 59, 'triple': None,
'quadruple': 60, 'quadruple': None,
'quintuple': 61 'quintuple': None
}, },
'room_guest': { 'room_guest': {
'single': 57, 'single': None,
'double': 58, 'double': None,
'triple': 59, 'triple': None,
'quadruple': 60, 'quadruple': None,
'quintuple': 61 'quintuple': None
} }
} }
@ -129,6 +133,9 @@ CATEGORIES_LIST_MAP = {
# Create a bunch of "room" items which will get added to the order once somebody gets a room. # Create a bunch of "room" items which will get added to the order once somebody gets a room.
# Map item_name -> room capacity # Map item_name -> room capacity
ROOM_CAPACITY_MAP = { ROOM_CAPACITY_MAP = {
# Default
'bed_in_room_no_room': 0,
# SACRO CUORE # SACRO CUORE
'bed_in_room_main_1': 1, 'bed_in_room_main_1': 1,
'bed_in_room_main_2': 2, 'bed_in_room_main_2': 2,

View File

@ -48,6 +48,7 @@ sslContext : SSLContext = ssl.create_default_context()
smptSender : smtplib.SMTP = None smptSender : smtplib.SMTP = None
async def sendEmail(message : MIMEMultipart): async def sendEmail(message : MIMEMultipart):
message['From'] = f'{EMAIL_SENDER_NAME} <{EMAIL_SENDER_MAIL}>'
await openSmptClient() await openSmptClient()
logger.debug(f"[SMPT] Sending mail {message['From']} -> {message['to']} '{message['Subject']}'") logger.debug(f"[SMPT] Sending mail {message['From']} -> {message['to']} '{message['Subject']}'")
sslLock.acquire() sslLock.acquire()
@ -87,7 +88,6 @@ async def send_unconfirm_message(room_order, orders):
message.attach(plain_text) message.attach(plain_text)
message.attach(html_text) message.attach(html_text)
message['Subject'] = f'[{EMAIL_SENDER_NAME}] Your room cannot be confirmed' message['Subject'] = f'[{EMAIL_SENDER_NAME}] Your room cannot be confirmed'
message['From'] = f'{EMAIL_SENDER_NAME} <{EMAIL_SENDER_MAIL}>'
message['To'] = f"{member.name} <{member.email}>" message['To'] = f"{member.name} <{member.email}>"
memberMessages.append(message) memberMessages.append(message)
@ -110,8 +110,14 @@ async def send_missing_propic_message(order, missingPropic, missingFursuitPropic
message.attach(plain_text) message.attach(plain_text)
message.attach(html_text) message.attach(html_text)
message['Subject'] = f"[{EMAIL_SENDER_NAME}] You haven't uploaded your badges yet!" message['Subject'] = f"[{EMAIL_SENDER_NAME}] You haven't uploaded your badges yet!"
message['From'] = f'{EMAIL_SENDER_NAME} <{EMAIL_SENDER_MAIL}>'
message['To'] = f"{order.name} <{order.email}>" message['To'] = f"{order.name} <{order.email}>"
await sendEmail(message) await sendEmail(message)
async def send_app_login_attempt(user, loginCode):
#TODO: Format a proper email and add it to messages.py
msg = MIMEText(f"Hello {user.name}!\n\nWe have received a request to login in the app. If you didn't do this, please ignore this email. Somebody is probably playing with you.\n\nYour login code is: {loginCode}\n\nPlease do not tell this to anybody!")
msg['Subject'] = '[Furizon] Your login code'
msg['To'] = f"{user.name} <{user.email}>"
await sendEmail(msg)

16
ext.py
View File

@ -35,16 +35,21 @@ class Order:
self.sponsorship = None self.sponsorship = None
self.has_early = False self.has_early = False
self.has_late = False self.has_late = False
self.first_name = None self.first_name = "None"
self.last_name = None self.last_name = "None"
self.country = 'xx' self.country = 'xx'
self.address = None self.address = None
self.checked_in = False self.checked_in = False
self.room_type = None self.room_type = None
self.daily = False self.daily = False
self.dailyDays = [] self.dailyDays = []
self.room_person_no = 0 self.bed_in_room = -1
self.room_person_no = -1
self.answers = [] self.answers = []
self.position_id = -1
self.position_positionid = -1
self.position_positiontypeid = -1
self.barcode = "None"
idata = data['invoice_address'] idata = data['invoice_address']
if idata: if idata:
@ -88,7 +93,7 @@ class Order:
roomTypeLst = key_from_value(ITEM_VARIATIONS_MAP['bed_in_room'], p['variation']) roomTypeLst = key_from_value(ITEM_VARIATIONS_MAP['bed_in_room'], p['variation'])
roomTypeId = roomTypeLst[0] if len(roomTypeLst) > 0 else None roomTypeId = roomTypeLst[0] if len(roomTypeLst) > 0 else None
self.bed_in_room = p['variation'] self.bed_in_room = p['variation']
self.room_person_no = ROOM_CAPACITY_MAP[roomTypeId] if roomTypeId in ROOM_CAPACITY_MAP else None self.room_person_no = ROOM_CAPACITY_MAP[roomTypeId] if roomTypeId in ROOM_CAPACITY_MAP else self.room_person_no
self.total = float(data['total']) self.total = float(data['total'])
self.fees = 0 self.fees = 0
@ -106,6 +111,9 @@ class Order:
self.phone = data['phone'] self.phone = data['phone']
self.room_errors = [] self.room_errors = []
self.loadAns() self.loadAns()
if(self.bed_in_room < 0):
self.status = "canceled" # Must refer to the previous status assignment
def loadAns(self): def loadAns(self):
self.shirt_size = self.ans('shirt_size') self.shirt_size = self.ans('shirt_size')
self.is_artist = True if self.ans('is_artist') != 'No' else False self.is_artist = True if self.ans('is_artist') != 'No' else False

View File

@ -1,6 +1,7 @@
from sanic.log import logger, logging from sanic.log import logger, logging
from logging import LogRecord from logging import LogRecord
from config import * from config import *
import traceback
METRICS_REQ_NO = 0 METRICS_REQ_NO = 0
METRICS_ERR_NO = 0 # Errors served to the clients METRICS_ERR_NO = 0 # Errors served to the clients
@ -47,7 +48,7 @@ def getMetricsText():
def getRoomCountersText(request): def getRoomCountersText(request):
out = [] out = []
try : try:
daily = 0 daily = 0
counters = {} counters = {}
counters_early = {} counters_early = {}
@ -61,11 +62,13 @@ def getRoomCountersText(request):
if(order.daily): if(order.daily):
daily += 1 daily += 1
else: else:
counters[order.bed_in_room] += 1 # Order.status must reflect the one in the Order() constructor inside ext.py
if(order.has_early): if(order.status in ["pending", "paid"] and hasattr(order, "bed_in_room") and order.bed_in_room in counters):
counters_early[order.bed_in_room] += 1 counters[order.bed_in_room] += 1
if(order.has_late): if(order.has_early):
counters_late[order.bed_in_room] += 1 counters_early[order.bed_in_room] += 1
if(order.has_late):
counters_late[order.bed_in_room] += 1
for id, count in counters.items(): for id, count in counters.items():
out.append(f'webint_order_room_counter{{days="normal", label="{ROOM_TYPE_NAMES[id]}"}} {count}') out.append(f'webint_order_room_counter{{days="normal", label="{ROOM_TYPE_NAMES[id]}"}} {count}')
@ -76,7 +79,8 @@ def getRoomCountersText(request):
out.append(f'webint_order_room_counter{{label="Daily"}} {daily}') out.append(f'webint_order_room_counter{{label="Daily"}} {daily}')
except Exception as e: except Exception as e:
print(e) print(traceback.format_exc())
logger.warning("Error in loading metrics rooms") logger.warning("Error in loading metrics rooms")
return "\n".join(out) return "\n".join(out)

View File

@ -326,7 +326,7 @@ async def confirm_room(request, order: Order, quotas: Quotas):
room_members.append(res) room_members.append(res)
if len(room_members) != order.room_person_no and order.room_person_no != None: if len(room_members) != order.room_person_no:
raise exceptions.BadRequest("The number of people in your room mismatches your type of ticket!") raise exceptions.BadRequest("The number of people in your room mismatches your type of ticket!")
for rm in room_members: for rm in room_members:

View File

@ -205,9 +205,11 @@ async def validate_rooms(request, rooms, om):
for rtu in failed_confirmed_rooms: for rtu in failed_confirmed_rooms:
order = rtu[0] order = rtu[0]
member_orders = rtu[2] member_orders = rtu[2]
logger.warning(f"[ROOM VALIDATION] [UNCONFIRMING] Unconfirming room {order.code}...")
# Unconfirm and email users about the room # Unconfirm and email users about the room
await unconfirm_room_by_order(order, member_orders, False, None, om) if UNCONFIRM_ROOMS_ENABLE:
await unconfirm_room_by_order(order, member_orders, False, None, om)
logger.info(f"[ROOM VALIDATION] Sending unconfirm notice to room members...") logger.info(f"[ROOM VALIDATION] Sending unconfirm notice to room members...")
sent_count = 0 sent_count = 0
@ -216,7 +218,8 @@ async def validate_rooms(request, rooms, om):
order = rtu[0] order = rtu[0]
member_orders = rtu[2] member_orders = rtu[2]
try: try:
await send_unconfirm_message(order, member_orders) if UNCONFIRM_ROOMS_ENABLE:
await send_unconfirm_message(order, member_orders)
sent_count += len(member_orders) sent_count += len(member_orders)
except Exception as ex: except Exception as ex:
if EXTRA_PRINTS: logger.exception(str(ex)) if EXTRA_PRINTS: logger.exception(str(ex))
@ -262,7 +265,7 @@ async def check_room(request, order, om=None):
room_members.append(res) room_members.append(res)
if len(room_members) != order.room_person_no and order.room_person_no != None: if len(room_members) != order.room_person_no and order.room_person_no != None and order.room_person_no >= 0:
room_errors.append((None, 'capacity_mismatch')) room_errors.append((None, 'capacity_mismatch'))
if order.room_confirmed: if order.room_confirmed:
allOk = False allOk = False