diff --git a/.gitignore b/.gitignore index 23d733b..90a11f9 100644 --- a/.gitignore +++ b/.gitignore @@ -168,4 +168,5 @@ diomerdas furizon.net/site/* furizon.net.zip stuff/secrets.py -backups/* \ No newline at end of file +backups/* +log.txt diff --git a/api.py b/api.py index 2e13108..d14f5a5 100644 --- a/api.py +++ b/api.py @@ -9,7 +9,9 @@ import random import string import httpx import json +import traceback from sanic.log import logger +from email_util import send_app_login_attempt 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] 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!") - msg['Subject'] = '[Furizon] Your login code' - msg['From'] = 'Furizon ' - 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: + await send_app_login_attempt(user, request.app.ctx.login_codes[code][0]) + except Exception: + logger.error(f"[API] [GET_TOKEN] Error while sending email.\n{traceback.format_exc()}") 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.'}) diff --git a/config.example.py b/config.example.py index 1d5a880..247ebec 100644 --- a/config.example.py +++ b/config.example.py @@ -46,6 +46,8 @@ DEV_MODE = True ACCESS_LOG = True EXTRA_PRINTS = True +UNCONFIRM_ROOMS_ENABLE = True + METRICS_PATH = "/welcome/metrics" # Additional configured locales. @@ -65,51 +67,53 @@ SPONSORSHIP_COLOR_MAP = { # Maps Products metadata name <--> ID ITEMS_ID_MAP = { - 'early_bird_ticket': 126, - 'regular_ticket': 127, - 'staff_ticket': 155, - 'daily_ticket': 162, - 'sponsorship_item': 129, - 'early_arrival_admission': 133, - 'late_departure_admission': 134, - 'membership_card_item': 128, - 'bed_in_room': 153, - 'room_type': 135, - 'room_guest': 136, - 'daily_1': 163, - 'daily_2': 164, - 'daily_3': 165, - 'daily_4': 166, + 'early_bird_ticket': None, + 'regular_ticket': None, + 'staff_ticket': None, + 'daily_ticket': None, + 'regular_bundle_sponsor_ticket': None, + 'sponsorship_item': None, + 'early_arrival_admission': None, + 'late_departure_admission': None, + 'membership_card_item': None, + 'bed_in_room': None, + 'room_type': None, + 'room_guest': None, + 'daily_1': None, + 'daily_2': None, + 'daily_3': None, + 'daily_4': None, 'daily_5': None } # Maps Products' variants metadata name <--> ID ITEM_VARIATIONS_MAP = { 'sponsorship_item': { - 'sponsorship_item_normal': 55, - 'sponsorship_item_super': 56 + 'sponsorship_item_normal': None, + 'sponsorship_item_super': None }, 'bed_in_room': { - 'bed_in_room_main_1': 83, - 'bed_in_room_main_2': 67, - 'bed_in_room_main_3': 68, - 'bed_in_room_main_4': 69, - 'bed_in_room_main_5': 70, - 'bed_in_room_overflow1_2': 75, + 'bed_in_room_no_room': None, + 'bed_in_room_main_1': None, + 'bed_in_room_main_2': None, + 'bed_in_room_main_3': None, + 'bed_in_room_main_4': None, + 'bed_in_room_main_5': None, + 'bed_in_room_overflow1_2': None, }, 'room_type': { - 'single': 57, - 'double': 58, - 'triple': 59, - 'quadruple': 60, - 'quintuple': 61 + 'single': None, + 'double': None, + 'triple': None, + 'quadruple': None, + 'quintuple': None }, 'room_guest': { - 'single': 57, - 'double': 58, - 'triple': 59, - 'quadruple': 60, - 'quintuple': 61 + 'single': None, + 'double': None, + 'triple': None, + 'quadruple': None, + '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. # Map item_name -> room capacity ROOM_CAPACITY_MAP = { + # Default + 'bed_in_room_no_room': 0, + # SACRO CUORE 'bed_in_room_main_1': 1, 'bed_in_room_main_2': 2, diff --git a/email_util.py b/email_util.py index 4687c5b..7b0fd01 100644 --- a/email_util.py +++ b/email_util.py @@ -48,6 +48,7 @@ sslContext : SSLContext = ssl.create_default_context() smptSender : smtplib.SMTP = None 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']}'") sslLock.acquire() @@ -87,7 +88,6 @@ async def send_unconfirm_message(room_order, orders): message.attach(plain_text) message.attach(html_text) 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}>" memberMessages.append(message) @@ -110,8 +110,14 @@ async def send_missing_propic_message(order, missingPropic, missingFursuitPropic message.attach(plain_text) message.attach(html_text) 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}>" 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) \ No newline at end of file diff --git a/ext.py b/ext.py index b891f2a..1a5f791 100644 --- a/ext.py +++ b/ext.py @@ -35,16 +35,21 @@ class Order: self.sponsorship = None self.has_early = False self.has_late = False - self.first_name = None - self.last_name = None + self.first_name = "None" + self.last_name = "None" self.country = 'xx' self.address = None self.checked_in = False self.room_type = None self.daily = False self.dailyDays = [] - self.room_person_no = 0 + self.bed_in_room = -1 + self.room_person_no = -1 self.answers = [] + self.position_id = -1 + self.position_positionid = -1 + self.position_positiontypeid = -1 + self.barcode = "None" idata = data['invoice_address'] if idata: @@ -88,7 +93,7 @@ class Order: roomTypeLst = key_from_value(ITEM_VARIATIONS_MAP['bed_in_room'], p['variation']) roomTypeId = roomTypeLst[0] if len(roomTypeLst) > 0 else None 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.fees = 0 @@ -106,6 +111,9 @@ class Order: self.phone = data['phone'] self.room_errors = [] self.loadAns() + + if(self.bed_in_room < 0): + self.status = "canceled" # Must refer to the previous status assignment def loadAns(self): self.shirt_size = self.ans('shirt_size') self.is_artist = True if self.ans('is_artist') != 'No' else False diff --git a/metrics.py b/metrics.py index 43f037d..8f5da5f 100644 --- a/metrics.py +++ b/metrics.py @@ -1,6 +1,7 @@ from sanic.log import logger, logging from logging import LogRecord from config import * +import traceback METRICS_REQ_NO = 0 METRICS_ERR_NO = 0 # Errors served to the clients @@ -47,7 +48,7 @@ def getMetricsText(): def getRoomCountersText(request): out = [] - try : + try: daily = 0 counters = {} counters_early = {} @@ -61,11 +62,13 @@ def getRoomCountersText(request): if(order.daily): daily += 1 else: - counters[order.bed_in_room] += 1 - if(order.has_early): - counters_early[order.bed_in_room] += 1 - if(order.has_late): - counters_late[order.bed_in_room] += 1 + # Order.status must reflect the one in the Order() constructor inside ext.py + if(order.status in ["pending", "paid"] and hasattr(order, "bed_in_room") and order.bed_in_room in counters): + counters[order.bed_in_room] += 1 + if(order.has_early): + counters_early[order.bed_in_room] += 1 + if(order.has_late): + counters_late[order.bed_in_room] += 1 for id, count in counters.items(): 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}') except Exception as e: - print(e) + print(traceback.format_exc()) + logger.warning("Error in loading metrics rooms") return "\n".join(out) diff --git a/room.py b/room.py index 3e1382f..6fb9dc3 100644 --- a/room.py +++ b/room.py @@ -326,7 +326,7 @@ async def confirm_room(request, order: Order, quotas: Quotas): 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!") for rm in room_members: diff --git a/utils.py b/utils.py index d347419..d82879f 100644 --- a/utils.py +++ b/utils.py @@ -205,9 +205,11 @@ async def validate_rooms(request, rooms, om): for rtu in failed_confirmed_rooms: order = rtu[0] member_orders = rtu[2] + logger.warning(f"[ROOM VALIDATION] [UNCONFIRMING] Unconfirming room {order.code}...") # 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...") sent_count = 0 @@ -216,7 +218,8 @@ async def validate_rooms(request, rooms, om): order = rtu[0] member_orders = rtu[2] try: - await send_unconfirm_message(order, member_orders) + if UNCONFIRM_ROOMS_ENABLE: + await send_unconfirm_message(order, member_orders) sent_count += len(member_orders) except Exception as ex: if EXTRA_PRINTS: logger.exception(str(ex)) @@ -262,7 +265,7 @@ async def check_room(request, order, om=None): 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')) if order.room_confirmed: allOk = False