From bfdd5a8bfcb19ca1abeffbca41d44539c3124e3f Mon Sep 17 00:00:00 2001 From: Jocelin Lebreton Date: Mon, 4 Mar 2024 21:38:58 +0000 Subject: [PATCH 01/13] Translated using Weblate (French) Currently translated at 96.5% (473 of 490 strings) Translation: Tandoor/Recipes Backend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-backend/fr/ --- cookbook/locale/fr/LC_MESSAGES/django.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cookbook/locale/fr/LC_MESSAGES/django.po b/cookbook/locale/fr/LC_MESSAGES/django.po index 91539a593..055875973 100644 --- a/cookbook/locale/fr/LC_MESSAGES/django.po +++ b/cookbook/locale/fr/LC_MESSAGES/django.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-05-18 14:28+0200\n" -"PO-Revision-Date: 2024-03-03 23:19+0000\n" +"PO-Revision-Date: 2024-03-05 22:19+0000\n" "Last-Translator: Jocelin Lebreton \n" "Language-Team: French \n" @@ -2128,7 +2128,7 @@ msgstr "Se connecter via %(provider)s" #, python-format msgid "You are about to sign in using a third party account from %(provider)s." msgstr "" -"ous êtes sur le point de vous connecter en utilisant un compte tiers depuis " +"Vous êtes sur le point de vous connecter en utilisant un compte tiers depuis " "%(provider)s." #: .\cookbook\templates\socialaccount\login.html:20 From f2ce164a1ee45d035f42644cd4a68439fb52ebc0 Mon Sep 17 00:00:00 2001 From: Jan Date: Tue, 5 Mar 2024 14:50:14 +0000 Subject: [PATCH 02/13] Translated using Weblate (German) Currently translated at 99.1% (562 of 567 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/de/ --- vue/src/locales/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vue/src/locales/de.json b/vue/src/locales/de.json index f1ad1d6ee..9f95f873c 100644 --- a/vue/src/locales/de.json +++ b/vue/src/locales/de.json @@ -114,7 +114,7 @@ "Create_New_Shopping Category": "Neue Einkaufskategorie erstellen", "Automate": "Automatisieren", "Type": "Typ", - "and_up": "& Hoch", + "and_up": "& mehr", "Unrated": "Unbewertet", "Shopping_list": "Einkaufsliste", "step_time_minutes": "Schritt Dauer in Minuten", From 8f55e1576746af37ed2b4f5812d6b374f365bb89 Mon Sep 17 00:00:00 2001 From: Michel Blankenstein Date: Tue, 5 Mar 2024 18:50:50 +0000 Subject: [PATCH 03/13] Translated using Weblate (Dutch) Currently translated at 91.3% (518 of 567 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/nl/ --- vue/src/locales/nl.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vue/src/locales/nl.json b/vue/src/locales/nl.json index 8387489c8..91a85bac0 100644 --- a/vue/src/locales/nl.json +++ b/vue/src/locales/nl.json @@ -520,5 +520,6 @@ "imperial_gallon": "imperial gal [imp gal] (Verenigd Koninkrijk, volume)", "imperial_tsp": "imperial thelepel [imp tsp] (UK, volume)", "Choose_Category": "Kies Categorie", - "Back": "Terug" + "Back": "Terug", + "err_importing_recipe": "Bij het importeren van het recept is een fout opgetreden!" } From 8e9285a24ee0bda51e29533c33bcddb94ee0a33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enric=20Bergad=C3=A0?= Date: Thu, 7 Mar 2024 22:49:50 +0000 Subject: [PATCH 04/13] Added translation using Weblate (Catalan) --- vue/src/locales/ca.json | 570 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 570 insertions(+) create mode 100644 vue/src/locales/ca.json diff --git a/vue/src/locales/ca.json b/vue/src/locales/ca.json new file mode 100644 index 000000000..d436dbd2b --- /dev/null +++ b/vue/src/locales/ca.json @@ -0,0 +1,570 @@ +{ + "warning_feature_beta": "", + "err_fetching_resource": "", + "err_creating_resource": "", + "err_updating_resource": "", + "err_deleting_resource": "", + "err_deleting_protected_resource": "", + "err_moving_resource": "", + "err_merging_resource": "", + "err_importing_recipe": "", + "success_fetching_resource": "", + "success_creating_resource": "", + "success_updating_resource": "", + "success_deleting_resource": "", + "success_moving_resource": "", + "success_merging_resource": "", + "file_upload_disabled": "", + "recipe_property_info": "", + "warning_space_delete": "", + "food_inherit_info": "", + "step_time_minutes": "", + "confirm_delete": "", + "import_running": "", + "all_fields_optional": "", + "convert_internal": "", + "show_only_internal": "", + "show_split_screen": "", + "Log_Recipe_Cooking": "", + "External_Recipe_Image": "", + "Add_to_Shopping": "", + "Add_to_Plan": "", + "Step_start_time": "", + "Sort_by_new": "", + "Table_of_Contents": "", + "Recipes_per_page": "", + "Show_as_header": "", + "Hide_as_header": "", + "Add_nutrition_recipe": "", + "Remove_nutrition_recipe": "", + "Copy_template_reference": "", + "per_serving": "", + "Save_and_View": "", + "Manage_Books": "", + "Meal_Plan": "", + "Select_Book": "", + "Select_File": "", + "Recipe_Image": "", + "Import_finished": "", + "View_Recipes": "", + "Log_Cooking": "", + "New_Recipe": "", + "Url_Import": "", + "Reset_Search": "", + "Recently_Viewed": "", + "Load_More": "", + "New_Keyword": "", + "Delete_Keyword": "", + "Edit_Keyword": "", + "Edit_Recipe": "", + "Move_Keyword": "", + "Merge_Keyword": "", + "Hide_Keywords": "", + "Hide_Recipes": "", + "Move_Up": "", + "Move_Down": "", + "Step_Name": "", + "Step_Type": "", + "Make_Header": "", + "Make_Ingredient": "", + "Amount": "", + "Enable_Amount": "", + "Disable_Amount": "", + "Ingredient Editor": "", + "Description_Replace": "", + "Instruction_Replace": "", + "Auto_Sort": "", + "Auto_Sort_Help": "", + "Private_Recipe": "", + "Private_Recipe_Help": "", + "reusable_help_text": "", + "open_data_help_text": "", + "Open_Data_Slug": "", + "Open_Data_Import": "", + "Properties_Food_Amount": "", + "Properties_Food_Unit": "", + "Calculator": "", + "FDC_ID": "", + "FDC_Search": "", + "FDC_ID_help": "", + "property_type_fdc_hint": "", + "Data_Import_Info": "", + "Update_Existing_Data": "", + "Use_Metric": "", + "Learn_More": "", + "converted_unit": "", + "converted_amount": "", + "base_unit": "", + "base_amount": "", + "Datatype": "", + "Input": "", + "Undo": "", + "NoMoreUndo": "", + "Number of Objects": "", + "Add_Step": "", + "Keywords": "", + "Books": "", + "Proteins": "", + "Fats": "", + "Carbohydrates": "", + "Calories": "", + "Energy": "", + "Nutrition": "", + "Date": "", + "StartDate": "", + "EndDate": "", + "Share": "", + "Automation": "", + "Parameter": "", + "Export": "", + "Copy": "", + "Rating": "", + "Close": "", + "Cancel": "", + "Link": "", + "Add": "", + "New": "", + "Note": "", + "Alignment": "", + "Success": "", + "Failure": "", + "Protected": "", + "Ingredients": "", + "Supermarket": "", + "Categories": "", + "Category": "", + "Selected": "", + "min": "", + "Servings": "", + "Waiting": "", + "Preparation": "", + "External": "", + "Size": "", + "Files": "", + "File": "", + "Edit": "", + "Image": "", + "Delete": "", + "Delete_All": "", + "Open": "", + "Ok": "", + "Save": "", + "Step": "", + "Search": "", + "Import": "", + "Print": "", + "Settings": "", + "or": "", + "and": "", + "Information": "", + "Download": "", + "Create": "", + "Search Settings": "", + "View": "", + "Recipes": "", + "Welcome": "", + "Move": "", + "Merge": "", + "Parent": "", + "Copy Link": "", + "Copy Token": "", + "delete_confirmation": "", + "move_confirmation": "", + "merge_confirmation": "", + "create_rule": "", + "move_selection": "", + "merge_selection": "", + "Root": "", + "Ignore_Shopping": "", + "Shopping_Category": "", + "Shopping_Categories": "", + "Shopping_input_placeholder": "", + "Edit_Food": "", + "Move_Food": "", + "New_Food": "", + "Hide_Food": "", + "Food_Alias": "", + "Unit_Alias": "", + "Keyword_Alias": "", + "Delete_Food": "", + "No_ID": "", + "Meal_Plan_Days": "", + "merge_title": "", + "move_title": "", + "Food": "", + "Property": "", + "Property_Editor": "", + "Conversion": "", + "Original_Text": "", + "Recipe_Book": "", + "del_confirmation_tree": "", + "delete_title": "", + "create_title": "", + "edit_title": "", + "Name": "", + "Properties": "", + "Type": "", + "Description": "", + "Recipe": "", + "tree_root": "", + "Icon": "", + "Unit": "", + "Decimals": "", + "Default_Unit": "", + "No_Results": "", + "New_Unit": "", + "Create_New_Shopping Category": "", + "Create_New_Food": "", + "Create_New_Keyword": "", + "Create_New_Unit": "", + "Create_New_Meal_Type": "", + "Create_New_Shopping_Category": "", + "and_up": "", + "and_down": "", + "Instructions": "", + "Unrated": "", + "Automate": "", + "Empty": "", + "Key_Ctrl": "", + "Key_Shift": "", + "Time": "", + "Text": "", + "Shopping_list": "", + "Added_by": "", + "Added_on": "", + "AddToShopping": "", + "IngredientInShopping": "", + "NotInShopping": "", + "OnHand": "", + "FoodOnHand": "", + "FoodNotOnHand": "", + "Undefined": "", + "Create_Meal_Plan_Entry": "", + "Edit_Meal_Plan_Entry": "", + "Title": "", + "Week": "", + "Month": "", + "Year": "", + "created_by": "", + "Planner": "", + "Planner_Settings": "", + "Period": "", + "Plan_Period_To_Show": "", + "Periods": "", + "Plan_Show_How_Many_Periods": "", + "Starting_Day": "", + "Meal_Types": "", + "Meal_Type": "", + "New_Entry": "", + "Clone": "", + "Drag_Here_To_Delete": "", + "Meal_Type_Required": "", + "Title_or_Recipe_Required": "", + "Color": "", + "New_Meal_Type": "", + "Use_Fractions": "", + "Use_Fractions_Help": "", + "AddFoodToShopping": "", + "RemoveFoodFromShopping": "", + "DeleteShoppingConfirm": "", + "IgnoredFood": "", + "Add_Servings_to_Shopping": "", + "Week_Numbers": "", + "Show_Week_Numbers": "", + "Export_As_ICal": "", + "Export_To_ICal": "", + "Cannot_Add_Notes_To_Shopping": "", + "Added_To_Shopping_List": "", + "Shopping_List_Empty": "", + "Next_Period": "", + "Previous_Period": "", + "Current_Period": "", + "Next_Day": "", + "Previous_Day": "", + "Inherit": "", + "InheritFields": "", + "FoodInherit": "", + "ShowUncategorizedFood": "", + "GroupBy": "", + "Language": "", + "Theme": "", + "CustomTheme": "", + "CustomThemeHelp": "", + "CustomImageHelp": "", + "CustomNavLogoHelp": "", + "CustomLogoHelp": "", + "CustomLogos": "", + "SupermarketCategoriesOnly": "", + "MoveCategory": "", + "CountMore": "", + "IgnoreThis": "", + "DelayFor": "", + "Warning": "", + "NoCategory": "", + "InheritWarning": "", + "ShowDelayed": "", + "ShowRecentlyCompleted": "", + "Completed": "", + "OfflineAlert": "", + "ShoppingBackgroundSyncWarning": "", + "shopping_share": "", + "shopping_auto_sync": "", + "one_url_per_line": "", + "mealplan_autoadd_shopping": "", + "mealplan_autoexclude_onhand": "", + "mealplan_autoinclude_related": "", + "default_delay": "", + "plan_share_desc": "", + "shopping_share_desc": "", + "shopping_auto_sync_desc": "", + "mealplan_autoadd_shopping_desc": "", + "mealplan_autoexclude_onhand_desc": "", + "mealplan_autoinclude_related_desc": "", + "default_delay_desc": "", + "filter_to_supermarket": "", + "Coming_Soon": "", + "Auto_Planner": "", + "New_Cookbook": "", + "Hide_Keyword": "", + "Hour": "", + "Hours": "", + "Day": "", + "Days": "", + "Second": "", + "Seconds": "", + "Clear": "", + "Users": "", + "Invites": "", + "err_move_self": "", + "nothing": "", + "err_merge_self": "", + "show_sql": "", + "filter_to_supermarket_desc": "", + "CategoryName": "", + "SupermarketName": "", + "CategoryInstruction": "", + "OrderInformation": "", + "shopping_recent_days_desc": "", + "shopping_recent_days": "", + "download_pdf": "", + "download_csv": "", + "csv_delim_help": "", + "csv_delim_label": "", + "SuccessClipboard": "", + "copy_to_clipboard": "", + "csv_prefix_help": "", + "csv_prefix_label": "", + "copy_markdown_table": "", + "in_shopping": "", + "DelayUntil": "", + "Pin": "", + "Unpin": "", + "PinnedConfirmation": "", + "UnpinnedConfirmation": "", + "mark_complete": "", + "QuickEntry": "", + "shopping_add_onhand_desc": "", + "shopping_add_onhand": "", + "related_recipes": "", + "today_recipes": "", + "sql_debug": "", + "remember_search": "", + "remember_hours": "", + "tree_select": "", + "OnHand_help": "", + "ignore_shopping_help": "", + "shopping_category_help": "", + "food_recipe_help": "", + "Foods": "", + "Account": "", + "Cosmetic": "", + "API": "", + "enable_expert": "", + "expert_mode": "", + "simple_mode": "", + "advanced": "", + "fields": "", + "show_keywords": "", + "show_foods": "", + "show_books": "", + "show_rating": "", + "show_units": "", + "show_filters": "", + "not": "", + "save_filter": "", + "filter_name": "", + "left_handed": "", + "left_handed_help": "", + "show_step_ingredients_setting": "", + "show_step_ingredients_setting_help": "", + "show_step_ingredients": "", + "hide_step_ingredients": "", + "Custom Filter": "", + "shared_with": "", + "sort_by": "", + "asc": "", + "desc": "", + "date_viewed": "", + "last_cooked": "", + "times_cooked": "", + "date_created": "", + "show_sortby": "", + "search_rank": "", + "make_now": "", + "Created": "", + "Updated": "", + "Unchanged": "", + "Error": "", + "make_now_count": "", + "recipe_filter": "", + "book_filter_help": "", + "review_shopping": "", + "view_recipe": "", + "copy_to_new": "", + "recipe_name": "", + "paste_ingredients_placeholder": "", + "paste_ingredients": "", + "ingredient_list": "", + "explain": "", + "filter": "", + "Website": "", + "App": "", + "Message": "", + "Bookmarklet": "", + "Sticky_Nav": "", + "Sticky_Nav_Help": "", + "Logo": "", + "Show_Logo": "", + "Show_Logo_Help": "", + "Nav_Color": "", + "Nav_Text_Mode": "", + "Nav_Text_Mode_Help": "", + "Nav_Color_Help": "", + "Space_Cosmetic_Settings": "", + "Use_Kj": "", + "Comments_setting": "", + "click_image_import": "", + "no_more_images_found": "", + "import_duplicates": "", + "paste_json": "", + "Click_To_Edit": "", + "search_no_recipes": "", + "search_import_help_text": "", + "search_create_help_text": "", + "warning_duplicate_filter": "", + "reset_children": "", + "reset_children_help": "", + "reset_food_inheritance": "", + "reset_food_inheritance_info": "", + "substitute_help": "", + "substitute_siblings_help": "", + "substitute_children_help": "", + "substitute_siblings": "", + "substitute_children": "", + "SubstituteOnHand": "", + "ChildInheritFields": "", + "ChildInheritFields_help": "", + "InheritFields_help": "", + "show_ingredients_table": "", + "show_ingredient_overview": "", + "Ingredient Overview": "", + "last_viewed": "", + "created_on": "", + "updatedon": "", + "Imported_From": "", + "advanced_search_settings": "", + "nothing_planned_today": "", + "no_pinned_recipes": "", + "Planned": "", + "Pinned": "", + "Imported": "", + "Quick actions": "", + "Ratings": "", + "Internal": "", + "Units": "", + "Manage_Emails": "", + "Change_Password": "", + "Social_Authentication": "", + "Random Recipes": "", + "parameter_count": "", + "select_keyword": "", + "add_keyword": "", + "select_file": "", + "select_recipe": "", + "select_unit": "", + "select_food": "", + "remove_selection": "", + "empty_list": "", + "Select": "", + "Supermarkets": "", + "User": "", + "Username": "", + "First_name": "", + "Last_name": "", + "Keyword": "", + "Advanced": "", + "Page": "", + "Single": "", + "Multiple": "", + "Reset": "", + "Disabled": "", + "Disable": "", + "Enable": "", + "Options": "", + "Create Food": "", + "create_food_desc": "", + "additional_options": "", + "Importer_Help": "", + "Documentation": "", + "Select_App_To_Import": "", + "Import_Supported": "", + "Export_Supported": "", + "Import_Not_Yet_Supported": "", + "Export_Not_Yet_Supported": "", + "Import_Result_Info": "", + "Recipes_In_Import": "", + "Toggle": "", + "total": "", + "Import_Error": "", + "Warning_Delete_Supermarket_Category": "", + "New_Supermarket": "", + "New_Supermarket_Category": "", + "Are_You_Sure": "", + "Valid Until": "", + "Split_All_Steps": "", + "Combine_All_Steps": "", + "Plural": "", + "plural_short": "", + "g": "", + "kg": "", + "ounce": "", + "pound": "", + "ml": "", + "l": "", + "fluid_ounce": "", + "pint": "", + "quart": "", + "gallon": "", + "tbsp": "", + "tsp": "", + "imperial_fluid_ounce": "", + "imperial_pint": "", + "imperial_quart": "", + "imperial_gallon": "", + "imperial_tbsp": "", + "imperial_tsp": "", + "Choose_Category": "", + "Back": "", + "Use_Plural_Unit_Always": "", + "Use_Plural_Unit_Simple": "", + "Use_Plural_Food_Always": "", + "Use_Plural_Food_Simple": "", + "plural_usage_info": "", + "Create Recipe": "", + "Import Recipe": "", + "Never_Unit": "", + "Transpose_Words": "", + "Name_Replace": "", + "Food_Replace": "", + "Unit_Replace": "" +} From 3489216dafedeca5429760837ddd617abf510677 Mon Sep 17 00:00:00 2001 From: Rich Schumacher Date: Thu, 7 Mar 2024 08:52:39 -0500 Subject: [PATCH 05/13] bug: Fix decimal.InvalidOperation on /system for some PG versions In https://github.com/TandoorRecipes/recipes/pull/2730 the /system page was improved to warn the user if the version of Postgres they are using is out of date and should be updated. The current code attempts to determine the major versions by replacing `00` with `.` and then converting to a `Decimal`. Unfortunately, it appears the only value this method _does not_ work for are initial releases of major versions, like `16.0.0`. For reference, either Postgres or the PsyCog driver represents the semver values but without the dots, so `16.0.0` becomes `1600000`. This change removes the string replace and Decimal conversion in favor of using the divmod() function. In this application it will return a tuple with the first element being the major version of Postgres. This is then used as before to compare against deprecated versions. --- cookbook/views/views.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cookbook/views/views.py b/cookbook/views/views.py index e3d057945..f5f643291 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -293,11 +293,10 @@ def system(request): if postgres: postgres_current = 16 # will need to be updated as PostgreSQL releases new major versions - from decimal import Decimal from django.db import connection - postgres_ver = Decimal(str(connection.pg_version).replace('00', '.')) + postgres_ver = divmod(connection.pg_version, 10000) if postgres_ver >= postgres_current: database_status = 'success' database_message = _('Everything is fine!') From 952d50d8dd8c4a9fbf01b475a4a3d7b631b1a0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enric=20Bergad=C3=A0?= Date: Thu, 7 Mar 2024 22:50:30 +0000 Subject: [PATCH 06/13] Translated using Weblate (Catalan) Currently translated at 85.5% (419 of 490 strings) Translation: Tandoor/Recipes Backend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-backend/ca/ --- cookbook/locale/ca/LC_MESSAGES/django.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cookbook/locale/ca/LC_MESSAGES/django.po b/cookbook/locale/ca/LC_MESSAGES/django.po index a3ba5fc87..4a37f25e4 100644 --- a/cookbook/locale/ca/LC_MESSAGES/django.po +++ b/cookbook/locale/ca/LC_MESSAGES/django.po @@ -13,8 +13,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-05-18 14:28+0200\n" -"PO-Revision-Date: 2023-07-06 21:19+0000\n" -"Last-Translator: Rubens \n" +"PO-Revision-Date: 2024-03-08 23:19+0000\n" +"Last-Translator: Enric Bergadà \n" "Language-Team: Catalan \n" "Language: ca\n" @@ -567,11 +567,11 @@ msgstr "No s'ha pogut analitzar el codi de la plantilla." #: .\cookbook\integration\copymethat.py:44 #: .\cookbook\integration\melarecipes.py:37 msgid "Favorite" -msgstr "" +msgstr "Preferit" #: .\cookbook\integration\copymethat.py:50 msgid "I made this" -msgstr "" +msgstr "Ho he fet jo" #: .\cookbook\integration\integration.py:218 msgid "" From f061e02a95c8e5bef2fc43da264ec5c9b76e2133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enric=20Bergad=C3=A0?= Date: Thu, 7 Mar 2024 22:54:10 +0000 Subject: [PATCH 07/13] Translated using Weblate (Catalan) Currently translated at 14.0% (80 of 568 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/ca/ --- vue/src/locales/ca.json | 160 ++++++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/vue/src/locales/ca.json b/vue/src/locales/ca.json index d436dbd2b..526cb30da 100644 --- a/vue/src/locales/ca.json +++ b/vue/src/locales/ca.json @@ -1,84 +1,84 @@ { - "warning_feature_beta": "", - "err_fetching_resource": "", - "err_creating_resource": "", - "err_updating_resource": "", - "err_deleting_resource": "", - "err_deleting_protected_resource": "", - "err_moving_resource": "", - "err_merging_resource": "", - "err_importing_recipe": "", - "success_fetching_resource": "", - "success_creating_resource": "", - "success_updating_resource": "", - "success_deleting_resource": "", - "success_moving_resource": "", - "success_merging_resource": "", - "file_upload_disabled": "", - "recipe_property_info": "", - "warning_space_delete": "", - "food_inherit_info": "", - "step_time_minutes": "", - "confirm_delete": "", - "import_running": "", - "all_fields_optional": "", - "convert_internal": "", - "show_only_internal": "", - "show_split_screen": "", - "Log_Recipe_Cooking": "", - "External_Recipe_Image": "", - "Add_to_Shopping": "", - "Add_to_Plan": "", - "Step_start_time": "", - "Sort_by_new": "", - "Table_of_Contents": "", - "Recipes_per_page": "", - "Show_as_header": "", - "Hide_as_header": "", - "Add_nutrition_recipe": "", - "Remove_nutrition_recipe": "", - "Copy_template_reference": "", - "per_serving": "", - "Save_and_View": "", - "Manage_Books": "", - "Meal_Plan": "", - "Select_Book": "", - "Select_File": "", - "Recipe_Image": "", - "Import_finished": "", - "View_Recipes": "", - "Log_Cooking": "", - "New_Recipe": "", - "Url_Import": "", - "Reset_Search": "", - "Recently_Viewed": "", - "Load_More": "", - "New_Keyword": "", - "Delete_Keyword": "", - "Edit_Keyword": "", - "Edit_Recipe": "", - "Move_Keyword": "", - "Merge_Keyword": "", - "Hide_Keywords": "", - "Hide_Recipes": "", - "Move_Up": "", - "Move_Down": "", - "Step_Name": "", - "Step_Type": "", - "Make_Header": "", - "Make_Ingredient": "", - "Amount": "", - "Enable_Amount": "", - "Disable_Amount": "", - "Ingredient Editor": "", - "Description_Replace": "", - "Instruction_Replace": "", - "Auto_Sort": "", - "Auto_Sort_Help": "", - "Private_Recipe": "", - "Private_Recipe_Help": "", - "reusable_help_text": "", - "open_data_help_text": "", + "warning_feature_beta": "Aquesta funció està en fase BETA (proves). Podrien aparèixer-hi errades i canvis importants en un futur (i es podria perdre informació relacionada amb la seva funcionalitat) quan la utilitzis .", + "err_fetching_resource": "Hi ha hagut una errada a l'hora d'obtenir el recurs!", + "err_creating_resource": "Hi ha hagut un error quan es creava el recurs!", + "err_updating_resource": "Hi ha hagut un error quan s'actualitzava el recurs!", + "err_deleting_resource": "Hi ha hagut un error mentre s'esborrava el recurs!", + "err_deleting_protected_resource": "L'objecte que esteu intentant eliminar s'està utilitzant i no es pot esborrar.", + "err_moving_resource": "Hi ha hagut un error movent el recurs!", + "err_merging_resource": "Hi ha hagut un error fusionant el recurs!", + "err_importing_recipe": "Hi ha hagut un error mentre s'importava la recepta!", + "success_fetching_resource": "S'ha obtingut el recurs amb èxit!", + "success_creating_resource": "El recurs ha estat creat amb èxit!", + "success_updating_resource": "El recurs s'ha actualitzat adequadament!", + "success_deleting_resource": "El recurs s'ha esborrat adequadament!", + "success_moving_resource": "El recurs s'ha mogut adequadament!", + "success_merging_resource": "El recurs s'ha fusionat adequadament!", + "file_upload_disabled": "La càrrega d'arxius no està habilitada per al vostre espai.", + "recipe_property_info": "També podeu afegir propietats als aliments per calcular-les automàticament en funció de la vostra recepta!", + "warning_space_delete": "Podeu eliminar el vostre espai incloent-hi les receptes, llistes de la compra, plans d'àpats i tot el que hi hàgiu creat. Un cop ho feu, no podreu tornar enrere. Esteu segurs que ho voleu fer?", + "food_inherit_info": "Camps que han de ser heretats per defecte.", + "step_time_minutes": "Temps del pas en minuts", + "confirm_delete": "Esteu segurs que voleu eliminar aquest {object}?", + "import_running": "Importació en curs, espereu!", + "all_fields_optional": "Tots els camps són opcionals i es poden deixar buits.", + "convert_internal": "Convertiu-ho en una recepta interna", + "show_only_internal": "Mostreu només les receptes internes", + "show_split_screen": "Vista dividida", + "Log_Recipe_Cooking": "Registre de receptes", + "External_Recipe_Image": "Imatge externa de la recepta", + "Add_to_Shopping": "Afegiu-ho al cistell", + "Add_to_Plan": "Afegiu-ho al pla", + "Step_start_time": "Hora d'inici", + "Sort_by_new": "Ordenar a partir del més nou", + "Table_of_Contents": "Taula de continguts", + "Recipes_per_page": "Receptes per pàgina", + "Show_as_header": "Mostreu com a títol", + "Hide_as_header": "Amagueu com a títol", + "Add_nutrition_recipe": "Afegir nutrició a la recepta", + "Remove_nutrition_recipe": "Esborreu nutrició de la recepta", + "Copy_template_reference": "Copieu el patró", + "per_serving": "per porció", + "Save_and_View": "Graveu-ho i mostreu-ho", + "Manage_Books": "Gestioneu els llibres", + "Meal_Plan": "Pla d'àpats", + "Select_Book": "Seleccioneu llibre", + "Select_File": "Seleccioneu arxiu", + "Recipe_Image": "Imatge de la recepta", + "Import_finished": "Importació finalitzada", + "View_Recipes": "Mostreu les receptes", + "Log_Cooking": "Registreu el que s'ha cuinat", + "New_Recipe": "Nova recepta", + "Url_Import": "Importeu des d'url", + "Reset_Search": "Reinicieu la cerca", + "Recently_Viewed": "Vistos recentment", + "Load_More": "Carregueu-ne més", + "New_Keyword": "Afegiu-hi una nova paraula clau", + "Delete_Keyword": "Esborreu paraula clau", + "Edit_Keyword": "Editeu paraula clau", + "Edit_Recipe": "Editeu recepta", + "Move_Keyword": "Moveu la paraula clau", + "Merge_Keyword": "Fusioneu paraula clau", + "Hide_Keywords": "Amagueu paraula clau", + "Hide_Recipes": "Amagueu receptes", + "Move_Up": "Moveu amunt", + "Move_Down": "Moveu avall", + "Step_Name": "Nom del pas", + "Step_Type": "Tipus de pas", + "Make_Header": "Establiu capçalera", + "Make_Ingredient": "Establiu ingredient", + "Amount": "Quantitat", + "Enable_Amount": "Habiliteu quantitat", + "Disable_Amount": "Deshabiliteu quantitat", + "Ingredient Editor": "Editor d'ingredients", + "Description_Replace": "Substituïu descripció", + "Instruction_Replace": "Substituïu instrucció", + "Auto_Sort": "Ordeneu automàticament", + "Auto_Sort_Help": "Moveu tots els ingredients al pas més adequat.", + "Private_Recipe": "Recepta privada", + "Private_Recipe_Help": "Només tu i la gent amb qui l'has compartit podran veure aquesta recepta.", + "reusable_help_text": "L'enllaç d'invitació es pot fer servir per més d'un usuari.", + "open_data_help_text": "El projecte de dades obertes de Tandoor proporciona dades per a Tandoor a partir de les contribucions de la comunitat. Aquest camp s'emplena automàticament quan s'importa i permet que es facin actualitzacions en un futur.", "Open_Data_Slug": "", "Open_Data_Import": "", "Properties_Food_Amount": "", From aebc4a45ffc22d26192b0e7109d95a4f5de4a676 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 9 Mar 2024 07:31:28 +0100 Subject: [PATCH 08/13] fixed boot script for systems that dont support ipv6 --- boot.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/boot.sh b/boot.sh index 97a94f477..ae3dbb51d 100644 --- a/boot.sh +++ b/boot.sh @@ -76,4 +76,11 @@ echo "Done" chmod -R 755 /opt/recipes/mediafiles -exec gunicorn -b "[::]:$TANDOOR_PORT" --workers $GUNICORN_WORKERS --threads $GUNICORN_THREADS --access-logfile - --error-logfile - --log-level $GUNICORN_LOG_LEVEL recipes.wsgi +ipv6_disable=$(cat /sys/module/ipv6/parameters/disable) + +# Check if IPv6 is enabled, only then run gunicorn with ipv6 support +if [ "$ipv6_disable" -eq 0 ]; then + exec gunicorn -b "[::]:$TANDOOR_PORT" --workers $GUNICORN_WORKERS --threads $GUNICORN_THREADS --access-logfile - --error-logfile - --log-level $GUNICORN_LOG_LEVEL recipes.wsgi +else + exec gunicorn -b ":$TANDOOR_PORT" --workers $GUNICORN_WORKERS --threads $GUNICORN_THREADS --access-logfile - --error-logfile - --log-level $GUNICORN_LOG_LEVEL recipes.wsgi +fi \ No newline at end of file From 37fb0418ac78dd5326bceac73ce71e60c33346c0 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 9 Mar 2024 07:44:32 +0100 Subject: [PATCH 09/13] fixed default page setting and made PWA respect that setting --- .../0217_alter_userpreference_default_page.py | 18 ++++++++++++++++++ cookbook/models.py | 2 ++ cookbook/views/views.py | 6 +++--- .../Settings/CosmeticSettingsComponent.vue | 9 +++++++++ vue/src/locales/en.json | 1 + 5 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 cookbook/migrations/0217_alter_userpreference_default_page.py diff --git a/cookbook/migrations/0217_alter_userpreference_default_page.py b/cookbook/migrations/0217_alter_userpreference_default_page.py new file mode 100644 index 000000000..ae02a1ab0 --- /dev/null +++ b/cookbook/migrations/0217_alter_userpreference_default_page.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.10 on 2024-03-09 06:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0216_delete_shoppinglist'), + ] + + operations = [ + migrations.AlterField( + model_name='userpreference', + name='default_page', + field=models.CharField(choices=[('SEARCH', 'Search'), ('PLAN', 'Meal-Plan'), ('BOOKS', 'Books'), ('SHOPPING', 'Shopping')], default='SEARCH', max_length=64), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index aab4ec554..d2e160b8d 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -449,11 +449,13 @@ class UserPreference(models.Model, PermissionModelMixin): SEARCH = 'SEARCH' PLAN = 'PLAN' BOOKS = 'BOOKS' + SHOPPING = 'SHOPPING' PAGES = ( (SEARCH, _('Search')), (PLAN, _('Meal-Plan')), (BOOKS, _('Books')), + (SHOPPING, _('Shopping')), ) user = AutoOneToOneField(User, on_delete=models.CASCADE, primary_key=True) diff --git a/cookbook/views/views.py b/cookbook/views/views.py index e3d057945..a2d23152d 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -38,7 +38,7 @@ def index(request): return HttpResponseRedirect(reverse_lazy('view_search')) try: - page_map = {UserPreference.SEARCH: reverse_lazy('view_search'), UserPreference.PLAN: reverse_lazy('view_plan'), UserPreference.BOOKS: reverse_lazy('view_books'), } + page_map = {UserPreference.SEARCH: reverse_lazy('view_search'), UserPreference.PLAN: reverse_lazy('view_plan'), UserPreference.BOOKS: reverse_lazy('view_books'), UserPreference.SHOPPING: reverse_lazy('view_shopping'),} return HttpResponseRedirect(page_map.get(request.user.userpreference.default_page)) except UserPreference.DoesNotExist: @@ -446,7 +446,7 @@ def web_manifest(request): theme_values['app_name'], "description": _("Manage recipes, shopping list, meal plans and more."), "icons": icons, "start_url": - "./search", "background_color": + "./", "background_color": theme_values['nav_bg_color'], "display": "standalone", "scope": ".", "theme_color": @@ -454,7 +454,7 @@ def web_manifest(request): [{"name": _("Plan"), "short_name": _("Plan"), "description": _("View your meal Plan"), "url": "./plan"}, {"name": _("Books"), "short_name": _("Books"), "description": _("View your cookbooks"), "url": "./books"}, {"name": _("Shopping"), "short_name": _("Shopping"), "description": _("View your shopping lists"), "url": - "./list/shopping-list/"}], "share_target": {"action": "/data/import/url", "method": "GET", "params": {"title": "title", "url": "url", "text": "text"}} + "./shopping/"}], "share_target": {"action": "/data/import/url", "method": "GET", "params": {"title": "title", "url": "url", "text": "text"}} } return JsonResponse(manifest_info, json_dumps_params={'indent': 4}) diff --git a/vue/src/components/Settings/CosmeticSettingsComponent.vue b/vue/src/components/Settings/CosmeticSettingsComponent.vue index b37866545..8ce754336 100644 --- a/vue/src/components/Settings/CosmeticSettingsComponent.vue +++ b/vue/src/components/Settings/CosmeticSettingsComponent.vue @@ -37,6 +37,15 @@ + + + {{$t('Search')}} + {{$t('Shopping')}} + {{$t('Meal_Plan')}} + {{$t('Books')}} + + +
diff --git a/vue/src/locales/en.json b/vue/src/locales/en.json index 0cfae7887..be25ef264 100644 --- a/vue/src/locales/en.json +++ b/vue/src/locales/en.json @@ -504,6 +504,7 @@ "Keyword": "Keyword", "Advanced": "Advanced", "Page": "Page", + "DefaultPage": "Default Page", "Single": "Single", "Multiple": "Multiple", "Reset": "Reset", From 9c92e0f4c08e59ec72fdacaa7a17878f81027e52 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 9 Mar 2024 07:47:33 +0100 Subject: [PATCH 10/13] fixed deleteting the selected supermarket in shopping breaking page --- vue/src/apps/ShoppingListView/ShoppingListView.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vue/src/apps/ShoppingListView/ShoppingListView.vue b/vue/src/apps/ShoppingListView/ShoppingListView.vue index b1c8b20be..173375466 100644 --- a/vue/src/apps/ShoppingListView/ShoppingListView.vue +++ b/vue/src/apps/ShoppingListView/ShoppingListView.vue @@ -569,6 +569,9 @@ export default { api.retrieveSupermarket(useUserPreferenceStore().device_settings.shopping_selected_supermarket.id).then(r => { useUserPreferenceStore().device_settings.shopping_selected_supermarket = r.data useUserPreferenceStore().updateDeviceSettings() + }).catch(err => { + useUserPreferenceStore().device_settings.shopping_selected_supermarket = null + useUserPreferenceStore().updateDeviceSettings() }) } From bb77f80abf6ec4d781cc6c9faf7324981f203f76 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 9 Mar 2024 07:56:22 +0100 Subject: [PATCH 11/13] fixed shopping category headers showing when only containing delayed entries --- vue/src/apps/ShoppingListView/ShoppingListView.vue | 2 +- vue/src/stores/ShoppingListStore.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/vue/src/apps/ShoppingListView/ShoppingListView.vue b/vue/src/apps/ShoppingListView/ShoppingListView.vue index 173375466..f5a22a316 100644 --- a/vue/src/apps/ShoppingListView/ShoppingListView.vue +++ b/vue/src/apps/ShoppingListView/ShoppingListView.vue @@ -75,7 +75,7 @@ + v-if="(c.count_unchecked > 0 || user_preference_store.device_settings.shopping_show_checked_entries) && (c.count_unchecked + c.count_checked) > 0 && (c.count_delayed_unchecked < c.count_unchecked ||user_preference_store.device_settings.shopping_show_delayed_entries )"> diff --git a/vue/src/stores/ShoppingListStore.js b/vue/src/stores/ShoppingListStore.js index 6a4aab1e7..bacaf86ab 100644 --- a/vue/src/stores/ShoppingListStore.js +++ b/vue/src/stores/ShoppingListStore.js @@ -65,6 +65,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, { let count_checked = 0 let count_unchecked_food = 0 let count_checked_food = 0 + let count_delayed_unchecked = 0 for (let fi in structure[i]['foods']) { let food_checked = true @@ -74,6 +75,9 @@ export const useShoppingListStore = defineStore(_STORE_ID, { } else { food_checked = false count_unchecked++ + if (structure[i]['foods'][fi]['entries'][ei].delay_until != null){ + count_delayed_unchecked++ + } } } if (food_checked) { @@ -87,6 +91,7 @@ export const useShoppingListStore = defineStore(_STORE_ID, { Vue.set(structure[i], 'count_checked', count_checked) Vue.set(structure[i], 'count_unchecked_food', count_unchecked_food) Vue.set(structure[i], 'count_checked_food', count_checked_food) + Vue.set(structure[i], 'count_delayed_unchecked', count_delayed_unchecked) total_unchecked += count_unchecked total_checked += count_checked From 36887b348864f65c478ceb7964993bfcaaa6cbd0 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 9 Mar 2024 12:36:24 +0100 Subject: [PATCH 12/13] added open data slug to shopping category form --- vue/src/utils/models.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/vue/src/utils/models.js b/vue/src/utils/models.js index 42182baf8..5e35ff599 100644 --- a/vue/src/utils/models.js +++ b/vue/src/utils/models.js @@ -427,6 +427,15 @@ export class Models { placeholder: "", optional: true, }, + open_data_slug: { + form_field: true, + type: "text", + field: "open_data_slug", + disabled: true, + label: "Open_Data_Slug", + help_text: "open_data_help_text", + optional: true, + }, }, }, } From 02523f532542e3e5c9bdd595edbc09ccc17f6c18 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 9 Mar 2024 12:54:49 +0100 Subject: [PATCH 13/13] fixed duplicate operation ID for plan-ical endpoint --- cookbook/urls.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/cookbook/urls.py b/cookbook/urls.py index 649f43826..fc09bcaf2 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -8,7 +8,6 @@ from rest_framework.schemas import get_schema_view from cookbook.version_info import TANDOOR_VERSION from recipes.settings import DEBUG, PLUGINS - from .models import (Automation, Comment, CustomFilter, Food, InviteLink, Keyword, PropertyType, Recipe, RecipeBook, RecipeBookEntry, RecipeImport, Space, Step, Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, UnitConversion, @@ -16,7 +15,7 @@ from .models import (Automation, Comment, CustomFilter, Food, InviteLink, Keywor from .views import api, data, delete, edit, import_export, lists, new, telegram, views from .views.api import CustomAuthToken, ImportOpenData - +import datetime # extend DRF default router class to allow including additional routers class DefaultRouter(routers.DefaultRouter): @@ -121,9 +120,9 @@ urlpatterns = [ path('api/get_recipe_file//', api.get_recipe_file, name='api_get_recipe_file'), path('api/sync_all/', api.sync_all, name='api_sync'), path('api/log_cooking//', api.log_cooking, name='api_log_cooking'), - path('api/plan-ical/', api.get_plan_ical, name='api_get_plan_ical_future'), - path('api/plan-ical//', api.get_plan_ical, name='api_get_plan_ical_from'), - path('api/plan-ical///', api.get_plan_ical, name='api_get_plan_ical'), + + path('api/plan-ical/', api.get_plan_ical, kwargs={'from_date': datetime.date.today(), 'to_date': None}, name='api_get_plan_ical_future'), + path('api/recipe-from-source/', api.RecipeUrlImportView.as_view(), name='api_recipe_from_source'), path('api/backup/', api.get_backup, name='api_backup'), path('api/ingredient-from-string/', api.ingredient_from_string, name='api_ingredient_from_string'), @@ -137,7 +136,7 @@ urlpatterns = [ path('docs/markdown/', views.markdown_info, name='docs_markdown'), path('docs/search/', views.search_info, name='docs_search'), path('docs/api/', views.api_info, name='docs_api'), - path('openapi/', get_schema_view(title="Django Recipes", version=TANDOOR_VERSION, public=True, permission_classes=(permissions.AllowAny, )), name='openapi-schema'), + path('openapi/', get_schema_view(title="Django Recipes", version=TANDOOR_VERSION, public=True, permission_classes=(permissions.AllowAny,)), name='openapi-schema'), path('api/', include((router.urls, 'api'))), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), path('api-token-auth/', CustomAuthToken.as_view()), @@ -148,13 +147,11 @@ urlpatterns = [ path('manifest.json', views.web_manifest, name='web_manifest'), ] - generic_models = ( Recipe, RecipeImport, Storage, ConnectorConfig, RecipeBook, SyncLog, Sync, Comment, RecipeBookEntry, InviteLink, UserSpace, Space ) - for m in generic_models: py_name = get_model_name(m) url_name = py_name.replace('_', '-')