From 8c8834e6aa0a166f97bbc14e7e9d066705684828 Mon Sep 17 00:00:00 2001 From: Mikhail Epifanov Date: Fri, 13 Sep 2024 22:36:05 +0200 Subject: [PATCH 1/7] dont log err.headers which can contain sensitive info --- cookbook/connectors/homeassistant.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cookbook/connectors/homeassistant.py b/cookbook/connectors/homeassistant.py index e2bdcc22d..3268c4cb1 100644 --- a/cookbook/connectors/homeassistant.py +++ b/cookbook/connectors/homeassistant.py @@ -3,7 +3,7 @@ from logging import Logger from typing import Dict, Tuple from urllib.parse import urljoin -from aiohttp import ClientError, request +from aiohttp import request, ClientResponseError from cookbook.connectors.connector import Connector from cookbook.models import ShoppingListEntry, ConnectorConfig, Space @@ -48,8 +48,8 @@ class HomeAssistant(Connector): try: await self.homeassistant_api_call("POST", "services/todo/add_item", data) - except ClientError as err: - self._logger.warning(f"received an exception from the api: {err=}, {type(err)=}") + except ClientResponseError as err: + self._logger.warning(f"received an exception from the api: {err.request_info.url=}, {err.request_info.method=}, {err.status=}, {err.message=}, {type(err)=}") async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None: if not self._config.on_shopping_list_entry_updated_enabled: @@ -76,9 +76,9 @@ class HomeAssistant(Connector): try: await self.homeassistant_api_call("POST", "services/todo/remove_item", data) - except ClientError as err: + except ClientResponseError as err: # This error will always trigger if the item is not present/found - self._logger.debug(f"received an exception from the api: {err=}, {type(err)=}") + self._logger.debug(f"received an exception from the api: {err.request_info.url=}, {err.request_info.method=}, {err.status=}, {err.message=}, {type(err)=}") async def close(self) -> None: pass From 41ee8cf66fa772a7a7f70af785205583116ab86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Muck=20P=C3=A9ter?= Date: Sat, 14 Sep 2024 12:34:11 +0000 Subject: [PATCH 2/7] Translated using Weblate (Hungarian) Currently translated at 81.5% (465 of 570 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/hu/ --- vue/src/locales/hu.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/vue/src/locales/hu.json b/vue/src/locales/hu.json index 339c3a4be..923bcd31e 100644 --- a/vue/src/locales/hu.json +++ b/vue/src/locales/hu.json @@ -8,11 +8,11 @@ "err_moving_resource": "Hiba történt egy erőforrás áthelyezésekor!", "err_merging_resource": "Hiba történt egy erőforrás egyesítésekor!", "success_fetching_resource": "Sikeresen lekérdezett erőforrást!", - "success_creating_resource": "", - "success_updating_resource": "", - "success_deleting_resource": "", - "success_moving_resource": "", - "success_merging_resource": "", + "success_creating_resource": "Sikeresen létrehoztam egy erőforrást!", + "success_updating_resource": "Sikeresen frissítettem egy erőforrást!", + "success_deleting_resource": "Sikeresen töröltem egy erőforrást!", + "success_moving_resource": "Sikeresen áthelyeztem egy erőforrást!", + "success_merging_resource": "Sikeresen egyesítettem egy erőforrást!", "file_upload_disabled": "A fájlfeltöltés nincs engedélyezve az Ön teréhez.", "step_time_minutes": "Lépés időtartama percben", "confirm_delete": "Biztos, hogy törölni akarja ezt a {object}?", From eb0a95f594a8cf257cf698a1389c03999de9763e Mon Sep 17 00:00:00 2001 From: Eugene Howe Date: Sun, 15 Sep 2024 10:44:30 -0400 Subject: [PATCH 3/7] Make HomeAssistant description field optional --- cookbook/connectors/homeassistant.py | 6 ++++-- cookbook/forms.py | 8 +++++++- ...nnectorconfig_supports_description_field.py | 18 ++++++++++++++++++ cookbook/models.py | 1 + cookbook/serializer.py | 2 +- .../tests/api/test_api_connector_config.py | 12 ++++++++++++ 6 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 cookbook/migrations/0219_connectorconfig_supports_description_field.py diff --git a/cookbook/connectors/homeassistant.py b/cookbook/connectors/homeassistant.py index e2bdcc22d..904afd078 100644 --- a/cookbook/connectors/homeassistant.py +++ b/cookbook/connectors/homeassistant.py @@ -43,13 +43,15 @@ class HomeAssistant(Connector): data = { "entity_id": self._config.todo_entity, "item": item, - "description": description, } + if self._config.supports_description_field: + data["description"] = description + try: await self.homeassistant_api_call("POST", "services/todo/add_item", data) except ClientError as err: - self._logger.warning(f"received an exception from the api: {err=}, {type(err)=}") + self._logger.warning(f"received an exception from the api: {err=}, {type(err)=} {data=}") async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None: if not self._config.on_shopping_list_entry_updated_enabled: diff --git a/cookbook/forms.py b/cookbook/forms.py index c0a670613..f3d6ec4bd 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -182,6 +182,12 @@ class ConnectorConfigForm(forms.ModelForm): required=False, ) + supports_description_field = forms.BooleanField( + help_text="Does the connector todo entity support the description field", + initial=True, + required=False, + ) + update_token = forms.CharField( widget=forms.TextInput(attrs={'autocomplete': 'update-token', 'type': 'password'}), required=False, @@ -198,7 +204,7 @@ class ConnectorConfigForm(forms.ModelForm): fields = ( 'name', 'type', 'enabled', 'on_shopping_list_entry_created_enabled', 'on_shopping_list_entry_updated_enabled', - 'on_shopping_list_entry_deleted_enabled', 'url', 'todo_entity', + 'on_shopping_list_entry_deleted_enabled', 'supports_description_field', 'url', 'todo_entity', ) help_texts = { diff --git a/cookbook/migrations/0219_connectorconfig_supports_description_field.py b/cookbook/migrations/0219_connectorconfig_supports_description_field.py new file mode 100644 index 000000000..2f2ac0749 --- /dev/null +++ b/cookbook/migrations/0219_connectorconfig_supports_description_field.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.15 on 2024-09-15 10:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0218_alter_mealplan_from_date_alter_mealplan_to_date'), + ] + + operations = [ + migrations.AddField( + model_name='connectorconfig', + name='supports_description_field', + field=models.BooleanField(default=True, help_text='Does the todo entity support the description field'), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 6c34d8183..e41560992 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -406,6 +406,7 @@ class ConnectorConfig(models.Model, PermissionModelMixin): on_shopping_list_entry_created_enabled = models.BooleanField(default=False) on_shopping_list_entry_updated_enabled = models.BooleanField(default=False) on_shopping_list_entry_deleted_enabled = models.BooleanField(default=False) + supports_description_field = models.BooleanField(default=True, help_text="Does the todo entity support the description field") url = models.URLField(blank=True, null=True) token = models.CharField(max_length=512, blank=True, null=True) diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 8a7114c46..1bdbbad6f 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -427,7 +427,7 @@ class ConnectorConfigConfigSerializer(SpacedModelSerializer): fields = ( 'id', 'name', 'url', 'token', 'todo_entity', 'enabled', 'on_shopping_list_entry_created_enabled', 'on_shopping_list_entry_updated_enabled', - 'on_shopping_list_entry_deleted_enabled', 'created_by' + 'on_shopping_list_entry_deleted_enabled', 'supports_description_field', 'created_by' ) read_only_fields = ('created_by',) diff --git a/cookbook/tests/api/test_api_connector_config.py b/cookbook/tests/api/test_api_connector_config.py index 79f496bf6..a7c490a78 100644 --- a/cookbook/tests/api/test_api_connector_config.py +++ b/cookbook/tests/api/test_api_connector_config.py @@ -99,11 +99,23 @@ def test_add(arg, request, a1_s2, obj_1): assert r.status_code == arg[1] if r.status_code == 201: assert response['name'] == 'test' + assert response['supports_description_field'] == True r = c.get(reverse(DETAIL_URL, args={response['id']})) assert r.status_code == 200 r = a1_s2.get(reverse(DETAIL_URL, args={response['id']})) assert r.status_code == 404 +def test_add_with_supports_description_field_false(a1_s2): + r = a1_s2.post( + reverse(LIST_URL), + {'name': 'test', 'url': 'http://localhost:8123/api', 'token': '1234', 'enabled': 'true', 'supports_description_field': 'false'}, + content_type='application/json' + ) + response = json.loads(r.content) + print(r.content) + assert r.status_code == 201 + assert response['name'] == 'test' + assert response['supports_description_field'] == False def test_delete(a1_s1, a1_s2, obj_1): r = a1_s2.delete( From 0259e000e3bbc818bc4d2e5d0dab00a7c5100c1e Mon Sep 17 00:00:00 2001 From: Bebbe K Date: Mon, 16 Sep 2024 11:42:28 +0000 Subject: [PATCH 4/7] Translated using Weblate (Swedish) Currently translated at 61.4% (300 of 488 strings) Translation: Tandoor/Recipes Backend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-backend/sv/ --- cookbook/locale/sv/LC_MESSAGES/django.po | 91 ++++++++++++------------ 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/cookbook/locale/sv/LC_MESSAGES/django.po b/cookbook/locale/sv/LC_MESSAGES/django.po index 7b1a08ca1..31823adaf 100644 --- a/cookbook/locale/sv/LC_MESSAGES/django.po +++ b/cookbook/locale/sv/LC_MESSAGES/django.po @@ -8,8 +8,8 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-08-01 15:04+0200\n" -"PO-Revision-Date: 2024-03-11 13:02+0000\n" -"Last-Translator: Kn \n" +"PO-Revision-Date: 2024-09-17 11:58+0000\n" +"Last-Translator: Bebbe K \n" "Language-Team: Swedish \n" "Language: sv\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.4.2\n" +"X-Generator: Weblate 5.6.2\n" #: .\cookbook\forms.py:45 msgid "" @@ -151,48 +151,61 @@ msgid "" "Select type method of search. Click here for " "full description of choices." msgstr "" +"Välj typ av sökmetod. Klicka här för " +"fullständig beskrivning av alternativen." #: .\cookbook\forms.py:341 msgid "" "Use fuzzy matching on units, keywords and ingredients when editing and " "importing recipes." msgstr "" +"Använd \"fuzzy\" matchning på enheter, nyckelord och ingredienser när du " +"redigerar och importerar recept." #: .\cookbook\forms.py:342 msgid "" "Fields to search ignoring accents. Selecting this option can improve or " "degrade search quality depending on language" msgstr "" +"Fält att söka medan man ignorerar accenter. Val av detta alternativ kan " +"förbättra eller försämra sökkvaliteten beroende på språk" #: .\cookbook\forms.py:343 msgid "" "Fields to search for partial matches. (e.g. searching for 'Pie' will return " "'pie' and 'piece' and 'soapie')" msgstr "" +"Fält att söka efter delvisa matchningar. (t.ex. att söka efter 'Pie' kommer " +"att returnera 'pie' och 'piece' och 'soapie')" #: .\cookbook\forms.py:344 msgid "" "Fields to search for beginning of word matches. (e.g. searching for 'sa' " "will return 'salad' and 'sandwich')" msgstr "" +"Fält att söka för matchningar i början av ord. (t.ex. att söka efter 'sa' " +"kommer att returnera 'salad' och 'sandwich')" #: .\cookbook\forms.py:345 msgid "" "Fields to 'fuzzy' search. (e.g. searching for 'recpie' will find 'recipe'.) " "Note: this option will conflict with 'web' and 'raw' methods of search." msgstr "" +"Fält för 'fuzzy'-sökning. (t.ex. att söka efter 'recpie' kommer att hitta " +"'recipe'.Observera: detta alternativet kommer att komma i konflikt med " +"sökmetoderna 'web' och 'raw'.)" #: .\cookbook\forms.py:346 msgid "" "Fields to full text search. Note: 'web', 'phrase', and 'raw' search methods " "only function with fulltext fields." msgstr "" +"Fält för fulltextsökning. Observera: Sökmetoderna 'web', 'phrase' och 'raw' " +"fungerar endast med fulltextfält." #: .\cookbook\forms.py:350 -#, fuzzy -#| msgid "Search" msgid "Search Method" -msgstr "Sök" +msgstr "Sök Metod" #: .\cookbook\forms.py:350 msgid "Fuzzy Lookups" @@ -211,22 +224,20 @@ msgid "Starts With" msgstr "Börjar med" #: .\cookbook\forms.py:351 -#, fuzzy -#| msgid "Search" msgid "Fuzzy Search" -msgstr "Sök" +msgstr "Fuzzy Sök" #: .\cookbook\forms.py:351 -#, fuzzy -#| msgid "Text" msgid "Full Text" -msgstr "Text" +msgstr "Hel Text" #: .\cookbook\helper\AllAuthCustomAdapter.py:41 msgid "" "In order to prevent spam, the requested email was not send. Please wait a " "few minutes and try again." msgstr "" +"För att förhindra spam, så skickades inte den begärda e-posten. Vänta några " +"minuter och försök igen." #: .\cookbook\helper\permission_helper.py:164 #: .\cookbook\helper\permission_helper.py:187 .\cookbook\views\views.py:117 @@ -255,19 +266,19 @@ msgstr "Du kan inte interagera med detta objekt för att det ägs inte av dig!" #: .\cookbook\helper\permission_helper.py:402 msgid "You have reached the maximum number of recipes for your space." -msgstr "" +msgstr "Du har nått det maximala antalet recept för din utrymme." #: .\cookbook\helper\permission_helper.py:414 msgid "You have more users than allowed in your space." -msgstr "" +msgstr "Du har mer användare än tillåtet för ditt utrymme." #: .\cookbook\helper\recipe_url_import.py:310 msgid "reverse rotation" -msgstr "" +msgstr "återvänd rotering" #: .\cookbook\helper\recipe_url_import.py:311 msgid "careful rotation" -msgstr "" +msgstr "försiktig rotering" #: .\cookbook\helper\recipe_url_import.py:312 msgid "knead" @@ -291,7 +302,7 @@ msgstr "sous-vide" #: .\cookbook\helper\shopping_helper.py:150 msgid "You must supply a servings size" -msgstr "" +msgstr "Du måste ange en portionstorlek" #: .\cookbook\helper\template_helper.py:95 #: .\cookbook\helper\template_helper.py:97 @@ -305,7 +316,7 @@ msgstr "Favorit" #: .\cookbook\integration\copymethat.py:50 msgid "I made this" -msgstr "" +msgstr "Jag gjorde den här" #: .\cookbook\integration\integration.py:209 msgid "" @@ -319,6 +330,8 @@ msgid "" "An unexpected error occurred during the import. Please make sure you have " "uploaded a valid file." msgstr "" +"Ett oväntat fel uppstod under importeringen. Se till att du har laddat upp " +"en giltig fil." #: .\cookbook\integration\integration.py:217 msgid "The following recipes were ignored because they already existed:" @@ -330,10 +343,8 @@ msgid "Imported %s recipes." msgstr "Importerade %s recept." #: .\cookbook\integration\openeats.py:28 -#, fuzzy -#| msgid "Recipe Home" msgid "Recipe source:" -msgstr "Recept Hem" +msgstr "Recept källa:" #: .\cookbook\integration\paprika.py:49 msgid "Notes" @@ -374,23 +385,25 @@ msgstr "Sektion" #: .\cookbook\management\commands\fix_duplicate_properties.py:15 msgid "Fixes foods with " -msgstr "" +msgstr "Korrigerar livsmedel med " #: .\cookbook\management\commands\rebuildindex.py:14 msgid "Rebuilds full text search index on Recipe" -msgstr "" +msgstr "Återuppbygger fulltextsökningens index för Recept" #: .\cookbook\management\commands\rebuildindex.py:18 msgid "Only Postgresql databases use full text search, no index to rebuild" msgstr "" +"Endast Postgresql-databaser använder fulltextsökning, inget index att " +"återuppbygga med" #: .\cookbook\management\commands\rebuildindex.py:29 msgid "Recipe index rebuild complete." -msgstr "" +msgstr "Recept index återbyggning färdig." #: .\cookbook\management\commands\rebuildindex.py:31 msgid "Recipe index rebuild failed." -msgstr "" +msgstr "Recept index återbyggning misslyckades." #: .\cookbook\migrations\0047_auto_20200602_1133.py:14 msgid "Breakfast" @@ -439,6 +452,8 @@ msgid "" "Maximum file storage for space in MB. 0 for unlimited, -1 to disable file " "upload." msgstr "" +"Maximal lagringsutrymme för utrymme i MB. 0 för obegränsad, -1 för att " +"inaktivera filuppladdning." #: .\cookbook\models.py:454 .\cookbook\templates\search.html:7 #: .\cookbook\templates\settings.html:18 @@ -462,7 +477,7 @@ msgstr "Handla" #: .\cookbook\models.py:752 msgid " is part of a recipe step and cannot be deleted" -msgstr "" +msgstr " är en del av ett receptsteg och kan inte tas bort" #: .\cookbook\models.py:918 msgid "Nutrition" @@ -501,34 +516,24 @@ msgid "Food Alias" msgstr "Alternativt namn för mat" #: .\cookbook\models.py:1468 -#, fuzzy -#| msgid "Units" msgid "Unit Alias" -msgstr "Enheter" +msgstr "Enhetsalias" #: .\cookbook\models.py:1469 -#, fuzzy -#| msgid "Keywords" msgid "Keyword Alias" -msgstr "Nyckelord" +msgstr "Nyckelordsalias" #: .\cookbook\models.py:1470 -#, fuzzy -#| msgid "Description" msgid "Description Replace" -msgstr "Beskrivning" +msgstr "Beskrivning Ersätt" #: .\cookbook\models.py:1471 -#, fuzzy -#| msgid "Instructions" msgid "Instruction Replace" -msgstr "Instruktioner" +msgstr "Instruktioner Ersätt" #: .\cookbook\models.py:1472 -#, fuzzy -#| msgid "New Unit" msgid "Never Unit" -msgstr "Ny enhet" +msgstr "Aldrig Enhet" #: .\cookbook\models.py:1473 msgid "Transpose Words" @@ -539,10 +544,8 @@ msgid "Food Replace" msgstr "Ersätt mat" #: .\cookbook\models.py:1475 -#, fuzzy -#| msgid "Edit Recipe" msgid "Unit Replace" -msgstr "Redigera recept" +msgstr "Ersätt Enhet" #: .\cookbook\models.py:1476 msgid "Name Replace" From e6eacc48d6b2560bf9651936c8e763e26cb5f908 Mon Sep 17 00:00:00 2001 From: Mikhail Epifanov Date: Tue, 17 Sep 2024 22:25:08 +0200 Subject: [PATCH 5/7] update code so it also works in DEBUG=false --- cookbook/apps.py | 16 ++++++---------- cookbook/connectors/connector_manager.py | 12 +++++++++++- cookbook/connectors/homeassistant.py | 8 +++++--- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/cookbook/apps.py b/cookbook/apps.py index 63b8296e8..c3fa140a5 100644 --- a/cookbook/apps.py +++ b/cookbook/apps.py @@ -16,15 +16,11 @@ class CookbookConfig(AppConfig): import cookbook.signals # noqa if not settings.DISABLE_EXTERNAL_CONNECTORS: - try: - from cookbook.connectors.connector_manager import ConnectorManager # Needs to be here to prevent loading race condition of oauth2 modules in models.py - handler = ConnectorManager() - post_save.connect(handler, dispatch_uid="connector_manager") - post_delete.connect(handler, dispatch_uid="connector_manager") - except Exception as e: - traceback.print_exc() - print('Failed to initialize connectors') - pass + from cookbook.connectors.connector_manager import ConnectorManager # Needs to be here to prevent loading race condition of oauth2 modules in models.py + handler = ConnectorManager() + post_save.connect(handler, dispatch_uid="post_save-connector_manager") + post_delete.connect(handler, dispatch_uid="post_delete-connector_manager") + # if not settings.DISABLE_TREE_FIX_STARTUP: # # when starting up run fix_tree to: # # a) make sure that nodes are sorted when switching between sort modes @@ -45,4 +41,4 @@ class CookbookConfig(AppConfig): # except Exception: # if DEBUG: # traceback.print_exc() - # pass # dont break startup just because fix could not run, need to investigate cases when this happens + # pass # dont break startup just because fix could not run, need to investigate cases when this happens \ No newline at end of file diff --git a/cookbook/connectors/connector_manager.py b/cookbook/connectors/connector_manager.py index 487aeca0d..4c99281a4 100644 --- a/cookbook/connectors/connector_manager.py +++ b/cookbook/connectors/connector_manager.py @@ -31,6 +31,15 @@ class Work: actionType: ActionType +class Singleton(type): + _instances = {} + + def __call__(cls, *args, **kwargs): + if cls not in cls._instances: + cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) + return cls._instances[cls] + + # The way ConnectionManager works is as follows: # 1. On init, it starts a worker & creates a queue for 'Work' # 2. Then any time its called, it verifies the type of action (create/update/delete) and if the item is of interest, pushes the Work (non-blocking) to the queue. @@ -39,7 +48,8 @@ class Work: # 3.2 If work is of type REGISTERED_CLASSES, it asynchronously fires of all connectors and wait for them to finish (runtime should depend on the 'slowest' connector) # 4. Work is marked as consumed, and next entry of the queue is consumed. # Each 'Work' is processed in sequential by the worker, so the throughput is about [workers * the slowest connector] -class ConnectorManager: +# The Singleton class is used for ConnectorManager to have a self-reference and so Python does not garbage collect it +class ConnectorManager(metaclass=Singleton): _logger: Logger _queue: queue.Queue _listening_to_classes = REGISTERED_CLASSES | ConnectorConfig diff --git a/cookbook/connectors/homeassistant.py b/cookbook/connectors/homeassistant.py index 3268c4cb1..75d283d5e 100644 --- a/cookbook/connectors/homeassistant.py +++ b/cookbook/connectors/homeassistant.py @@ -13,6 +13,8 @@ class HomeAssistant(Connector): _config: ConnectorConfig _logger: Logger + _required_foreign_keys = ("food", "unit", "created_by") + def __init__(self, config: ConnectorConfig): if not config.token or not config.url or not config.todo_entity: raise ValueError("config for HomeAssistantConnector in incomplete") @@ -38,7 +40,7 @@ class HomeAssistant(Connector): item, description = _format_shopping_list_entry(shopping_list_entry) - self._logger.debug(f"adding {item=}") + self._logger.debug(f"adding {item=} with {description=} to {self._config.todo_entity}") data = { "entity_id": self._config.todo_entity, @@ -60,14 +62,14 @@ class HomeAssistant(Connector): if not self._config.on_shopping_list_entry_deleted_enabled: return - if not hasattr(shopping_list_entry._state.fields_cache, "food"): + if not all(k in shopping_list_entry._state.fields_cache for k in self._required_foreign_keys): # Sometimes the food foreign key is not loaded, and we cant load it from an async process self._logger.debug("required property was not present in ShoppingListEntry") return item, _ = _format_shopping_list_entry(shopping_list_entry) - self._logger.debug(f"removing {item=}") + self._logger.debug(f"removing {item=} from {self._config.todo_entity}") data = { "entity_id": self._config.todo_entity, From 5478b7d550910ed5549d8c3f19c5b5c970e3eaf3 Mon Sep 17 00:00:00 2001 From: Georgii Bogdanov Date: Sat, 21 Sep 2024 21:03:30 +0000 Subject: [PATCH 6/7] Translated using Weblate (Russian) Currently translated at 62.9% (359 of 570 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/ru/ --- vue/src/locales/ru.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vue/src/locales/ru.json b/vue/src/locales/ru.json index 343e549b7..285f18d51 100644 --- a/vue/src/locales/ru.json +++ b/vue/src/locales/ru.json @@ -1,5 +1,5 @@ { - "warning_feature_beta": "Данный функционал находится в стадии BETA (тестируется). Возможны баги и серьезные изменения функционала в будущем.", + "warning_feature_beta": "Данный функционал находится в стадии бета-тестирования. Возможны баги и серьезные изменения функционала в будущем.", "err_fetching_resource": "Ошибка при загрузке продукта!", "err_creating_resource": "Ошибка при создании продукта!", "err_updating_resource": "Ошибка при редактировании продукта!", @@ -359,5 +359,7 @@ "Auto_Sort": "Автоматическая сортировка", "Amount": "Количество", "per_serving": "за порцию", - "Instruction_Replace": "Изменить Инструкцию" + "Instruction_Replace": "Изменить Инструкцию", + "recipe_property_info": "Вы также можете добавить свойства к продуктам, чтобы автоматически рассчитывать их на основе вашего рецепта!", + "open_data_help_text": "Проект Tandoor Open Data предоставляет предоставленные сообществом данные для Tandoor. Это поле заполняется автоматически при импорте и допускает обновления в будущем." } From 72c638ca6fb54720fe82801f3e24ccf3614f8aca Mon Sep 17 00:00:00 2001 From: Emmker Date: Sun, 22 Sep 2024 17:58:18 +0000 Subject: [PATCH 7/7] Translated using Weblate (Greek) Currently translated at 99.8% (569 of 570 strings) Translation: Tandoor/Recipes Frontend Translate-URL: http://translate.tandoor.dev/projects/tandoor/recipes-frontend/el/ --- vue/src/locales/el.json | 53 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/vue/src/locales/el.json b/vue/src/locales/el.json index a82e74141..c9e77a3cb 100644 --- a/vue/src/locales/el.json +++ b/vue/src/locales/el.json @@ -517,5 +517,56 @@ "imperial_gallon": "αυτοκρατορικό γαλόνι [imp gal] (Ηνωμένο Βασίλειο, όγκος)", "imperial_tbsp": "αυτοκρατορικό κουτάλι της σούπας [imp tbsp] (Ηνωμένο Βασίλειο, όγκος)", "Choose_Category": "Επιλογή κατηγορίας", - "Back": "Πίσω" + "Back": "Πίσω", + "Calculator": "Υπολογιστής", + "us_cup": "φλιτζάνι (ΗΠΑ, όγκος)", + "Created": "Δημιουργήθηκε", + "Logo": "Λογότυπο", + "Nav_Text_Mode_Help": "Συμπεριφέρεται διαφορετικά για κάθε θέμα.", + "Properties_Food_Amount": "Ιδιότητες Ποσότητα Φαγητού", + "show_step_ingredients": "Εμφάνιση των συστατικών του βήματος", + "make_now_count": "Το πολύ να λείπουν συστατικά", + "Error": "Σφάλμα", + "Nav_Text_Mode": "Λειτουγία κειμένου πλοήγησης", + "Input": "Εισαγογή", + "Undo": "Ανέρεση", + "NoMoreUndo": "Δεν υπάρχουν αλλαγές για ανέρεση.", + "Delete_All": "Διαγραφή όλων", + "created_by": "Δημιουργήθηκε από", + "CustomLogoHelp": "Ανεβάστε τετράγωνες εικόνες σε διαφορετικά μεγέθη για αλλαγή σε λογότυπο στην καρτέλα του προγράμματος περιήγησης και στο εγκατεστημένο Web App.", + "CustomNavLogoHelp": "Μεταφορτώστε μια εικόνα για χρήση ως λογότυπο της γραμμής πλοήγησης.", + "ShowRecentlyCompleted": "Πρόσφατα αντικείμενα που ολοκληρώθηκαν", + "ShoppingBackgroundSyncWarning": "Κακό δίκτυο, αναμονή συγχρονισμού...", + "Name_Replace": "Αντικατάσταση Ονόματος", + "Transpose_Words": "Μεταφορά λέξεων", + "err_importing_recipe": "Υπάρχει σφάλμα στην εισαγωγή της σύνταγης!", + "Properties_Food_Unit": "Ιδιότητες Μονάδα Φαγητού", + "show_step_ingredients_setting": "Εμφάνιση συστατικών δίπλα στα βήματα της συνταγής", + "show_step_ingredients_setting_help": "Προσθέστε τον πίνακα συστατικών δίπλα στα βήματα της συνταγής. Ισχύει κατά τη δημιουργία. Μπορεί να παρακαμφθεί στην προβολή επεξεργασίας συνταγής.", + "hide_step_ingredients": "Απόκρυψη των συστατικών του βήματος", + "property_type_fdc_hint": "Μόνο οι τύποι ιδιοτήτων με ταυτότητα FDC, μπορούν να τραβήξουν αυτόματα δεδομένα απο την βάση δεδομένων του FDC", + "FDC_Search": "Αναζήτηση FDC", + "StartDate": "Ημερομηνία Έναρξης", + "CustomImageHelp": "Ανεβάστε μια εικόνα για να εμφανίζεται στην επισκόπηση χώρου", + "CustomThemeHelp": "Αντικαταστήστε τα στυλ του επιλεγμένου θέματος μεταφορτώνοντας ένα προσαρμοσμένο αρχείο CSS.", + "CustomTheme": "Προσαρμοσμένο Θέμα", + "Shopping_input_placeholder": "π.χ. Πατάτα/100 Πατάτες/100 γρ Πατατες", + "Property_Editor": "Επεξεργαστής Ιδιοτήτων", + "CustomLogos": "Προσαρμοσμένα λογότυπα", + "Updated": "Επεξεργάστηκε", + "Unchanged": "Αμετάβλητο", + "Show_Logo": "Εμφάνιση λογότυπου", + "Show_Logo_Help": "Εμφάνιση λογότυπου του Tandoor ή του space στη γραμμή πλοήγησης.", + "Space_Cosmetic_Settings": "Ορισμένες ρυθμίσεις εμφάνισης μπορούν να αλλάξουν από τους διαχειριστές του χώρου και θα παρακάμψουν τις ρυθμίσεις πελάτη για αυτόν τον χώρο.", + "show_ingredients_table": "Εμφάνιση ένός πίνακα με τα συστατικά δίπλα στο κείμενο του βήματος", + "Enable": "Ενεργοποίηση", + "Alignment": "Ευθυγράμμιση", + "FDC_ID_help": "Ταυτότητα βάσης δεδομένων FDC", + "EndDate": "Ημερομηνία Λήξης", + "FDC_ID": "Ταυτότητα FDC", + "OrderInformation": "Τα αντικείμενα ταξινομούνται από μικρό σε μεγάλο αριθμό.", + "Never_Unit": "Ποτέ Μονάδα", + "DefaultPage": "Προεπιλεγμένη σελίδα", + "Food_Replace": "Αντικατάσταση Φαγητού", + "Unit_Replace": "Αντικατάσταση Μονάδας" }