diff --git a/Dockerfile-raspi b/Dockerfile-raspi index b1b57757e..15ce51d5f 100644 --- a/Dockerfile-raspi +++ b/Dockerfile-raspi @@ -2,7 +2,7 @@ FROM python:3.9-alpine3.15 #Install all dependencies. -RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg libwebp libxml2-dev libxslt-dev py-cryptography openldap +RUN apk add --no-cache postgresql-libs postgresql-client gettext zlib libjpeg libwebp libxml2-dev libxslt-dev py-cryptography openldap gcompat #Print all logs without buffering it. ENV PYTHONUNBUFFERED 1 @@ -15,19 +15,16 @@ RUN mkdir /opt/recipes WORKDIR /opt/recipes COPY requirements.txt ./ - RUN \ if [ `apk --print-arch` = "armv7" ]; then \ printf "[global]\nextra-index-url=https://www.piwheels.org/simple\n" > /etc/pip.conf ; \ fi - -RUN apk add --no-cache --virtual .build-deps gcc musl-dev postgresql-dev zlib-dev jpeg-dev libwebp-dev openssl-dev libffi-dev cargo openldap-dev python3-dev && \ +RUN apk add --no-cache --virtual .build-deps gcc musl-dev zlib-dev jpeg-dev libwebp-dev python3-dev && \ echo -n "INPUT ( libldap.so )" > /usr/lib/libldap_r.so && \ python -m venv venv && \ /opt/recipes/venv/bin/python -m pip install --upgrade pip && \ venv/bin/pip install wheel==0.37.1 && \ - venv/bin/pip install setuptools_rust==1.1.2 && \ - venv/bin/pip install -r requirements.txt --no-cache-dir &&\ + venv/bin/pip install -r requirements.txt --no-cache-dir --no-binary=Pillow && \ apk --purge del .build-deps #Copy project and execute it. diff --git a/cookbook/helper/recipe_html_import.py b/cookbook/helper/recipe_html_import.py index 7fa7beaf2..f78ccb79e 100644 --- a/cookbook/helper/recipe_html_import.py +++ b/cookbook/helper/recipe_html_import.py @@ -9,6 +9,8 @@ from recipe_scrapers._utils import get_host_name, normalize_string from cookbook.helper import recipe_url_import as helper from cookbook.helper.scrapers.scrapers import text_scraper +from recipe_scrapers import scrape_me +from recipe_scrapers._exceptions import NoSchemaFoundInWildMode def get_recipe_from_source(text, url, request): @@ -63,34 +65,41 @@ def get_recipe_from_source(text, url, request): html_data = [] images = [] text = unquote(text) + scrape = None - try: - parse_list.append(remove_graph(json.loads(text))) - if not url and 'url' in parse_list[0]: - url = parse_list[0]['url'] - scrape = text_scraper("", url=url) + if url: + try: + scrape = scrape_me(url_path=url, wild_mode=True) + except(NoSchemaFoundInWildMode): + pass + if not scrape: + try: + parse_list.append(remove_graph(json.loads(text))) + if not url and 'url' in parse_list[0]: + url = parse_list[0]['url'] + scrape = text_scraper("", url=url) - except JSONDecodeError: - soup = BeautifulSoup(text, "html.parser") - html_data = get_from_html(soup) - images += get_images_from_source(soup, url) - for el in soup.find_all('script', type='application/ld+json'): - el = remove_graph(el) - if not url and 'url' in el: - url = el['url'] - if type(el) == list: - for le in el: - parse_list.append(le) - elif type(el) == dict: - parse_list.append(el) - for el in soup.find_all(type='application/json'): - el = remove_graph(el) - if type(el) == list: - for le in el: - parse_list.append(le) - elif type(el) == dict: - parse_list.append(el) - scrape = text_scraper(text, url=url) + except JSONDecodeError: + soup = BeautifulSoup(text, "html.parser") + html_data = get_from_html(soup) + images += get_images_from_source(soup, url) + for el in soup.find_all('script', type='application/ld+json'): + el = remove_graph(el) + if not url and 'url' in el: + url = el['url'] + if type(el) == list: + for le in el: + parse_list.append(le) + elif type(el) == dict: + parse_list.append(el) + for el in soup.find_all(type='application/json'): + el = remove_graph(el) + if type(el) == list: + for le in el: + parse_list.append(le) + elif type(el) == dict: + parse_list.append(el) + scrape = text_scraper(text, url=url) recipe_json = helper.get_from_scraper(scrape, request) diff --git a/cookbook/helper/recipe_url_import.py b/cookbook/helper/recipe_url_import.py index 9ad34528e..0d8688b20 100644 --- a/cookbook/helper/recipe_url_import.py +++ b/cookbook/helper/recipe_url_import.py @@ -114,7 +114,14 @@ def get_from_scraper(scrape, request): except Exception: pass - if source_url := scrape.url: + try: + source_url = scrape.canonical_url() + except Exception: + try: + source_url = scrape.url + except Exception: + pass + if source_url: recipe_json['source_url'] = source_url try: keywords.append(source_url.replace('http://', '').replace('https://', '').split('/')[0]) @@ -129,9 +136,11 @@ def get_from_scraper(scrape, request): ingredient_parser = IngredientParser(request, True) recipe_json['steps'] = [] - - for i in parse_instructions(scrape.instructions()): - recipe_json['steps'].append({'instruction': i, 'ingredients': [], }) + try: + for i in parse_instructions(scrape.instructions()): + recipe_json['steps'].append({'instruction': i, 'ingredients': [], }) + except Exception: + pass if len(recipe_json['steps']) == 0: recipe_json['steps'].append({'instruction': '', 'ingredients': [], }) diff --git a/cookbook/helper/scrapers/scrapers.py b/cookbook/helper/scrapers/scrapers.py index 6d785a5ef..eb93cc2c2 100644 --- a/cookbook/helper/scrapers/scrapers.py +++ b/cookbook/helper/scrapers/scrapers.py @@ -1,6 +1,6 @@ from bs4 import BeautifulSoup from json import JSONDecodeError -from recipe_scrapers import SCRAPERS, get_host_name +from recipe_scrapers import SCRAPERS from recipe_scrapers._factory import SchemaScraperFactory from recipe_scrapers._schemaorg import SchemaOrg @@ -15,13 +15,7 @@ SCRAPERS.update(CUSTOM_SCRAPERS) def text_scraper(text, url=None): - domain = None - if url: - domain = get_host_name(url) - if domain in SCRAPERS: - scraper_class = SCRAPERS[domain] - else: - scraper_class = SchemaScraperFactory.SchemaScraper + scraper_class = SchemaScraperFactory.SchemaScraper class TextScraper(scraper_class): def __init__( diff --git a/cookbook/integration/paprika.py b/cookbook/integration/paprika.py index 9a82c4aa7..010783e3a 100644 --- a/cookbook/integration/paprika.py +++ b/cookbook/integration/paprika.py @@ -27,7 +27,7 @@ class Paprika(Integration): recipe.description = '' if len(recipe_json['description'].strip()) > 500 else recipe_json['description'].strip() try: - if 'servings' in recipe_json['servings']: + if 'servings' in recipe_json: recipe.servings = parse_servings(recipe_json['servings']) recipe.servings_text = parse_servings_text(recipe_json['servings']) diff --git a/cookbook/integration/plantoeat.py b/cookbook/integration/plantoeat.py index d1004f70c..b0ed72181 100644 --- a/cookbook/integration/plantoeat.py +++ b/cookbook/integration/plantoeat.py @@ -78,7 +78,11 @@ class Plantoeat(Integration): current_recipe = '' for fl in file.readlines(): - line = fl.decode("windows-1250") + try: + line = fl.decode("utf-8") + except UnicodeDecodeError: + line = fl.decode("windows-1250") + if line.startswith('--------------'): if current_recipe != '': recipe_list.append(current_recipe) diff --git a/cookbook/locale/bg/LC_MESSAGES/django.mo b/cookbook/locale/bg/LC_MESSAGES/django.mo new file mode 100644 index 000000000..c32ef729b Binary files /dev/null and b/cookbook/locale/bg/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/da/LC_MESSAGES/django.mo b/cookbook/locale/da/LC_MESSAGES/django.mo new file mode 100644 index 000000000..6a41d0845 Binary files /dev/null and b/cookbook/locale/da/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/de/LC_MESSAGES/django.mo b/cookbook/locale/de/LC_MESSAGES/django.mo index 31540b401..ca69d9d23 100644 Binary files a/cookbook/locale/de/LC_MESSAGES/django.mo and b/cookbook/locale/de/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/en/LC_MESSAGES/django.mo b/cookbook/locale/en/LC_MESSAGES/django.mo index c105e6f5a..71cbdf3e9 100644 Binary files a/cookbook/locale/en/LC_MESSAGES/django.mo and b/cookbook/locale/en/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/es/LC_MESSAGES/django.mo b/cookbook/locale/es/LC_MESSAGES/django.mo index 816625711..22c5b5a5f 100644 Binary files a/cookbook/locale/es/LC_MESSAGES/django.mo and b/cookbook/locale/es/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/fi/LC_MESSAGES/django.mo b/cookbook/locale/fi/LC_MESSAGES/django.mo index b9be440da..e2dcd751f 100644 Binary files a/cookbook/locale/fi/LC_MESSAGES/django.mo and b/cookbook/locale/fi/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/lv/LC_MESSAGES/django.mo b/cookbook/locale/lv/LC_MESSAGES/django.mo index 549d42409..1c622548c 100644 Binary files a/cookbook/locale/lv/LC_MESSAGES/django.mo and b/cookbook/locale/lv/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/nl/LC_MESSAGES/django.mo b/cookbook/locale/nl/LC_MESSAGES/django.mo index 3e47112e8..1737ecb6f 100644 Binary files a/cookbook/locale/nl/LC_MESSAGES/django.mo and b/cookbook/locale/nl/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/pt/LC_MESSAGES/django.mo b/cookbook/locale/pt/LC_MESSAGES/django.mo index 29ea99108..b57ca7660 100644 Binary files a/cookbook/locale/pt/LC_MESSAGES/django.mo and b/cookbook/locale/pt/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/rn/LC_MESSAGES/django.mo b/cookbook/locale/rn/LC_MESSAGES/django.mo index e1b8647a2..195f68023 100644 Binary files a/cookbook/locale/rn/LC_MESSAGES/django.mo and b/cookbook/locale/rn/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/sv/LC_MESSAGES/django.mo b/cookbook/locale/sv/LC_MESSAGES/django.mo index 5cdadd541..78852a15a 100644 Binary files a/cookbook/locale/sv/LC_MESSAGES/django.mo and b/cookbook/locale/sv/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/tr/LC_MESSAGES/django.mo b/cookbook/locale/tr/LC_MESSAGES/django.mo index 5a707dffc..94cbafa57 100644 Binary files a/cookbook/locale/tr/LC_MESSAGES/django.mo and b/cookbook/locale/tr/LC_MESSAGES/django.mo differ diff --git a/cookbook/locale/zh_CN/LC_MESSAGES/django.mo b/cookbook/locale/zh_CN/LC_MESSAGES/django.mo index 21386ba1a..89dc7d481 100644 Binary files a/cookbook/locale/zh_CN/LC_MESSAGES/django.mo and b/cookbook/locale/zh_CN/LC_MESSAGES/django.mo differ diff --git a/docs/install/docker.md b/docs/install/docker.md index 72ec9cf96..244334fbc 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -343,6 +343,11 @@ ProxyPassReverse / http://localhost:8080/ # replace port !!!info Always wait at least 2-3 minutes after the very first start, since migrations will take some time! +!!!warning + If you want to use Tandoor on a Raspberry Pi running a 32-bit operating system you will need to use the following + docker image tags: `latest-raspi`, `beta-raspi` and the versioned `-raspi` + We strongly recommend using the new 64-bit Raspian image as the 32-bit version is not tested. + If you're having issues with installing Tandoor on your Raspberry Pi or similar device, follow these instructions: diff --git a/recipes/locale/de/LC_MESSAGES/django.mo b/recipes/locale/de/LC_MESSAGES/django.mo index 8e8d7cc58..24682470f 100644 Binary files a/recipes/locale/de/LC_MESSAGES/django.mo and b/recipes/locale/de/LC_MESSAGES/django.mo differ diff --git a/recipes/locale/en/LC_MESSAGES/django.mo b/recipes/locale/en/LC_MESSAGES/django.mo index c105e6f5a..71cbdf3e9 100644 Binary files a/recipes/locale/en/LC_MESSAGES/django.mo and b/recipes/locale/en/LC_MESSAGES/django.mo differ diff --git a/recipes/locale/hu_HU/LC_MESSAGES/django.mo b/recipes/locale/hu_HU/LC_MESSAGES/django.mo index 600222a28..6c5906d1c 100644 Binary files a/recipes/locale/hu_HU/LC_MESSAGES/django.mo and b/recipes/locale/hu_HU/LC_MESSAGES/django.mo differ diff --git a/recipes/locale/pt/LC_MESSAGES/django.mo b/recipes/locale/pt/LC_MESSAGES/django.mo index c105e6f5a..71cbdf3e9 100644 Binary files a/recipes/locale/pt/LC_MESSAGES/django.mo and b/recipes/locale/pt/LC_MESSAGES/django.mo differ diff --git a/recipes/locale/rn/LC_MESSAGES/django.mo b/recipes/locale/rn/LC_MESSAGES/django.mo index 600222a28..6c5906d1c 100644 Binary files a/recipes/locale/rn/LC_MESSAGES/django.mo and b/recipes/locale/rn/LC_MESSAGES/django.mo differ diff --git a/recipes/settings.py b/recipes/settings.py index 9df776b7b..f94fcee9e 100644 --- a/recipes/settings.py +++ b/recipes/settings.py @@ -366,8 +366,10 @@ USE_TZ = True LANGUAGES = [ ('hy', _('Armenian ')), + ('bg', _('Bulgarian')), ('ca', _('Catalan')), ('cs', _('Czech')), + ('da', _('Danish')), ('nl', _('Dutch')), ('en', _('English')), ('fr', _('French')), diff --git a/vue/src/apps/ShoppingListView/ShoppingListView.vue b/vue/src/apps/ShoppingListView/ShoppingListView.vue index efeade1b4..0587c3cdc 100644 --- a/vue/src/apps/ShoppingListView/ShoppingListView.vue +++ b/vue/src/apps/ShoppingListView/ShoppingListView.vue @@ -234,7 +234,7 @@ {{ r.recipe_mealplan.name }} - {{ r.recipe_mealplan.recipe_name }} + {{ r.recipe_mealplan.recipe_name }} - {{ $t("New Entry") }} + {{ $t("New_Entry") }}
@@ -781,7 +781,7 @@ import GenericMultiselect from "@/components/GenericMultiselect" import LookupInput from "@/components/Modals/LookupInput" import ShoppingModal from "@/components/Modals/ShoppingModal" -import {ApiMixin, getUserPreference, StandardToasts, makeToast} from "@/utils/utils" +import {ApiMixin, getUserPreference, StandardToasts, makeToast, ResolveUrlMixin} from "@/utils/utils" import {ApiApiFactory} from "@/utils/openapi/api" Vue.use(BootstrapVue) @@ -790,7 +790,7 @@ let SETTINGS_COOKIE_NAME = "shopping_settings" export default { name: "ShoppingListView", - mixins: [ApiMixin], + mixins: [ApiMixin,ResolveUrlMixin], components: { ContextMenu, ContextMenuItem, diff --git a/vue/src/locales/en.json b/vue/src/locales/en.json index c52fbb3f7..845bd9abb 100644 --- a/vue/src/locales/en.json +++ b/vue/src/locales/en.json @@ -202,6 +202,7 @@ "Starting_Day": "Starting day of the week", "Meal_Types": "Meal types", "Meal_Type": "Meal type", + "New_Entry": "New Entry", "Clone": "Clone", "Drag_Here_To_Delete": "Drag here to delete", "Meal_Type_Required": "Meal type is required",