From df4f2eaf81eb74597b968811dee5fb809d7899ec Mon Sep 17 00:00:00 2001 From: Stranck Date: Mon, 13 May 2024 13:30:21 +0200 Subject: [PATCH] Improved CSV export --- admin.py | 86 ++++++++++++++++++++++++++++++++++++++++++++++++- app.py | 3 +- export.py | 87 -------------------------------------------------- ext.py | 2 +- tpl/admin.html | 2 ++ 5 files changed, 89 insertions(+), 91 deletions(-) delete mode 100644 export.py diff --git a/admin.py b/admin.py index 7a8d384..3bbbd96 100644 --- a/admin.py +++ b/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/') 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/') 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') \ No newline at end of file + 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"}) \ No newline at end of file diff --git a/app.py b/app.py index f029ba2..51e2088 100644 --- a/app.py +++ b/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): diff --git a/export.py b/export.py deleted file mode 100644 index 99277ab..0000000 --- a/export.py +++ /dev/null @@ -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) diff --git a/ext.py b/ext.py index 1039f7d..8db2788 100644 --- a/ext.py +++ b/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']: diff --git a/tpl/admin.html b/tpl/admin.html index 98acde6..35627d1 100644 --- a/tpl/admin.html +++ b/tpl/admin.html @@ -16,6 +16,8 @@ Verify Rooms Remind badge upload Auto-confirm Rooms + Export CSV + Export hotel CSV
{% include 'components/confirm_action_modal.html' %}