From 393a1e4c1aadf7af7ba008989b5cc1c6f67a5995 Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:47:05 -0600 Subject: [PATCH 01/10] fix: Cocktail Builder Enhancements (#4672) --- .../g/_groupSlug/recipes/finder/index.vue | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/frontend/pages/g/_groupSlug/recipes/finder/index.vue b/frontend/pages/g/_groupSlug/recipes/finder/index.vue index cd0248b4c3a..86219f35a1f 100644 --- a/frontend/pages/g/_groupSlug/recipes/finder/index.vue +++ b/frontend/pages/g/_groupSlug/recipes/finder/index.vue @@ -220,7 +220,7 @@ - + ([]); function addFood(food: IngredientFood) { selectedFoods.value.push(food); + handleFoodUpdates(); } function removeFood(food: IngredientFood) { selectedFoods.value = selectedFoods.value.filter((f) => f.id !== food.id); + handleFoodUpdates(); + } + function handleFoodUpdates() { + selectedFoods.value.sort((a, b) => (a.pluralName || a.name).localeCompare(b.pluralName || b.name)); + preferences.value.foodIds = selectedFoods.value.map((food) => food.id); } watch( () => selectedFoods.value, () => { - selectedFoods.value.sort((a, b) => (a.pluralName || a.name).localeCompare(b.pluralName || b.name)); - preferences.value.foodIds = selectedFoods.value.map((food) => food.id); - } + handleFoodUpdates(); + }, ) const toolStore = isOwnGroup.value ? useToolStore() : usePublicToolStore(groupSlug.value); const selectedTools = ref([]); function addTool(tool: RecipeTool) { selectedTools.value.push(tool); + handleToolUpdates(); } function removeTool(tool: RecipeTool) { selectedTools.value = selectedTools.value.filter((t) => t.id !== tool.id); + handleToolUpdates(); + } + function handleToolUpdates() { + selectedTools.value.sort((a, b) => a.name.localeCompare(b.name)); + preferences.value.toolIds = selectedTools.value.map((tool) => tool.id); } watch( () => selectedTools.value, () => { - selectedTools.value.sort((a, b) => a.name.localeCompare(b.name)); - preferences.value.toolIds = selectedTools.value.map((tool) => tool.id); + handleToolUpdates(); } ) From da3e1b4c00b0f0f6d02c2f5c3c14a564f1744062 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:03:35 +0100 Subject: [PATCH 02/10] fix(deps): update dependency openai to v1.56.1 (#4673) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index cb0d5072419..55eaab94335 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1602,13 +1602,13 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openai" -version = "1.56.0" +version = "1.56.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" files = [ - {file = "openai-1.56.0-py3-none-any.whl", hash = "sha256:0751a6e139a09fca2e9cbbe8a62bfdab901b5865249d2555d005decf966ef9c3"}, - {file = "openai-1.56.0.tar.gz", hash = "sha256:f7fa159c8e18e7f9a8d71ff4b8052452ae70a4edc6b76a6e97eda00d5364923f"}, + {file = "openai-1.56.1-py3-none-any.whl", hash = "sha256:38e61183c2a98fedebbbb04a909a052d9f897358b070483fc0caff17300a227c"}, + {file = "openai-1.56.1.tar.gz", hash = "sha256:8b0449f22a0c318441eae8a8a789753c3b2cac86542be51ca45df788e26aa180"}, ] [package.dependencies] From 497424528dbd7d09f6469c3602cdbcf76a9d30e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:09:12 -0600 Subject: [PATCH 03/10] fix(deps): update dependency pydantic to v2.10.3 (#4674) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 55eaab94335..45f414fa323 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2071,13 +2071,13 @@ files = [ [[package]] name = "pydantic" -version = "2.10.2" +version = "2.10.3" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"}, - {file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"}, + {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, + {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, ] [package.dependencies] From f1e9615efda1aa6066079ee1ae111f63e3af072e Mon Sep 17 00:00:00 2001 From: Arshad Basha <43876926+Arshad561@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:07:54 -0700 Subject: [PATCH 04/10] fix: Meal Plan Notes allow Submission Without Title/Note Text (#4615) Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com> --- .../pages/household/mealplan/planner/edit.vue | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/frontend/pages/household/mealplan/planner/edit.vue b/frontend/pages/household/mealplan/planner/edit.vue index a03f8c59577..a94f446618a 100644 --- a/frontend/pages/household/mealplan/planner/edit.vue +++ b/frontend/pages/household/mealplan/planner/edit.vue @@ -22,6 +22,7 @@ resetDialog(); " @close="resetDialog()" + :submitDisabled="isCreateDisabled" > @@ -253,6 +255,7 @@ export default defineComponent({ const api = useUserApi(); const { $auth } = useContext(); const { household } = useHouseholdSelf(); + const requiredRule = (value: any) => !!value || "Required." const state = ref({ dialog: false, @@ -315,6 +318,14 @@ export default defineComponent({ userId: $auth.user?.id || "", }); + const isCreateDisabled = computed(() => { + if (dialog.note) { + return !newMeal.title.trim(); + } + return !newMeal.recipeId; + }); + + function openDialog(date: Date) { newMeal.date = format(date, "yyyy-MM-dd"); state.value.dialog = true; @@ -373,6 +384,8 @@ export default defineComponent({ onMoveCallback, planTypeOptions, getEntryTypeText, + requiredRule, + isCreateDisabled, // Dialog dialog, From a6cbf1308e36a91ce67a2af354b6f005ddb095fc Mon Sep 17 00:00:00 2001 From: Michael Chisholm Date: Thu, 5 Dec 2024 02:57:57 +1000 Subject: [PATCH 05/10] feat: Move alembic config into mealie package for easier distribution (#4329) --- Taskfile.yml | 2 +- docker/Dockerfile | 4 ---- {alembic => mealie/alembic}/README | 0 alembic.ini => mealie/alembic/alembic.ini | 2 +- {alembic => mealie/alembic}/env.py | 2 +- {alembic => mealie/alembic}/script.py.mako | 2 +- ...22-02-21-19.56.24_6b0f5f32d602_initial_tables.py | 0 ...707191_convert_quantity_from_integer_to_float.py | 0 ...dbee5fe9_add_original_text_column_to_recipes_.py | 0 ...1-19.19.55_59eb59135381_add_tags_to_cookbooks.py | 0 ...c897ad62_add_require_all_for_cookbook_filters.py | 0 ..._ab0bae02578f_add_use_abbreviation_column_to_.py | 0 ...-21.05.34_f30cf048c228_add_new_webhook_fields.py | 0 ...910655_add_login_attemps_and_locked_at_field_.py | 0 ...bfa50d0ed_add_is_ocr_recipe_column_to_recipes.py | 0 ...719d_add_extras_to_shopping_lists_list_items_.py | 0 ...2ea7a807915c_add_recipe_timeline_events_table.py | 0 ...3519381ad_renamed_timeline_event_message_and_.py | 0 ...066ad_add_recipe_scale_to_shopping_list_item_.py | 0 ....44_165d943c64ee_add_related_user_to_mealplan.py | 0 ...5f73b01a7a_add_missing_foreign_key_and_order_.py | 0 ...bf731a0_add_more_indices_necessary_for_search.py | 0 ...5ab195a474eb_add_normalized_search_properties.py | 0 ...4a08da2108_added_shopping_list_label_settings.py | 0 ...52_38514b39a824_add_auth_method_to_user_table.py | 0 ...3-06.47.04_b3dbb554ba53_postgres_fuzzy_search.py | 0 ...-08-06-21.00.34_04ac51cbe9a4_added_group_slug.py | 0 ...5b5225403_added_recipe_note_to_shopping_list_.py | 0 ...cfdad6b7355_remove_tool_name_and_slug_unique_.py | 0 ...b154f79a_added_normalized_unit_and_food_names.py | 0 ...4.29.26_dded3119c1fe_added_unique_constraints.py | 0 ...fe99_added_plural_names_and_alias_tables_for_.py | 0 ...5.07_2298bb460ffd_added_user_to_shopping_list.py | 2 +- ...10-05.08.32_09aba125b57a_add_oidc_auth_method.py | 0 ...d2de42_migrate_favorites_and_ratings_to_user_.py | 2 +- ...1.05.20_7788478a0338_add_group_recipe_actions.py | 2 +- ...0.17.03_32d69327997b_add_staple_flag_to_foods.py | 3 +-- ...24-07-12-16.16.29_feecc8ffb956_add_households.py | 2 +- ...ffdf_added_household_recipe_lock_setting_and_.py | 1 - ...4bd37ccc8_add_households_filter_to_meal_plans.py | 2 +- ..._602927e1013e_add_the_rest_of_the_schema_org_.py | 1 - ...40fd06_added_query_filter_string_to_cookbook_.py | 2 +- ...97397b4631_add_summary_to_recipe_instructions.py | 1 - ....50.59_b1020f328e98_add_recipe_yield_quantity.py | 2 +- mealie/db/init_db.py | 8 ++++---- mealie/services/backups_v2/alchemy_exporter.py | 13 ++++--------- pyproject.toml | 4 ++-- tests/utils/alembic_reader.py | 4 ++-- 48 files changed, 24 insertions(+), 37 deletions(-) rename {alembic => mealie/alembic}/README (100%) rename alembic.ini => mealie/alembic/alembic.ini (98%) rename {alembic => mealie/alembic}/env.py (100%) rename {alembic => mealie/alembic}/script.py.mako (100%) rename {alembic => mealie/alembic}/versions/2022-02-21-19.56.24_6b0f5f32d602_initial_tables.py (100%) rename {alembic => mealie/alembic}/versions/2022-03-23-17.43.34_263dd6707191_convert_quantity_from_integer_to_float.py (100%) rename {alembic => mealie/alembic}/versions/2022-03-27-19.30.28_f1a2dbee5fe9_add_original_text_column_to_recipes_.py (100%) rename {alembic => mealie/alembic}/versions/2022-03-31-19.19.55_59eb59135381_add_tags_to_cookbooks.py (100%) rename {alembic => mealie/alembic}/versions/2022-04-03-10.48.51_09dfc897ad62_add_require_all_for_cookbook_filters.py (100%) rename {alembic => mealie/alembic}/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py (100%) rename {alembic => mealie/alembic}/versions/2022-06-15-21.05.34_f30cf048c228_add_new_webhook_fields.py (100%) rename {alembic => mealie/alembic}/versions/2022-08-12-19.05.59_188374910655_add_login_attemps_and_locked_at_field_.py (100%) rename {alembic => mealie/alembic}/versions/2022-08-13-17.07.07_089bfa50d0ed_add_is_ocr_recipe_column_to_recipes.py (100%) rename {alembic => mealie/alembic}/versions/2022-08-29-13.57.40_44e8d670719d_add_extras_to_shopping_lists_list_items_.py (100%) rename {alembic => mealie/alembic}/versions/2022-09-27-14.53.14_2ea7a807915c_add_recipe_timeline_events_table.py (100%) rename {alembic => mealie/alembic}/versions/2022-11-03-13.10.24_1923519381ad_renamed_timeline_event_message_and_.py (100%) rename {alembic => mealie/alembic}/versions/2022-11-22-03.42.45_167eb69066ad_add_recipe_scale_to_shopping_list_item_.py (100%) rename {alembic => mealie/alembic}/versions/2023-01-21-16.54.44_165d943c64ee_add_related_user_to_mealplan.py (100%) rename {alembic => mealie/alembic}/versions/2023-02-07-20.57.21_ff5f73b01a7a_add_missing_foreign_key_and_order_.py (100%) rename {alembic => mealie/alembic}/versions/2023-02-10-21.18.32_16160bf731a0_add_more_indices_necessary_for_search.py (100%) rename {alembic => mealie/alembic}/versions/2023-02-14-20.45.41_5ab195a474eb_add_normalized_search_properties.py (100%) rename {alembic => mealie/alembic}/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py (100%) rename {alembic => mealie/alembic}/versions/2023-02-22-21.45.52_38514b39a824_add_auth_method_to_user_table.py (100%) rename {alembic => mealie/alembic}/versions/2023-04-13-06.47.04_b3dbb554ba53_postgres_fuzzy_search.py (100%) rename {alembic => mealie/alembic}/versions/2023-08-06-21.00.34_04ac51cbe9a4_added_group_slug.py (100%) rename {alembic => mealie/alembic}/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py (100%) rename {alembic => mealie/alembic}/versions/2023-08-15-16.25.07_bcfdad6b7355_remove_tool_name_and_slug_unique_.py (100%) rename {alembic => mealie/alembic}/versions/2023-09-01-14.55.42_0341b154f79a_added_normalized_unit_and_food_names.py (100%) rename {alembic => mealie/alembic}/versions/2023-10-04-14.29.26_dded3119c1fe_added_unique_constraints.py (100%) rename {alembic => mealie/alembic}/versions/2023-10-19-19.22.55_ba1e4a6cfe99_added_plural_names_and_alias_tables_for_.py (100%) rename {alembic => mealie/alembic}/versions/2024-02-23-16.15.07_2298bb460ffd_added_user_to_shopping_list.py (100%) rename {alembic => mealie/alembic}/versions/2024-03-10-05.08.32_09aba125b57a_add_oidc_auth_method.py (100%) rename {alembic => mealie/alembic}/versions/2024-03-18-02.28.15_d7c6efd2de42_migrate_favorites_and_ratings_to_user_.py (100%) rename {alembic => mealie/alembic}/versions/2024-04-07-01.05.20_7788478a0338_add_group_recipe_actions.py (100%) rename {alembic => mealie/alembic}/versions/2024-06-22-10.17.03_32d69327997b_add_staple_flag_to_foods.py (99%) rename {alembic => mealie/alembic}/versions/2024-07-12-16.16.29_feecc8ffb956_add_households.py (100%) rename {alembic => mealie/alembic}/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py (99%) rename {alembic => mealie/alembic}/versions/2024-09-18-14.52.55_1fe4bd37ccc8_add_households_filter_to_meal_plans.py (100%) rename {alembic => mealie/alembic}/versions/2024-10-01-14.17.00_602927e1013e_add_the_rest_of_the_schema_org_.py (99%) rename {alembic => mealie/alembic}/versions/2024-10-08-21.17.31_86054b40fd06_added_query_filter_string_to_cookbook_.py (100%) rename {alembic => mealie/alembic}/versions/2024-10-20-09.47.46_3897397b4631_add_summary_to_recipe_instructions.py (99%) rename {alembic => mealie/alembic}/versions/2024-10-23-15.50.59_b1020f328e98_add_recipe_yield_quantity.py (100%) diff --git a/Taskfile.yml b/Taskfile.yml index a9ca44ac021..70f6f23dd9f 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -151,7 +151,7 @@ tasks: py:migrate: desc: generates a new database migration file e.g. task py:migrate -- "add new column" cmds: - - poetry run alembic revision --autogenerate -m "{{ .CLI_ARGS }}" + - poetry run alembic --config mealie/alembic/alembic.ini revision --autogenerate -m "{{ .CLI_ARGS }}" - task: py:format ui:build: diff --git a/docker/Dockerfile b/docker/Dockerfile index 6c9c09066ee..056825c4195 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -109,10 +109,6 @@ COPY --from=crfpp /usr/local/bin/crf_test /usr/local/bin/crf_test COPY ./mealie $MEALIE_HOME/mealie COPY ./poetry.lock ./pyproject.toml $MEALIE_HOME/ -# Alembic -COPY ./alembic $MEALIE_HOME/alembic -COPY ./alembic.ini $MEALIE_HOME/ - # venv already has runtime deps installed we get a quicker install WORKDIR $MEALIE_HOME RUN . $VENV_PATH/bin/activate && poetry install -E pgsql --only main diff --git a/alembic/README b/mealie/alembic/README similarity index 100% rename from alembic/README rename to mealie/alembic/README diff --git a/alembic.ini b/mealie/alembic/alembic.ini similarity index 98% rename from alembic.ini rename to mealie/alembic/alembic.ini index c068265c89d..d955e61bebc 100644 --- a/alembic.ini +++ b/mealie/alembic/alembic.ini @@ -2,7 +2,7 @@ [alembic] # path to migration scripts -script_location = alembic +script_location = %(here)s # template used to generate migration files file_template = %%(year)d-%%(month).2d-%%(day).2d-%%(hour).2d.%%(minute).2d.%%(second).2d_%%(rev)s_%%(slug)s diff --git a/alembic/env.py b/mealie/alembic/env.py similarity index 100% rename from alembic/env.py rename to mealie/alembic/env.py index 4b38d2830e8..bff312261e8 100644 --- a/alembic/env.py +++ b/mealie/alembic/env.py @@ -1,9 +1,9 @@ from typing import Any import sqlalchemy as sa +from alembic import context import mealie.db.models._all_models # noqa: F401 -from alembic import context from mealie.core.config import get_app_settings from mealie.db.models._model_base import SqlAlchemyBase diff --git a/alembic/script.py.mako b/mealie/alembic/script.py.mako similarity index 100% rename from alembic/script.py.mako rename to mealie/alembic/script.py.mako index 3bf7e9e4d13..ccd9c8a36c4 100644 --- a/alembic/script.py.mako +++ b/mealie/alembic/script.py.mako @@ -6,9 +6,9 @@ Create Date: ${create_date} """ import sqlalchemy as sa +from alembic import op import mealie.db.migration_types -from alembic import op % if imports: ${imports} % endif diff --git a/alembic/versions/2022-02-21-19.56.24_6b0f5f32d602_initial_tables.py b/mealie/alembic/versions/2022-02-21-19.56.24_6b0f5f32d602_initial_tables.py similarity index 100% rename from alembic/versions/2022-02-21-19.56.24_6b0f5f32d602_initial_tables.py rename to mealie/alembic/versions/2022-02-21-19.56.24_6b0f5f32d602_initial_tables.py diff --git a/alembic/versions/2022-03-23-17.43.34_263dd6707191_convert_quantity_from_integer_to_float.py b/mealie/alembic/versions/2022-03-23-17.43.34_263dd6707191_convert_quantity_from_integer_to_float.py similarity index 100% rename from alembic/versions/2022-03-23-17.43.34_263dd6707191_convert_quantity_from_integer_to_float.py rename to mealie/alembic/versions/2022-03-23-17.43.34_263dd6707191_convert_quantity_from_integer_to_float.py diff --git a/alembic/versions/2022-03-27-19.30.28_f1a2dbee5fe9_add_original_text_column_to_recipes_.py b/mealie/alembic/versions/2022-03-27-19.30.28_f1a2dbee5fe9_add_original_text_column_to_recipes_.py similarity index 100% rename from alembic/versions/2022-03-27-19.30.28_f1a2dbee5fe9_add_original_text_column_to_recipes_.py rename to mealie/alembic/versions/2022-03-27-19.30.28_f1a2dbee5fe9_add_original_text_column_to_recipes_.py diff --git a/alembic/versions/2022-03-31-19.19.55_59eb59135381_add_tags_to_cookbooks.py b/mealie/alembic/versions/2022-03-31-19.19.55_59eb59135381_add_tags_to_cookbooks.py similarity index 100% rename from alembic/versions/2022-03-31-19.19.55_59eb59135381_add_tags_to_cookbooks.py rename to mealie/alembic/versions/2022-03-31-19.19.55_59eb59135381_add_tags_to_cookbooks.py diff --git a/alembic/versions/2022-04-03-10.48.51_09dfc897ad62_add_require_all_for_cookbook_filters.py b/mealie/alembic/versions/2022-04-03-10.48.51_09dfc897ad62_add_require_all_for_cookbook_filters.py similarity index 100% rename from alembic/versions/2022-04-03-10.48.51_09dfc897ad62_add_require_all_for_cookbook_filters.py rename to mealie/alembic/versions/2022-04-03-10.48.51_09dfc897ad62_add_require_all_for_cookbook_filters.py diff --git a/alembic/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py b/mealie/alembic/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py similarity index 100% rename from alembic/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py rename to mealie/alembic/versions/2022-06-01-11.12.06_ab0bae02578f_add_use_abbreviation_column_to_.py diff --git a/alembic/versions/2022-06-15-21.05.34_f30cf048c228_add_new_webhook_fields.py b/mealie/alembic/versions/2022-06-15-21.05.34_f30cf048c228_add_new_webhook_fields.py similarity index 100% rename from alembic/versions/2022-06-15-21.05.34_f30cf048c228_add_new_webhook_fields.py rename to mealie/alembic/versions/2022-06-15-21.05.34_f30cf048c228_add_new_webhook_fields.py diff --git a/alembic/versions/2022-08-12-19.05.59_188374910655_add_login_attemps_and_locked_at_field_.py b/mealie/alembic/versions/2022-08-12-19.05.59_188374910655_add_login_attemps_and_locked_at_field_.py similarity index 100% rename from alembic/versions/2022-08-12-19.05.59_188374910655_add_login_attemps_and_locked_at_field_.py rename to mealie/alembic/versions/2022-08-12-19.05.59_188374910655_add_login_attemps_and_locked_at_field_.py diff --git a/alembic/versions/2022-08-13-17.07.07_089bfa50d0ed_add_is_ocr_recipe_column_to_recipes.py b/mealie/alembic/versions/2022-08-13-17.07.07_089bfa50d0ed_add_is_ocr_recipe_column_to_recipes.py similarity index 100% rename from alembic/versions/2022-08-13-17.07.07_089bfa50d0ed_add_is_ocr_recipe_column_to_recipes.py rename to mealie/alembic/versions/2022-08-13-17.07.07_089bfa50d0ed_add_is_ocr_recipe_column_to_recipes.py diff --git a/alembic/versions/2022-08-29-13.57.40_44e8d670719d_add_extras_to_shopping_lists_list_items_.py b/mealie/alembic/versions/2022-08-29-13.57.40_44e8d670719d_add_extras_to_shopping_lists_list_items_.py similarity index 100% rename from alembic/versions/2022-08-29-13.57.40_44e8d670719d_add_extras_to_shopping_lists_list_items_.py rename to mealie/alembic/versions/2022-08-29-13.57.40_44e8d670719d_add_extras_to_shopping_lists_list_items_.py diff --git a/alembic/versions/2022-09-27-14.53.14_2ea7a807915c_add_recipe_timeline_events_table.py b/mealie/alembic/versions/2022-09-27-14.53.14_2ea7a807915c_add_recipe_timeline_events_table.py similarity index 100% rename from alembic/versions/2022-09-27-14.53.14_2ea7a807915c_add_recipe_timeline_events_table.py rename to mealie/alembic/versions/2022-09-27-14.53.14_2ea7a807915c_add_recipe_timeline_events_table.py diff --git a/alembic/versions/2022-11-03-13.10.24_1923519381ad_renamed_timeline_event_message_and_.py b/mealie/alembic/versions/2022-11-03-13.10.24_1923519381ad_renamed_timeline_event_message_and_.py similarity index 100% rename from alembic/versions/2022-11-03-13.10.24_1923519381ad_renamed_timeline_event_message_and_.py rename to mealie/alembic/versions/2022-11-03-13.10.24_1923519381ad_renamed_timeline_event_message_and_.py diff --git a/alembic/versions/2022-11-22-03.42.45_167eb69066ad_add_recipe_scale_to_shopping_list_item_.py b/mealie/alembic/versions/2022-11-22-03.42.45_167eb69066ad_add_recipe_scale_to_shopping_list_item_.py similarity index 100% rename from alembic/versions/2022-11-22-03.42.45_167eb69066ad_add_recipe_scale_to_shopping_list_item_.py rename to mealie/alembic/versions/2022-11-22-03.42.45_167eb69066ad_add_recipe_scale_to_shopping_list_item_.py diff --git a/alembic/versions/2023-01-21-16.54.44_165d943c64ee_add_related_user_to_mealplan.py b/mealie/alembic/versions/2023-01-21-16.54.44_165d943c64ee_add_related_user_to_mealplan.py similarity index 100% rename from alembic/versions/2023-01-21-16.54.44_165d943c64ee_add_related_user_to_mealplan.py rename to mealie/alembic/versions/2023-01-21-16.54.44_165d943c64ee_add_related_user_to_mealplan.py diff --git a/alembic/versions/2023-02-07-20.57.21_ff5f73b01a7a_add_missing_foreign_key_and_order_.py b/mealie/alembic/versions/2023-02-07-20.57.21_ff5f73b01a7a_add_missing_foreign_key_and_order_.py similarity index 100% rename from alembic/versions/2023-02-07-20.57.21_ff5f73b01a7a_add_missing_foreign_key_and_order_.py rename to mealie/alembic/versions/2023-02-07-20.57.21_ff5f73b01a7a_add_missing_foreign_key_and_order_.py diff --git a/alembic/versions/2023-02-10-21.18.32_16160bf731a0_add_more_indices_necessary_for_search.py b/mealie/alembic/versions/2023-02-10-21.18.32_16160bf731a0_add_more_indices_necessary_for_search.py similarity index 100% rename from alembic/versions/2023-02-10-21.18.32_16160bf731a0_add_more_indices_necessary_for_search.py rename to mealie/alembic/versions/2023-02-10-21.18.32_16160bf731a0_add_more_indices_necessary_for_search.py diff --git a/alembic/versions/2023-02-14-20.45.41_5ab195a474eb_add_normalized_search_properties.py b/mealie/alembic/versions/2023-02-14-20.45.41_5ab195a474eb_add_normalized_search_properties.py similarity index 100% rename from alembic/versions/2023-02-14-20.45.41_5ab195a474eb_add_normalized_search_properties.py rename to mealie/alembic/versions/2023-02-14-20.45.41_5ab195a474eb_add_normalized_search_properties.py diff --git a/alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py b/mealie/alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py similarity index 100% rename from alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py rename to mealie/alembic/versions/2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings.py diff --git a/alembic/versions/2023-02-22-21.45.52_38514b39a824_add_auth_method_to_user_table.py b/mealie/alembic/versions/2023-02-22-21.45.52_38514b39a824_add_auth_method_to_user_table.py similarity index 100% rename from alembic/versions/2023-02-22-21.45.52_38514b39a824_add_auth_method_to_user_table.py rename to mealie/alembic/versions/2023-02-22-21.45.52_38514b39a824_add_auth_method_to_user_table.py diff --git a/alembic/versions/2023-04-13-06.47.04_b3dbb554ba53_postgres_fuzzy_search.py b/mealie/alembic/versions/2023-04-13-06.47.04_b3dbb554ba53_postgres_fuzzy_search.py similarity index 100% rename from alembic/versions/2023-04-13-06.47.04_b3dbb554ba53_postgres_fuzzy_search.py rename to mealie/alembic/versions/2023-04-13-06.47.04_b3dbb554ba53_postgres_fuzzy_search.py diff --git a/alembic/versions/2023-08-06-21.00.34_04ac51cbe9a4_added_group_slug.py b/mealie/alembic/versions/2023-08-06-21.00.34_04ac51cbe9a4_added_group_slug.py similarity index 100% rename from alembic/versions/2023-08-06-21.00.34_04ac51cbe9a4_added_group_slug.py rename to mealie/alembic/versions/2023-08-06-21.00.34_04ac51cbe9a4_added_group_slug.py diff --git a/alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py b/mealie/alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py similarity index 100% rename from alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py rename to mealie/alembic/versions/2023-08-14-19.30.49_1825b5225403_added_recipe_note_to_shopping_list_.py diff --git a/alembic/versions/2023-08-15-16.25.07_bcfdad6b7355_remove_tool_name_and_slug_unique_.py b/mealie/alembic/versions/2023-08-15-16.25.07_bcfdad6b7355_remove_tool_name_and_slug_unique_.py similarity index 100% rename from alembic/versions/2023-08-15-16.25.07_bcfdad6b7355_remove_tool_name_and_slug_unique_.py rename to mealie/alembic/versions/2023-08-15-16.25.07_bcfdad6b7355_remove_tool_name_and_slug_unique_.py diff --git a/alembic/versions/2023-09-01-14.55.42_0341b154f79a_added_normalized_unit_and_food_names.py b/mealie/alembic/versions/2023-09-01-14.55.42_0341b154f79a_added_normalized_unit_and_food_names.py similarity index 100% rename from alembic/versions/2023-09-01-14.55.42_0341b154f79a_added_normalized_unit_and_food_names.py rename to mealie/alembic/versions/2023-09-01-14.55.42_0341b154f79a_added_normalized_unit_and_food_names.py diff --git a/alembic/versions/2023-10-04-14.29.26_dded3119c1fe_added_unique_constraints.py b/mealie/alembic/versions/2023-10-04-14.29.26_dded3119c1fe_added_unique_constraints.py similarity index 100% rename from alembic/versions/2023-10-04-14.29.26_dded3119c1fe_added_unique_constraints.py rename to mealie/alembic/versions/2023-10-04-14.29.26_dded3119c1fe_added_unique_constraints.py diff --git a/alembic/versions/2023-10-19-19.22.55_ba1e4a6cfe99_added_plural_names_and_alias_tables_for_.py b/mealie/alembic/versions/2023-10-19-19.22.55_ba1e4a6cfe99_added_plural_names_and_alias_tables_for_.py similarity index 100% rename from alembic/versions/2023-10-19-19.22.55_ba1e4a6cfe99_added_plural_names_and_alias_tables_for_.py rename to mealie/alembic/versions/2023-10-19-19.22.55_ba1e4a6cfe99_added_plural_names_and_alias_tables_for_.py diff --git a/alembic/versions/2024-02-23-16.15.07_2298bb460ffd_added_user_to_shopping_list.py b/mealie/alembic/versions/2024-02-23-16.15.07_2298bb460ffd_added_user_to_shopping_list.py similarity index 100% rename from alembic/versions/2024-02-23-16.15.07_2298bb460ffd_added_user_to_shopping_list.py rename to mealie/alembic/versions/2024-02-23-16.15.07_2298bb460ffd_added_user_to_shopping_list.py index d9afe0beda1..311e376db5c 100644 --- a/alembic/versions/2024-02-23-16.15.07_2298bb460ffd_added_user_to_shopping_list.py +++ b/mealie/alembic/versions/2024-02-23-16.15.07_2298bb460ffd_added_user_to_shopping_list.py @@ -9,10 +9,10 @@ from uuid import UUID import sqlalchemy as sa +from alembic import op from sqlalchemy import orm import mealie.db.migration_types -from alembic import op from mealie.core.root_logger import get_logger logger = get_logger() diff --git a/alembic/versions/2024-03-10-05.08.32_09aba125b57a_add_oidc_auth_method.py b/mealie/alembic/versions/2024-03-10-05.08.32_09aba125b57a_add_oidc_auth_method.py similarity index 100% rename from alembic/versions/2024-03-10-05.08.32_09aba125b57a_add_oidc_auth_method.py rename to mealie/alembic/versions/2024-03-10-05.08.32_09aba125b57a_add_oidc_auth_method.py diff --git a/alembic/versions/2024-03-18-02.28.15_d7c6efd2de42_migrate_favorites_and_ratings_to_user_.py b/mealie/alembic/versions/2024-03-18-02.28.15_d7c6efd2de42_migrate_favorites_and_ratings_to_user_.py similarity index 100% rename from alembic/versions/2024-03-18-02.28.15_d7c6efd2de42_migrate_favorites_and_ratings_to_user_.py rename to mealie/alembic/versions/2024-03-18-02.28.15_d7c6efd2de42_migrate_favorites_and_ratings_to_user_.py index 357f660f50a..8873532bcf6 100644 --- a/alembic/versions/2024-03-18-02.28.15_d7c6efd2de42_migrate_favorites_and_ratings_to_user_.py +++ b/mealie/alembic/versions/2024-03-18-02.28.15_d7c6efd2de42_migrate_favorites_and_ratings_to_user_.py @@ -12,10 +12,10 @@ from uuid import uuid4 import sqlalchemy as sa +from alembic import op from sqlalchemy import orm import mealie.db.migration_types -from alembic import op # revision identifiers, used by Alembic. revision = "d7c6efd2de42" diff --git a/alembic/versions/2024-04-07-01.05.20_7788478a0338_add_group_recipe_actions.py b/mealie/alembic/versions/2024-04-07-01.05.20_7788478a0338_add_group_recipe_actions.py similarity index 100% rename from alembic/versions/2024-04-07-01.05.20_7788478a0338_add_group_recipe_actions.py rename to mealie/alembic/versions/2024-04-07-01.05.20_7788478a0338_add_group_recipe_actions.py index 39810210b67..ad390b1725a 100644 --- a/alembic/versions/2024-04-07-01.05.20_7788478a0338_add_group_recipe_actions.py +++ b/mealie/alembic/versions/2024-04-07-01.05.20_7788478a0338_add_group_recipe_actions.py @@ -7,9 +7,9 @@ """ import sqlalchemy as sa +from alembic import op import mealie.db.migration_types -from alembic import op # revision identifiers, used by Alembic. revision = "7788478a0338" diff --git a/alembic/versions/2024-06-22-10.17.03_32d69327997b_add_staple_flag_to_foods.py b/mealie/alembic/versions/2024-06-22-10.17.03_32d69327997b_add_staple_flag_to_foods.py similarity index 99% rename from alembic/versions/2024-06-22-10.17.03_32d69327997b_add_staple_flag_to_foods.py rename to mealie/alembic/versions/2024-06-22-10.17.03_32d69327997b_add_staple_flag_to_foods.py index bd8cf64f545..8537a8c0de9 100644 --- a/alembic/versions/2024-06-22-10.17.03_32d69327997b_add_staple_flag_to_foods.py +++ b/mealie/alembic/versions/2024-06-22-10.17.03_32d69327997b_add_staple_flag_to_foods.py @@ -7,9 +7,8 @@ """ import sqlalchemy as sa -from sqlalchemy import orm - from alembic import op +from sqlalchemy import orm # revision identifiers, used by Alembic. revision = "32d69327997b" diff --git a/alembic/versions/2024-07-12-16.16.29_feecc8ffb956_add_households.py b/mealie/alembic/versions/2024-07-12-16.16.29_feecc8ffb956_add_households.py similarity index 100% rename from alembic/versions/2024-07-12-16.16.29_feecc8ffb956_add_households.py rename to mealie/alembic/versions/2024-07-12-16.16.29_feecc8ffb956_add_households.py index 2ad26f093e6..0578a764302 100644 --- a/alembic/versions/2024-07-12-16.16.29_feecc8ffb956_add_households.py +++ b/mealie/alembic/versions/2024-07-12-16.16.29_feecc8ffb956_add_households.py @@ -12,11 +12,11 @@ from uuid import uuid4 import sqlalchemy as sa +from alembic import op from slugify import slugify from sqlalchemy import orm import mealie.db.migration_types -from alembic import op from mealie.core.config import get_app_settings # revision identifiers, used by Alembic. diff --git a/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py b/mealie/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py similarity index 99% rename from alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py rename to mealie/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py index 83f2e55186a..be8f54ce645 100644 --- a/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py +++ b/mealie/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py @@ -9,7 +9,6 @@ from textwrap import dedent import sqlalchemy as sa - from alembic import op # revision identifiers, used by Alembic. diff --git a/alembic/versions/2024-09-18-14.52.55_1fe4bd37ccc8_add_households_filter_to_meal_plans.py b/mealie/alembic/versions/2024-09-18-14.52.55_1fe4bd37ccc8_add_households_filter_to_meal_plans.py similarity index 100% rename from alembic/versions/2024-09-18-14.52.55_1fe4bd37ccc8_add_households_filter_to_meal_plans.py rename to mealie/alembic/versions/2024-09-18-14.52.55_1fe4bd37ccc8_add_households_filter_to_meal_plans.py index a127e72f44a..6460aa5bb65 100644 --- a/alembic/versions/2024-09-18-14.52.55_1fe4bd37ccc8_add_households_filter_to_meal_plans.py +++ b/mealie/alembic/versions/2024-09-18-14.52.55_1fe4bd37ccc8_add_households_filter_to_meal_plans.py @@ -7,9 +7,9 @@ """ import sqlalchemy as sa +from alembic import op import mealie.db.migration_types -from alembic import op # revision identifiers, used by Alembic. revision = "1fe4bd37ccc8" diff --git a/alembic/versions/2024-10-01-14.17.00_602927e1013e_add_the_rest_of_the_schema_org_.py b/mealie/alembic/versions/2024-10-01-14.17.00_602927e1013e_add_the_rest_of_the_schema_org_.py similarity index 99% rename from alembic/versions/2024-10-01-14.17.00_602927e1013e_add_the_rest_of_the_schema_org_.py rename to mealie/alembic/versions/2024-10-01-14.17.00_602927e1013e_add_the_rest_of_the_schema_org_.py index dbeea910fa6..cca6ec7d9bf 100644 --- a/alembic/versions/2024-10-01-14.17.00_602927e1013e_add_the_rest_of_the_schema_org_.py +++ b/mealie/alembic/versions/2024-10-01-14.17.00_602927e1013e_add_the_rest_of_the_schema_org_.py @@ -7,7 +7,6 @@ """ import sqlalchemy as sa - from alembic import op # revision identifiers, used by Alembic. diff --git a/alembic/versions/2024-10-08-21.17.31_86054b40fd06_added_query_filter_string_to_cookbook_.py b/mealie/alembic/versions/2024-10-08-21.17.31_86054b40fd06_added_query_filter_string_to_cookbook_.py similarity index 100% rename from alembic/versions/2024-10-08-21.17.31_86054b40fd06_added_query_filter_string_to_cookbook_.py rename to mealie/alembic/versions/2024-10-08-21.17.31_86054b40fd06_added_query_filter_string_to_cookbook_.py index 3f5eb908c8d..6737cdf5977 100644 --- a/alembic/versions/2024-10-08-21.17.31_86054b40fd06_added_query_filter_string_to_cookbook_.py +++ b/mealie/alembic/versions/2024-10-08-21.17.31_86054b40fd06_added_query_filter_string_to_cookbook_.py @@ -7,9 +7,9 @@ """ import sqlalchemy as sa +from alembic import op from sqlalchemy import orm -from alembic import op from mealie.db.models._model_utils import guid # revision identifiers, used by Alembic. diff --git a/alembic/versions/2024-10-20-09.47.46_3897397b4631_add_summary_to_recipe_instructions.py b/mealie/alembic/versions/2024-10-20-09.47.46_3897397b4631_add_summary_to_recipe_instructions.py similarity index 99% rename from alembic/versions/2024-10-20-09.47.46_3897397b4631_add_summary_to_recipe_instructions.py rename to mealie/alembic/versions/2024-10-20-09.47.46_3897397b4631_add_summary_to_recipe_instructions.py index 1175ca6ef9d..eba3b1b1a9f 100644 --- a/alembic/versions/2024-10-20-09.47.46_3897397b4631_add_summary_to_recipe_instructions.py +++ b/mealie/alembic/versions/2024-10-20-09.47.46_3897397b4631_add_summary_to_recipe_instructions.py @@ -7,7 +7,6 @@ """ import sqlalchemy as sa - from alembic import op # revision identifiers, used by Alembic. diff --git a/alembic/versions/2024-10-23-15.50.59_b1020f328e98_add_recipe_yield_quantity.py b/mealie/alembic/versions/2024-10-23-15.50.59_b1020f328e98_add_recipe_yield_quantity.py similarity index 100% rename from alembic/versions/2024-10-23-15.50.59_b1020f328e98_add_recipe_yield_quantity.py rename to mealie/alembic/versions/2024-10-23-15.50.59_b1020f328e98_add_recipe_yield_quantity.py index 4aee9ab795b..ba9b21db23f 100644 --- a/alembic/versions/2024-10-23-15.50.59_b1020f328e98_add_recipe_yield_quantity.py +++ b/mealie/alembic/versions/2024-10-23-15.50.59_b1020f328e98_add_recipe_yield_quantity.py @@ -7,9 +7,9 @@ """ import sqlalchemy as sa +from alembic import op from sqlalchemy import orm -from alembic import op from mealie.db.models._model_utils.guid import GUID from mealie.services.scraper.cleaner import clean_yield diff --git a/mealie/db/init_db.py b/mealie/db/init_db.py index 9dc3b13981e..75950a5a299 100644 --- a/mealie/db/init_db.py +++ b/mealie/db/init_db.py @@ -3,11 +3,11 @@ from pathlib import Path from time import sleep -from sqlalchemy import engine, orm, text - from alembic import command, config, script from alembic.config import Config from alembic.runtime import migration +from sqlalchemy import engine, orm, text + from mealie.core import root_logger from mealie.core.config import get_app_settings from mealie.db.db_setup import session_context @@ -22,7 +22,7 @@ from mealie.services.group_services.group_service import GroupService from mealie.services.household_services.household_service import HouseholdService -PROJECT_DIR = Path(__file__).parent.parent.parent +ALEMBIC_DIR = Path(__file__).parent.parent / "alembic" logger = root_logger.get_logger() @@ -101,7 +101,7 @@ def main(): if max_retry == 0: raise ConnectionError("Database connection failed - exiting application.") - alembic_cfg_path = os.getenv("ALEMBIC_CONFIG_FILE", default=str(PROJECT_DIR / "alembic.ini")) + alembic_cfg_path = os.getenv("ALEMBIC_CONFIG_FILE", default=str(ALEMBIC_DIR / "alembic.ini")) if not os.path.isfile(alembic_cfg_path): raise Exception("Provided alembic config path doesn't exist") diff --git a/mealie/services/backups_v2/alchemy_exporter.py b/mealie/services/backups_v2/alchemy_exporter.py index 95dc1d37a2b..24fd37544f5 100644 --- a/mealie/services/backups_v2/alchemy_exporter.py +++ b/mealie/services/backups_v2/alchemy_exporter.py @@ -3,25 +3,23 @@ import uuid from logging import Logger from os import path -from pathlib import Path from textwrap import dedent from typing import Any +from alembic import command +from alembic.config import Config from fastapi.encoders import jsonable_encoder from pydantic import BaseModel from sqlalchemy import Connection, ForeignKey, ForeignKeyConstraint, MetaData, Table, create_engine, insert, text from sqlalchemy.engine import base from sqlalchemy.orm import sessionmaker -from alembic import command -from alembic.config import Config from mealie.db import init_db from mealie.db.fixes.fix_migration_data import fix_migration_data +from mealie.db.init_db import ALEMBIC_DIR from mealie.db.models._model_utils.guid import GUID from mealie.services._base_service import BaseService -PROJECT_DIR = Path(__file__).parent.parent.parent.parent - class ForeignKeyDisabler: def __init__(self, connection: Connection, dialect_name: str, *, logger: Logger | None = None): @@ -193,15 +191,12 @@ def restore(self, db_dump: dict) -> None: alembic_data = db_dump["alembic_version"] alembic_version = alembic_data[0]["version_num"] - alembic_cfg_path = os.getenv("ALEMBIC_CONFIG_FILE", default=str(PROJECT_DIR / "alembic.ini")) + alembic_cfg_path = os.getenv("ALEMBIC_CONFIG_FILE", default=str(ALEMBIC_DIR / "alembic.ini")) if not path.isfile(alembic_cfg_path): raise Exception("Provided alembic config path doesn't exist") alembic_cfg = Config(alembic_cfg_path) - # alembic's file resolver wants to use the "mealie" subdirectory when called from within the server package - # Just override this to use the correct migrations path - alembic_cfg.set_main_option("script_location", path.join(PROJECT_DIR, "alembic")) command.upgrade(alembic_cfg, alembic_version) del db_dump["alembic_version"] diff --git a/pyproject.toml b/pyproject.toml index 73c86eca939..0171889c925 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -158,8 +158,8 @@ select = [ [tool.ruff.lint.per-file-ignores] "__init__.py" = ["E402", "E501"] -"alembic/versions/2022*" = ["E501"] -"alembic/versions/2023*" = ["E501"] +"mealie/alembic/versions/2022*" = ["E501", "I001"] +"mealie/alembic/versions/2023*" = ["E501", "I001"] "dev/scripts/all_recipes_stress_test.py" = ["E501"] "ldap_provider.py" = ["UP032"] "tests/conftest.py" = ["E402"] diff --git a/tests/utils/alembic_reader.py b/tests/utils/alembic_reader.py index 2bba446f456..e8fda449436 100644 --- a/tests/utils/alembic_reader.py +++ b/tests/utils/alembic_reader.py @@ -2,9 +2,9 @@ import pathlib from functools import lru_cache -from mealie.db.init_db import PROJECT_DIR +from mealie.db.init_db import ALEMBIC_DIR -ALEMBIC_MIGRATIONS = PROJECT_DIR / "alembic" / "versions" +ALEMBIC_MIGRATIONS = ALEMBIC_DIR / "versions" def import_file(module_name: str, file_path: pathlib.Path): From 0e6a40e210d3adb0c1194c977718bab17f85ce48 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:41:02 -0600 Subject: [PATCH 06/10] fix: remove import button from recipe data view (#4680) --- frontend/pages/group/data/recipes.vue | 6 ------ 1 file changed, 6 deletions(-) diff --git a/frontend/pages/group/data/recipes.vue b/frontend/pages/group/data/recipes.vue index 37bc477608e..112b8795d4f 100644 --- a/frontend/pages/group/data/recipes.vue +++ b/frontend/pages/group/data/recipes.vue @@ -136,12 +136,6 @@ - - - {{ $t('general.import') }} - str: # create/insert household household_id = generate_id() - timestamp = datetime.now(timezone.utc).isoformat() + timestamp = datetime.now(UTC).isoformat() household_data = { "id": household_id, "name": settings.DEFAULT_HOUSEHOLD, diff --git a/mealie/core/release_checker.py b/mealie/core/release_checker.py index 53afa3fba61..b5d2bf9e2e5 100644 --- a/mealie/core/release_checker.py +++ b/mealie/core/release_checker.py @@ -3,7 +3,7 @@ import requests -_LAST_RESET = None +_LAST_RESET: datetime.datetime | None = None @lru_cache(maxsize=1) @@ -32,7 +32,7 @@ def get_latest_version() -> str: global _LAST_RESET - now = datetime.datetime.now(datetime.timezone.utc) + now = datetime.datetime.now(datetime.UTC) if not _LAST_RESET or now - _LAST_RESET > datetime.timedelta(days=MAX_DAYS_OLD): _LAST_RESET = now diff --git a/mealie/core/security/providers/auth_provider.py b/mealie/core/security/providers/auth_provider.py index 4c98879eb09..ce10afd7d75 100644 --- a/mealie/core/security/providers/auth_provider.py +++ b/mealie/core/security/providers/auth_provider.py @@ -1,5 +1,5 @@ import abc -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from typing import Generic, TypeVar import jwt @@ -45,7 +45,7 @@ def create_access_token(data: dict, expires_delta: timedelta | None = None) -> t to_encode = data.copy() expires_delta = expires_delta or timedelta(hours=settings.TOKEN_TIME) - expire = datetime.now(timezone.utc) + expires_delta + expire = datetime.now(UTC) + expires_delta to_encode["exp"] = expire to_encode["iss"] = ISS diff --git a/mealie/core/security/security.py b/mealie/core/security/security.py index 34893cc1233..bdc364e55d6 100644 --- a/mealie/core/security/security.py +++ b/mealie/core/security/security.py @@ -1,5 +1,5 @@ import secrets -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from pathlib import Path import jwt @@ -34,7 +34,7 @@ def create_access_token(data: dict, expires_delta: timedelta | None = None) -> s to_encode = data.copy() expires_delta = expires_delta or timedelta(hours=settings.TOKEN_TIME) - expire = datetime.now(timezone.utc) + expires_delta + expire = datetime.now(UTC) + expires_delta to_encode["exp"] = expire return jwt.encode(to_encode, settings.SECRET, algorithm=ALGORITHM) diff --git a/mealie/core/settings/settings.py b/mealie/core/settings/settings.py index a0fb6e800bf..7558a29c51b 100644 --- a/mealie/core/settings/settings.py +++ b/mealie/core/settings/settings.py @@ -1,7 +1,7 @@ import logging import os import secrets -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path from typing import Annotated, Any, NamedTuple @@ -160,7 +160,7 @@ def DAILY_SCHEDULE_TIME_UTC(self) -> ScheduleTime: local_tz = tzlocal() now = datetime.now(local_tz) local_time = now.replace(hour=local_hour, minute=local_minute) - utc_time = local_time.astimezone(timezone.utc) + utc_time = local_time.astimezone(UTC) self.logger.debug(f"Local time: {local_hour}:{local_minute} | UTC time: {utc_time.hour}:{utc_time.minute}") return ScheduleTime(utc_time.hour, utc_time.minute) diff --git a/mealie/db/models/_model_utils/datetime.py b/mealie/db/models/_model_utils/datetime.py index 5c24d1d526e..69222f8388b 100644 --- a/mealie/db/models/_model_utils/datetime.py +++ b/mealie/db/models/_model_utils/datetime.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from sqlalchemy.types import DateTime, TypeDecorator @@ -7,14 +7,14 @@ def get_utc_now(): """ Returns the current time in UTC. """ - return datetime.now(timezone.utc) + return datetime.now(UTC) def get_utc_today(): """ Returns the current date in UTC. """ - return datetime.now(timezone.utc).date() + return datetime.now(UTC).date() class NaiveDateTime(TypeDecorator): @@ -35,7 +35,7 @@ def process_bind_param(self, value: datetime | None, dialect): try: if value.tzinfo is not None: - value = value.astimezone(timezone.utc) + value = value.astimezone(UTC) return value.replace(tzinfo=None) except Exception: return value @@ -43,7 +43,7 @@ def process_bind_param(self, value: datetime | None, dialect): def process_result_value(self, value: datetime | None, dialect): try: if value is not None: - value = value.replace(tzinfo=timezone.utc) + value = value.replace(tzinfo=UTC) except Exception: pass diff --git a/mealie/db/models/household/shopping_list.py b/mealie/db/models/household/shopping_list.py index 02f60a56a18..f076107429a 100644 --- a/mealie/db/models/household/shopping_list.py +++ b/mealie/db/models/household/shopping_list.py @@ -1,5 +1,5 @@ from contextvars import ContextVar -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import TYPE_CHECKING, Optional from pydantic import ConfigDict @@ -227,7 +227,7 @@ def update_shopping_lists(session: orm.Session, _): if not shopping_list: continue - shopping_list.updated_at = datetime.now(timezone.utc) + shopping_list.updated_at = datetime.now(UTC) local_session.commit() except Exception: local_session.rollback() diff --git a/mealie/db/models/household/webhooks.py b/mealie/db/models/household/webhooks.py index 5b52f8ec636..9c8c6e58faf 100644 --- a/mealie/db/models/household/webhooks.py +++ b/mealie/db/models/household/webhooks.py @@ -1,4 +1,4 @@ -from datetime import datetime, time, timezone +from datetime import UTC, datetime, time from typing import TYPE_CHECKING, Optional from sqlalchemy import Boolean, ForeignKey, String, Time, orm @@ -30,7 +30,7 @@ class GroupWebhooksModel(SqlAlchemyBase, BaseMixins): # New Fields webhook_type: Mapped[str | None] = mapped_column(String, default="") # Future use for different types of webhooks - scheduled_time: Mapped[time | None] = mapped_column(Time, default=lambda: datetime.now(timezone.utc).time()) + scheduled_time: Mapped[time | None] = mapped_column(Time, default=lambda: datetime.now(UTC).time()) # Column is no longer used but is kept for since it's super annoying to # delete a column in SQLite and it's not a big deal to keep it around diff --git a/mealie/db/models/recipe/recipe.py b/mealie/db/models/recipe/recipe.py index ebbb0bfc963..60dc8c86f5c 100644 --- a/mealie/db/models/recipe/recipe.py +++ b/mealie/db/models/recipe/recipe.py @@ -1,4 +1,4 @@ -from datetime import date, datetime, timezone +from datetime import UTC, date, datetime from typing import TYPE_CHECKING import sqlalchemy as sa @@ -207,7 +207,7 @@ def __init__( if notes: self.notes = [Note(**n) for n in notes] - self.date_updated = datetime.now(timezone.utc) + self.date_updated = datetime.now(UTC) # SQLAlchemy events do not seem to register things that are set during auto_init if name is not None: diff --git a/mealie/db/models/recipe/recipe_timeline.py b/mealie/db/models/recipe/recipe_timeline.py index 402606e50b4..57fdc9f2212 100644 --- a/mealie/db/models/recipe/recipe_timeline.py +++ b/mealie/db/models/recipe/recipe_timeline.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import TYPE_CHECKING from sqlalchemy import ForeignKey, String @@ -48,4 +48,4 @@ def __init__( timestamp=None, **_, ) -> None: - self.timestamp = timestamp or datetime.now(timezone.utc) + self.timestamp = timestamp or datetime.now(UTC) diff --git a/mealie/db/models/recipe/shared.py b/mealie/db/models/recipe/shared.py index 9d90bcc1772..7f2634a576f 100644 --- a/mealie/db/models/recipe/shared.py +++ b/mealie/db/models/recipe/shared.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from typing import TYPE_CHECKING from uuid import uuid4 @@ -15,7 +15,7 @@ def defaut_expires_at_time() -> datetime: - return datetime.now(timezone.utc) + timedelta(days=30) + return datetime.now(UTC) + timedelta(days=30) class RecipeShareTokenModel(SqlAlchemyBase, BaseMixins): diff --git a/mealie/repos/repository_generic.py b/mealie/repos/repository_generic.py index 87d406d3bb4..50dfa801c49 100644 --- a/mealie/repos/repository_generic.py +++ b/mealie/repos/repository_generic.py @@ -2,7 +2,7 @@ import random from collections.abc import Iterable -from datetime import datetime, timezone +from datetime import UTC, datetime from math import ceil from typing import Any, Generic, TypeVar @@ -70,7 +70,7 @@ def household_id(self) -> UUID4 | None: return self._household_id def _random_seed(self) -> str: - return str(datetime.now(tz=timezone.utc)) + return str(datetime.now(tz=UTC)) def _log_exception(self, e: Exception) -> None: self.logger.error(f"Error processing query for Repo model={self.model.__name__} schema={self.schema.__name__}") diff --git a/mealie/repos/repository_meals.py b/mealie/repos/repository_meals.py index 34187e35fb4..ec6a35076a5 100644 --- a/mealie/repos/repository_meals.py +++ b/mealie/repos/repository_meals.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from sqlalchemy import select @@ -13,7 +13,7 @@ def get_today(self) -> list[ReadPlanEntry]: if not self.household_id: raise Exception("household_id not set") - today = datetime.now(tz=timezone.utc).date() + today = datetime.now(tz=UTC).date() stmt = select(GroupMealPlan).filter( GroupMealPlan.date == today, GroupMealPlan.household_id == self.household_id ) diff --git a/mealie/repos/repository_recipes.py b/mealie/repos/repository_recipes.py index 4b907ee3f58..0997902504f 100644 --- a/mealie/repos/repository_recipes.py +++ b/mealie/repos/repository_recipes.py @@ -1,7 +1,7 @@ import re as re from collections.abc import Sequence from random import randint -from typing import cast +from typing import Self, cast from uuid import UUID import sqlalchemy as sa @@ -10,7 +10,6 @@ from slugify import slugify from sqlalchemy import orm from sqlalchemy.exc import IntegrityError -from typing_extensions import Self from mealie.db.models.household.household import Household from mealie.db.models.recipe.category import Category diff --git a/mealie/routes/households/controller_webhooks.py b/mealie/routes/households/controller_webhooks.py index 8c8c25600d7..251bb36175a 100644 --- a/mealie/routes/households/controller_webhooks.py +++ b/mealie/routes/households/controller_webhooks.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from functools import cached_property from fastapi import APIRouter, BackgroundTasks, Depends @@ -45,7 +45,7 @@ def rerun_webhooks(self): """Manually re-fires all previously scheduled webhooks for today""" start_time = datetime.min.time() - start_dt = datetime.combine(datetime.now(timezone.utc).date(), start_time) + start_dt = datetime.combine(datetime.now(UTC).date(), start_time) post_group_webhooks(start_dt=start_dt, group_id=self.group.id, household_id=self.household.id) @router.get("/{item_id}", response_model=ReadWebhook) diff --git a/mealie/schema/_mealie/datetime_parse.py b/mealie/schema/_mealie/datetime_parse.py index 0e482d9a875..9e0042bc615 100644 --- a/mealie/schema/_mealie/datetime_parse.py +++ b/mealie/schema/_mealie/datetime_parse.py @@ -3,7 +3,7 @@ """ import re -from datetime import date, datetime, time, timedelta, timezone +from datetime import UTC, date, datetime, time, timedelta, timezone date_expr = r"(?P\d{4})-(?P\d{1,2})-(?P\d{1,2})" time_expr = ( @@ -39,7 +39,7 @@ r"$" ) -EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc) +EPOCH = datetime(1970, 1, 1, tzinfo=UTC) # if greater than this, the number is in ms, if less than or equal it's in seconds # (in seconds this is 11th October 2603, in ms it's 20th August 1970) MS_WATERSHED = int(2e10) @@ -87,12 +87,12 @@ def from_unix_seconds(seconds: int | float) -> datetime: while abs(seconds) > MS_WATERSHED: seconds /= 1000 dt = EPOCH + timedelta(seconds=seconds) - return dt.replace(tzinfo=timezone.utc) + return dt.replace(tzinfo=UTC) def _parse_timezone(value: str | None, error: type[Exception]) -> None | int | timezone: if value == "Z": - return timezone.utc + return UTC elif value is not None: offset_mins = int(value[-2:]) if len(value) > 3 else 0 offset = 60 * int(value[1:3]) + offset_mins diff --git a/mealie/schema/_mealie/mealie_model.py b/mealie/schema/_mealie/mealie_model.py index 4f670ba2242..d7d70a6dcba 100644 --- a/mealie/schema/_mealie/mealie_model.py +++ b/mealie/schema/_mealie/mealie_model.py @@ -2,16 +2,15 @@ import re from collections.abc import Sequence -from datetime import datetime, timezone +from datetime import UTC, datetime from enum import Enum -from typing import ClassVar, Protocol, TypeVar +from typing import ClassVar, Protocol, Self, TypeVar from humps.main import camelize from pydantic import UUID4, AliasChoices, BaseModel, ConfigDict, Field, model_validator from sqlalchemy import Select, desc, func, or_, text from sqlalchemy.orm import InstrumentedAttribute, Session from sqlalchemy.orm.interfaces import LoaderOption -from typing_extensions import Self from mealie.db.models._model_base import SqlAlchemyBase @@ -88,7 +87,7 @@ def set_tz_info(self) -> Self: if not isinstance(val, datetime): continue if not val.tzinfo: - setattr(self, field, val.replace(tzinfo=timezone.utc)) + setattr(self, field, val.replace(tzinfo=UTC)) return self diff --git a/mealie/schema/household/webhook.py b/mealie/schema/household/webhook.py index 6c6510b0aa8..f42054ed52f 100644 --- a/mealie/schema/household/webhook.py +++ b/mealie/schema/household/webhook.py @@ -32,7 +32,7 @@ def validate_scheduled_time(cls, v): type: datetime is treated as a value with a timezone """ parser_funcs = [ - lambda x: parse_datetime(x).astimezone(datetime.timezone.utc).time(), + lambda x: parse_datetime(x).astimezone(datetime.UTC).time(), parse_time, ] diff --git a/mealie/schema/recipe/recipe_share_token.py b/mealie/schema/recipe/recipe_share_token.py index fd4e376cf30..0e876a05a3b 100644 --- a/mealie/schema/recipe/recipe_share_token.py +++ b/mealie/schema/recipe/recipe_share_token.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from pydantic import UUID4, ConfigDict, Field from sqlalchemy.orm import selectinload @@ -11,7 +11,7 @@ def defaut_expires_at_time() -> datetime: - return datetime.now(timezone.utc) + timedelta(days=30) + return datetime.now(UTC) + timedelta(days=30) class RecipeShareTokenCreate(MealieModel): diff --git a/mealie/schema/recipe/recipe_timeline_events.py b/mealie/schema/recipe/recipe_timeline_events.py index 02de699ceb8..88d1072f83c 100644 --- a/mealie/schema/recipe/recipe_timeline_events.py +++ b/mealie/schema/recipe/recipe_timeline_events.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from enum import Enum from pathlib import Path from typing import Annotated @@ -40,7 +40,7 @@ class RecipeTimelineEventIn(MealieModel): message: str | None = Field(None, alias="eventMessage") image: Annotated[TimelineEventImage | None, Field(validate_default=True)] = TimelineEventImage.does_not_have_image - timestamp: datetime = datetime.now(timezone.utc) + timestamp: datetime = datetime.now(UTC) model_config = ConfigDict(use_enum_values=True) diff --git a/mealie/schema/user/user.py b/mealie/schema/user/user.py index 8bada9194c6..f4e1228b4b5 100644 --- a/mealie/schema/user/user.py +++ b/mealie/schema/user/user.py @@ -1,4 +1,4 @@ -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from pathlib import Path from typing import Annotated, Any, Generic, TypeVar from uuid import UUID @@ -218,7 +218,7 @@ def is_locked(self) -> bool: return False lockout_expires_at = self.locked_at + timedelta(hours=get_app_settings().SECURITY_USER_LOCKOUT_TIME) - return lockout_expires_at > datetime.now(timezone.utc) + return lockout_expires_at > datetime.now(UTC) def directory(self) -> Path: return PrivateUser.get_directory(self.id) diff --git a/mealie/services/backups_v2/backup_v2.py b/mealie/services/backups_v2/backup_v2.py index fe8289ed778..01c19244897 100644 --- a/mealie/services/backups_v2/backup_v2.py +++ b/mealie/services/backups_v2/backup_v2.py @@ -25,7 +25,7 @@ def _sqlite(self) -> None: db_file = self.settings.DB_URL.removeprefix("sqlite:///") # type: ignore # Create a backup of the SQLite database - timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y.%m.%d") + timestamp = datetime.datetime.now(datetime.UTC).strftime("%Y.%m.%d") shutil.copy(db_file, self.directories.DATA_DIR.joinpath(f"mealie_{timestamp}.bak.db")) def _postgres(self) -> None: @@ -37,7 +37,7 @@ def backup(self) -> Path: exclude_ext = {".zip"} exclude_dirs = {"backups", ".temp"} - timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y.%m.%d.%H.%M.%S") + timestamp = datetime.datetime.now(datetime.UTC).strftime("%Y.%m.%d.%H.%M.%S") backup_name = f"mealie_{timestamp}.zip" backup_file = self.directories.BACKUP_DIR / backup_name diff --git a/mealie/services/event_bus_service/event_bus_listeners.py b/mealie/services/event_bus_service/event_bus_listeners.py index dd19992d9e3..586876c6318 100644 --- a/mealie/services/event_bus_service/event_bus_listeners.py +++ b/mealie/services/event_bus_service/event_bus_listeners.py @@ -2,7 +2,7 @@ import json from abc import ABC, abstractmethod from collections.abc import Generator -from datetime import datetime, timezone +from datetime import UTC, datetime from typing import cast from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit @@ -163,8 +163,8 @@ def get_scheduled_webhooks(self, start_dt: datetime, end_dt: datetime) -> list[R with self.ensure_session() as session: stmt = select(GroupWebhooksModel).where( GroupWebhooksModel.enabled == True, # noqa: E712 - required for SQLAlchemy comparison - GroupWebhooksModel.scheduled_time > start_dt.astimezone(timezone.utc).time(), - GroupWebhooksModel.scheduled_time <= end_dt.astimezone(timezone.utc).time(), + GroupWebhooksModel.scheduled_time > start_dt.astimezone(UTC).time(), + GroupWebhooksModel.scheduled_time <= end_dt.astimezone(UTC).time(), GroupWebhooksModel.group_id == self.group_id, GroupWebhooksModel.household_id == self.household_id, ) diff --git a/mealie/services/event_bus_service/event_types.py b/mealie/services/event_bus_service/event_types.py index 56bf6350d51..6e3e54b059e 100644 --- a/mealie/services/event_bus_service/event_types.py +++ b/mealie/services/event_bus_service/event_types.py @@ -1,5 +1,5 @@ import uuid -from datetime import date, datetime, timezone +from datetime import UTC, date, datetime from enum import Enum, auto from typing import Any @@ -193,4 +193,4 @@ class Event(MealieModel): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.event_id = uuid.uuid4() - self.timestamp = datetime.now(timezone.utc) + self.timestamp = datetime.now(UTC) diff --git a/mealie/services/exporter/exporter.py b/mealie/services/exporter/exporter.py index 1b66cc54954..056f680fbcd 100644 --- a/mealie/services/exporter/exporter.py +++ b/mealie/services/exporter/exporter.py @@ -43,7 +43,7 @@ def run(self, db: AllRepositories) -> GroupDataExport: name="Data Export", size=pretty_size(export_path.stat().st_size), filename=export_path.name, - expires=datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(days=1), + expires=datetime.datetime.now(datetime.UTC) + datetime.timedelta(days=1), ) db.group_exports.create(group_data_export) diff --git a/mealie/services/migrations/copymethat.py b/mealie/services/migrations/copymethat.py index 6b9c925c530..fd00e4266d9 100644 --- a/mealie/services/migrations/copymethat.py +++ b/mealie/services/migrations/copymethat.py @@ -1,6 +1,6 @@ import tempfile import zipfile -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path from bs4 import BeautifulSoup @@ -35,7 +35,7 @@ def __init__(self, **kwargs): self.name = "copymethat" self.key_aliases = [ - MigrationAlias(key="last_made", alias="made_this", func=lambda x: datetime.now(timezone.utc)), + MigrationAlias(key="last_made", alias="made_this", func=lambda x: datetime.now(UTC)), MigrationAlias(key="notes", alias="recipeNotes"), MigrationAlias(key="orgURL", alias="original_link"), MigrationAlias(key="rating", alias="ratingValue"), diff --git a/mealie/services/recipe/recipe_service.py b/mealie/services/recipe/recipe_service.py index 8bf3f1bba5f..02eb2fa9a6c 100644 --- a/mealie/services/recipe/recipe_service.py +++ b/mealie/services/recipe/recipe_service.py @@ -1,7 +1,7 @@ import json import os import shutil -from datetime import datetime, timezone +from datetime import UTC, datetime from pathlib import Path from shutil import copytree, rmtree from typing import Any @@ -192,7 +192,7 @@ def create_one(self, create_data: Recipe | CreateRecipe) -> Recipe: recipe_id=new_recipe.id, subject=self.t("recipe.recipe-created"), event_type=TimelineEventType.system, - timestamp=new_recipe.created_at or datetime.now(timezone.utc), + timestamp=new_recipe.created_at or datetime.now(UTC), ) self.repos.recipe_timeline_events.create(timeline_event_data) diff --git a/mealie/services/scheduler/scheduler_service.py b/mealie/services/scheduler/scheduler_service.py index 893912205b7..5ee5eb1a34a 100644 --- a/mealie/services/scheduler/scheduler_service.py +++ b/mealie/services/scheduler/scheduler_service.py @@ -1,5 +1,5 @@ import asyncio -from datetime import datetime, timedelta, timezone +from datetime import UTC, datetime, timedelta from pathlib import Path from mealie.core import root_logger @@ -28,7 +28,7 @@ async def start(): async def schedule_daily(): - now = datetime.now(timezone.utc) + now = datetime.now(UTC) daily_schedule_time = get_app_settings().DAILY_SCHEDULE_TIME_UTC logger.debug(f"Current time is {now} and DAILY_SCHEDULE_TIME (in UTC) is {daily_schedule_time}") diff --git a/mealie/services/scheduler/tasks/create_timeline_events.py b/mealie/services/scheduler/tasks/create_timeline_events.py index 3f08ba647e1..1806e1217f2 100644 --- a/mealie/services/scheduler/tasks/create_timeline_events.py +++ b/mealie/services/scheduler/tasks/create_timeline_events.py @@ -1,4 +1,4 @@ -from datetime import datetime, time, timedelta, timezone +from datetime import UTC, datetime, time, timedelta from pydantic import UUID4 from sqlalchemy.orm import Session @@ -45,7 +45,7 @@ def _create_mealplan_timeline_events_for_household( else: event_subject = f"{user.full_name} made this for {mealplan.entry_type.value}" - query_start_time = datetime.combine(datetime.now(timezone.utc).date(), time.min) + query_start_time = datetime.combine(datetime.now(UTC).date(), time.min) query_end_time = query_start_time + timedelta(days=1) query = PaginationQuery( query_filter=( @@ -116,7 +116,7 @@ def _create_mealplan_timeline_events_for_group(event_time: datetime, session: Se def create_mealplan_timeline_events() -> None: - event_time = datetime.now(timezone.utc) + event_time = datetime.now(UTC) with session_context() as session: repos = get_repositories(session) diff --git a/mealie/services/scheduler/tasks/post_webhooks.py b/mealie/services/scheduler/tasks/post_webhooks.py index e3a57459a16..5298fa2c8d3 100644 --- a/mealie/services/scheduler/tasks/post_webhooks.py +++ b/mealie/services/scheduler/tasks/post_webhooks.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from pydantic import UUID4 @@ -18,7 +18,7 @@ EventWebhookData, ) -last_ran = datetime.now(timezone.utc) +last_ran = datetime.now(UTC) def post_group_webhooks( @@ -32,7 +32,7 @@ def post_group_webhooks( start_dt = start_dt or last_ran # end the query at the current time - last_ran = end_dt = datetime.now(timezone.utc) + last_ran = end_dt = datetime.now(UTC) if group_id is None: # publish the webhook event to each group's event bus @@ -80,7 +80,7 @@ def post_group_webhooks( def post_single_webhook(webhook: ReadWebhook, message: str = "") -> None: - dt = datetime.min.replace(tzinfo=timezone.utc) + dt = datetime.min.replace(tzinfo=UTC) event_type = EventTypes.webhook_task event_document_data = EventWebhookData( diff --git a/mealie/services/scheduler/tasks/purge_group_exports.py b/mealie/services/scheduler/tasks/purge_group_exports.py index ea69821f151..a92dd2d5e1d 100644 --- a/mealie/services/scheduler/tasks/purge_group_exports.py +++ b/mealie/services/scheduler/tasks/purge_group_exports.py @@ -17,7 +17,7 @@ def purge_group_data_exports(max_minutes_old=ONE_DAY_AS_MINUTES): logger = root_logger.get_logger() logger.debug("purging group data exports") - limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(minutes=max_minutes_old) + limit = datetime.datetime.now(datetime.UTC) - datetime.timedelta(minutes=max_minutes_old) with session_context() as session: stmt = select(GroupDataExportsModel).filter(cast(GroupDataExportsModel.expires, NaiveDateTime) <= limit) @@ -39,7 +39,7 @@ def purge_excess_files() -> None: directories = get_app_dirs() logger = root_logger.get_logger() - limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(minutes=ONE_DAY_AS_MINUTES * 2) + limit = datetime.datetime.now(datetime.UTC) - datetime.timedelta(minutes=ONE_DAY_AS_MINUTES * 2) for file in directories.GROUPS_DIR.glob("**/export/*.zip"): # TODO: fix comparison types diff --git a/mealie/services/scheduler/tasks/purge_password_reset.py b/mealie/services/scheduler/tasks/purge_password_reset.py index f783e95913f..99aab0f6b5e 100644 --- a/mealie/services/scheduler/tasks/purge_password_reset.py +++ b/mealie/services/scheduler/tasks/purge_password_reset.py @@ -14,7 +14,7 @@ def purge_password_reset_tokens(): """Purges all events after x days""" logger.debug("purging password reset tokens") - limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=MAX_DAYS_OLD) + limit = datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=MAX_DAYS_OLD) with session_context() as session: stmt = delete(PasswordResetModel).filter(PasswordResetModel.created_at <= limit) diff --git a/mealie/services/scheduler/tasks/purge_registration.py b/mealie/services/scheduler/tasks/purge_registration.py index 58e09c9eb65..855a0358191 100644 --- a/mealie/services/scheduler/tasks/purge_registration.py +++ b/mealie/services/scheduler/tasks/purge_registration.py @@ -14,7 +14,7 @@ def purge_group_registration(): """Purges all events after x days""" logger.debug("purging expired registration tokens") - limit = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=MAX_DAYS_OLD) + limit = datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=MAX_DAYS_OLD) with session_context() as session: stmt = delete(GroupInviteToken).filter(GroupInviteToken.created_at <= limit) diff --git a/mealie/services/user_services/user_service.py b/mealie/services/user_services/user_service.py index 51db3f6e055..b73c1b41753 100644 --- a/mealie/services/user_services/user_service.py +++ b/mealie/services/user_services/user_service.py @@ -1,4 +1,4 @@ -from datetime import datetime, timezone +from datetime import UTC, datetime from mealie.repos.repository_factory import AllRepositories from mealie.schema.user.user import PrivateUser @@ -30,7 +30,7 @@ def reset_locked_users(self, force: bool = False) -> int: return unlocked def lock_user(self, user: PrivateUser) -> PrivateUser: - user.locked_at = datetime.now(timezone.utc) + user.locked_at = datetime.now(UTC) return self.repos.users.update(user.id, user) def unlock_user(self, user: PrivateUser) -> PrivateUser: diff --git a/poetry.lock b/poetry.lock index 45f414fa323..f4f4a951bcd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand. [[package]] name = "aiofiles" @@ -67,7 +67,6 @@ files = [ ] [package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" @@ -117,9 +116,6 @@ files = [ {file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} - [[package]] name = "authlib" version = "1.3.2" @@ -565,13 +561,13 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "distlib" -version = "0.3.6" +version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" files = [ - {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, - {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, ] [[package]] @@ -585,20 +581,6 @@ files = [ {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, ] -[[package]] -name = "exceptiongroup" -version = "1.1.0" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"}, - {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"}, -] - -[package.extras] -test = ["pytest (>=6)"] - [[package]] name = "extruct" version = "0.18.0" @@ -645,18 +627,19 @@ standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "htt [[package]] name = "filelock" -version = "3.9.0" +version = "3.16.1" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.9.0-py3-none-any.whl", hash = "sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d"}, - {file = "filelock-3.9.0.tar.gz", hash = "sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de"}, + {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, + {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, ] [package.extras] -docs = ["furo (>=2022.12.7)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -testing = ["covdefaults (>=2.2.2)", "coverage (>=7.0.1)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] +typing = ["typing-extensions (>=4.12.2)"] [[package]] name = "freezegun" @@ -1549,7 +1532,6 @@ files = [ [package.dependencies] mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} typing-extensions = ">=4.6.0" [package.extras] @@ -1911,18 +1893,19 @@ tests-min = ["defusedxml", "packaging", "pytest"] [[package]] name = "platformdirs" -version = "2.6.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.3.6" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, - {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, ] [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -2295,15 +2278,10 @@ files = [ [package.dependencies] astroid = ">=3.3.5,<=3.4.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = [ - {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, -] +dill = {version = ">=0.3.7", markers = "python_version >= \"3.12\""} isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" platformdirs = ">=2.2.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} tomlkit = ">=0.10.1" [package.extras] @@ -2371,11 +2349,9 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=1.5,<2" -tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] @@ -2838,7 +2814,6 @@ files = [ [package.dependencies] markdown-it-py = ">=2.2.0" pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""} [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] @@ -2872,19 +2847,23 @@ files = [ [[package]] name = "setuptools" -version = "67.1.0" +version = "75.6.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "setuptools-67.1.0-py3-none-any.whl", hash = "sha256:a7687c12b444eaac951ea87a9627c4f904ac757e7abdc5aac32833234af90378"}, - {file = "setuptools-67.1.0.tar.gz", hash = "sha256:e261cdf010c11a41cb5cb5f1bf3338a7433832029f559a6a7614bd42a967c300"}, + {file = "setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d"}, + {file = "setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1)", "ruff (>=0.7.0)"] +core = ["importlib_metadata (>=6)", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1)", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] [[package]] name = "six" @@ -3042,17 +3021,6 @@ files = [ {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, ] -[[package]] -name = "tomli" -version = "1.2.3" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"}, - {file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"}, -] - [[package]] name = "tomlkit" version = "0.11.6" @@ -3198,7 +3166,6 @@ h11 = ">=0.8" httptools = {version = ">=0.6.3", optional = true, markers = "extra == \"standard\""} python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} -typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} @@ -3252,23 +3219,23 @@ test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)" [[package]] name = "virtualenv" -version = "20.17.1" +version = "20.28.0" description = "Virtual Python Environment builder" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "virtualenv-20.17.1-py3-none-any.whl", hash = "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4"}, - {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, + {file = "virtualenv-20.28.0-py3-none-any.whl", hash = "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0"}, + {file = "virtualenv-20.28.0.tar.gz", hash = "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa"}, ] [package.dependencies] -distlib = ">=0.3.6,<1" -filelock = ">=3.4.1,<4" -platformdirs = ">=2.4,<3" +distlib = ">=0.3.7,<1" +filelock = ">=3.12.2,<4" +platformdirs = ">=3.9.1,<5" [package.extras] -docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] -testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] +test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] [[package]] name = "w3lib" @@ -3445,5 +3412,5 @@ pgsql = ["psycopg2-binary"] [metadata] lock-version = "2.0" -python-versions = "^3.10" -content-hash = "55dbb0d6a3e28964743f87ae1d3a4ead8428cf1051ea97839edb325f39c526ba" +python-versions = "^3.12" +content-hash = "70a06c4bc96fda6284e61a84db5770d969ea06e78caaa5860966b53768607929" diff --git a/pyproject.toml b/pyproject.toml index 0171889c925..5c9eacf8fea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ orjson = "^3.8.0" psycopg2-binary = { version = "^2.9.1", optional = true } pydantic = "^2.6.1" pyhumps = "^3.5.3" -python = "^3.10" +python = "^3.12" python-dateutil = "^2.8.2" python-dotenv = "^1.0.0" python-ldap = "^3.3.1" @@ -105,7 +105,7 @@ pgsql = ["psycopg2-binary"] follow_imports = "skip" ignore_missing_imports = true plugins = "pydantic.mypy" -python_version = "3.10" +python_version = "3.12" strict_optional = true [tool.ruff] @@ -135,8 +135,8 @@ exclude = [ "venv", ] -# Assume Python 3.10. -target-version = "py310" +# Assume Python 3.12. +target-version = "py312" [tool.ruff.lint] # Enable Pyflakes `E` and `F` codes by default. From d9a1db557cca1ba70ca25c147597110ebeb164be Mon Sep 17 00:00:00 2001 From: niteflyunicorns <86175805+niteflyunicorns@users.noreply.github.com> Date: Wed, 4 Dec 2024 21:59:17 -0700 Subject: [PATCH 08/10] feat: Add 'No Shopping Lists Found' message (#4661) Co-authored-by: Michael Genson <71845777+michael-genson@users.noreply.github.com> --- .../Domain/Recipe/RecipeDialogAddToShoppingList.vue | 5 +++++ frontend/lang/messages/en-US.json | 3 ++- frontend/pages/shopping-lists/index.vue | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/frontend/components/Domain/Recipe/RecipeDialogAddToShoppingList.vue b/frontend/components/Domain/Recipe/RecipeDialogAddToShoppingList.vue index 37e10ed5b41..789d59bd41a 100644 --- a/frontend/components/Domain/Recipe/RecipeDialogAddToShoppingList.vue +++ b/frontend/components/Domain/Recipe/RecipeDialogAddToShoppingList.vue @@ -1,6 +1,11 @@