diff --git a/__pycache__/celery_worker.cpython-312.pyc b/__pycache__/celery_worker.cpython-312.pyc new file mode 100644 index 0000000..993f222 Binary files /dev/null and b/__pycache__/celery_worker.cpython-312.pyc differ diff --git a/__pycache__/celery_worker.cpython-313.pyc b/__pycache__/celery_worker.cpython-313.pyc new file mode 100644 index 0000000..df96583 Binary files /dev/null and b/__pycache__/celery_worker.cpython-313.pyc differ diff --git a/__pycache__/webserver.cpython-312.pyc b/__pycache__/webserver.cpython-312.pyc index eed7273..6a51b01 100644 Binary files a/__pycache__/webserver.cpython-312.pyc and b/__pycache__/webserver.cpython-312.pyc differ diff --git a/__pycache__/webserver.cpython-313.pyc b/__pycache__/webserver.cpython-313.pyc index 35d01e3..e1740f5 100644 Binary files a/__pycache__/webserver.cpython-313.pyc and b/__pycache__/webserver.cpython-313.pyc differ diff --git a/celery_worker.py b/celery_worker.py new file mode 100644 index 0000000..fd83e29 --- /dev/null +++ b/celery_worker.py @@ -0,0 +1,30 @@ +from webserver import create_app # This imports your initialized Flask app +from celery import Celery + +def make_celery(flask_app): + celery = Celery( + flask_app.import_name, + broker='redis://192.168.1.67:6379', # Use your actual Redis config + backend='redis://192.168.1.67:6379' + ) + celery.conf.update(flask_app.config) + class ContextTask(celery.Task): + def __call__(self, *args, **kwargs): + with flask_app.app_context(): + return self.run(*args, **kwargs) + celery.Task = ContextTask + return celery + +celery = make_celery(create_app()) + +@celery.task +def print_noon_message(): + print("It's noon! Task executed by Celery.") + +from celery.schedules import crontab +celery.conf.beat_schedule = { + 'print-noon-task': { + 'task': 'celery_worker.print_noon_message', + 'schedule': crontab(minute='*/1'), + }, +} \ No newline at end of file diff --git a/celerybeat-schedule b/celerybeat-schedule new file mode 100644 index 0000000..237da49 Binary files /dev/null and b/celerybeat-schedule differ diff --git a/celerybeat-schedule-shm b/celerybeat-schedule-shm new file mode 100644 index 0000000..bee3ced Binary files /dev/null and b/celerybeat-schedule-shm differ diff --git a/celerybeat-schedule-wal b/celerybeat-schedule-wal new file mode 100644 index 0000000..3b2733b Binary files /dev/null and b/celerybeat-schedule-wal differ diff --git a/logs/database.log b/logs/database.log index 456f65e..e3a529a 100644 --- a/logs/database.log +++ b/logs/database.log @@ -236,4 +236,73 @@ sql='WITH arguments AS ( SELECT %s AS year, %s AS month),sum_cte AS ( SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id ),cte_recipe_items AS ( SELECT rp_item.qty, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM main_recipe_items rp_item LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid )SELECT events.*, COALESCE(row_to_json(recipes.*), '{}') as recipe, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_recipe_items g WHERE g.rp_id = recipes.id) AS rp_itemsFROM main_plan_events eventsLEFT JOIN main_recipes recipes ON recipes.recipe_uuid = events.recipe_uuidWHERE event_date_end >= make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) AND event_date_start < (make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) + INTERVAL '1 month');') 2025-08-12 11:13:30.870202 --- ERROR --- DatabaseError(message='missing FROM-clause entry for table "recipe_missing_items"LINE 25: COALESCE(recipe_missing_items.has_missing_ingredients,... ^', payload=(2025, 8), - sql='WITH arguments AS ( SELECT %s AS year, %s AS month),sum_cte AS ( SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id ),cte_recipe_items AS ( SELECT rp_item.rp_id, rp_item.qty, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM main_recipe_items rp_item LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid ), recipe_missing_items AS ( SELECT rp_id, bool_or(qty > quantity_on_hand) AS has_missing_ingredients FROM cte_recipe_items GROUP BY rp_id)SELECT events.*, COALESCE(row_to_json(recipes.*), '{}') as recipe, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_recipe_items g WHERE g.rp_id = recipes.id) AS rp_items, COALESCE(recipe_missing_items.has_missing_ingredients, FALSE) AS has_missing_ingredientsFROM main_plan_events eventsLEFT JOIN main_recipes recipes ON recipes.recipe_uuid = events.recipe_uuidWHERE event_date_end >= make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) AND event_date_start < (make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) + INTERVAL '1 month');') \ No newline at end of file + sql='WITH arguments AS ( SELECT %s AS year, %s AS month),sum_cte AS ( SELECT mi.item_uuid, SUM(mil.quantity_on_hand)::FLOAT8 AS total_sum FROM main_item_locations mil JOIN main_items mi ON mil.part_id = mi.id GROUP BY mi.id ),cte_recipe_items AS ( SELECT rp_item.rp_id, rp_item.qty, COALESCE(sum_cte.total_sum, 0) as quantity_on_hand FROM main_recipe_items rp_item LEFT JOIN sum_cte ON sum_cte.item_uuid = rp_item.item_uuid ), recipe_missing_items AS ( SELECT rp_id, bool_or(qty > quantity_on_hand) AS has_missing_ingredients FROM cte_recipe_items GROUP BY rp_id)SELECT events.*, COALESCE(row_to_json(recipes.*), '{}') as recipe, (SELECT COALESCE(array_agg(row_to_json(g)), '{}') FROM cte_recipe_items g WHERE g.rp_id = recipes.id) AS rp_items, COALESCE(recipe_missing_items.has_missing_ingredients, FALSE) AS has_missing_ingredientsFROM main_plan_events eventsLEFT JOIN main_recipes recipes ON recipes.recipe_uuid = events.recipe_uuidWHERE event_date_end >= make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) AND event_date_start < (make_date((SELECT year FROM arguments), (SELECT month FROM arguments), 1) + INTERVAL '1 month');') +2025-08-13 05:57:51.664542 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (489, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:57:52.543637 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (490, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:57:59.264995 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (491, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:05.574433 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (492, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:05.759833 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (493, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:13.545144 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (494, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:17.277887 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (495, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:18.060764 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (496, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:18.238774 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (497, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:18.417773 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (498, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:21.253662 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (499, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:21.412016 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (500, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:49.785521 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (501, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:54.323920 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (502, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:54.795245 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (503, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:54.964411 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (504, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:55.098509 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (505, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:56.160562 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (506, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:58:56.248810 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (507, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:59:00.781015 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (508, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:59:01.156483 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (509, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 05:59:01.352075 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (510, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') +2025-08-13 14:48:16.893199 --- ERROR --- DatabaseError(message='null value in column "barcode" of relation "main_logistics_info" violates not-null constraintDETAIL: Failing row contains (511, null, 1, 1, 1, 1).', + payload=(None, 1, 1, 1, 1), + sql='INSERT INTO main_logistics_info(barcode, primary_location, primary_zone, auto_issue_location, auto_issue_zone) VALUES (%s, %s, %s, %s, %s) RETURNING *;') \ No newline at end of file diff --git a/run-server.bat b/run-server.bat new file mode 100644 index 0000000..672750e --- /dev/null +++ b/run-server.bat @@ -0,0 +1,9 @@ +@echo off +REM Start Flask web server +start "Flask Server" cmd /k python webserver.py + +REM Start Celery worker (use --pool=solo for Windows) +start "Celery Worker" cmd /k python -m celery -A celery_worker.celery worker --pool=solo --loglevel=info + +REM Start Celery beat scheduler +start "Celery Beat" cmd /k python -m celery -A celery_worker.celery beat --loglevel=info \ No newline at end of file diff --git a/webserver.py b/webserver.py index dd7d6b1..cda83e0 100644 --- a/webserver.py +++ b/webserver.py @@ -16,40 +16,45 @@ from application.meal_planner import meal_planner_api from flasgger import Swagger from outh import oauth -app = Flask(__name__, instance_relative_config=True) -oauth.init_app(app) -swagger = Swagger(app) -app.config.from_pyfile('application.cfg.py') +def create_app(): + app = Flask(__name__, instance_relative_config=True) + oauth.init_app(app) + swagger = Swagger(app) + app.config.from_pyfile('application.cfg.py') -oauth.register( - name=app.config['OAUTH_NAME'], - client_id=app.config['OAUTH_CLIENT_ID'], - client_secret=app.config['OAUTH_CLIENT_SECRET'], - access_token_url=app.config['OAUTH_ACCESS_TOKEN_URL'], - authorize_url=app.config['OAUTH_AUTHORIZE_URL'], - userinfo_endpoint=app.config['OAUTH_USERINFO_ENDPOINT'], - api_base_url=app.config['OAUTH_API_BASE_URL'], - jwks_uri=app.config['OAUTH_JWKS_URI'], - client_kwargs=app.config['OAUTH_CLIENT_KWARGS'], -) + oauth.register( + name=app.config['OAUTH_NAME'], + client_id=app.config['OAUTH_CLIENT_ID'], + client_secret=app.config['OAUTH_CLIENT_SECRET'], + access_token_url=app.config['OAUTH_ACCESS_TOKEN_URL'], + authorize_url=app.config['OAUTH_AUTHORIZE_URL'], + userinfo_endpoint=app.config['OAUTH_USERINFO_ENDPOINT'], + api_base_url=app.config['OAUTH_API_BASE_URL'], + jwks_uri=app.config['OAUTH_JWKS_URI'], + client_kwargs=app.config['OAUTH_CLIENT_KWARGS'], + ) -assets = Environment(app) -app.secret_key = app.config['APP_SECRET'] -app.register_blueprint(access_api.access_api, url_prefix="/access") -app.register_blueprint(administration_api.admin_api, url_prefix='/administration') -app.register_blueprint(items_API.items_api, url_prefix='/items') -app.register_blueprint(poe_api.point_of_ease, url_prefix='/poe') -app.register_blueprint(site_management_api.site_management_api, url_prefix="/site-management") -app.register_blueprint(receipts_api.receipt_api, url_prefix='/receipts') -app.register_blueprint(shoplist_api.shopping_list_api, url_prefix="/shopping-lists") -app.register_blueprint(recipes_api.recipes_api, url_prefix='/recipes') -app.register_blueprint(meal_planner_api.meal_planner_api, url_prefix='/planner') + assets = Environment(app) + app.secret_key = app.config['APP_SECRET'] + app.register_blueprint(access_api.access_api, url_prefix="/access") + app.register_blueprint(administration_api.admin_api, url_prefix='/administration') + app.register_blueprint(items_API.items_api, url_prefix='/items') + app.register_blueprint(poe_api.point_of_ease, url_prefix='/poe') + app.register_blueprint(site_management_api.site_management_api, url_prefix="/site-management") + app.register_blueprint(receipts_api.receipt_api, url_prefix='/receipts') + app.register_blueprint(shoplist_api.shopping_list_api, url_prefix="/shopping-lists") + app.register_blueprint(recipes_api.recipes_api, url_prefix='/recipes') + app.register_blueprint(meal_planner_api.meal_planner_api, url_prefix='/planner') -js = Bundle('js/uikit.min.js', 'js/uikit-icons.min.js', output='gen/main.js') -assets.register('js_all', js) + js = Bundle('js/uikit.min.js', 'js/uikit-icons.min.js', output='gen/main.js') + assets.register('js_all', js) + + assets.init_app(app) + return app + +app = create_app() -assets.init_app(app) @app.context_processor def inject_user(): @@ -108,4 +113,5 @@ def home(): session['selected_site'] = sites[0] return redirect("/items") -app.run(host="0.0.0.0", port=5810, debug=True) \ No newline at end of file +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5810, debug=True) \ No newline at end of file