From dc556c60a959f3bae2b0584e3ae554eae8b83c47 Mon Sep 17 00:00:00 2001 From: Vassili Minaev Date: Thu, 20 Mar 2025 03:10:43 -0600 Subject: [PATCH] Refactor --- apps/calendar/app.py | 47 +++++++++++++++---------------- apps/calendar/static/js/script.js | 25 ++++++++++++++-- apps/reporter/app.py | 13 ++------- apps/reporter/queries.py | 33 ++++++++-------------- main.py | 13 ++++++--- 5 files changed, 67 insertions(+), 64 deletions(-) diff --git a/apps/calendar/app.py b/apps/calendar/app.py index 7d82bab..ff49947 100644 --- a/apps/calendar/app.py +++ b/apps/calendar/app.py @@ -15,13 +15,6 @@ def datetime_format(postdata): return formatted def init_app(app): - async def db_query(query, params=()): - await app['dcur'].execute(query, params) - q = app['dcur'].mogrify(query, params) - r = await app['dcur'].fetchall() - result = [{k: (str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for k, v in row.items()} for row in r] - return (q, result) - routes = web.RouteTableDef() @routes.get('') @@ -45,40 +38,44 @@ def init_app(app): await aiohttp_security.check_permission(request, 'user') querystring = "SELECT * FROM events WHERE deleted=false AND %s BETWEEN datefrom AND dateto;" if request.match_info['day']: - query, response = await db_query(querystring, (request.match_info['day'],)) + response = await request.config_dict["query"](querystring, (request.match_info['day'],)) else: - query, response = await db_query(querystring.replace("%s", "CURDATE()")) - return web.json_response(response) + response = await request.config_dict["query"](querystring.replace("%s", "CURDATE()")) + formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response] + return web.json_response(formatted) @routes.get('/events/month/{month}') async def get_events_monthly(request): await aiohttp_security.check_permission(request, 'user') querystring = "SELECT * FROM events WHERE deleted=false AND %s BETWEEN DATE_FORMAT(datefrom, '%%Y-%%m') AND DATE_FORMAT(dateto, '%%Y-%%m');" if request.match_info['month']: - query, response = await db_query(querystring, (request.match_info['month'],)) + response = await request.config_dict["query"](querystring, (request.match_info['month'],)) else: - query, response = await db_query(querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')")) - return web.json_response(response) + response = await request.config_dict["query"](querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')")) + formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response] + return web.json_response(formatted) @routes.get('/admin/day/{day}') async def get_events_daily(request): await aiohttp_security.check_permission(request, 'admin') querystring = "SELECT * FROM events WHERE %s BETWEEN datefrom AND dateto;" if request.match_info['day']: - query, response = await db_query(querystring, (request.match_info['day'],)) + response = await request.config_dict["query"](querystring, (request.match_info['day'],)) else: - query, response = await db_query(querystring.replace("%s", "CURDATE()")) - return web.json_response(response) + response = await request.config_dict["query"](querystring.replace("%s", "CURDATE()")) + formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response] + return web.json_response(formatted) @routes.get('/admin/month/{month}') async def get_events_monthly(request): await aiohttp_security.check_permission(request, 'admin') querystring = "SELECT * FROM events WHERE %s BETWEEN DATE_FORMAT(datefrom, '%%Y-%%m') AND DATE_FORMAT(dateto, '%%Y-%%m');" if request.match_info['month']: - query, response = await db_query(querystring, (request.match_info['month'],)) + response = await request.config_dict["query"](querystring, (request.match_info['month'],)) else: - query, response = await db_query(querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')")) - return web.json_response(response) + response = await request.config_dict["query"](querystring.replace("%s", "DATE_FORMAT(CURDATE(), '%%Y-%%m')")) + formatted = [[(str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for v in row] for row in response] + return web.json_response(formatted) @routes.post('/event/add') async def event_add(request): @@ -87,9 +84,9 @@ def init_app(app): formatted = datetime_format(postdata) querystring = "INSERT INTO events(name, message, timefrom, timeto, timetbd, datefrom, dateto, datetbd) VALUES(%s,%s,%s,%s,%s,%s,%s,%s);" params = (postdata["name"], postdata["message"], formatted["timefrom"], formatted["timeto"], "timetbd" in postdata, postdata["datefrom"], postdata["dateto"], "datetbd" in postdata) - query, response = await db_query(querystring, params) + response = await request.config_dict["query"](querystring, params) # await update(request) - logevent(request, query) + #logevent(request, query) raise web.HTTPFound(app['prefix']) @routes.post('/event/{id}/edit') @@ -100,9 +97,9 @@ def init_app(app): querystring = "UPDATE events SET name=%s, message=%s, timefrom=%s, timeto=%s, timetbd=%s, datefrom=%s, dateto=%s, datetbd=%s WHERE id=%s;" params = (postdata["name"], postdata["message"], formatted["timefrom"], formatted["timeto"], "timetbd" in postdata, postdata["datefrom"], postdata["dateto"], "datetbd" in postdata, request.match_info['id']) - query, response = await db_query(querystring, params) + response = await request.config_dict["query"](querystring, params) # await update(request) - logevent(request, query) + #logevent(request, query) raise web.HTTPFound(app['prefix']) @routes.post('/event/{id}/delete') @@ -110,9 +107,9 @@ def init_app(app): await aiohttp_security.check_permission(request, 'user') postdata = await request.post() querystring = "UPDATE events SET deleted=true WHERE id=%s;" - query, response = await db_query(querystring, (request.match_info['id'],)) + response = await request.config_dict["query"](querystring, (request.match_info['id'],)) # await update(request) - logevent(request, query) + #logevent(request, query) raise web.HTTPFound(app['prefix']) app.add_routes(routes) \ No newline at end of file diff --git a/apps/calendar/static/js/script.js b/apps/calendar/static/js/script.js index dcf1a5e..9206f97 100644 --- a/apps/calendar/static/js/script.js +++ b/apps/calendar/static/js/script.js @@ -22,6 +22,21 @@ let weeks = []; let startOfWorkDay, endOfWorkDay, startOfDay, endOfDay, startOfMonth, endOfMonth, startOfCalMonth, endOfCalMonth, lastEvent; +const event_to_object = (datum) => { + return { + id: datum[0], + name: datum[1], + message: datum[2], + timefrom: datum[3], + timeto: datum[4], + timetbd: datum[5], + datefrom: datum[6], + dateto: datum[7], + datetbd: datum[8], + deleted: datum[9] + } +} + const init_times = (today) => { startOfWorkDay = today.hour(8).minute(0).second(0); endOfWorkDay = today.hour(17).minute(0).second(0); @@ -342,7 +357,8 @@ const day_onload = (request) => { //else { } let dailyEvents = []; let allDayEvents = []; - for (let event of data) { + for (let datum of data) { + let event = event_to_object(datum); const tf = dayjs(event.timefrom, "H:mm:ss"); event.datefrom = dayjs(event.datefrom); event.timefrom = dayjs(event.datefrom).hour(tf.hour()).minute(tf.minute()); @@ -388,7 +404,10 @@ const month_onload = (request) => { data = JSON.parse(request.responseText); } //else { } - for (let event of data) { + let converted_data = []; + for (let datum of data) { + let event = event_to_object(datum); + converted_data.push(event); let tf = dayjs(event.timefrom, "H:mm:ss"); event.datefrom = dayjs(event.datefrom); event.timefrom = dayjs(event.datefrom).hour(tf.hour()).minute(tf.minute()); @@ -408,7 +427,7 @@ const month_onload = (request) => { } event.colour = event.deleted ? "#ff0000" : "#32acea"; } - setup_monthly(data); + setup_monthly(converted_data); } const adjustField = (field) => { diff --git a/apps/reporter/app.py b/apps/reporter/app.py index 1d81d15..07129cd 100644 --- a/apps/reporter/app.py +++ b/apps/reporter/app.py @@ -79,13 +79,6 @@ def init_app(app): app['stats'] = {'reports_ran': 0, 'status': 'Normal'} app['menu'] = build_menu(app) - async def db_query(query, params=()): - await app['cur'].execute(query, params) - q = app['cur'].mogrify(query, params) - r = await app['cur'].fetchall() - result = [{k: (str(v) if isinstance(v, datetime.date) or isinstance(v, datetime.timedelta) else v) for k, v in row.items()} for row in r] - return (q, result) - routes = web.RouteTableDef() app.add_subapp('/admin', subapps.admin) @@ -133,9 +126,7 @@ def init_app(app): return web.json_response([]) params = () - await request.config_dict['cur'].execute(query, params) - q = request.config_dict['cur'].mogrify(query, params) - results = await request.config_dict['cur'].fetchall() + results = await request.config_dict['query'](query, params) return web.json_response([row[0] for row in results], dumps=simplejson.dumps) @@ -306,7 +297,7 @@ def init_app(app): else: user_options[fieldname] = value - query_response = await report['query'](request.config_dict['cur'], user_options) + query_response = await report['query'](request.config_dict['query'], user_options) report_options = { 'formatting': report.get('formatting', True), 'group_by': report.get('group_by') diff --git a/apps/reporter/queries.py b/apps/reporter/queries.py index ec6315c..94a9094 100644 --- a/apps/reporter/queries.py +++ b/apps/reporter/queries.py @@ -1,8 +1,4 @@ -from decimal import Decimal -import datetime -from dateutil.relativedelta import relativedelta - -async def orders_by_employee(cursor, options): +async def orders_by_employee(query_fn, options): errors = {} if options["date"]["from"] == '' or options["date"]["to"] == '': @@ -35,8 +31,7 @@ async def orders_by_employee(cursor, options): ) AS inter ON O.OrderID = inter.OrderID WHERE O.OrderDate BETWEEN %s AND %s;""".format(",".join(['%s'] * len(options["category"]))) - await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) - rows = await cursor.fetchall() + rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) results = [] for row in rows: @@ -46,7 +41,7 @@ async def orders_by_employee(cursor, options): return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'} -async def orders_by_location(cursor, options): +async def orders_by_location(query_fn, options): errors = {} if "location" not in options: @@ -86,8 +81,7 @@ async def orders_by_location(cursor, options): WHERE O.OrderDate BETWEEN %s AND %s;\ """.format(location_query[options["location"]], ",".join(['%s'] * len(options["category"]))) - await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) - rows = await cursor.fetchall() + rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) results = [] for row in rows: @@ -97,7 +91,7 @@ async def orders_by_location(cursor, options): return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'} -async def orders_by_product(cursor, options): +async def orders_by_product(query_fn, options): errors = {} if options["date"]["from"] == '' or options["date"]["to"] == '': @@ -125,8 +119,7 @@ async def orders_by_product(cursor, options): AND O.OrderDate BETWEEN %s AND %s;\ """.format(",".join(['%s'] * len(options["category"]))) - await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) - rows = await cursor.fetchall() + rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) results = [] for row in rows: @@ -136,7 +129,7 @@ async def orders_by_product(cursor, options): return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'} -async def orders_by_supplier(cursor, options): +async def orders_by_supplier(query_fn, options): errors = {} if options["date"]["from"] == '' or options["date"]["to"] == '': @@ -166,8 +159,7 @@ async def orders_by_supplier(cursor, options): AND O.OrderDate BETWEEN %s AND %s;\ """.format(",".join(['%s'] * len(options["category"]))) - await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) - rows = await cursor.fetchall() + rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) results = [] for row in rows: @@ -177,7 +169,7 @@ async def orders_by_supplier(cursor, options): return {'status': 'ok', 'rows': results, 'period': f'{options["date"]["from"]} - {options["date"]["to"]}'} -async def pivot_table(cursor, options): +async def pivot_table(query_fn, options): errors = {} valid_rows = set(['month', 'year', 'employee', 'shipper', 'customer', 'supplier', 'category', 'product']) valid_columns = set(['month', 'year', 'employee', 'shipper', 'category']) @@ -252,11 +244,10 @@ async def pivot_table(cursor, options): groupcols=', '+parts[options['columns']][1] if options["columns"] != 'none' else '' ) - await cursor.execute(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) - response = await cursor.fetchall() + rows = await query_fn(query, [*options["category"].keys(), options["date"]["from"], options["date"]["to"]]) if options["columns"] == 'none': - results = [ list(row) for row in response ] + results = [ list(row) for row in rows ] value_lookup = {'sales': 'Order Value', 'qty': 'Item Quantity'} rv = {'status': 'ok', 'rows': results, 'columns': [{'name': options['rows'].capitalize()}, {'name': value_lookup[options["values"]], 'format': '$'}]} return rv @@ -264,7 +255,7 @@ async def pivot_table(cursor, options): results = [] intermediate = {} cols = set() - for row in response: + for row in rows: if row[0] is None: continue cols.add(row[1]) diff --git a/main.py b/main.py index ba157ea..5a1aa34 100644 --- a/main.py +++ b/main.py @@ -7,9 +7,6 @@ import aiomysql from pymysql.err import OperationalError import datetime -import simplejson -from dateutil.relativedelta import relativedelta -import urllib.parse import psutil # Local @@ -23,7 +20,15 @@ async def mysql_engine(app): pool = await aiomysql.create_pool(autocommit=True, **app['config']['database']) app['con'] = await pool.acquire() app['cur'] = await app['con'].cursor() - app['dcur'] = await app['con'].cursor(aiomysql.DictCursor) + + async def db_query(query, params=()): + await app['cur'].execute(query, params) + #q = app['cur'].mogrify(query, params) + r = await app['cur'].fetchall() + #return (q, r) + return r + app['query'] = db_query + except OperationalError as e: print(e) print("Done.")