We're so back #16

Merged
stranck merged 9 commits from drew-dev into stranck-dev 2024-02-09 15:09:26 +00:00
6 changed files with 123 additions and 82 deletions
Showing only changes of commit 16ae51fb08 - Show all commits

2
app.py
View File

@ -140,7 +140,7 @@ async def welcome(request, order: Order, quota: Quotas):
room_members.append(await app.ctx.om.get_order(code=member_id, cached=True)) room_members.append(await app.ctx.om.get_order(code=member_id, cached=True))
tpl = app.ctx.tpl.get_template('welcome.html') tpl = app.ctx.tpl.get_template('welcome.html')
return html(tpl.render(order=order, quota=quota, room_members=room_members, pending_roommates=pending_roommates)) return html(tpl.render(order=order, quota=quota, room_members=room_members, pending_roommates=pending_roommates, ROOM_ERROR_MESSAGES=ROOM_ERROR_MESSAGES))
@app.route("/manage/download_ticket") @app.route("/manage/download_ticket")

12
ext.py
View File

@ -98,6 +98,7 @@ class Order:
self.payment_provider = data['payment_provider'] self.payment_provider = data['payment_provider']
self.comment = data['comment'] self.comment = data['comment']
self.phone = data['phone'] self.phone = data['phone']
self.room_issues = []
self.loadAns() self.loadAns()
def loadAns(self): def loadAns(self):
self.shirt_size = self.ans('shirt_size') self.shirt_size = self.ans('shirt_size')
@ -131,6 +132,9 @@ class Order:
def __getitem__(self, var): def __getitem__(self, var):
return self.data[var] return self.data[var]
def set_room_errors (self, to_set):
for s in to_set: self.room_issues.append (s)
def ans(self, name): def ans(self, name):
for p in self.data['positions']: for p in self.data['positions']:
for a in p['answers']: for a in p['answers']:
@ -221,6 +225,7 @@ class Order:
self.time = -1 self.time = -1
self.loadAns() self.loadAns()
@dataclass @dataclass
class Quotas: class Quotas:
def __init__(self, data): def __init__(self, data):
@ -255,7 +260,7 @@ class OrderManager:
async def updateCache(self): async def updateCache(self):
t = time() t = time()
if(t - self.lastCacheUpdate > CACHE_EXPIRE_TIME): if(t - self.lastCacheUpdate > CACHE_EXPIRE_TIME):
print("Re-filling cache!") print("[TIME] Re-filling cache!")
await self.fill_cache() await self.fill_cache()
self.lastCacheUpdate = t self.lastCacheUpdate = t
@ -289,6 +294,11 @@ class OrderManager:
self.remove_cache(o.code) self.remove_cache(o.code)
else: else:
self.add_cache(Order(o)) self.add_cache(Order(o))
self.lastCacheUpdate = time()
for o in self.cache.values():
if o.code == o.room_id:
print(o.room_name)
await validate_room(None, o, self)
async def get_order(self, request=None, code=None, secret=None, nfc_id=None, cached=False): async def get_order(self, request=None, code=None, secret=None, nfc_id=None, cached=False):

75
room.py
View File

@ -1,6 +1,3 @@
from email.mime.text import MIMEText
from messages import ROOM_ERROR_MESSAGES
import smtplib
from sanic.response import html, redirect, text from sanic.response import html, redirect, text
from sanic import Blueprint, exceptions from sanic import Blueprint, exceptions
from random import choice from random import choice
@ -360,78 +357,6 @@ async def confirm_room(request, order: Order, quotas: Quotas):
return redirect('/manage/welcome') return redirect('/manage/welcome')
async def unconfirm_room_by_order(order, throw=True, request=None):
if not order.room_confirmed and throw:
raise exceptions.BadRequest("Room is not confirmed!")
ppl = get_people_in_room_by_code(request, order.code)
for p in ppl:
await p.edit_answer('room_confirmed', "False")
await p.send_answers()
async def validate_room(request, order):
check, room_errors, member_orders = await check_room(request, order)
if check == True: return
try:
# Build message
issues_str = ""
for err in room_errors:
if err in ROOM_ERROR_MESSAGES:
issues_str += f" - {ROOM_ERROR_MESSAGES['err']}"
memberMessages = []
for member in member_orders:
msg = MIMEText(f"Hello {member.name}!\n\nWe had to unconfirm your room {order.room_name} due to th{'ese issues' if len(room_errors) > 1 else 'is issue'}:\n{issues_str}\n\nPlease contact your room's owner or contact our support for further informations at https://furizon.net/contact/.\nThank you")
msg['Subject'] = '[Furizon] Your room cannot be confirmed'
msg['From'] = 'Furizon <no-reply@furizon.net>'
msg['To'] = f"{member.name} <{member.email}>"
memberMessages.append(msg)
if (len(memberMessages) == 0): return
s = smtplib.SMTP_SSL(SMTP_HOST)
s.login(SMTP_USER, SMTP_PASSWORD)
for message in memberMessages:
s.sendmail(message['From'], message['to'], message.as_string())
s.quit()
except Exception as ex:
if EXTRA_PRINTS: print(ex)
async def check_room(request, order):
room_errors = []
room_members = []
if not order or not order.room_id or order.room_id != order.code: return False, room_errors, room_members
# This is not needed anymore you buy tickets already
#if quotas.get_left(len(order.room_members)) == 0:
# raise exceptions.BadRequest("There are no more rooms of this size to reserve.")
bed_in_room = order.bed_in_room # Variation id of the ticket for that kind of room
for m in order.room_members:
if m == order.code:
res = order
else:
res = await request.app.ctx.om.get_order(code=m)
# Room user in another room
if res.room_id != order.code:
room_errors.append('room_id_mismatch')
if res.status != 'paid':
room_errors.append('unpaid')
if res.bed_in_room != bed_in_room:
room_errors.append('type_mismatch')
if res.daily:
room_errors.append('daily')
room_members.append(res)
if len(room_members) != order.room_person_no and order.room_person_no != None:
room_errors.append('capacity_mismatch')
return len(room_errors) == 0, room_errors, room_members
async def get_room (request, code): async def get_room (request, code):
order_data = await request.app.ctx.om.get_order(code=code) order_data = await request.app.ctx.om.get_order(code=code)
if not order_data or not order_data.room_owner: return None if not order_data or not order_data.room_owner: return None

View File

@ -14,6 +14,15 @@
{% if order.room_id and not order.room_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> <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 %}
{% if order.room_id and len(order.room_issues) > 0 %}
<p class="notice">⚠️ There are some issues with your room:
<ul>
{% for issue in issues %}
<li>{{ROOM_ERROR_MESSAGES[issue]}}</li>
{% endfor %}
</ul>
</p>
{% endif %}
{# Show notice if the room is confirmed #} {# Show notice if the room is confirmed #}
{% if order.room_confirmed %} {% if order.room_confirmed %}

View File

@ -17,7 +17,7 @@
<picture> <picture>
<source srcset="/res/furizon.png" media="(prefers-color-scheme:dark)"> <source srcset="/res/furizon.png" media="(prefers-color-scheme:dark)">
<img src="/res/furizon-light.png" style="height:4rem;text-align:center;" <img src="/res/furizon-light.png" style="height:4rem;text-align:center;"
> onload="window.location.href = '/manage/noseocount/'">
</picture> </picture>
</header> </header>
</main> </main>

101
utils.py
View File

@ -2,6 +2,9 @@ from os.path import join
from sanic import exceptions from sanic import exceptions
from config import * from config import *
import httpx import httpx
from email.mime.text import MIMEText
from messages import ROOM_ERROR_MESSAGES
import smtplib
METADATA_TAG = "meta_data" METADATA_TAG = "meta_data"
VARIATIONS_TAG = "variations" VARIATIONS_TAG = "variations"
@ -133,10 +136,104 @@ async def get_order_by_code(request, code, throwException=False):
raise exceptions.BadRequest(f"[getOrderByCode] Code {code} not found!") raise exceptions.BadRequest(f"[getOrderByCode] Code {code} not found!")
return res return res
def get_people_in_room_by_code(request, code): def get_people_in_room_by_code(request, code, om=None):
c = request.app.ctx.om.cache if not om: om = request.app.ctx.om
c = om.cache
ret = [] ret = []
for person in c.values(): for person in c.values():
if person.room_id == code: if person.room_id == code:
ret.append(person) ret.append(person)
return ret return ret
async def unconfirm_room_by_order(order, throw=True, request=None, om=None):
if not om: om = request.app.ctx.om
if not order.room_confirmed:
if throw:
raise exceptions.BadRequest("Room is not confirmed!")
else:
return
ppl = get_people_in_room_by_code(request, order.code, om)
for p in ppl:
await p.edit_answer('room_confirmed', "False")
await p.send_answers()
async def validate_room(request, order, om):
if not om: om = request.app.ctx.om
# Validate room
check, room_errors, member_orders = await check_room(request, order, om)
if check == True: return
print(f'[ROOM VALIDATION FAILED] {order.code} has failed room validation.', room_errors)
order.set_room_errors(room_errors)
# End here if room is not confirmed
if not order.room_confirmed: return
# Unconfirm and email users about the room
await unconfirm_room_by_order(order, False, None, om)
try:
# Build message
issues_str = ""
for err in room_errors:
if err in ROOM_ERROR_MESSAGES:
issues_str += f" - {ROOM_ERROR_MESSAGES[err]}"
memberMessages = []
for member in member_orders:
msg_text = f"Hello {member.name}!\n\n"
msg_text += f"We had to unconfirm your room '{order.room_name}'"
msg_text += f" due to th{'ese issues' if len(room_errors) > 1 else 'is issue'}:\n{issues_str}\n\n"
msg_text += f"Please contact your room's owner or contact our support for further informations at https://furizon.net/contact/.\nThank you"
msg = MIMEText(msg_text)
msg['Subject'] = '[Furizon] Your room cannot be confirmed'
msg['From'] = 'Furizon <no-reply@furizon.net>'
msg['To'] = f"{member.name} <{member.email}>"
memberMessages.append(msg)
if len(memberMessages) == 0: return
s = smtplib.SMTP_SSL(SMTP_HOST, 587)
s.login(SMTP_USER, SMTP_PASSWORD)
for message in memberMessages:
s.sendmail(message['From'], message['to'], message.as_string())
s.quit()
except Exception as ex:
if EXTRA_PRINTS: print('could not send emails', ex)
async def check_room(request, order, om=None):
room_errors = []
room_members = []
if not om: om = request.app.ctx.om
if not order or not order.room_id or order.room_id != order.code: return False, room_errors, room_members
# This is not needed anymore you buy tickets already
#if quotas.get_left(len(order.room_members)) == 0:
# raise exceptions.BadRequest("There are no more rooms of this size to reserve.")
bed_in_room = order.bed_in_room # Variation id of the ticket for that kind of room
for m in order.room_members:
if m == order.code:
res = order
else:
res = await om.get_order(code=m)
# Room user in another room
if res.room_id != order.code:
room_errors.append('room_id_mismatch')
if res.status != 'paid':
room_errors.append('unpaid')
if res.bed_in_room != bed_in_room:
room_errors.append('type_mismatch')
if res.daily:
room_errors.append('daily')
room_members.append(res)
if len(room_members) != order.room_person_no and order.room_person_no != None:
room_errors.append('capacity_mismatch')
return len(room_errors) == 0, room_errors, room_members