Skip to content

Commit 4c0ace1

Browse files
committed
Merge branch 'develop'
2 parents 1bfe5bb + cae26e7 commit 4c0ace1

File tree

27 files changed

+511
-423
lines changed

27 files changed

+511
-423
lines changed

cookbook/apps.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,11 @@ def ready(self):
1616
import cookbook.signals # noqa
1717

1818
if not settings.DISABLE_EXTERNAL_CONNECTORS:
19-
try:
20-
from cookbook.connectors.connector_manager import ConnectorManager # Needs to be here to prevent loading race condition of oauth2 modules in models.py
21-
handler = ConnectorManager()
22-
post_save.connect(handler, dispatch_uid="connector_manager")
23-
post_delete.connect(handler, dispatch_uid="connector_manager")
24-
except Exception as e:
25-
traceback.print_exc()
26-
print('Failed to initialize connectors')
27-
pass
19+
from cookbook.connectors.connector_manager import ConnectorManager # Needs to be here to prevent loading race condition of oauth2 modules in models.py
20+
handler = ConnectorManager()
21+
post_save.connect(handler, dispatch_uid="post_save-connector_manager")
22+
post_delete.connect(handler, dispatch_uid="post_delete-connector_manager")
23+
2824
# if not settings.DISABLE_TREE_FIX_STARTUP:
2925
# # when starting up run fix_tree to:
3026
# # a) make sure that nodes are sorted when switching between sort modes
@@ -45,4 +41,4 @@ def ready(self):
4541
# except Exception:
4642
# if DEBUG:
4743
# traceback.print_exc()
48-
# pass # dont break startup just because fix could not run, need to investigate cases when this happens
44+
# pass # dont break startup just because fix could not run, need to investigate cases when this happens

cookbook/connectors/connector_manager.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ class Work:
3131
actionType: ActionType
3232

3333

34+
class Singleton(type):
35+
_instances = {}
36+
37+
def __call__(cls, *args, **kwargs):
38+
if cls not in cls._instances:
39+
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
40+
return cls._instances[cls]
41+
42+
3443
# The way ConnectionManager works is as follows:
3544
# 1. On init, it starts a worker & creates a queue for 'Work'
3645
# 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:
3948
# 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)
4049
# 4. Work is marked as consumed, and next entry of the queue is consumed.
4150
# Each 'Work' is processed in sequential by the worker, so the throughput is about [workers * the slowest connector]
42-
class ConnectorManager:
51+
# The Singleton class is used for ConnectorManager to have a self-reference and so Python does not garbage collect it
52+
class ConnectorManager(metaclass=Singleton):
4353
_logger: Logger
4454
_queue: queue.Queue
4555
_listening_to_classes = REGISTERED_CLASSES | ConnectorConfig

cookbook/connectors/homeassistant.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from typing import Dict, Tuple
44
from urllib.parse import urljoin
55

6-
from aiohttp import ClientError, request
6+
from aiohttp import request, ClientResponseError
77

88
from cookbook.connectors.connector import Connector
99
from cookbook.models import ShoppingListEntry, ConnectorConfig, Space
@@ -13,6 +13,8 @@ class HomeAssistant(Connector):
1313
_config: ConnectorConfig
1414
_logger: Logger
1515

16+
_required_foreign_keys = ("food", "unit", "created_by")
17+
1618
def __init__(self, config: ConnectorConfig):
1719
if not config.token or not config.url or not config.todo_entity:
1820
raise ValueError("config for HomeAssistantConnector in incomplete")
@@ -38,18 +40,20 @@ async def on_shopping_list_entry_created(self, space: Space, shopping_list_entry
3840

3941
item, description = _format_shopping_list_entry(shopping_list_entry)
4042

41-
self._logger.debug(f"adding {item=}")
43+
self._logger.debug(f"adding {item=} with {description=} to {self._config.todo_entity}")
4244

4345
data = {
4446
"entity_id": self._config.todo_entity,
4547
"item": item,
46-
"description": description,
4748
}
4849

50+
if self._config.supports_description_field:
51+
data["description"] = description
52+
4953
try:
5054
await self.homeassistant_api_call("POST", "services/todo/add_item", data)
51-
except ClientError as err:
52-
self._logger.warning(f"received an exception from the api: {err=}, {type(err)=}")
55+
except ClientResponseError as err:
56+
self._logger.warning(f"received an exception from the api: {err.request_info.url=}, {err.request_info.method=}, {err.status=}, {err.message=}, {type(err)=}")
5357

5458
async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
5559
if not self._config.on_shopping_list_entry_updated_enabled:
@@ -60,14 +64,14 @@ async def on_shopping_list_entry_deleted(self, space: Space, shopping_list_entry
6064
if not self._config.on_shopping_list_entry_deleted_enabled:
6165
return
6266

63-
if not hasattr(shopping_list_entry._state.fields_cache, "food"):
67+
if not all(k in shopping_list_entry._state.fields_cache for k in self._required_foreign_keys):
6468
# Sometimes the food foreign key is not loaded, and we cant load it from an async process
6569
self._logger.debug("required property was not present in ShoppingListEntry")
6670
return
6771

6872
item, _ = _format_shopping_list_entry(shopping_list_entry)
6973

70-
self._logger.debug(f"removing {item=}")
74+
self._logger.debug(f"removing {item=} from {self._config.todo_entity}")
7175

7276
data = {
7377
"entity_id": self._config.todo_entity,
@@ -76,9 +80,9 @@ async def on_shopping_list_entry_deleted(self, space: Space, shopping_list_entry
7680

7781
try:
7882
await self.homeassistant_api_call("POST", "services/todo/remove_item", data)
79-
except ClientError as err:
83+
except ClientResponseError as err:
8084
# This error will always trigger if the item is not present/found
81-
self._logger.debug(f"received an exception from the api: {err=}, {type(err)=}")
85+
self._logger.debug(f"received an exception from the api: {err.request_info.url=}, {err.request_info.method=}, {err.status=}, {err.message=}, {type(err)=}")
8286

8387
async def close(self) -> None:
8488
pass

cookbook/forms.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ class ConnectorConfigForm(forms.ModelForm):
182182
required=False,
183183
)
184184

185+
supports_description_field = forms.BooleanField(
186+
help_text="Does the connector todo entity support the description field",
187+
initial=True,
188+
required=False,
189+
)
190+
185191
update_token = forms.CharField(
186192
widget=forms.TextInput(attrs={'autocomplete': 'update-token', 'type': 'password'}),
187193
required=False,
@@ -198,7 +204,7 @@ class Meta:
198204

199205
fields = (
200206
'name', 'type', 'enabled', 'on_shopping_list_entry_created_enabled', 'on_shopping_list_entry_updated_enabled',
201-
'on_shopping_list_entry_deleted_enabled', 'url', 'todo_entity',
207+
'on_shopping_list_entry_deleted_enabled', 'supports_description_field', 'url', 'todo_entity',
202208
)
203209

204210
help_texts = {

cookbook/helper/recipe_url_import.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ def get_from_scraper(scrape, request):
2828
source_url = scrape.url
2929
except Exception:
3030
pass
31-
if source_url:
31+
if source_url == "https://urlnotfound.none" or not source_url:
32+
recipe_json['source_url'] = ''
33+
else:
3234
recipe_json['source_url'] = source_url
3335
try:
3436
keywords.append(source_url.replace('http://', '').replace('https://', '').split('/')[0])

cookbook/locale/de/LC_MESSAGES/django.po

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ msgstr ""
1515
"Project-Id-Version: PACKAGE VERSION\n"
1616
"Report-Msgid-Bugs-To: \n"
1717
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
18-
"PO-Revision-Date: 2024-07-31 13:05+0000\n"
19-
"Last-Translator: vabene1111 <[email protected]>\n"
20-
"Language-Team: German <http://translate.tandoor.dev/projects/tandoor/recipes-"
21-
"backend/de/>\n"
18+
"PO-Revision-Date: 2024-09-27 13:58+0000\n"
19+
"Last-Translator: supaeasy <[email protected]>\n"
20+
"Language-Team: German <http://translate.tandoor.dev/projects/tandoor/"
21+
"recipes-backend/de/>\n"
2222
"Language: de\n"
2323
"MIME-Version: 1.0\n"
2424
"Content-Type: text/plain; charset=UTF-8\n"
@@ -478,7 +478,7 @@ msgstr "Essensplan"
478478
#: .\cookbook\models.py:456 .\cookbook\templates\base.html:122
479479
#: .\cookbook\views\views.py:459
480480
msgid "Books"
481-
msgstr "Bücher"
481+
msgstr "Kochbücher"
482482

483483
#: .\cookbook\models.py:457 .\cookbook\templates\base.html:118
484484
#: .\cookbook\views\views.py:460
@@ -542,10 +542,8 @@ msgid "Instruction Replace"
542542
msgstr "Anleitung ersetzen"
543543

544544
#: .\cookbook\models.py:1472
545-
#, fuzzy
546-
#| msgid "New Unit"
547545
msgid "Never Unit"
548-
msgstr "Neue Einheit"
546+
msgstr "Nie Einheit"
549547

550548
#: .\cookbook\models.py:1473
551549
msgid "Transpose Words"
@@ -2143,7 +2141,7 @@ msgstr ""
21432141

21442142
#: .\cookbook\templates\system.html:86
21452143
msgid "Allowed Hosts"
2146-
msgstr ""
2144+
msgstr "Erlaubte Hosts"
21472145

21482146
#: .\cookbook\templates\system.html:90
21492147
msgid ""
@@ -2153,6 +2151,11 @@ msgid ""
21532151
"this.\n"
21542152
" "
21552153
msgstr ""
2154+
"\n"
2155+
" Die erlaubten Hosts sind so konfiguriert, dass sie jeden Host "
2156+
"erlauben. Das mag in einigen Fällen in Ordnung sein, sollte aber im "
2157+
"Regelfall vermieden werden. Bitte lies in der Dokumentation dazu nach.\n"
2158+
" "
21562159

21572160
#: .\cookbook\templates\system.html:97
21582161
msgid "Database"
@@ -2504,16 +2507,12 @@ msgid "Filter for entries with the given recipe"
25042507
msgstr "Filter für Einträge mit dem angegebenen Rezept"
25052508

25062509
#: .\cookbook\views\api.py:1292
2507-
#, fuzzy
2508-
#| msgid ""
2509-
#| "Returns the shopping list entry with a primary key of id. Multiple "
2510-
#| "values allowed."
25112510
msgid ""
25122511
"Return the Automations matching the automation type. Multiple values "
25132512
"allowed."
25142513
msgstr ""
2515-
"Zeigt denjenigen Eintrag auf der Einkaufliste mit der angegebenen ID. Kann "
2516-
"mehrfach angegeben werden."
2514+
"Zeigt Automationen, die dem Automationstyp entsprechen. Kann mehrfach "
2515+
"angegeben werden."
25172516

25182517
#: .\cookbook\views\api.py:1415
25192518
msgid "Nothing to do."
@@ -2582,10 +2581,8 @@ msgstr ""
25822581
"Monitor verwendet wird."
25832582

25842583
#: .\cookbook\views\delete.py:135
2585-
#, fuzzy
2586-
#| msgid "Storage Backend"
25872584
msgid "Connectors Config Backend"
2588-
msgstr "Speicherquelle"
2585+
msgstr "Backendkonfiguration für Konnektoren"
25892586

25902587
#: .\cookbook\views\delete.py:157
25912588
msgid "Invite Link"
@@ -2644,10 +2641,8 @@ msgid "Shopping List"
26442641
msgstr "Einkaufsliste"
26452642

26462643
#: .\cookbook\views\lists.py:77 .\cookbook\views\new.py:98
2647-
#, fuzzy
2648-
#| msgid "Storage Backend"
26492644
msgid "Connector Config Backend"
2650-
msgstr "Speicherquelle"
2645+
msgstr "Backendkonfiguration für Konnektoren"
26512646

26522647
#: .\cookbook\views\lists.py:91
26532648
msgid "Invite Links"
@@ -2743,7 +2738,7 @@ msgstr "Sie verwenden PostgreSQL %(v1)s. PostgreSQL %(v2)s wird empfohlen"
27432738

27442739
#: .\cookbook\views\views.py:313
27452740
msgid "Unable to determine PostgreSQL version."
2746-
msgstr ""
2741+
msgstr "PostgreSQL version konnte nicht erkannt werden."
27472742

27482743
#: .\cookbook\views\views.py:317
27492744
msgid ""
@@ -2755,18 +2750,14 @@ msgstr ""
27552750
"PostgreSQL-Datenbanken funktionieren."
27562751

27572752
#: .\cookbook\views\views.py:360
2758-
#, fuzzy
2759-
#| msgid ""
2760-
#| "The setup page can only be used to create the first user! If you have "
2761-
#| "forgotten your superuser credentials please consult the django "
2762-
#| "documentation on how to reset passwords."
27632753
msgid ""
27642754
"The setup page can only be used to create the first "
27652755
"user! If you have forgotten your superuser credentials "
27662756
"please consult the django documentation on how to reset passwords."
27672757
msgstr ""
2768-
"Die Setup-Seite kann nur für den ersten Nutzer verwendet werden. Zum "
2769-
"Zurücksetzen von Passwörtern bitte der Django-Dokumentation folgen."
2758+
"Die Setup-Seite kann nur für den ersten Nutzer verwendet "
2759+
"werden. Falls du die Superuser Logindaten vergessen "
2760+
"hast, folge bitte der Django-Dokumentation um Passwörter zurückzusetzen."
27702761

27712762
#: .\cookbook\views\views.py:369
27722763
msgid "Passwords dont match!"

cookbook/locale/el/LC_MESSAGES/django.po

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ msgstr ""
88
"Project-Id-Version: PACKAGE VERSION\n"
99
"Report-Msgid-Bugs-To: \n"
1010
"POT-Creation-Date: 2024-08-01 15:04+0200\n"
11-
"PO-Revision-Date: 2023-08-21 09:19+0000\n"
12-
"Last-Translator: Theodoros Grammenos <teogramm@outlook.com>\n"
13-
"Language-Team: Greek <http://translate.tandoor.dev/projects/tandoor/recipes-"
14-
"backend/el/>\n"
11+
"PO-Revision-Date: 2024-09-23 21:58+0000\n"
12+
"Last-Translator: Emmker <emmker@gmail.com>\n"
13+
"Language-Team: Greek <http://translate.tandoor.dev/projects/tandoor/"
14+
"recipes-backend/el/>\n"
1515
"Language: el\n"
1616
"MIME-Version: 1.0\n"
1717
"Content-Type: text/plain; charset=UTF-8\n"
1818
"Content-Transfer-Encoding: 8bit\n"
1919
"Plural-Forms: nplurals=2; plural=n != 1;\n"
20-
"X-Generator: Weblate 4.15\n"
20+
"X-Generator: Weblate 5.6.2\n"
2121

2222
#: .\cookbook\forms.py:45
2323
msgid ""
@@ -33,7 +33,7 @@ msgstr "Όνομα"
3333

3434
#: .\cookbook\forms.py:62 .\cookbook\forms.py:246 .\cookbook\views\lists.py:103
3535
msgid "Keywords"
36-
msgstr "Λέξεις κλειδιά"
36+
msgstr "Λέξεις Κλειδιά"
3737

3838
#: .\cookbook\forms.py:62
3939
msgid "Preparation time in minutes"
@@ -98,7 +98,7 @@ msgstr ""
9898

9999
#: .\cookbook\forms.py:205
100100
msgid "http://homeassistant.local:8123/api for example"
101-
msgstr ""
101+
msgstr "http://homeassistant.local:8123/api για παράδειγμα"
102102

103103
#: .\cookbook\forms.py:222 .\cookbook\views\edit.py:117
104104
msgid "Storage"

0 commit comments

Comments
 (0)