Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
vabene1111 committed Apr 4, 2024
2 parents 20e0c94 + d766927 commit b9e806b
Show file tree
Hide file tree
Showing 107 changed files with 368 additions and 32,096 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:

steps:
- uses: actions/checkout@v4
- uses: awalsh128/[email protected].1
- uses: awalsh128/[email protected].2
with:
packages: libsasl2-dev python3-dev libldap2-dev libssl-dev
version: 1.0
Expand Down
5 changes: 2 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"name": "Python Debugger: Django",
"type": "debugpy",
Expand All @@ -24,8 +23,8 @@
],
"console": "integratedTerminal",
"env": {
"//comment": "coverage and pytest can't both be running at the same time",
"PYTEST_ADDOPTS": "--no-cov -n 2"
// coverage and pytest can't both be running at the same time
"PYTEST_ADDOPTS": "--no-cov"
},
"django": true,
"justMyCode": true
Expand Down
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg li
#Print all logs without buffering it.
ENV PYTHONUNBUFFERED 1

ENV DOCKER true

#This port will be used by gunicorn.
EXPOSE 8080

Expand Down Expand Up @@ -33,6 +35,12 @@ RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-de
#Copy project and execute it.
COPY . ./

# collect the static files
RUN /opt/recipes/venv/bin/python manage.py collectstatic_js_reverse
RUN /opt/recipes/venv/bin/python manage.py collectstatic --noinput
# copy the collected static files to a different location, so they can be moved into a potentially mounted volume
RUN mv /opt/recipes/staticfiles /opt/recipes/staticfiles-collect

# collect information from git repositories
RUN /opt/recipes/venv/bin/python version.py
# delete git repositories to reduce image size
Expand Down
17 changes: 13 additions & 4 deletions boot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,21 @@ echo "Migrating database"

python manage.py migrate

echo "Generating static files"
if [[ "${DOCKER}" == "true" ]]; then
echo "Copying cached static files from docker build"

python manage.py collectstatic_js_reverse
python manage.py collectstatic --noinput
mkdir -p /opt/recipes/staticfiles
rm -rf /opt/recipes/staticfiles/*
mv /opt/recipes/staticfiles-collect/* /opt/recipes/staticfiles
rm -rf /opt/recipes/staticfiles-collect
else
echo "Collecting static files, this may take a while..."

python manage.py collectstatic_js_reverse
python manage.py collectstatic --noinput

echo "Done"
echo "Done"
fi

chmod -R 755 /opt/recipes/mediafiles

Expand Down
74 changes: 46 additions & 28 deletions cookbook/connectors/homeassistant.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,53 @@
import logging
from logging import Logger
from typing import Dict, Tuple
from urllib.parse import urljoin

from homeassistant_api import Client, HomeassistantAPIError, Domain
from aiohttp import ClientError, request

from cookbook.connectors.connector import Connector
from cookbook.models import ShoppingListEntry, ConnectorConfig, Space


class HomeAssistant(Connector):
_domains_cache: dict[str, Domain]
_config: ConnectorConfig
_logger: Logger
_client: Client

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")

self._domains_cache = dict()
if config.url[-1] != "/":
config.url += "/"
self._config = config
self._logger = logging.getLogger("connector.HomeAssistant")
self._client = Client(self._config.url, self._config.token, async_cache_session=False, use_async=True)

async def homeassistant_api_call(self, method: str, path: str, data: Dict) -> str:
headers = {
"Authorization": f"Bearer {self._config.token}",
"Content-Type": "application/json"
}
async with request(method, urljoin(self._config.url, path), headers=headers, json=data) as response:
response.raise_for_status()
return await response.json()

async def on_shopping_list_entry_created(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
if not self._config.on_shopping_list_entry_created_enabled:
return

item, description = _format_shopping_list_entry(shopping_list_entry)

todo_domain = self._domains_cache.get('todo')
try:
if todo_domain is None:
todo_domain = await self._client.async_get_domain('todo')
self._domains_cache['todo'] = todo_domain
logging.debug(f"adding {item=} to {self._config.name}")

data = {
"entity_id": self._config.todo_entity,
"item": item,
"description": description,
}

logging.debug(f"pushing {item} to {self._config.name}")
await todo_domain.add_item(entity_id=self._config.todo_entity, item=item)
except HomeassistantAPIError as err:
try:
await self.homeassistant_api_call("POST", "services/todo/add_item", data)
except ClientError as err:
self._logger.warning(f"[HomeAssistant {self._config.name}] Received an exception from the api: {err=}, {type(err)=}")

async def on_shopping_list_entry_updated(self, space: Space, shopping_list_entry: ShoppingListEntry) -> None:
Expand All @@ -48,24 +59,31 @@ async def on_shopping_list_entry_deleted(self, space: Space, shopping_list_entry
if not self._config.on_shopping_list_entry_deleted_enabled:
return

item, description = _format_shopping_list_entry(shopping_list_entry)
if not hasattr(shopping_list_entry._state.fields_cache, "food"):
# 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

todo_domain = self._domains_cache.get('todo')
try:
if todo_domain is None:
todo_domain = await self._client.async_get_domain('todo')
self._domains_cache['todo'] = todo_domain
item, _ = _format_shopping_list_entry(shopping_list_entry)

logging.debug(f"deleting {item} from {self._config.name}")
await todo_domain.remove_item(entity_id=self._config.todo_entity, item=item)
except HomeassistantAPIError as err:
self._logger.warning(f"[HomeAssistant {self._config.name}] Received an exception from the api: {err=}, {type(err)=}")
logging.debug(f"removing {item=} from {self._config.name}")

data = {
"entity_id": self._config.todo_entity,
"item": item,
}

try:
await self.homeassistant_api_call("POST", "services/todo/remove_item", data)
except ClientError as err:
# This error will always trigger if the item is not present/found
self._logger.debug(f"[HomeAssistant {self._config.name}] Received an exception from the api: {err=}, {type(err)=}")

async def close(self) -> None:
await self._client.async_cache_session.close()
pass


def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry):
def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry) -> Tuple[str, str]:
item = shopping_list_entry.food.name
if shopping_list_entry.amount > 0:
item += f" ({shopping_list_entry.amount:.2f}".rstrip('0').rstrip('.')
Expand All @@ -76,10 +94,10 @@ def _format_shopping_list_entry(shopping_list_entry: ShoppingListEntry):
else:
item += ")"

description = "Imported by TandoorRecipes"
description = "From TandoorRecipes"
if shopping_list_entry.created_by.first_name and len(shopping_list_entry.created_by.first_name) > 0:
description += f", created by {shopping_list_entry.created_by.first_name}"
description += f", by {shopping_list_entry.created_by.first_name}"
else:
description += f", created by {shopping_list_entry.created_by.username}"
description += f", by {shopping_list_entry.created_by.username}"

return item, description
8 changes: 0 additions & 8 deletions cookbook/helper/CustomTestRunner.py

This file was deleted.

2 changes: 1 addition & 1 deletion cookbook/helper/property_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def calculate_recipe_properties(self, recipe):
# TODO move to central helper ? --> use defaultdict
@staticmethod
def add_or_create(d, key, value, food):
if key in d:
if key in d and d[key]['value']:
d[key]['value'] += value
else:
d[key] = {'id': food.id, 'food': food.name, 'value': value}
Expand Down
22 changes: 13 additions & 9 deletions cookbook/locale/es/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-03-21 14:39+0100\n"
"PO-Revision-Date: 2023-09-25 09:59+0000\n"
"Last-Translator: Matias Laporte <laportematias+weblate@gmail.com>\n"
"PO-Revision-Date: 2024-03-27 19:02+0000\n"
"Last-Translator: Axel Breiterman <axelbreiterman@gmail.com>\n"
"Language-Team: Spanish <http://translate.tandoor.dev/projects/tandoor/"
"recipes-backend/es/>\n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.15\n"
"X-Generator: Weblate 5.4.2\n"

#: .\cookbook\forms.py:45
msgid ""
Expand Down Expand Up @@ -97,14 +97,16 @@ msgid ""
"<a href=\"https://www.home-assistant.io/docs/authentication/#your-account-"
"profile\">Long Lived Access Token</a> for your HomeAssistant instance"
msgstr ""
"<a href=\"https://www.home-assistant.io/docs/authentication/#your-account-"
"profile\">Token de larga duración</a>para tu instancia de HomeAssistant"

#: .\cookbook\forms.py:193
msgid "Something like http://homeassistant.local:8123/api"
msgstr ""
msgstr "Algo similar a http://homeassistant.local:8123/api"

#: .\cookbook\forms.py:205
msgid "http://homeassistant.local:8123/api for example"
msgstr ""
msgstr "por ejemplo http://homeassistant.local:8123/api for example"

#: .\cookbook\forms.py:222 .\cookbook\views\edit.py:117
msgid "Storage"
Expand Down Expand Up @@ -279,7 +281,7 @@ msgstr "Ha alcanzado el número máximo de recetas para su espacio."

#: .\cookbook\helper\permission_helper.py:414
msgid "You have more users than allowed in your space."
msgstr ""
msgstr "Tenés mas usuarios que los permitidos en tu espacio"

#: .\cookbook\helper\recipe_url_import.py:304
#, fuzzy
Expand Down Expand Up @@ -309,7 +311,7 @@ msgstr "fermentar"

#: .\cookbook\helper\recipe_url_import.py:310
msgid "sous-vide"
msgstr ""
msgstr "sous-vide"

#: .\cookbook\helper\shopping_helper.py:150
msgid "You must supply a servings size"
Expand All @@ -318,7 +320,7 @@ msgstr "Debe proporcionar un tamaño de porción"
#: .\cookbook\helper\template_helper.py:95
#: .\cookbook\helper\template_helper.py:97
msgid "Could not parse template code."
msgstr ""
msgstr "No se pudo parsear el código de la planitlla."

#: .\cookbook\integration\copymethat.py:44
#: .\cookbook\integration\melarecipes.py:37
Expand All @@ -342,6 +344,8 @@ msgid ""
"An unexpected error occurred during the import. Please make sure you have "
"uploaded a valid file."
msgstr ""
"Ocurrió un error inesperado al importar. Por favor asegurate de haber subido "
"un archivo válido."

#: .\cookbook\integration\integration.py:217
msgid "The following recipes were ignored because they already existed:"
Expand Down Expand Up @@ -457,7 +461,7 @@ msgstr "Calorías"

#: .\cookbook\migrations\0190_auto_20230525_1506.py:20
msgid "kcal"
msgstr ""
msgstr "kcal"

#: .\cookbook\models.py:325
msgid ""
Expand Down
Loading

0 comments on commit b9e806b

Please sign in to comment.