From 94cfc36ed5b0ffad1cfd3aabf3a74706acf3569f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kubo=C5=A1ek?= Date: Tue, 9 Jan 2024 11:04:57 +0000 Subject: [PATCH 01/13] Translated using Weblate (Czech) Currently translated at 100.0% (362 of 362 strings) Translation: Tandoor/Recipes Backend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-backend/cs/ --- cookbook/locale/cs/LC_MESSAGES/django.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cookbook/locale/cs/LC_MESSAGES/django.po b/cookbook/locale/cs/LC_MESSAGES/django.po index 513d8c04..d028da3b 100644 --- a/cookbook/locale/cs/LC_MESSAGES/django.po +++ b/cookbook/locale/cs/LC_MESSAGES/django.po @@ -11,8 +11,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-02-09 18:01+0100\n" -"PO-Revision-Date: 2023-07-31 14:19+0000\n" -"Last-Translator: Mára Štěpánek \n" +"PO-Revision-Date: 2024-01-09 12:07+0000\n" +"Last-Translator: Jan Kubošek \n" "Language-Team: Czech \n" "Language: cs\n" @@ -190,7 +190,7 @@ msgid "" "Leave empty for dropbox and enter only base url for nextcloud " "(/remote.php/webdav/ is added automatically)" msgstr "" -"Pro dropbox ponechejte nevyplňené pole. Pro nextcloud použijte pouze " +"Pro dropbox ponechejte nevyplněné pole. Pro nextcloud použijte pouze " "základní url (/remote.php/webdav/ bude přidán automaticky)." #: .\cookbook\forms.py:263 @@ -529,7 +529,7 @@ msgstr "Dávková úprava receptu" #: .\cookbook\templates\batch\edit.html:20 msgid "Add the specified keywords to all recipes containing a word" -msgstr "Přidat štítek ke všem receptům, které obsahují specifické slovo." +msgstr "Přidat štítek ke všem receptům, které obsahují specifické slovo" #: .\cookbook\templates\batch\monitor.html:6 .\cookbook\views\edit.py:66 msgid "Sync" From 1f3cd11964665f2fa6e1d9ed799884cebebcef8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kubo=C5=A1ek?= Date: Tue, 9 Jan 2024 11:48:39 +0000 Subject: [PATCH 02/13] Translated using Weblate (Czech) Currently translated at 90.5% (491 of 542 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/cs/ --- vue/src/locales/cs.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/vue/src/locales/cs.json b/vue/src/locales/cs.json index 15c27a48..7e4f1cd2 100644 --- a/vue/src/locales/cs.json +++ b/vue/src/locales/cs.json @@ -16,14 +16,14 @@ "file_upload_disabled": "Nahrávání souborů není povoleno pro Váš prostor.", "warning_space_delete": "Můžete smazat váš prostor včetně všech receptů, nákupních seznamů, jídelníčků a všeho ostatního, co jste vytvořili. Tuto akci nemůžete vzít zpět! Jste si jisti, že chcete pokračovat?", "food_inherit_info": "Pole potravin, která budou standardně zděděna.", - "step_time_minutes": "Nastavte čas v minutách", + "step_time_minutes": "Délka kroku v minutách", "confirm_delete": "Jste si jisti že chcete odstranit tento {objekt}?", "import_running": "Probíhá import, čekejte prosím!", "all_fields_optional": "Všechna pole jsou nepviná a mohou být ponechána prázdná.", "convert_internal": "Převést na interní recept", "show_only_internal": "Zobrazit pouze interní recepty", "show_split_screen": "Rozdělené zobrazení", - "Log_Recipe_Cooking": "", + "Log_Recipe_Cooking": "Záznam vaření podle receptu", "External_Recipe_Image": "Externí obrázek receptu", "Add_to_Shopping": "Přidat k nákupu", "Add_to_Plan": "Přidat do jídelníčku", @@ -35,7 +35,7 @@ "Hide_as_header": "Skryj jako nadpis", "Add_nutrition_recipe": "Přidat nutriční hodnoty", "Remove_nutrition_recipe": "Smazat nutriční hodnoty", - "Copy_template_reference": "", + "Copy_template_reference": "Zkopírovat šablonu na ingredienci", "Save_and_View": "Uložit & Zobrazit", "Manage_Books": "Spravovat kuchařky", "Meal_Plan": "Jídelníček", @@ -44,7 +44,7 @@ "Recipe_Image": "Obrázek k receptu", "Import_finished": "Import dokončen", "View_Recipes": "Zobrazit recepty", - "Log_Cooking": "", + "Log_Cooking": "Zaznamenat vaření podle receptu", "New_Recipe": "Nový recept", "Url_Import": "Import pomocí URL odkazu", "Reset_Search": "Zrušit filtry vyhledávání", @@ -76,14 +76,14 @@ "Private_Recipe_Help": "Recept můžete zobrazit pouze vy a lidé, se kterými jej sdílíte.", "reusable_help_text": "Má-li pozvánka platit pro více než jednoho uživatele.", "Add_Step": "Přidat krok", - "Keywords": "Klíčová slova", + "Keywords": "Štítky", "Books": "Kuchařky", "Proteins": "Proteiny", "Fats": "Tuky", "Carbohydrates": "Sacharidy", "Calories": "Kalorie", "Energy": "Energie", - "Nutrition": "", + "Nutrition": "Výživové hodnoty", "Date": "Datum", "Share": "Sdílet", "Automation": "Automatizace", @@ -162,7 +162,7 @@ "Food": "Potravina", "Original_Text": "Původní text", "Recipe_Book": "Kuchařka", - "del_confirmation_tree": "Jste si jistí, že chcete odstranit {source} se všemi pořazenými ?", + "del_confirmation_tree": "Jste si jistí, že chcete odstranit {source} i se všemi potomky?", "delete_title": "Smazat {type}", "create_title": "Nový {type}", "edit_title": "Upravit {type}", @@ -170,7 +170,7 @@ "Type": "Typ", "Description": "Popis", "Recipe": "Recept", - "tree_root": "", + "tree_root": "Kořen stromu", "Icon": "Ikona", "Unit": "Jednotka", "Decimals": "Desetinná místa", From 8efc3de11f675371352d348f6c74e232f83d0e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ra=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Tue, 9 Jan 2024 11:45:32 +0000 Subject: [PATCH 03/13] Translated using Weblate (Czech) Currently translated at 90.5% (491 of 542 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/cs/ --- vue/src/locales/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vue/src/locales/cs.json b/vue/src/locales/cs.json index 7e4f1cd2..9bda0aa4 100644 --- a/vue/src/locales/cs.json +++ b/vue/src/locales/cs.json @@ -36,7 +36,7 @@ "Add_nutrition_recipe": "Přidat nutriční hodnoty", "Remove_nutrition_recipe": "Smazat nutriční hodnoty", "Copy_template_reference": "Zkopírovat šablonu na ingredienci", - "Save_and_View": "Uložit & Zobrazit", + "Save_and_View": "Uložit a zobrazit", "Manage_Books": "Spravovat kuchařky", "Meal_Plan": "Jídelníček", "Select_Book": "Vyber kuchařku", From 4b1a80a0ed40f7675c651ff270d42000dc99b0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kubo=C5=A1ek?= Date: Tue, 9 Jan 2024 17:38:44 +0000 Subject: [PATCH 04/13] Translated using Weblate (Czech) Currently translated at 92.0% (510 of 554 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/cs/ --- vue/src/locales/cs.json | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/vue/src/locales/cs.json b/vue/src/locales/cs.json index 9bda0aa4..0229b467 100644 --- a/vue/src/locales/cs.json +++ b/vue/src/locales/cs.json @@ -23,7 +23,7 @@ "convert_internal": "Převést na interní recept", "show_only_internal": "Zobrazit pouze interní recepty", "show_split_screen": "Rozdělené zobrazení", - "Log_Recipe_Cooking": "Záznam vaření podle receptu", + "Log_Recipe_Cooking": "Záznam vaření receptu", "External_Recipe_Image": "Externí obrázek receptu", "Add_to_Shopping": "Přidat k nákupu", "Add_to_Plan": "Přidat do jídelníčku", @@ -35,7 +35,7 @@ "Hide_as_header": "Skryj jako nadpis", "Add_nutrition_recipe": "Přidat nutriční hodnoty", "Remove_nutrition_recipe": "Smazat nutriční hodnoty", - "Copy_template_reference": "Zkopírovat šablonu na ingredienci", + "Copy_template_reference": "Zkopírovat šablonu odkazu", "Save_and_View": "Uložit a zobrazit", "Manage_Books": "Spravovat kuchařky", "Meal_Plan": "Jídelníček", @@ -271,7 +271,7 @@ "default_delay": "Výchozí doba odložení v hodinách", "plan_share_desc": "Nové položky v jídelníčku budou automaticky sdíleny s vybranými uživateli.", "shopping_share_desc": "Uživatelé uvidí všechny položky na vašem nákupním seznamu. Abyste viděli položky na jejich seznamu, musí si přidat vás.", - "shopping_auto_sync_desc": "Nastavením 0 dojde k vypnutí automatické synchronizace. Při prohlížení nákupního seznamu je vždy po uplynutí nastaveného počtu vteřin aktualizován o změny, které mohli provést jiní uživatelé. To je užitečné, pokud nakupujete ve více lidech, ale může používat více dat.", + "shopping_auto_sync_desc": "Zadáním hodnoty 0 se automatická synchronizace vypne. Při prohlížení nákupního seznamu se seznam aktualizuje po stanovených sekundách, aby se synchronizovaly změny, které mohl provést někdo jiný. To je užitečné při nakupování s více lidmi, ale spotřebovávají se při tom mobilní data.", "mealplan_autoadd_shopping_desc": "Automaticky podle jídelníčku přidat ingredience na nákupní seznam.", "mealplan_autoexclude_onhand_desc": "Nepřidávat ingredience, které jsou k dispozici, na nákupní seznam, když je vytvořen podle jídelníčku (manuálně nebo automaticky).", "mealplan_autoinclude_related_desc": "Když je nákupní seznam vytvořen podle jídelníčku, přidat i položky z přidružených receptů.", @@ -359,7 +359,7 @@ "times_cooked": "Kolkrát vařeno", "date_created": "Datum vytvoření", "show_sortby": "Zobrazit Seřazeno podle", - "search_rank": "", + "search_rank": "Skóre shody", "make_now": "", "recipe_filter": "Filtrovat recepty", "book_filter_help": "Zahrnout i recepty z filtru stejně jako manuálně přidané.", @@ -479,10 +479,10 @@ "Create Recipe": "Vytvořit recept", "Import Recipe": "Importovat recept", "per_serving": "na porci", - "open_data_help_text": "Projekt Tandoor Open Data nabízí komunitou poskytnutá data pro Tandoor. Toto pole je automaticky vyplněno při importu a může být později upraveno.", - "Data_Import_Info": "Rozšiřte svůj prostor o seznamy potravin, jednotek a další spravované komunitou, a vylepšete tak svoji sbírku receptů.", + "open_data_help_text": "Projekt Tandoor Open Data nabízí komunitou poskytnutá otevřená data pro Tandoor. Toto pole se vyplní automaticky při importu a umožňuje budoucí aktualizace.", + "Data_Import_Info": "Rozšiřte svůj prostor o seznamy potravin, jednotek a dalších položek spravovaných komunitou, a vylepšete tak svoji sbírku receptů.", "Update_Existing_Data": "Aktualizovat existující data", - "Use_Metric": "Používat metrické jednotky", + "Use_Metric": "Použít metrické jednotky", "Learn_More": "Zjistit víc", "converted_unit": "Převedená jendotka", "converted_amount": "Převedené množství", @@ -494,5 +494,23 @@ "Conversion": "Převod", "Properties": "Vlastnosti", "recipe_property_info": "Můžete také přidávat vlastnosti k Vašim potravinám. Hodnoty budou automaticky přepočteny na základě Vašeho receptu!", - "total": "celkem" + "total": "celkem", + "CustomTheme": "Vlastní téma", + "CustomThemeHelp": "Přepsat styly vybraného motivu nahráním vlastního souboru CSS.", + "CustomLogoHelp": "Nahrajte čtvercové obrázky různých velikostí pro úpravu loga v záložce prohlížeče a v nainstalované webové aplikaci.", + "err_importing_recipe": "Během importu receptu došlo k chybě!", + "Open_Data_Slug": "Identifikátor pro otevřená data", + "Open_Data_Import": "Import otevřených dat", + "FDC_Search": "Vyhledávání v FDC", + "property_type_fdc_hint": "Data z databáze FDC mohou automaticky čerpat pouze typy vlastností se zadaným FDC ID", + "StartDate": "Počáteční datum", + "EndDate": "Konečné datum", + "Welcome": "Vítejte", + "Property_Editor": "Editovat nutriční vlastnosti", + "FDC_ID": "FDC ID", + "FDC_ID_help": "ID v databázi FDC", + "CustomImageHelp": "Nahrajte obrázek, který se zobrazí v přehledu prostoru.", + "CustomNavLogoHelp": "Nahrajte obrázek, který se má zobrazit jako logo v navigačním panelu.", + "CustomLogos": "Vlastní loga", + "OrderInformation": "Položky jsou seřazeny podle čísel od malých po velké." } From 5f7a57a258221991b71d5c977468752c3b68aae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ra=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Tue, 9 Jan 2024 12:11:51 +0000 Subject: [PATCH 05/13] Translated using Weblate (Czech) Currently translated at 92.0% (510 of 554 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/cs/ --- vue/src/locales/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vue/src/locales/cs.json b/vue/src/locales/cs.json index 0229b467..58e305b1 100644 --- a/vue/src/locales/cs.json +++ b/vue/src/locales/cs.json @@ -44,7 +44,7 @@ "Recipe_Image": "Obrázek k receptu", "Import_finished": "Import dokončen", "View_Recipes": "Zobrazit recepty", - "Log_Cooking": "Zaznamenat vaření podle receptu", + "Log_Cooking": "Zaznamenat vaření", "New_Recipe": "Nový recept", "Url_Import": "Import pomocí URL odkazu", "Reset_Search": "Zrušit filtry vyhledávání", From e7d9d7b7b342080a6b010d9742c67352c9c6b762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kubo=C5=A1ek?= Date: Tue, 9 Jan 2024 19:47:05 +0000 Subject: [PATCH 06/13] Translated using Weblate (Czech) Currently translated at 100.0% (554 of 554 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/cs/ --- vue/src/locales/cs.json | 50 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/vue/src/locales/cs.json b/vue/src/locales/cs.json index 58e305b1..13a4e320 100644 --- a/vue/src/locales/cs.json +++ b/vue/src/locales/cs.json @@ -328,7 +328,7 @@ "OnHand_help": "Potravina je v inventáři a nebude automaticky přidána na nákupní seznam. Status \"k dipozici\" je sdílen s nakupujícími uživateli.", "ignore_shopping_help": "Nikdy nepřidávat potravinu na nákupní seznam (např. voda)", "shopping_category_help": "Obchody mohou být seřazeny a třízeny pomocí nákupních kategorií podle rozvržení uliček a regálů.", - "food_recipe_help": "", + "food_recipe_help": "Pokud zde uvedete recept, bude tento recept připojen k jakémukoli jinému receptu, který používá tuto potravinu", "Foods": "Potraviny", "Account": "Účet", "Cosmetic": "Zobrazení", @@ -360,7 +360,7 @@ "date_created": "Datum vytvoření", "show_sortby": "Zobrazit Seřazeno podle", "search_rank": "Skóre shody", - "make_now": "", + "make_now": "Udělat hned", "recipe_filter": "Filtrovat recepty", "book_filter_help": "Zahrnout i recepty z filtru stejně jako manuálně přidané.", "review_shopping": "Zkontrolovat nákupní položky před uložením", @@ -392,9 +392,9 @@ "search_create_help_text": "Vytvořit nový recept přímo v Tandoor.", "warning_duplicate_filter": "Varování: Kvůli technickým omezení může použití několika filtrů se stejnou kombinací (a/nebo/ne) přinést neočekávaný výsledek.", "reset_children": "Resetovat propsání podřízených", - "reset_children_help": "", + "reset_children_help": "Přepíše všechny potomky hodnotami dle nastavení zděděných polí. Pokud není nastaveno pole Děděná pole potomků, tak bude nastaveno pole Zděděná pole na aktuální hodnotu.", "reset_food_inheritance": "Resetovat propisování", - "reset_food_inheritance_info": "", + "reset_food_inheritance_info": "Obnoví u všech potravin pole Zděděné pole a na výchozí hodnotu a nastavit daná pole dle rodiče.", "substitute_help": "Při hledání podle ingrediencí, které jsou k dispozici, jsou zvažovány náhrady.", "substitute_siblings_help": "Všechny potraviny, které sdílejí nadřazenou položku jsou považovány za náhrady.", "substitute_children_help": "Všechny potraviny, které jsou podřízeny této, jsou považovány za náhražky.", @@ -512,5 +512,45 @@ "CustomImageHelp": "Nahrajte obrázek, který se zobrazí v přehledu prostoru.", "CustomNavLogoHelp": "Nahrajte obrázek, který se má zobrazit jako logo v navigačním panelu.", "CustomLogos": "Vlastní loga", - "OrderInformation": "Položky jsou seřazeny podle čísel od malých po velké." + "OrderInformation": "Položky jsou seřazeny podle čísel od malých po velké.", + "kg": "kilogram [kg] (metrický systém, hmotnost)", + "g": "gram [g] (metrický systém, hmotnost)", + "ounce": "unce [oz] (imperiální systém, hmotnost)", + "pound": "libra (hmotnost)", + "Properties_Food_Unit": "Jednotka nutriční vlastnosti", + "Properties_Food_Amount": "Množství nutriční vlastnosti", + "tsp": "lžička [tsp] (US, objem)", + "imperial_tsp": "lžička imperiální [imp tbsp] (UK, objem)", + "Transpose_Words": "Transponovat slova", + "show_step_ingredients_setting": "Zobrazit ingredience u jednotlivých kroků receptu", + "Logo": "Logo", + "Show_Logo": "Zobrazit logo", + "show_step_ingredients_setting_help": "Zobrazí tabulku ingrediencí vedle kroků receptu. Nastavení se aplikuje při vytváření receptu a následně je možné volbu změnit při úpravě receptu.", + "show_step_ingredients": "Zobrazit ingredience u kroku", + "hide_step_ingredients": "Skrýt ingredience u kroku", + "Show_Logo_Help": "Zobrazit logo Tandoor nebo logo prostoru na navigačním panelu.", + "Nav_Text_Mode_Help": "Pro každé téma se chová jinak.", + "Space_Cosmetic_Settings": "Některá kosmetická nastavení mohou měnit správci prostoru a budou mít přednost před nastavením klienta pro daný prostor.", + "Nav_Text_Mode": "Textový režim navigace", + "show_ingredients_table": "Zobrazit tabulku složek vedle textu kroku", + "pint": "pinta [pt] (US, objem)", + "quart": "quart [qt] (US, objem)", + "imperial_fluid_ounce": "tekutá unce imperiální [imp fl oz] (UK, objem)", + "imperial_pint": "pinta imperiální [imp pt] (UK, objem)", + "imperial_quart": "quart imperiální [imp qt] (UK, objem)", + "gallon": "galon [gal] (US, objem)", + "tbsp": "lžíce [tbsp] (US, objem)", + "imperial_gallon": "galon imperiální [imp gal] (UK, objem)", + "imperial_tbsp": "lžíce imperiální [imp tbsp] (UK, objem)", + "Choose_Category": "Vyberte kategorii", + "Back": "Zpět", + "Food_Replace": "Nahrazení v surovině", + "Unit_Replace": "Nahrazení v jednotce", + "Name_Replace": "Nahrazení v názvu", + "ml": "mililitr [ml] (metrický systém, objem)", + "l": "litr [l] (metrický systém, objem)", + "fluid_ounce": "tekutá unce [fl oz] (US, objem)", + "make_now_count": "Nejvyšší počet chybějících ingrediencí", + "Alignment": "Zarovnání", + "Never_Unit": "Není jednotkou" } From b4f158b913ef8bcdd15ff8da851c9d62980b1455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kubo=C5=A1ek?= Date: Wed, 10 Jan 2024 00:54:20 +0000 Subject: [PATCH 07/13] Translated using Weblate (Czech) Currently translated at 100.0% (554 of 554 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/cs/ --- vue/src/locales/cs.json | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/vue/src/locales/cs.json b/vue/src/locales/cs.json index 13a4e320..ebf1e49b 100644 --- a/vue/src/locales/cs.json +++ b/vue/src/locales/cs.json @@ -50,13 +50,13 @@ "Reset_Search": "Zrušit filtry vyhledávání", "Recently_Viewed": "Naposledy prohlížené", "Load_More": "Načíst další", - "New_Keyword": "Nové klíčové slovo", - "Delete_Keyword": "Smazat klíčové slovo", - "Edit_Keyword": "Upravit klíčové slovo", + "New_Keyword": "Nový štítek", + "Delete_Keyword": "Smazat štítek", + "Edit_Keyword": "Upravit štítek", "Edit_Recipe": "Upravit recept", - "Move_Keyword": "Přesunout klíčové slovo", - "Merge_Keyword": "Sloučit klíčové slovo", - "Hide_Keywords": "Skrýt klíčové slovo", + "Move_Keyword": "Přesunout štítek", + "Merge_Keyword": "Sloučit štítek", + "Hide_Keywords": "Skrýt štítek", "Hide_Recipes": "Skrýt recept", "Move_Up": "Nahoru", "Move_Down": "Dolů", @@ -153,7 +153,7 @@ "Hide_Food": "Skrýt potravinu", "Food_Alias": "Přezdívka potraviny", "Unit_Alias": "Přezdívka jednotky", - "Keyword_Alias": "Přezdívka klíčového slova", + "Keyword_Alias": "Přezdívka štítku", "Delete_Food": "Smazat potravinu", "No_ID": "ID nenalezeno, odstranění není možné.", "Meal_Plan_Days": "Budoucí jídelníčky", @@ -179,7 +179,7 @@ "New_Unit": "Nová jednotka", "Create_New_Shopping Category": "Vytvořit novou nákupní kategorii", "Create_New_Food": "Přidat novou potravinu", - "Create_New_Keyword": "Přidat nové klíčové slovo", + "Create_New_Keyword": "Přidat nový štítek", "Create_New_Unit": "Přidat novou jednotku", "Create_New_Meal_Type": "Přidat nový druh jídla", "Create_New_Shopping_Category": "Přidat novou nákupní kategorii", @@ -254,7 +254,7 @@ "SupermarketCategoriesOnly": "Pouze kategorie obchodu", "MoveCategory": "Přesunout do: ", "CountMore": "...+{count} víc", - "IgnoreThis": "Nikdy automaticky nepřídávat {food} na nákupní seznam", + "IgnoreThis": "Nikdy nepřidávat automaticky {food} na nákupní seznam", "DelayFor": "Odložit na {hours} hodin", "Warning": "Varování", "NoCategory": "Není vybrána žádná kategorie.", @@ -280,7 +280,7 @@ "Coming_Soon": "Již brzy", "Auto_Planner": "Automatický plánovač", "New_Cookbook": "Nová kuchařka", - "Hide_Keyword": "Skrýt klíčová slova", + "Hide_Keyword": "Skrýt štítky", "Hour": "Hodina", "Hours": "Hodiny", "Day": "Den", @@ -328,7 +328,7 @@ "OnHand_help": "Potravina je v inventáři a nebude automaticky přidána na nákupní seznam. Status \"k dipozici\" je sdílen s nakupujícími uživateli.", "ignore_shopping_help": "Nikdy nepřidávat potravinu na nákupní seznam (např. voda)", "shopping_category_help": "Obchody mohou být seřazeny a třízeny pomocí nákupních kategorií podle rozvržení uliček a regálů.", - "food_recipe_help": "Pokud zde uvedete recept, bude tento recept připojen k jakémukoli jinému receptu, který používá tuto potravinu", + "food_recipe_help": "Zde uvedený recept bude připojen k jakémukoli jinému receptu, který používá tuto potravinu", "Foods": "Potraviny", "Account": "Účet", "Cosmetic": "Zobrazení", @@ -338,7 +338,7 @@ "simple_mode": "Jednoduchý režim", "advanced": "Pokročilé", "fields": "Pole", - "show_keywords": "Zobrazit klíčová slova", + "show_keywords": "Zobrazit štítky", "show_foods": "Zobrazit potraviny", "show_books": "Zobrazit kuchařky", "show_rating": "Zobrazit hodnocení", @@ -392,9 +392,9 @@ "search_create_help_text": "Vytvořit nový recept přímo v Tandoor.", "warning_duplicate_filter": "Varování: Kvůli technickým omezení může použití několika filtrů se stejnou kombinací (a/nebo/ne) přinést neočekávaný výsledek.", "reset_children": "Resetovat propsání podřízených", - "reset_children_help": "Přepíše všechny potomky hodnotami dle nastavení zděděných polí. Pokud není nastaveno pole Děděná pole potomků, tak bude nastaveno pole Zděděná pole na aktuální hodnotu.", + "reset_children_help": "Přepíše všechny potomky hodnotami dle nastavení propisovaných polí. Pokud není nastaveno pole Propisovaná pole podřízených, tak bude nastaveno pole Propsat hodnoty polí na aktuální hodnotu.", "reset_food_inheritance": "Resetovat propisování", - "reset_food_inheritance_info": "Obnoví u všech potravin pole Zděděné pole a na výchozí hodnotu a nastavit daná pole dle rodiče.", + "reset_food_inheritance_info": "Obnoví u všech potravin propisovaná pole na výchozí hodnotu a nastavit daná pole dle nadřazené položky.", "substitute_help": "Při hledání podle ingrediencí, které jsou k dispozici, jsou zvažovány náhrady.", "substitute_siblings_help": "Všechny potraviny, které sdílejí nadřazenou položku jsou považovány za náhrady.", "substitute_children_help": "Všechny potraviny, které jsou podřízeny této, jsou považovány za náhražky.", @@ -425,8 +425,8 @@ "Social_Authentication": "Přihlašování pomocí účtů sociálních sítí", "Random Recipes": "Náhodné recepty", "parameter_count": "Parametr {count}", - "select_keyword": "Vybrat klíčové slovo", - "add_keyword": "Přidat klíčové slovo", + "select_keyword": "Vybrat štítek", + "add_keyword": "Přidat štítek", "select_file": "Vybrat soubor", "select_recipe": "Vybrat recept", "select_unit": "Vybrat jednotku", @@ -439,7 +439,7 @@ "Username": "Uživatelské jméno", "First_name": "Jméno", "Last_name": "Příjmení", - "Keyword": "Klíčové slovo", + "Keyword": "Štítek", "Advanced": "Rozšířené", "Page": "Stránka", "Single": "Jednoduchý", @@ -490,10 +490,10 @@ "base_amount": "Základní množství", "Datatype": "Datový typ", "Number of Objects": "Počet Objektů", - "Property": "Vlastnost", + "Property": "Nutriční vlastnost", "Conversion": "Převod", - "Properties": "Vlastnosti", - "recipe_property_info": "Můžete také přidávat vlastnosti k Vašim potravinám. Hodnoty budou automaticky přepočteny na základě Vašeho receptu!", + "Properties": "Nutriční vlastnosti", + "recipe_property_info": "Nutriční hodnoty se automaticky dopočtou podle receptu, pokud zadáte nutriční hodnoty přímo potravinám!", "total": "celkem", "CustomTheme": "Vlastní téma", "CustomThemeHelp": "Přepsat styly vybraného motivu nahráním vlastního souboru CSS.", @@ -544,7 +544,7 @@ "imperial_tbsp": "lžíce imperiální [imp tbsp] (UK, objem)", "Choose_Category": "Vyberte kategorii", "Back": "Zpět", - "Food_Replace": "Nahrazení v surovině", + "Food_Replace": "Nahrazení v potravině", "Unit_Replace": "Nahrazení v jednotce", "Name_Replace": "Nahrazení v názvu", "ml": "mililitr [ml] (metrický systém, objem)", From 72b0bd7f1ee591e9774829b9f2f9d09ab712b186 Mon Sep 17 00:00:00 2001 From: Cilantro4858 Date: Fri, 12 Jan 2024 20:35:43 +0000 Subject: [PATCH 08/13] Translated using Weblate (German) Currently translated at 100.0% (554 of 554 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/de/ --- vue/src/locales/de.json | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/vue/src/locales/de.json b/vue/src/locales/de.json index 6bdea528..c2f3df5b 100644 --- a/vue/src/locales/de.json +++ b/vue/src/locales/de.json @@ -536,5 +536,24 @@ "Unit_Replace": "Einheit Ersetzen", "quart": "\"Quart\" [qt] (US, Volumen)", "imperial_quart": "Engl. \"Quart\" [imp qt] (UK, Volumen)", - "err_importing_recipe": "Beim Importieren des Rezeptes ist ein Fehler aufgetreten!" + "err_importing_recipe": "Beim Importieren des Rezeptes ist ein Fehler aufgetreten!", + "property_type_fdc_hint": "Nur Nährwerte mit einer FDC ID können automatisch Daten aus der FDC Datenbank beziehen", + "Property_Editor": "Nährwerte bearbeiten", + "CustomTheme": "Benutzerdefiniertes Theme", + "CustomThemeHelp": "Überschreiben Sie die Stile des ausgewählten Themes, indem Sie eine eigene CSS-Datei hochladen.", + "CustomLogoHelp": "Laden Sie quadratische Bilder in verschiedenen Größen hoch, um das Logo im Browsertab und der installierten Webanwendung zu ändern.", + "Show_Logo_Help": "Zeigen Sie das Tandoor- oder Space-Logo in der Navigationsleiste an.", + "Space_Cosmetic_Settings": "Einige optische Einstellungen können von Administratoren des Bereichs geändert werden und setzen die Client-Einstellungen für diesen Bereich außer Kraft.", + "Properties_Food_Amount": "Nährwertangaben", + "Properties_Food_Unit": "Nährwert Einheit", + "FDC_Search": "FDC Suche", + "Logo": "Logo", + "Show_Logo": "Logo anzeigen", + "Nav_Text_Mode": "Navigation Textmodus", + "Nav_Text_Mode_Help": "Verhält sich bei jedem Theme anders.", + "FDC_ID": "FDC ID", + "FDC_ID_help": "FDC Datenbank ID", + "CustomImageHelp": "Laden Sie ein Bild hoch, das in der Space-Übersicht angezeigt werden soll.", + "CustomNavLogoHelp": "Laden Sie ein Bild hoch, das als Logo für die Navigationsleiste verwendet werden soll.", + "CustomLogos": "Individuelle Logos" } From 26408c33f41955ed0e4ead50bb68c2467ad34fa2 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sat, 13 Jan 2024 07:42:54 +0800 Subject: [PATCH 09/13] removed debug code --- cookbook/templatetags/theming_tags.py | 21 +++++++++++---------- recipes/settings.py | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/cookbook/templatetags/theming_tags.py b/cookbook/templatetags/theming_tags.py index f35096fd..fb7e1405 100644 --- a/cookbook/templatetags/theming_tags.py +++ b/cookbook/templatetags/theming_tags.py @@ -63,14 +63,15 @@ def get_theming_values(space, user): for logo in list(tv.keys()): if logo.startswith('logo_color_') and getattr(space, logo, None): tv[logo] = getattr(space, logo).file.url - if space.custom_space_theme: - tv['custom_theme'] = space.custom_space_theme.file.url - if space.space_theme in themes: - tv['theme'] = static(themes[space.space_theme]) - if space.nav_logo: - tv['nav_logo'] = space.nav_logo.file.url - if space.nav_bg_color: - tv['nav_bg_color'] = space.nav_bg_color - if space.nav_text_color and space.nav_text_color in nav_text_type_mapping: - tv['nav_text_class'] = nav_text_type_mapping[space.nav_text_color] + + if space.custom_space_theme: + tv['custom_theme'] = space.custom_space_theme.file.url + if space.space_theme in themes: + tv['theme'] = static(themes[space.space_theme]) + if space.nav_logo: + tv['nav_logo'] = space.nav_logo.file.url + if space.nav_bg_color: + tv['nav_bg_color'] = space.nav_bg_color + if space.nav_text_color and space.nav_text_color in nav_text_type_mapping: + tv['nav_text_class'] = nav_text_type_mapping[space.nav_text_color] return tv diff --git a/recipes/settings.py b/recipes/settings.py index a22cd394..644bf8a4 100644 --- a/recipes/settings.py +++ b/recipes/settings.py @@ -57,7 +57,7 @@ COMMENT_PREF_DEFAULT = bool(int(os.getenv('COMMENT_PREF_DEFAULT', True))) FRACTION_PREF_DEFAULT = bool(int(os.getenv('FRACTION_PREF_DEFAULT', False))) KJ_PREF_DEFAULT = bool(int(os.getenv('KJ_PREF_DEFAULT', False))) STICKY_NAV_PREF_DEFAULT = bool(int(os.getenv('STICKY_NAV_PREF_DEFAULT', True))) -UNAUTHENTICATED_THEME_FROM_SPACE = 2 #int(os.getenv('UNAUTHENTICATED_THEME_FROM_SPACE', 0)) +UNAUTHENTICATED_THEME_FROM_SPACE = int(os.getenv('UNAUTHENTICATED_THEME_FROM_SPACE', 0)) # minimum interval that users can set for automatic sync of shopping lists SHOPPING_MIN_AUTOSYNC_INTERVAL = int( From 2ba2b97f9c5045f37aa8a026ef885e7707982ca0 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sun, 14 Jan 2024 08:40:05 +0800 Subject: [PATCH 10/13] moved manifest to use main theming function --- cookbook/templatetags/theming_tags.py | 25 ++++++++++---------- cookbook/tests/other/test_theming.py | 33 +++++++++++++++------------ cookbook/views/views.py | 22 ++++++++---------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/cookbook/templatetags/theming_tags.py b/cookbook/templatetags/theming_tags.py index fb7e1405..52503f44 100644 --- a/cookbook/templatetags/theming_tags.py +++ b/cookbook/templatetags/theming_tags.py @@ -10,6 +10,10 @@ register = template.Library() @register.simple_tag def theme_values(request): + return get_theming_values(request) + + +def get_theming_values(request): space = None if request.space: space = request.space @@ -17,10 +21,6 @@ def theme_values(request): with scopes_disabled(): space = Space.objects.filter(id=UNAUTHENTICATED_THEME_FROM_SPACE).first() - return get_theming_values(space, request.user) - - -def get_theming_values(space, user): themes = { UserPreference.BOOTSTRAP: 'themes/bootstrap.min.css', UserPreference.FLATLY: 'themes/flatly.min.css', @@ -48,15 +48,14 @@ def get_theming_values(space, user): 'sticky_nav': 'position: sticky; top: 0; left: 0; z-index: 1000;', } - - if user.is_authenticated: - if user.userpreference.theme in themes: - tv['theme'] = static(themes[user.userpreference.theme]) - if user.userpreference.nav_bg_color: - tv['nav_bg_color'] = user.userpreference.nav_bg_color - if user.userpreference.nav_text_color and user.userpreference.nav_text_color in nav_text_type_mapping: - tv['nav_text_class'] = nav_text_type_mapping[user.userpreference.nav_text_color] - if not user.userpreference.nav_sticky: + if request.user.is_authenticated: + if request.user.userpreference.theme in themes: + tv['theme'] = static(themes[ request.user.userpreference.theme]) + if request.user.userpreference.nav_bg_color: + tv['nav_bg_color'] = request.user.userpreference.nav_bg_color + if request.user.userpreference.nav_text_color and request.user.userpreference.nav_text_color in nav_text_type_mapping: + tv['nav_text_class'] = nav_text_type_mapping[ request.user.userpreference.nav_text_color] + if not request.user.userpreference.nav_sticky: tv['sticky_nav'] = '' if space: diff --git a/cookbook/tests/other/test_theming.py b/cookbook/tests/other/test_theming.py index d9aa0189..1407a6e2 100644 --- a/cookbook/tests/other/test_theming.py +++ b/cookbook/tests/other/test_theming.py @@ -1,19 +1,24 @@ from django.contrib import auth from django.templatetags.static import static +from django.test import RequestFactory from cookbook.models import Space, UserPreference, UserFile from cookbook.templatetags.theming_tags import theme_values, get_theming_values def test_theming_function(space_1, u1_s1): - user = auth.get_user(u1_s1) - # uf = UserFile.objects.create(name='test', space=space_1, created_by=user) #TODO add file tests - assert get_theming_values(space_1, user)['theme'] == static('themes/tandoor.min.css') - assert get_theming_values(space_1, user)['nav_bg_color'] == '#ddbf86' - assert get_theming_values(space_1, user)['nav_text_class'] == 'navbar-light' - assert get_theming_values(space_1, user)['nav_logo'] == static('assets/brand_logo.png') - assert get_theming_values(space_1, user)['sticky_nav'] == 'position: sticky; top: 0; left: 0; z-index: 1000;' + # uf = UserFile.objects.create(name='test', space=space_1, created_by=user) #TODO add file tests + user = auth.get_user(u1_s1) + request = RequestFactory() + request.user = auth.get_user(u1_s1) + request.space = space_1 + + assert get_theming_values(request)['theme'] == static('themes/tandoor.min.css') + assert get_theming_values(request)['nav_bg_color'] == '#ddbf86' + assert get_theming_values(request)['nav_text_class'] == 'navbar-light' + assert get_theming_values(request)['nav_logo'] == static('assets/brand_logo.png') + assert get_theming_values(request)['sticky_nav'] == 'position: sticky; top: 0; left: 0; z-index: 1000;' user.userpreference.theme = UserPreference.TANDOOR_DARK user.userpreference.nav_bg_color = '#ffffff' @@ -21,16 +26,16 @@ def test_theming_function(space_1, u1_s1): user.userpreference.nav_sticky = False user.userpreference.save() - assert get_theming_values(space_1, user)['theme'] == static('themes/tandoor_dark.min.css') - assert get_theming_values(space_1, user)['nav_bg_color'] == '#ffffff' - assert get_theming_values(space_1, user)['nav_text_class'] == 'navbar-dark' - assert get_theming_values(space_1, user)['sticky_nav'] == '' + assert get_theming_values(request)['theme'] == static('themes/tandoor_dark.min.css') + assert get_theming_values(request)['nav_bg_color'] == '#ffffff' + assert get_theming_values(request)['nav_text_class'] == 'navbar-dark' + assert get_theming_values(request)['sticky_nav'] == '' space_1.space_theme = Space.BOOTSTRAP space_1.nav_bg_color = '#000000' space_1.nav_text_color = UserPreference.DARK space_1.save() - assert get_theming_values(space_1, user)['theme'] == static('themes/bootstrap.min.css') - assert get_theming_values(space_1, user)['nav_bg_color'] == '#000000' - assert get_theming_values(space_1, user)['nav_text_class'] == 'navbar-light' + assert get_theming_values(request)['theme'] == static('themes/bootstrap.min.css') + assert get_theming_values(request)['nav_bg_color'] == '#000000' + assert get_theming_values(request)['nav_text_class'] == 'navbar-light' diff --git a/cookbook/views/views.py b/cookbook/views/views.py index 328ea65e..cedc5a83 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -31,6 +31,7 @@ from cookbook.helper.permission_helper import (group_required, has_group_permiss from cookbook.models import (Comment, CookLog, InviteLink, SearchFields, SearchPreference, ShareLink, Space, UserSpace, ViewLog) from cookbook.tables import CookLogTable, ViewLogTable +from cookbook.templatetags.theming_tags import get_theming_values from cookbook.version_info import VERSION_INFO from recipes.settings import PLUGINS, BASE_DIR @@ -481,18 +482,13 @@ def report_share_abuse(request, token): def web_manifest(request): - icons = [ - {"src": static("/assets/logo_color.svg"), "sizes": "any"}, - {"src": static("/assets/logo_color144.png"), "type": "image/png", "sizes": "144x144"}, - {"src": static("/assets/logo_color512.png"), "type": "image/png", "sizes": "512x512"} - ] + theme_values = get_theming_values(request) - if request.user.is_authenticated and getattr(request.space, 'logo_color_svg') and getattr(request.space, 'logo_color_144') and getattr(request.space, 'logo_color_512'): - icons = [ - {"src": request.space.logo_color_svg.file.url, "sizes": "any"}, - {"src": request.space.logo_color_144.file.url, "type": "image/png", "sizes": "144x144"}, - {"src": request.space.logo_color_512.file.url, "type": "image/png", "sizes": "512x512"} - ] + icons = [ + {"src": theme_values['logo_color_svg'], "sizes": "any"}, + {"src": theme_values['logo_color_144'], "type": "image/png", "sizes": "144x144"}, + {"src": theme_values['logo_color_512'], "type": "image/png", "sizes": "512x512"} + ] manifest_info = { "name": "Tandoor Recipes", @@ -500,10 +496,10 @@ def web_manifest(request): "description": _("Manage recipes, shopping list, meal plans and more."), "icons": icons, "start_url": "./search", - "background_color": "#ffcb76", + "background_color": theme_values['nav_bg_color'], "display": "standalone", "scope": ".", - "theme_color": "#ffcb76", + "theme_color": theme_values['nav_bg_color'], "shortcuts": [ { "name": _("Plan"), From 8d90fada1da9ffd118583428ae8a70cbbb27876d Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sun, 14 Jan 2024 15:33:14 +0800 Subject: [PATCH 11/13] fixed theming breaking for users without space --- cookbook/templatetags/theming_tags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/templatetags/theming_tags.py b/cookbook/templatetags/theming_tags.py index 52503f44..a3b40e56 100644 --- a/cookbook/templatetags/theming_tags.py +++ b/cookbook/templatetags/theming_tags.py @@ -15,7 +15,7 @@ def theme_values(request): def get_theming_values(request): space = None - if request.space: + if 'space' in request: space = request.space if not request.user.is_authenticated and UNAUTHENTICATED_THEME_FROM_SPACE > 0: with scopes_disabled(): From 35eff630ffc82e35414e69f85e1c38f3909bd2b0 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sun, 14 Jan 2024 15:39:02 +0800 Subject: [PATCH 12/13] updated theming tests --- cookbook/tests/other/test_theming.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cookbook/tests/other/test_theming.py b/cookbook/tests/other/test_theming.py index 1407a6e2..68e90e99 100644 --- a/cookbook/tests/other/test_theming.py +++ b/cookbook/tests/other/test_theming.py @@ -14,6 +14,7 @@ def test_theming_function(space_1, u1_s1): request.user = auth.get_user(u1_s1) request.space = space_1 + # defaults apply without setting anything (user preference is automatically created with these defaults) assert get_theming_values(request)['theme'] == static('themes/tandoor.min.css') assert get_theming_values(request)['nav_bg_color'] == '#ddbf86' assert get_theming_values(request)['nav_text_class'] == 'navbar-light' @@ -26,6 +27,7 @@ def test_theming_function(space_1, u1_s1): user.userpreference.nav_sticky = False user.userpreference.save() + # user values apply if only those are present assert get_theming_values(request)['theme'] == static('themes/tandoor_dark.min.css') assert get_theming_values(request)['nav_bg_color'] == '#ffffff' assert get_theming_values(request)['nav_text_class'] == 'navbar-dark' @@ -36,6 +38,14 @@ def test_theming_function(space_1, u1_s1): space_1.nav_text_color = UserPreference.DARK space_1.save() + # space settings apply when set assert get_theming_values(request)['theme'] == static('themes/bootstrap.min.css') assert get_theming_values(request)['nav_bg_color'] == '#000000' assert get_theming_values(request)['nav_text_class'] == 'navbar-light' + + user.userspace_set.all().delete() + + # default user settings should apply when user has no space + assert get_theming_values(request)['nav_bg_color'] == '#ddbf86' + assert get_theming_values(request)['nav_text_class'] == 'navbar-light' + assert get_theming_values(request)['nav_logo'] == static('assets/brand_logo.png') From bb52f8902dc223275f5913cb05e84b00b58ca968 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Mon, 15 Jan 2024 07:41:51 +0800 Subject: [PATCH 13/13] added max spaces per user + added custom app name + fixed theming tests --- ...pp_name_userpreference_max_owned_spaces.py | 23 ++++++++++++++ cookbook/models.py | 15 +++++++-- cookbook/templatetags/theming_tags.py | 21 +++++++------ cookbook/tests/other/test_theming.py | 31 ++++++++++++++----- cookbook/views/views.py | 9 ++++-- docs/system/configuration.md | 12 +++++++ recipes/settings.py | 1 + 7 files changed, 91 insertions(+), 21 deletions(-) create mode 100644 cookbook/migrations/0208_space_app_name_userpreference_max_owned_spaces.py diff --git a/cookbook/migrations/0208_space_app_name_userpreference_max_owned_spaces.py b/cookbook/migrations/0208_space_app_name_userpreference_max_owned_spaces.py new file mode 100644 index 00000000..44837d48 --- /dev/null +++ b/cookbook/migrations/0208_space_app_name_userpreference_max_owned_spaces.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.7 on 2024-01-14 23:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0207_space_logo_color_128_space_logo_color_144_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='space', + name='app_name', + field=models.CharField(blank=True, max_length=40, null=True), + ), + migrations.AddField( + model_name='userpreference', + name='max_owned_spaces', + field=models.IntegerField(default=100), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 0614c974..8cb239ae 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -24,7 +24,7 @@ from PIL import Image from treebeard.mp_tree import MP_Node, MP_NodeManager from recipes.settings import (COMMENT_PREF_DEFAULT, FRACTION_PREF_DEFAULT, KJ_PREF_DEFAULT, - SORT_TREE_BY_NAME, STICKY_NAV_PREF_DEFAULT) + SORT_TREE_BY_NAME, STICKY_NAV_PREF_DEFAULT, MAX_OWNED_SPACES_PREF_DEFAULT) def get_user_display_name(self): @@ -288,7 +288,7 @@ class Space(ExportModelOperationsMixin('space'), models.Model): nav_logo = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_nav_logo') nav_bg_color = models.CharField(max_length=8, default='', blank=True, ) nav_text_color = models.CharField(max_length=16, choices=NAV_TEXT_COLORS, default=BLANK) - + app_name = models.CharField(max_length=40, null=True, blank=True, ) logo_color_32 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_32') logo_color_128 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_128') logo_color_144 = models.ForeignKey("UserFile", on_delete=models.SET_NULL, null=True, blank=True, related_name='space_logo_color_144') @@ -409,7 +409,7 @@ class UserPreference(models.Model, PermissionModelMixin): nav_text_color = models.CharField(max_length=16, choices=NAV_TEXT_COLORS, default=DARK) nav_show_logo = models.BooleanField(default=True) nav_sticky = models.BooleanField(default=STICKY_NAV_PREF_DEFAULT) - + max_owned_spaces = models.IntegerField(default=MAX_OWNED_SPACES_PREF_DEFAULT) default_unit = models.CharField(max_length=32, default='g') use_fractions = models.BooleanField(default=FRACTION_PREF_DEFAULT) use_kj = models.BooleanField(default=KJ_PREF_DEFAULT) @@ -434,6 +434,15 @@ class UserPreference(models.Model, PermissionModelMixin): created_at = models.DateTimeField(auto_now_add=True) objects = ScopedManager(space='space') + def save(self, *args, **kwargs): + if not self.pk: + self.max_owned_spaces = MAX_OWNED_SPACES_PREF_DEFAULT + self.comments = COMMENT_PREF_DEFAULT + self.nav_sticky = STICKY_NAV_PREF_DEFAULT + self.use_kj = KJ_PREF_DEFAULT + self.use_fractions = FRACTION_PREF_DEFAULT + + return super().save(*args, **kwargs) def __str__(self): return str(self.user) diff --git a/cookbook/templatetags/theming_tags.py b/cookbook/templatetags/theming_tags.py index a3b40e56..d69ae7b0 100644 --- a/cookbook/templatetags/theming_tags.py +++ b/cookbook/templatetags/theming_tags.py @@ -15,7 +15,7 @@ def theme_values(request): def get_theming_values(request): space = None - if 'space' in request: + if getattr(request,'space',None): space = request.space if not request.user.is_authenticated and UNAUTHENTICATED_THEME_FROM_SPACE > 0: with scopes_disabled(): @@ -46,16 +46,17 @@ def get_theming_values(request): 'nav_bg_color': '#ddbf86', 'nav_text_class': 'navbar-light', 'sticky_nav': 'position: sticky; top: 0; left: 0; z-index: 1000;', + 'app_name': 'Tandoor Recipes', } - if request.user.is_authenticated: - if request.user.userpreference.theme in themes: - tv['theme'] = static(themes[ request.user.userpreference.theme]) - if request.user.userpreference.nav_bg_color: - tv['nav_bg_color'] = request.user.userpreference.nav_bg_color - if request.user.userpreference.nav_text_color and request.user.userpreference.nav_text_color in nav_text_type_mapping: - tv['nav_text_class'] = nav_text_type_mapping[ request.user.userpreference.nav_text_color] - if not request.user.userpreference.nav_sticky: + if request.user.is_authenticated: + if request.user.userpreference.theme in themes: + tv['theme'] = static(themes[request.user.userpreference.theme]) + if request.user.userpreference.nav_bg_color: + tv['nav_bg_color'] = request.user.userpreference.nav_bg_color + if request.user.userpreference.nav_text_color and request.user.userpreference.nav_text_color in nav_text_type_mapping: + tv['nav_text_class'] = nav_text_type_mapping[request.user.userpreference.nav_text_color] + if not request.user.userpreference.nav_sticky: tv['sticky_nav'] = '' if space: @@ -73,4 +74,6 @@ def get_theming_values(request): tv['nav_bg_color'] = space.nav_bg_color if space.nav_text_color and space.nav_text_color in nav_text_type_mapping: tv['nav_text_class'] = nav_text_type_mapping[space.nav_text_color] + if space.app_name: + tv['app_name'] = space.app_name return tv diff --git a/cookbook/tests/other/test_theming.py b/cookbook/tests/other/test_theming.py index 68e90e99..7abaccda 100644 --- a/cookbook/tests/other/test_theming.py +++ b/cookbook/tests/other/test_theming.py @@ -1,6 +1,7 @@ from django.contrib import auth from django.templatetags.static import static from django.test import RequestFactory +from django_scopes import scopes_disabled from cookbook.models import Space, UserPreference, UserFile from cookbook.templatetags.theming_tags import theme_values, get_theming_values @@ -20,32 +21,48 @@ def test_theming_function(space_1, u1_s1): assert get_theming_values(request)['nav_text_class'] == 'navbar-light' assert get_theming_values(request)['nav_logo'] == static('assets/brand_logo.png') assert get_theming_values(request)['sticky_nav'] == 'position: sticky; top: 0; left: 0; z-index: 1000;' + assert get_theming_values(request)['app_name'] == 'Tandoor Recipes' - user.userpreference.theme = UserPreference.TANDOOR_DARK - user.userpreference.nav_bg_color = '#ffffff' - user.userpreference.nav_text_color = UserPreference.LIGHT - user.userpreference.nav_sticky = False - user.userpreference.save() + with scopes_disabled(): + up = UserPreference.objects.filter(user=request.user).first() + up.theme = UserPreference.TANDOOR_DARK + up.nav_bg_color = '#ffffff' + up.nav_text_color = UserPreference.LIGHT + up.nav_sticky = False + up.save() + + request = RequestFactory() + request.user = auth.get_user(u1_s1) + request.space = space_1 # user values apply if only those are present assert get_theming_values(request)['theme'] == static('themes/tandoor_dark.min.css') assert get_theming_values(request)['nav_bg_color'] == '#ffffff' assert get_theming_values(request)['nav_text_class'] == 'navbar-dark' assert get_theming_values(request)['sticky_nav'] == '' + assert get_theming_values(request)['app_name'] == 'Tandoor Recipes' space_1.space_theme = Space.BOOTSTRAP space_1.nav_bg_color = '#000000' space_1.nav_text_color = UserPreference.DARK + space_1.app_name = 'test_app_name' space_1.save() + request = RequestFactory() + request.user = auth.get_user(u1_s1) + request.space = space_1 + # space settings apply when set assert get_theming_values(request)['theme'] == static('themes/bootstrap.min.css') assert get_theming_values(request)['nav_bg_color'] == '#000000' assert get_theming_values(request)['nav_text_class'] == 'navbar-light' + assert get_theming_values(request)['app_name'] == 'test_app_name' user.userspace_set.all().delete() + request = RequestFactory() + request.user = auth.get_user(u1_s1) # default user settings should apply when user has no space - assert get_theming_values(request)['nav_bg_color'] == '#ddbf86' - assert get_theming_values(request)['nav_text_class'] == 'navbar-light' + assert get_theming_values(request)['nav_bg_color'] == '#ffffff' + assert get_theming_values(request)['nav_text_class'] == 'navbar-dark' assert get_theming_values(request)['nav_logo'] == static('assets/brand_logo.png') diff --git a/cookbook/views/views.py b/cookbook/views/views.py index cedc5a83..1c12c77d 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -79,6 +79,11 @@ def space_overview(request): messages.add_message(request, messages.WARNING, _('This feature is not available in the demo version!')) else: if create_form.is_valid(): + if Space.objects.filter(created_by=request.user).count() >= request.user.userpreference.max_owned_spaces: + messages.add_message(request, messages.ERROR, + _('You have the reached the maximum amount of spaces that can be owned by you.') + f' ({request.user.userpreference.max_owned_spaces})') + return HttpResponseRedirect(reverse('view_space_overview')) + created_space = Space.objects.create( name=create_form.cleaned_data['name'], created_by=request.user, @@ -491,8 +496,8 @@ def web_manifest(request): ] manifest_info = { - "name": "Tandoor Recipes", - "short_name": "Tandoor", + "name": theme_values['app_name'], + "short_name": theme_values['app_name'], "description": _("Manage recipes, shopping list, meal plans and more."), "icons": icons, "start_url": "./search", diff --git a/docs/system/configuration.md b/docs/system/configuration.md index c2351134..f6e64d24 100644 --- a/docs/system/configuration.md +++ b/docs/system/configuration.md @@ -524,6 +524,18 @@ The default value for the user preference 'sticky navigation' (always show navba STICKY_NAV_PREF_DEFAULT=1 ``` +#### Max owned spaces + +> default `100` - options: `0-X` + +The default for the number of spaces a user can own. By setting to 0 space creation for users will be disabled. +Superusers can always bypass this limit. + +``` +MAX_OWNED_SPACES_PREF_DEFAULT=100 +``` + + ### Cosmetic / Preferences #### Timezone diff --git a/recipes/settings.py b/recipes/settings.py index 644bf8a4..4f4328d0 100644 --- a/recipes/settings.py +++ b/recipes/settings.py @@ -57,6 +57,7 @@ COMMENT_PREF_DEFAULT = bool(int(os.getenv('COMMENT_PREF_DEFAULT', True))) FRACTION_PREF_DEFAULT = bool(int(os.getenv('FRACTION_PREF_DEFAULT', False))) KJ_PREF_DEFAULT = bool(int(os.getenv('KJ_PREF_DEFAULT', False))) STICKY_NAV_PREF_DEFAULT = bool(int(os.getenv('STICKY_NAV_PREF_DEFAULT', True))) +MAX_OWNED_SPACES_PREF_DEFAULT = int(os.getenv('MAX_OWNED_SPACES_PREF_DEFAULT', 100)) UNAUTHENTICATED_THEME_FROM_SPACE = int(os.getenv('UNAUTHENTICATED_THEME_FROM_SPACE', 0)) # minimum interval that users can set for automatic sync of shopping lists