Makeroom wizard #27
|
@ -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
15
api.py
|
@ -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.'})
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
16
ext.py
|
@ -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
|
||||||
|
|
18
metrics.py
18
metrics.py
|
@ -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)
|
||||||
|
|
||||||
|
|
2
room.py
2
room.py
|
@ -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:
|
||||||
|
|
9
utils.py
9
utils.py
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue