Compare commits
2 Commits
cd2a5405db
...
ab2c8d4b85
Author | SHA1 | Date |
---|---|---|
drew | ab2c8d4b85 | |
Stranck | df4f2eaf81 |
86
admin.py
86
admin.py
|
@ -4,7 +4,10 @@ from room import unconfirm_room_by_order
|
|||
from config import *
|
||||
from utils import *
|
||||
from ext import *
|
||||
from io import StringIO
|
||||
from sanic.log import logger
|
||||
import csv
|
||||
import time
|
||||
|
||||
bp = Blueprint("admin", url_prefix="/manage/admin")
|
||||
|
||||
|
@ -42,6 +45,7 @@ async def login_as(request, code, order:Order):
|
|||
|
||||
@bp.get('/room/verify')
|
||||
async def verify_rooms(request, order:Order):
|
||||
await clear_cache(request, order)
|
||||
already_checked, success = await request.app.ctx.om.update_cache()
|
||||
if not already_checked and success:
|
||||
orders = filter(lambda x: x.status not in ['c', 'e'] and x.room_id == x.code, request.app.ctx.om.cache.values())
|
||||
|
@ -56,6 +60,7 @@ async def unconfirm_room(request, code, order:Order):
|
|||
|
||||
@bp.get('/room/autoconfirm')
|
||||
async def autoconfirm_room(request, code, 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):
|
||||
|
@ -65,6 +70,7 @@ async def autoconfirm_room(request, code, order:Order):
|
|||
|
||||
@bp.get('/room/delete/<code>')
|
||||
async def delete_room(request, code, order:Order):
|
||||
await clear_cache(request, order)
|
||||
dOrder = await get_order_by_code(request, code, throwException=True)
|
||||
|
||||
ppl = await get_people_in_room_by_code(request, code)
|
||||
|
@ -84,6 +90,7 @@ async def delete_room(request, code, order:Order):
|
|||
|
||||
@bp.post('/room/rename/<code>')
|
||||
async def rename_room(request, code, order:Order):
|
||||
await clear_cache(request, order)
|
||||
dOrder = await get_order_by_code(request, code, throwException=True)
|
||||
|
||||
name = request.form.get('name')
|
||||
|
@ -107,4 +114,81 @@ async def propic_remind_missing(request, order:Order):
|
|||
# print(f"{order.code}: prp={missingPropic} fpr={missingFursuitPropic} - {order.name}")
|
||||
await send_missing_propic_message(order, missingPropic, missingFursuitPropic)
|
||||
|
||||
return redirect(f'/manage/admin')
|
||||
return redirect(f'/manage/admin')
|
||||
|
||||
@bp.get('/export/export')
|
||||
async def export_export(request, order:Order):
|
||||
await clear_cache(request, order)
|
||||
|
||||
data = StringIO()
|
||||
w = csv.writer(data)
|
||||
|
||||
w.writerow(['Status', 'Code', 'First name', 'Last name', 'Nick', 'State', 'Card', 'Artist', 'Fursuiter', 'Sponsorhip', 'Early', 'Late', 'Daily', 'Daily days', 'Shirt', 'Room type', 'Room count', 'Room members', 'Payment', 'Price', 'Refunds', 'Staff'])
|
||||
|
||||
orders = request.app.ctx.om.cache.values()
|
||||
order: Order
|
||||
for order in orders:
|
||||
w.writerow([
|
||||
order.status,
|
||||
order.code,
|
||||
order.first_name,
|
||||
order.last_name,
|
||||
order.name,
|
||||
order.country,
|
||||
order.has_card,
|
||||
order.is_artist,
|
||||
order.is_fursuiter,
|
||||
order.sponsorship,
|
||||
order.has_early,
|
||||
order.has_late,
|
||||
order.daily,
|
||||
','.join(order.dailyDays),
|
||||
order.shirt_size,
|
||||
ROOM_TYPE_NAMES[order.bed_in_room] if order.bed_in_room in ROOM_TYPE_NAMES else "-",
|
||||
len(order.room_members),
|
||||
','.join(order.room_members),
|
||||
order.payment_provider,
|
||||
order.total - order.fees,
|
||||
order.refunds,
|
||||
order.ans('staff_role') or 'attendee',
|
||||
])
|
||||
|
||||
data.seek(0)
|
||||
str = data.read() #data.read().decode("UTF-8")
|
||||
data.flush()
|
||||
data.close()
|
||||
|
||||
return raw(str, status=200, headers={'Content-Disposition': f'attachment; filename="export_{int(time.time())}.csv"', "Content-Type": "text/csv; charset=UTF-8"})
|
||||
|
||||
@bp.get('/export/hotel')
|
||||
async def export_hotel(request, order:Order):
|
||||
await clear_cache(request, order)
|
||||
|
||||
data = StringIO()
|
||||
w = csv.writer(data)
|
||||
|
||||
w.writerow(['Room type', 'Room name', 'Room code', 'First name', 'Last name', 'Birthday', 'Address', 'Email', 'Phone number', 'Status'])
|
||||
|
||||
orders = sorted(request.app.ctx.om.cache.values(), key=lambda d: (d.room_id if d.room_id != None else "~"))
|
||||
order: Order
|
||||
for order in orders:
|
||||
w.writerow([
|
||||
ROOM_TYPE_NAMES[order.bed_in_room] if order.bed_in_room in ROOM_TYPE_NAMES else "-",
|
||||
order.room_name,
|
||||
order.room_id,
|
||||
order.first_name,
|
||||
order.last_name,
|
||||
order.birth_date,
|
||||
order.address,
|
||||
order.email,
|
||||
order.phone,
|
||||
order.status,
|
||||
order.code
|
||||
])
|
||||
|
||||
data.seek(0)
|
||||
str = data.read() #data.read().decode("UTF-8")
|
||||
data.flush()
|
||||
data.close()
|
||||
|
||||
return raw(str, status=200, headers={'Content-Disposition': f'attachment; filename="hotel_{int(time.time())}.csv"', "Content-Type": "text/csv; charset=UTF-8"})
|
3
app.py
3
app.py
|
@ -29,14 +29,13 @@ app.ext.add_dependency(Quotas, get_quotas)
|
|||
from room import bp as room_bp
|
||||
from propic import bp as propic_bp
|
||||
from karaoke import bp as karaoke_bp
|
||||
from export import bp as export_bp
|
||||
from stats import bp as stats_bp
|
||||
from api import bp as api_bp
|
||||
from carpooling import bp as carpooling_bp
|
||||
from checkin import bp as checkin_bp
|
||||
from admin import bp as admin_bp
|
||||
|
||||
app.blueprint([room_bp, karaoke_bp, propic_bp, export_bp, stats_bp, api_bp, carpooling_bp, checkin_bp, admin_bp])
|
||||
app.blueprint([room_bp, karaoke_bp, propic_bp, stats_bp, api_bp, carpooling_bp, checkin_bp, admin_bp])
|
||||
|
||||
|
||||
async def clear_session(response):
|
||||
|
|
87
export.py
87
export.py
|
@ -1,87 +0,0 @@
|
|||
from sanic.response import text
|
||||
from sanic import Blueprint, exceptions
|
||||
from ext import *
|
||||
from config import headers, ADMINS, ORGANIZER, EVENT_NAME
|
||||
|
||||
bp = Blueprint("export", url_prefix="/manage/export")
|
||||
|
||||
@bp.route("/export.csv")
|
||||
async def export_csv(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!")
|
||||
if not order.isAdmin(): raise exceptions.Forbidden("Birichino :)")
|
||||
|
||||
page = 0
|
||||
orders = {}
|
||||
|
||||
ret = 'status;code;nome;cognome;nick;nazione;tessera;artista;fursuiter;sponsorship;early;late;shirt;roomsize;roommembers;payment;price;refunds;staff\n'
|
||||
|
||||
while 1:
|
||||
page += 1
|
||||
|
||||
r = httpx.get(f'https://reg.furizon.net/api/v1/organizers/{ORGANIZER}/events/{EVENT_NAME}/orders/?page={page}', headers=headers)
|
||||
if r.status_code == 404: break
|
||||
|
||||
for r in r.json()['results']:
|
||||
|
||||
o = Order(r)
|
||||
orders[o.code] = o
|
||||
|
||||
ret += (';'.join(map(lambda x: str(x),
|
||||
[
|
||||
o.status,
|
||||
o.code,
|
||||
o.first_name,
|
||||
o.last_name,
|
||||
o.name,
|
||||
o.country,
|
||||
o.has_card or '',
|
||||
o.is_artist or '',
|
||||
o.is_fursuiter or '',
|
||||
o.sponsorship or '',
|
||||
o.has_early or '',
|
||||
o.has_late or '',
|
||||
o.shirt_size,
|
||||
len(o.room_members),
|
||||
','.join(o.room_members),
|
||||
o.payment_provider,
|
||||
o.total-o.fees,
|
||||
o.refunds,
|
||||
o.ans('staff_role') or 'attendee',
|
||||
]))) + "\n"
|
||||
|
||||
return text(ret)
|
||||
|
||||
@bp.route("/hotel_export.csv")
|
||||
async def export_hotel_csv(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!")
|
||||
if order.code not in ['HWUC9','9YKGJ']: raise exceptions.Forbidden("Birichino :)")
|
||||
|
||||
page = 0
|
||||
orders = {}
|
||||
|
||||
ret = 'code;nome;cognome;datanascita;posnascita;indirizzo;mail;status\n'
|
||||
|
||||
while 1:
|
||||
page += 1
|
||||
|
||||
r = httpx.get(f'https://reg.furizon.net/api/v1/organizers/{ORGANIZER}/events/{EVENT_NAME}/orders/?page={page}', headers=headers)
|
||||
if r.status_code == 404: break
|
||||
|
||||
for r in r.json()['results']:
|
||||
|
||||
o = Order(r)
|
||||
orders[o.code] = o
|
||||
|
||||
ret += (';'.join(map(lambda x: str(x),
|
||||
[
|
||||
o.code,
|
||||
o.first_name,
|
||||
o.last_name,
|
||||
o.birth_date,
|
||||
o.birth_location,
|
||||
o.address,
|
||||
o.email,
|
||||
o.status
|
||||
]))) + "\n"
|
||||
|
||||
return text(ret)
|
2
ext.py
2
ext.py
|
@ -57,7 +57,7 @@ class Order:
|
|||
|
||||
idata = data['invoice_address']
|
||||
if idata:
|
||||
self.address = f"{idata['street']} - {idata['zipcode']} {idata['city']} - {idata['country']}"
|
||||
self.address = f"{idata['street'].strip()} - {idata['zipcode'].strip()} {idata['city'].strip()} - {idata['country'].strip()}".replace("\n", "").replace("\r", "")
|
||||
self.country = idata['country']
|
||||
|
||||
for p in self.data['positions']:
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
<a href="/manage/admin/room/verify" role="button" title="Will unconfirm rooms that fail the default check. Useful when editing answers from Pretix">Verify Rooms</a>
|
||||
<a href="#" onclick="confirmAction('propicReminder', this)" role="button" title="Will remind via mail all people who event uploaded a badge to do it" action="/manage/admin/propic/remind">Remind badge upload</a>
|
||||
<a href="/manage/admin/room/autoconfirm" role="button" title="Will confirm all the full rooms that are still unconfirmed">Auto-confirm Rooms</a>
|
||||
<a download href="/manage/admin/export/export" role="button" title="Will export most of informations about the orders">Export CSV</a>
|
||||
<a download href="/manage/admin/export/hotel" role="button" title="Will export a CSV for the hotel accomodation">Export hotel CSV</a>
|
||||
<hr>
|
||||
{% include 'components/confirm_action_modal.html' %}
|
||||
</main>
|
||||
|
|
Loading…
Reference in New Issue