From 78686faad35a1b70ee3a0a2115dcb4f450906819 Mon Sep 17 00:00:00 2001 From: Manon Brun Date: Fri, 5 Apr 2024 15:57:09 +0100 Subject: [PATCH 01/17] fix: rounding units --- vue/src/components/PropertyViewComponent.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vue/src/components/PropertyViewComponent.vue b/vue/src/components/PropertyViewComponent.vue index 6cceeccd7..b7c1a871a 100644 --- a/vue/src/components/PropertyViewComponent.vue +++ b/vue/src/components/PropertyViewComponent.vue @@ -67,7 +67,7 @@ From 38b22f3a561c6e947a4844cf244a55c09cdab21c Mon Sep 17 00:00:00 2001 From: smilerz Date: Fri, 5 Apr 2024 08:36:32 -0500 Subject: [PATCH 02/17] setup project level linting with flake8 project level formatting with prettier project level formatting with yapf --- .flake8 | 22 +++++++++++ .vscode/settings.json | 9 ++++- docs/contribute.md | 86 +++++++++++++++++++++++++++++-------------- pyproject.toml | 14 +++++++ requirements.txt | 3 ++ vue/package.json | 6 +++ 6 files changed, 111 insertions(+), 29 deletions(-) create mode 100644 .flake8 create mode 100644 pyproject.toml diff --git a/.flake8 b/.flake8 new file mode 100644 index 000000000..f3353121e --- /dev/null +++ b/.flake8 @@ -0,0 +1,22 @@ +[flake8] +extend-ignore = + # Whitespace before ':' - Required for black compatibility + E203, + # Line break occurred before a binary operator - Required for black compatibility + W503, + # Comparison to False should be 'if cond is False:' or 'if not cond:' + E712 +exclude = + .git, + **/__pycache__, + **/.git, + **/.svn, + **/.hg, + **/CVS, + **/.DS_Store, + .vscode, + **/*.pyc +per-file-ignores= + cookbook/apps.py:F401 +max-line-length = 179 + diff --git a/.vscode/settings.json b/.vscode/settings.json index 1f900399c..b7c5c054b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,5 +3,10 @@ "cookbook/tests" ], "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true -} \ No newline at end of file + "python.testing.pytestEnabled": true, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[python]": { + "editor.defaultFormatter": "eeyore.yapf", + } +} diff --git a/docs/contribute.md b/docs/contribute.md index 545ded755..7e5c4eece 100644 --- a/docs/contribute.md +++ b/docs/contribute.md @@ -1,59 +1,88 @@ If you like this application and want it to improve, feel free to contribute to its development. !!! success "Contribution List" - If you help bring this project forward you deserve to be credited for it. - Feel free to add yourself to `CONTRIBUTERS.md` or message me to add you if you have contributed anything. +If you help bring this project forward you deserve to be credited for it. +Feel free to add yourself to `CONTRIBUTERS.md` or message me to add you if you have contributed anything. ## Issues + The most basic but also very important way of contributing is reporting issues and commenting on ideas and feature requests over at [GitHub issues](https://github.com/vabene1111/recipes/issues). Without feedback improvement can't happen, so don't hesitate to say what you want to say. ## Contributing Code + If you want to contribute bug fixes or small tweaks then your pull requests are always welcome! !!! danger "Discuss First!" - If you want to contribute larger features that introduce more complexity to the project please - make sure to **first submit a technical description** outlining what and how you want to do it. - This allows me and the community to give feedback and manage the complexity of the overall - application. If you don't do this please don't be mad if I reject your PR +If you want to contribute larger features that introduce more complexity to the project please +make sure to **first submit a technical description** outlining what and how you want to do it. +This allows me and the community to give feedback and manage the complexity of the overall +application. If you don't do this please don't be mad if I reject your PR !!! info - The dev setup is a little messy as this application combines the best (at least in my opinion) of both Django and Vue.js. +The dev setup is a little messy as this application combines the best (at least in my opinion) of both Django and Vue.js. ### Devcontainer Setup -There is a [devcontainer](https://containers.dev) set up to ease development. It is optimized for VSCode, but should be able to -be used by other editors as well. Once the container is running, you can do things like start a Django dev server, start a Vue.js + +There is a [devcontainer](https://containers.dev) set up to ease development. It is optimized for VSCode, but should be able to +be used by other editors as well. Once the container is running, you can do things like start a Django dev server, start a Vue.js dev server, run python tests, etc. by either using the VSCode tasks below, or manually running commands described in the individual technology sections below. In VSCode, simply check out the git repository, and then via the command palette, choose `Dev Containers: Reopen in container`. -If you need to change python dependencies (requierments.txt) or OS packages, you will need to rebuild the container. If you are +If you need to change python dependencies (requierments.txt) or OS packages, you will need to rebuild the container. If you are changing OS package requirements, you will need to update both the main `Dockerfile` and the `.devcontainer/Dockerfile`. ### VSCode Tasks -If you use VSCode, there are a number of tasks that are available. Here are a few of the key ones: -* `Setup Dev Server` - Runs all the prerequisite steps so that the dev server can be run inside VSCode. -* `Setup Tests` - Runs all prerequisites so tests can be run inside VSCode. +If you use VSCode, there are a number of tasks that are available. Here are a few of the key ones: + +- `Setup Dev Server` - Runs all the prerequisite steps so that the dev server can be run inside VSCode. +- `Setup Tests` - Runs all prerequisites so tests can be run inside VSCode. Once these are run, you should be able to run/debug a django server in VSCode as well as run/debug tests directly through VSCode. There are also a few other tasks specified in case you have specific development needs: -* `Run Dev Server` - Runs a django development server not connected to VSCode. -* `Run all pytests` - Runs all the pytests outside of VSCode. -* `Yarn Serve` - Runs development Vue.js server not connected to VSCode. Useful if you want to make Vue changes and see them in realtime. -* `Serve Documentation` - Runs a documentation server. Useful if you want to see how changes to documentation show up. +- `Run Dev Server` - Runs a django development server not connected to VSCode. +- `Run all pytests` - Runs all the pytests outside of VSCode. +- `Yarn Serve` - Runs development Vue.js server not connected to VSCode. Useful if you want to make Vue changes and see them in realtime. +- `Serve Documentation` - Runs a documentation server. Useful if you want to see how changes to documentation show up. + +!!! info linting and formating +This project uses black, flake8, isort, prettier, and ESLint to lint and format the code. In order to submit a PR you must use the +project standard configurations. + + ##### VSCode: + Install the official plugins: black-formatter, flake8, isort + Add the following line to your settings.json: + ``` json + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter", + } + ``` + + ##### PyCharm + Add the following line to your settings.json: + ``` json + "[python]": { + "editor.defaultFormatter": "ms-python.flake8", + "editor.formatOnSave": true + }, + ``` ### Django -This application is developed using the Django framework for Python. They have excellent + +This application is developed using the Django framework for Python. They have excellent [documentation](https://www.djangoproject.com/start/) on how to get started, so I will only give you the basics here. 1. Clone this repository wherever you like and install the Python language for your OS (I recommend using version 3.10 or above). 2. Open it in your favorite editor/IDE (e.g. PyCharm). - a. If you want, create a virtual environment for all your packages. + a. If you want, create a virtual environment for all your packages. 3. Install all required packages: `pip install -r requirements.txt`. 4. Run the migrations: `python manage.py migrate`. 5. Start the development server: `python manage.py runserver`. @@ -62,15 +91,17 @@ There is **no** need to set any environment variables. By default, a simple SQLi populated from default values. ### Vue.js -Most new frontend pages are build using [Vue.js](https://vuejs.org/). + +Most new frontend pages are build using [Vue.js](https://vuejs.org/). In order to work on these pages, you will have to install a Javascript package manager of your choice. The following examples use yarn. In the `vue` folder run `yarn install` to install the dependencies. After that you can use `yarn serve` to start the development server, -and proceed to test your changes. If you do not wish to work on those pages, but instead want the application to work properly during -development, run `yarn build` to build the frontend pages once. +and proceed to test your changes. If you do not wish to work on those pages, but instead want the application to work properly during +development, run `yarn build` to build the frontend pages once. #### API Client + The API Client is generated automatically from the OpenAPI interface provided by the Django REST framework. For this [openapi-generator](https://github.com/OpenAPITools/openapi-generator) is used. @@ -81,6 +112,7 @@ Navigate to `vue/src/utils/openapi`. Generate the schema using `openapi-generator-cli generate -g typescript-axios -i http://127.0.0.1:8000/openapi/`. (Replace your dev server url if required.) ## Contribute Documentation + The documentation is built from the markdown files in the [docs](https://github.com/vabene1111/recipes/tree/develop/docs) folder of the GitHub repository. @@ -104,14 +136,14 @@ You can simply register an account and then follow these steps to add translatio 4. Go back to the dashboard. It now shows you the relevant translations for your languages. Click on the pencil icon to get started. !!! info "Creating a new language" - To create a new language you must first select Tandoor (the project) and then a component. - Here you will have the option to add the language. Afterwards you can also simply add it to the other components as well. - Once a new language is (partially) finished let me know on GitHub so I can add it to the language-switcher in Tandoor itself. +To create a new language you must first select Tandoor (the project) and then a component. +Here you will have the option to add the language. Afterwards you can also simply add it to the other components as well. +Once a new language is (partially) finished let me know on GitHub so I can add it to the language-switcher in Tandoor itself. There is also [a lot of documentation](https://docs.weblate.org/en/latest/user/translating.html) available from Weblate directly. ![2021-04-11_16-03](https://user-images.githubusercontent.com/6819595/114307359-926e0380-9adf-11eb-9a2b-febba56e4d8c.gif) -It is also possible to provide the translations directly by creating a new language -using `manage.py makemessages -l -i venv`. Once finished, simply open a PR with the changed files. This sometimes causes issues merging +It is also possible to provide the translations directly by creating a new language +using `manage.py makemessages -l -i venv`. Once finished, simply open a PR with the changed files. This sometimes causes issues merging with weblate, so I would prefer the use of weblate. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..974b61d90 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[tool.yapf] +column_limit = 179 +based_on_style = "pep8" +# each_dict_entry_on_separate_line = true +DISABLE_ENDING_COMMA_HEURISTIC = false +COALESCE_BRACKETS = true +DEDENT_CLOSING_BRACKETS = true +FORCE_MULTILINE_DICT = false + +[tool.isort] +multi_line_output = 3 +include_trailing_comma = true +skip = [".gitignore", ".dockerignore"] +line_length = 179 diff --git a/requirements.txt b/requirements.txt index b457d2c46..03574e211 100644 --- a/requirements.txt +++ b/requirements.txt @@ -53,3 +53,6 @@ pytest-factoryboy==2.6.0 pytest-html==4.1.1 pytest-asyncio==0.23.5 pytest-xdist==3.5.0 +autopep8==2.0.4 +flake8==6.1.0 +yapf==0.40.2 diff --git a/vue/package.json b/vue/package.json index 02c8fe1fc..5615b558d 100644 --- a/vue/package.json +++ b/vue/package.json @@ -97,5 +97,11 @@ "resolutions": { "@vue/cli-plugin-pwa/workbox-webpack-plugin": "^5.1.3", "coa": "2.0.2" + }, + "prettier": { + "printWidth": 179, + "trailingComma": "es5", + "tabWidth": 2, + "semi": false } } From 99868e4e805db11085f6a0cc7030b616b501bbe3 Mon Sep 17 00:00:00 2001 From: tooboredtocode Date: Mon, 8 Apr 2024 23:56:49 +0200 Subject: [PATCH 03/17] Reapply "Merge pull request #3055 from tooboredtocode/develop" This reverts commit f14acc371d7cf7ac7bcd6c1bd102f7d3c6a6b2b8. --- Dockerfile | 8 ++++++++ boot.sh | 17 +++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3f17d0f11..c5856bcfa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 @@ -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 diff --git a/boot.sh b/boot.sh index ae3dbb51d..ab5d7fddd 100644 --- a/boot.sh +++ b/boot.sh @@ -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..." -echo "Done" + python manage.py collectstatic_js_reverse + python manage.py collectstatic --noinput + + echo "Done" +fi chmod -R 755 /opt/recipes/mediafiles From 42b7d1afcb880e65338370ffce9737302456e08e Mon Sep 17 00:00:00 2001 From: tooboredtocode Date: Mon, 8 Apr 2024 23:58:10 +0200 Subject: [PATCH 04/17] fix: image not working in docker compose environments --- boot.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/boot.sh b/boot.sh index ab5d7fddd..c14d66aab 100644 --- a/boot.sh +++ b/boot.sh @@ -68,12 +68,16 @@ echo "Migrating database" python manage.py migrate if [[ "${DOCKER}" == "true" ]]; then - echo "Copying cached static files from docker build" + if [[ -d "/opt/recipes/staticfiles-collect" ]]; then + echo "Copying cached static files from docker build" - mkdir -p /opt/recipes/staticfiles - rm -rf /opt/recipes/staticfiles/* - mv /opt/recipes/staticfiles-collect/* /opt/recipes/staticfiles - rm -rf /opt/recipes/staticfiles-collect + 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 "Static files are already up to date" + fi else echo "Collecting static files, this may take a while..." From 2e6cc3e58e9d1e107eeda962bf7ea792c8859b23 Mon Sep 17 00:00:00 2001 From: smilerz Date: Mon, 8 Apr 2024 19:16:18 -0500 Subject: [PATCH 05/17] document configurations required for formatting and linting --- .vscode/settings.json | 4 +- docs/contribute.md | 149 ------------------- docs/contribute/assets/flake8_watcher.png | Bin 0 -> 45703 bytes docs/contribute/assets/isort_watcher.png | Bin 0 -> 41279 bytes docs/contribute/assets/linting_error.png | Bin 0 -> 14811 bytes docs/contribute/assets/prettier_watcher.png | Bin 0 -> 41813 bytes docs/contribute/assets/yapf_watcher.png | Bin 0 -> 41470 bytes docs/contribute/contribute.md | 55 +++++++ docs/contribute/documentation.md | 26 ++++ docs/contribute/guidelines.md | 63 ++++++++ docs/contribute/installation.md | 39 +++++ docs/contribute/pycharm.md | 62 ++++++++ docs/contribute/related.md | 25 ++++ docs/contribute/translations.md | 21 +++ docs/contribute/vscode.md | 45 ++++++ docs/system/settings.md | 27 ---- mkdocs.yml | 14 +- pyproject.toml | 4 +- recipes/settings.py | 153 +++++++++++++++----- vue/package.json | 4 +- vue/yarn.lock | 5 + 21 files changed, 476 insertions(+), 220 deletions(-) delete mode 100644 docs/contribute.md create mode 100644 docs/contribute/assets/flake8_watcher.png create mode 100644 docs/contribute/assets/isort_watcher.png create mode 100644 docs/contribute/assets/linting_error.png create mode 100644 docs/contribute/assets/prettier_watcher.png create mode 100644 docs/contribute/assets/yapf_watcher.png create mode 100644 docs/contribute/contribute.md create mode 100644 docs/contribute/documentation.md create mode 100644 docs/contribute/guidelines.md create mode 100644 docs/contribute/installation.md create mode 100644 docs/contribute/pycharm.md create mode 100644 docs/contribute/related.md create mode 100644 docs/contribute/translations.md create mode 100644 docs/contribute/vscode.md delete mode 100644 docs/system/settings.md diff --git a/.vscode/settings.json b/.vscode/settings.json index b7c5c054b..c3e6602d3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,5 +8,7 @@ "editor.defaultFormatter": "esbenp.prettier-vscode", "[python]": { "editor.defaultFormatter": "eeyore.yapf", - } + }, + "yapf.args": [], + "isort.args": [] } diff --git a/docs/contribute.md b/docs/contribute.md deleted file mode 100644 index 7e5c4eece..000000000 --- a/docs/contribute.md +++ /dev/null @@ -1,149 +0,0 @@ -If you like this application and want it to improve, feel free to contribute to its development. - -!!! success "Contribution List" -If you help bring this project forward you deserve to be credited for it. -Feel free to add yourself to `CONTRIBUTERS.md` or message me to add you if you have contributed anything. - -## Issues - -The most basic but also very important way of contributing is reporting issues and commenting on ideas and feature requests -over at [GitHub issues](https://github.com/vabene1111/recipes/issues). - -Without feedback improvement can't happen, so don't hesitate to say what you want to say. - -## Contributing Code - -If you want to contribute bug fixes or small tweaks then your pull requests are always welcome! - -!!! danger "Discuss First!" -If you want to contribute larger features that introduce more complexity to the project please -make sure to **first submit a technical description** outlining what and how you want to do it. -This allows me and the community to give feedback and manage the complexity of the overall -application. If you don't do this please don't be mad if I reject your PR - -!!! info -The dev setup is a little messy as this application combines the best (at least in my opinion) of both Django and Vue.js. - -### Devcontainer Setup - -There is a [devcontainer](https://containers.dev) set up to ease development. It is optimized for VSCode, but should be able to -be used by other editors as well. Once the container is running, you can do things like start a Django dev server, start a Vue.js -dev server, run python tests, etc. by either using the VSCode tasks below, or manually running commands described in the individual -technology sections below. - -In VSCode, simply check out the git repository, and then via the command palette, choose `Dev Containers: Reopen in container`. - -If you need to change python dependencies (requierments.txt) or OS packages, you will need to rebuild the container. If you are -changing OS package requirements, you will need to update both the main `Dockerfile` and the `.devcontainer/Dockerfile`. - -### VSCode Tasks - -If you use VSCode, there are a number of tasks that are available. Here are a few of the key ones: - -- `Setup Dev Server` - Runs all the prerequisite steps so that the dev server can be run inside VSCode. -- `Setup Tests` - Runs all prerequisites so tests can be run inside VSCode. - -Once these are run, you should be able to run/debug a django server in VSCode as well as run/debug tests directly through VSCode. -There are also a few other tasks specified in case you have specific development needs: - -- `Run Dev Server` - Runs a django development server not connected to VSCode. -- `Run all pytests` - Runs all the pytests outside of VSCode. -- `Yarn Serve` - Runs development Vue.js server not connected to VSCode. Useful if you want to make Vue changes and see them in realtime. -- `Serve Documentation` - Runs a documentation server. Useful if you want to see how changes to documentation show up. - -!!! info linting and formating -This project uses black, flake8, isort, prettier, and ESLint to lint and format the code. In order to submit a PR you must use the -project standard configurations. - - ##### VSCode: - Install the official plugins: black-formatter, flake8, isort - Add the following line to your settings.json: - ``` json - "editor.formatOnSave": true, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "[python]": { - "editor.defaultFormatter": "ms-python.black-formatter", - } - ``` - - ##### PyCharm - Add the following line to your settings.json: - ``` json - "[python]": { - "editor.defaultFormatter": "ms-python.flake8", - "editor.formatOnSave": true - }, - ``` - -### Django - -This application is developed using the Django framework for Python. They have excellent -[documentation](https://www.djangoproject.com/start/) on how to get started, so I will only give you the basics here. - -1. Clone this repository wherever you like and install the Python language for your OS (I recommend using version 3.10 or above). -2. Open it in your favorite editor/IDE (e.g. PyCharm). - a. If you want, create a virtual environment for all your packages. -3. Install all required packages: `pip install -r requirements.txt`. -4. Run the migrations: `python manage.py migrate`. -5. Start the development server: `python manage.py runserver`. - -There is **no** need to set any environment variables. By default, a simple SQLite database is used and all settings are -populated from default values. - -### Vue.js - -Most new frontend pages are build using [Vue.js](https://vuejs.org/). - -In order to work on these pages, you will have to install a Javascript package manager of your choice. The following examples use yarn. - -In the `vue` folder run `yarn install` to install the dependencies. After that you can use `yarn serve` to start the development server, -and proceed to test your changes. If you do not wish to work on those pages, but instead want the application to work properly during -development, run `yarn build` to build the frontend pages once. - -#### API Client - -The API Client is generated automatically from the OpenAPI interface provided by the Django REST framework. -For this [openapi-generator](https://github.com/OpenAPITools/openapi-generator) is used. - -Install it using your desired setup method. (For example, using `npm install @openapitools/openapi-generator-cli -g`.) - -Navigate to `vue/src/utils/openapi`. - -Generate the schema using `openapi-generator-cli generate -g typescript-axios -i http://127.0.0.1:8000/openapi/`. (Replace your dev server url if required.) - -## Contribute Documentation - -The documentation is built from the markdown files in the [docs](https://github.com/vabene1111/recipes/tree/develop/docs) -folder of the GitHub repository. - -In order to contribute to the documentation, you can fork the repository and edit the markdown files in the browser. - -Now install mkdocs and dependencies: `pip install mkdocs-material mkdocs-include-markdown-plugin`. - -If you want to test the documentation, locally run `mkdocs serve` from the project root. - -## Contribute Translations - -If you know any foreign languages that the project has not been completely translated to yet, feel free to contribute translations. - -Translations are managed on [translate.tandoor.dev](https://translate.tandoor.dev/), a self hosted instance of [Weblate](https://weblate.org/de/). - -You can simply register an account and then follow these steps to add translations: - -1. After registering, you are asked to select your languages. This is optional but allows weblate to only show you relevant translations. -2. In the navigation click on `Projects` and then `Browse all projects`. -3. Select Tandoor and on the top-right hand corner, select `Watch project Tandoor` (click on `Not watching`). -4. Go back to the dashboard. It now shows you the relevant translations for your languages. Click on the pencil icon to get started. - -!!! info "Creating a new language" -To create a new language you must first select Tandoor (the project) and then a component. -Here you will have the option to add the language. Afterwards you can also simply add it to the other components as well. -Once a new language is (partially) finished let me know on GitHub so I can add it to the language-switcher in Tandoor itself. - -There is also [a lot of documentation](https://docs.weblate.org/en/latest/user/translating.html) available from Weblate directly. - -![2021-04-11_16-03](https://user-images.githubusercontent.com/6819595/114307359-926e0380-9adf-11eb-9a2b-febba56e4d8c.gif) - -It is also possible to provide the translations directly by creating a new language -using `manage.py makemessages -l -i venv`. Once finished, simply open a PR with the changed files. This sometimes causes issues merging -with weblate, so I would prefer the use of weblate. diff --git a/docs/contribute/assets/flake8_watcher.png b/docs/contribute/assets/flake8_watcher.png new file mode 100644 index 0000000000000000000000000000000000000000..f5bf77be098c61d05d339d7d7fe9e0775955e6f6 GIT binary patch literal 45703 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 literal 0 HcmV?d00001 diff --git a/docs/contribute/assets/isort_watcher.png b/docs/contribute/assets/isort_watcher.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9c1d787215005091a6eaca906dfef1c1f3d2f7 GIT binary patch literal 41279 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

ohTG9A~v#%_i~z0P+T*G&O;T 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�MOe)!yV?)HnqXqco4 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�vzRRq((G3#GYpj*&dUk3mE7IfK``C+crjkgtl0S ztnL4`U&%SL3O|>z1AYnz5dtaU5v5GdKLqr#3d~*6Jl#r`oEPD4c#d*THXstXu>nMN zh=vC$g6XH|G*~jY*c5gm}2?Vq)K%@FK;bbBvmY^1siyQ z_cFo$!TGT#@j*lYPRX>RWY`i;jZoL|qw|ijjDXg&wZ^~9(7K;Z7Bc|^S>RBPN1*Jl zrOiKSMJ#w~JS{$UKq}VEsUa_Yuv)OB_xmP!aU*s!InZLlA{6gfH(Pcv>+uy=Iq;Vj z{^kYSuS!RQc&ylaw{AP8QM(k4x8bLQ&4otExj6^LgXhM_%b&UG56`nmmi_7;n#z$S zY~I|OZ$0^`6F)g%PN23ll>*j$(?sZYG1)B!B- zwi3%s{G=2aJdpjV@+0k(`FCK)D2zliWZ($vY#)TMW~z9u`w^4`Ph%gXI?p1{x_h7J z$jSYLX!2JYfA0iVcfyvktKkI60|qN{j3@?-Di2Ub{8~ zfHMb|v7kuHhKb8KF7(-&W&=_8un9vwKEJ4!F<5eu{KJ~f(=AEN&i+FuAna5&@aA=w zGOw>dbWXSl0M%S#*fz?iId~8a=)N8CGu!6HSK0=L6f(?fcH|-Zk{aiWwc%>v_?Wv= zA=UZ=73oWyb%eZe^DH!^zhXh`9yrP`ZaYF#;T!Y_)g|tS_9_Hrhjer#a2q2*MY8J|DF`e|(``pF*cqgKz-l(>?A z2opy`f{k9_Y*&9C)CVE7z-+CTU8_ADk1?J;MhTYQ8bmrQgEjQ%?>n=qKt0~ARp{53 z{ub{J+d_Fq6|>HhM>#BXim9wkZ$YQ8b<4Ti3qctmy=$x>*#zgp$5L7zK=6>EtV8cE zWOZ`I*m~>)J}6RNU@%ziHFe1r25QSlBFopzFiXNfWlMMG{pzfIv6F`TlYd^{f#T&X zbmG%)fiqAi_V%PB{Estabe7d7?eo_h7@&8JzXQ1EroQ*0&laosDJz^oTPnLY%)%gTe8wny<8FfNZI z7HCXW6EL&2uhFPCGW*wI>64_HFVP^QT4?e?^f5TE!a=~^NnD!#FA>6ECsepH;1+i4 zP6f=EtxOGPF8pd2e?D2uwp!?X@tKU@5nrE04TSaIo-$HD;nN%0AMbFx5~ENBneaj9 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 SyLK#Amd8_ literal 0 HcmV?d00001 diff --git a/docs/contribute/assets/yapf_watcher.png b/docs/contribute/assets/yapf_watcher.png new file mode 100644 index 0000000000000000000000000000000000000000..9ddd968cdea376e2e36e216c98e8b889c193618b GIT binary patch literal 41470 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℘Xe--L?C_Pn5*)Wp$ss*|b~70;qJj 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 Settings -> Plugins +2. Download and install [File Watchers](https://plugins.jetbrains.com/plugin/7177-file-watchers) +3. Navigate to File -> Settings -> Tools -> Black +4. Confirm 'Use Black Formatter' is unchecked for both 'On code reformat' and 'On save' + +## Setup flake8 Watcher + +1. Navigate to File -> Settings -> Tools -> File Watchers +2. Click the '+' to add a new watcher. +3. Configure the watcher as below. + + ![flake8_watcher](assets/flake8_watcher.png) + +4. Navigate to File -> Settings -> Editor -> Inspections -> File watcher problems +5. Under Severity select 'Edit Severities' +6. Click the '+' to add a severity calling it 'Linting Error' +7. Configure a background and effect as below. + + ![linting error](assets/linting_error.png) + +## Setup isort + +1. Navigate to File -> Settings -> Tools -> File Watchers +2. Click the '+' to add a new watcher. +3. Configure the watcher as below. + + ![yapf_watcher](assets/isort_watcher.png) + +## Setup yapf + +1. Navigate to File -> Settings -> Tools -> File Watchers +2. Click the '+' to add a new watcher. +3. Configure the watcher as below. + + ![yapf_watcher](assets/yapf_watcher.png) + + +!!! hint + Adding a comma at the end of a list will trigger yapf to put each element of the list on a new line + +## Setup prettier + +1. Navigate to File -> Settings -> Tools -> File Watchers +2. Click the '+' to add a new watcher. +3. Change 'File Type' to 'Any'. +4. Click the three dots next to 'Scope' to create a custom scope. +5. Click '+' to add a new scope + +- Name: prettier +- Pattern: `file:vue/src//*||file:vue3/src//*||file:docs//*` + +6. Configure the watcher as below. + + ![perttier_watcher](assets/prettier_watcher.png) + +- Arguments: `--cwd $ProjectFileDir$\vue prettier -w --config $ProjectFileDir$\.prettierrc $FilePath$` + +## Setup Volar?? diff --git a/docs/contribute/related.md b/docs/contribute/related.md new file mode 100644 index 000000000..ad2cce45a --- /dev/null +++ b/docs/contribute/related.md @@ -0,0 +1,25 @@ +## Recipe Scraper + +While not directly related to Tandoor, we make extensive use of the brilliant [recipe-scrapers](https://github.com/hhursev/recipe-scrapers) +package by hhursev. + +If you have the skills to add new sites or help resolve issues you are indirectly helping Tandoor. + +## Unofficial mobile app + +Maintained by [phantomate](https://github.com/phantomate/Untare) + +[iPhone](https://apps.apple.com/nl/app/untare/id6448643329?l=en&platform=iphone) +[Android](https://play.google.com/store/apps/details?id=unofficial.tandoor.recipes) + +## GPT Recipe + +Maintained by [John Pedrie](https://github.com/jdpedrie/gpt-recipe) + +Convert pictures of recipes to a structure that can be imported to Tandoor with ChatGPT. + +## Tandoor Menu Generator + +Maintained by [smilerz](https://github.com/smilerz/tandoor-menu-generator) + +Generate a mealplan tbased on complex criteria and optionally insert it into an SVG menu template. diff --git a/docs/contribute/translations.md b/docs/contribute/translations.md new file mode 100644 index 000000000..cd8d451c2 --- /dev/null +++ b/docs/contribute/translations.md @@ -0,0 +1,21 @@ +Translations are managed on [translate.tandoor.dev](https://translate.tandoor.dev/), a self hosted instance of [Weblate](https://weblate.org/de/). + +You can simply register an account and then follow these steps to add translations: + +1. After registering, you are asked to select your languages. This is optional but allows weblate to only show you relevant translations. +2. In the navigation click on `Projects` and then `Browse all projects`. +3. Select Tandoor and on the top-right hand corner, select `Watch project Tandoor` (click on `Not watching`). +4. Go back to the dashboard. It now shows you the relevant translations for your languages. Click on the pencil icon to get started. + +!!! info "Creating a new language" +To create a new language you must first select Tandoor (the project) and then a component. +Here you will have the option to add the language. Afterwards you can also simply add it to the other components as well. +Once a new language is (partially) finished let me know on GitHub so I can add it to the language-switcher in Tandoor itself. + +There is also [a lot of documentation](https://docs.weblate.org/en/latest/user/translating.html) available from Weblate directly. + +![2021-04-11_16-03](https://user-images.githubusercontent.com/6819595/114307359-926e0380-9adf-11eb-9a2b-febba56e4d8c.gif) + +It is also possible to provide the translations directly by creating a new language +using `manage.py makemessages -l -i venv`. Once finished, simply open a PR with the changed files. This sometimes causes issues merging +with weblate, so I would prefer the use of weblate. diff --git a/docs/contribute/vscode.md b/docs/contribute/vscode.md new file mode 100644 index 000000000..ab938d0ed --- /dev/null +++ b/docs/contribute/vscode.md @@ -0,0 +1,45 @@ +Configurations for debugging django, volar, testing, linting and formatting are all include in the project files. + +## Extensions + +VSCode can be configured to format and lint on save instead of manually formatting files before submitting a pull request. +To enable auto-formatting and linting install the following extensions in VSCode: + +Name: Flake8 +Publisher: Microsoft +VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=ms-python.flake8 + +Name: yapf +Publisher: EeyoreLee +VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=eeyore.yapf + +Name: isort +Publisher: Microsoft +VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=ms-python.isort + +Name: Vue - Official +Publisher: Vue +VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=Vue.volar + +Name: Prettier - Code formatter +Publisher: Prettier +VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode + + +!!! hint + Adding a comma at the end of a list will trigger yapf to put each element of the list on a new line + +## VSCode Tasks + +There are a number of built in tasks that are available. Here are a few of the key ones: + +- `Setup Dev Server` - Runs all the prerequisite steps so that the dev server can be run inside VSCode. +- `Setup Tests` - Runs all prerequisites so tests can be run inside VSCode. + +Once these are run, you should be able to run/debug a django server in VSCode as well as run/debug tests directly through VSCode. +There are also a few other tasks specified in case you have specific development needs: + +- `Run Dev Server` - Runs a django development server not connected to VSCode. +- `Run all pytests` - Runs all the pytests outside of VSCode. +- `Yarn Serve` - Runs development Vue.js server not connected to VSCode. Useful if you want to make Vue changes and see them in realtime. +- `Serve Documentation` - Runs a documentation server. Useful if you want to see how changes to documentation show up. diff --git a/docs/system/settings.md b/docs/system/settings.md deleted file mode 100644 index 990090fd8..000000000 --- a/docs/system/settings.md +++ /dev/null @@ -1,27 +0,0 @@ -Following is a description of the different settings for a space - -!!! WARNING WIP - Some settings and especially this page is work in Progress and the settings may - behave differently the described here. - -## Use Plural form - -Default Value: `off` - -This setting enables tandoor to display a plural form of a food or unit, if the -plural version is entered for the food or unit. The plural version is displayed if the -amount needed for a recipe is greater than 1 and will be adjusted to the current amount. - -In addition, this setting enables two new settings for an ingredient: - -- Always show the plural version of the food: This will always display the plural version for -a food, even if the amount is below or equal to 1. Requirement for this setting to activate -is a plural version available in the database. -- Always show the plural version of the unit: This will always display the plural version for -a unit, even if the amount is below or equal to 1. Requirement for this setting to activate -is a plural version available in the database. - -!!! WARNING Note - This setting is only meant to be a very simple version to enable some kind of pluralization - for food and units. This feature may not meet your needs, but pluralization is a difficult - topic and was discussed [here](https://github.com/TandoorRecipes/recipes/pull/1860). diff --git a/mkdocs.yml b/mkdocs.yml index 68d2b70a9..f51e36471 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -36,6 +36,7 @@ nav: - TrueNAS Portainer: install/truenas_portainer.md - WSL: install/wsl.md - ArchLinux: install/archlinux.md + - HomeAssistant: install/homeassistant.md - Manual: install/manual.md - Other setups: install/other.md - Features: @@ -46,10 +47,21 @@ nav: - Connectors: features/connectors.md - Storages and Sync: features/external_recipes.md - Import/Export: features/import_export.md + - Telegram bot: features/telegram_bot.md - System: - Configuration: system/configuration.md - Updating: system/updating.md + - Migrate sqlite to postgres: system/migration_sqlite-postgres.md - Permission System: system/permissions.md - Backup: system/backup.md - - Contributing: contribute.md + - Contributing: + - Overview: contribute/contribute.md + - Translations: contribute/translations.md + - Documentation: contribute/documentation.md + - Code: contribute/guidelines.md + - Installation: contribute/installation.md + - IDE Setup: + - VSCode: contribute/vscode.md + - PyCharm: contribute/pycharm.md + - Related Projects: contribute/related.md - FAQ: faq.md diff --git a/pyproject.toml b/pyproject.toml index 974b61d90..33bc62172 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,12 @@ [tool.yapf] column_limit = 179 based_on_style = "pep8" -# each_dict_entry_on_separate_line = true DISABLE_ENDING_COMMA_HEURISTIC = false COALESCE_BRACKETS = true DEDENT_CLOSING_BRACKETS = true FORCE_MULTILINE_DICT = false [tool.isort] -multi_line_output = 3 -include_trailing_comma = true +multi_line_output = 5 skip = [".gitignore", ".dockerignore"] line_length = 179 diff --git a/recipes/settings.py b/recipes/settings.py index 268c8f68b..d9b2b6b24 100644 --- a/recipes/settings.py +++ b/recipes/settings.py @@ -104,10 +104,30 @@ MESSAGE_TAGS = {messages.ERROR: 'danger'} # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', - 'django.contrib.sites', 'django.contrib.staticfiles', 'django.contrib.postgres', 'oauth2_provider', 'django_tables2', 'corsheaders', 'crispy_forms', - 'crispy_bootstrap4', 'rest_framework', 'rest_framework.authtoken', 'django_cleanup.apps.CleanupConfig', 'webpack_loader', 'django_js_reverse', 'hcaptcha', 'allauth', - 'allauth.account', 'allauth.socialaccount', 'cookbook.apps.CookbookConfig', 'treebeard', + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.sites', + 'django.contrib.staticfiles', + 'django.contrib.postgres', + 'oauth2_provider', + 'django_tables2', + 'corsheaders', + 'crispy_forms', + 'crispy_bootstrap4', + 'rest_framework', + 'rest_framework.authtoken', + 'django_cleanup.apps.CleanupConfig', + 'webpack_loader', + 'django_js_reverse', + 'hcaptcha', + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'cookbook.apps.CookbookConfig', + 'treebeard', ] PLUGINS_DIRECTORY = os.path.join(BASE_DIR, 'recipes', 'plugins') @@ -177,10 +197,18 @@ ENABLE_PDF_EXPORT = bool(int(os.getenv('ENABLE_PDF_EXPORT', False))) EXPORT_FILE_CACHE_DURATION = int(os.getenv('EXPORT_FILE_CACHE_DURATION', 600)) MIDDLEWARE = [ - 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.locale.LocaleMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'cookbook.helper.scope_middleware.ScopeMiddleware', 'allauth.account.middleware.AccountMiddleware', + 'corsheaders.middleware.CorsMiddleware', + 'django.middleware.security.SecurityMiddleware', + 'whitenoise.middleware.WhiteNoiseMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.locale.LocaleMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'cookbook.helper.scope_middleware.ScopeMiddleware', + 'allauth.account.middleware.AccountMiddleware', ] if DEBUG_TOOLBAR: @@ -211,7 +239,11 @@ if LDAP_AUTH: AUTH_LDAP_START_TLS = bool(int(os.getenv('AUTH_LDAP_START_TLS', False))) AUTH_LDAP_BIND_DN = os.getenv('AUTH_LDAP_BIND_DN') AUTH_LDAP_BIND_PASSWORD = os.getenv('AUTH_LDAP_BIND_PASSWORD') - AUTH_LDAP_USER_SEARCH = LDAPSearch(os.getenv('AUTH_LDAP_USER_SEARCH_BASE_DN'), ldap.SCOPE_SUBTREE, os.getenv('AUTH_LDAP_USER_SEARCH_FILTER_STR', '(uid=%(user)s)'), ) + AUTH_LDAP_USER_SEARCH = LDAPSearch( + os.getenv('AUTH_LDAP_USER_SEARCH_BASE_DN'), + ldap.SCOPE_SUBTREE, + os.getenv('AUTH_LDAP_USER_SEARCH_FILTER_STR', '(uid=%(user)s)'), + ) AUTH_LDAP_USER_ATTR_MAP = ast.literal_eval(os.getenv('AUTH_LDAP_USER_ATTR_MAP')) if os.getenv('AUTH_LDAP_USER_ATTR_MAP') else { 'first_name': 'givenName', 'last_name': 'sn', @@ -238,7 +270,10 @@ if LDAP_AUTH: }, } -AUTHENTICATION_BACKENDS += ['django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend', ] +AUTHENTICATION_BACKENDS += [ + 'django.contrib.auth.backends.ModelBackend', + 'allauth.account.auth_backends.AuthenticationBackend', +] # django allauth site id SITE_ID = int(os.getenv('ALLAUTH_SITE_ID', 1)) @@ -252,15 +287,20 @@ if REMOTE_USER_AUTH: # Password validation # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators -AUTH_PASSWORD_VALIDATORS = [{ - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', -}, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', -}, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', -}, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', -}, ] +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') @@ -269,25 +309,35 @@ READ_SCOPE = 'read' WRITE_SCOPE = 'write' REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': - ('rest_framework.authentication.SessionAuthentication', 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', 'rest_framework.authentication.BasicAuthentication', - ), - 'DEFAULT_PERMISSION_CLASSES': ['rest_framework.permissions.IsAuthenticated', ], + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.SessionAuthentication', + 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', + 'rest_framework.authentication.BasicAuthentication', + ), + 'DEFAULT_PERMISSION_CLASSES': [ + 'rest_framework.permissions.IsAuthenticated', + ], } ROOT_URLCONF = 'recipes.urls' -TEMPLATES = [{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'cookbook', 'templates')], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', 'django.template.context_processors.media', 'cookbook.helper.context_processors.context_settings', - ], +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'cookbook', 'templates')], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + 'django.template.context_processors.media', + 'cookbook.helper.context_processors.context_settings', + ], + }, }, -}, ] +] WSGI_APPLICATION = 'recipes.wsgi.application' @@ -358,7 +408,12 @@ def setup_database(db_url=None, db_options=None, db_engine=None, pg_host=None, p DATABASES = setup_database() -CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'default', }} +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + 'LOCATION': 'default', + } +} # Vue webpack settings VUE_DIR = os.path.join(BASE_DIR, 'vue') @@ -402,9 +457,25 @@ USE_L10N = True USE_TZ = True -LANGUAGES = [('hy', _('Armenian ')), ('bg', _('Bulgarian')), ('ca', _('Catalan')), ('cs', _('Czech')), ('da', _('Danish')), ('nl', _('Dutch')), ('en', _('English')), - ('fr', _('French')), ('de', _('German')), ('hu', _('Hungarian')), ('it', _('Italian')), ('lv', _('Latvian')), ('nb', _('Norwegian ')), ('pl', _('Polish')), - ('ru', _('Russian')), ('es', _('Spanish')), ('sv', _('Swedish')), ] +LANGUAGES = [ + ('hy', _('Armenian ')), + ('bg', _('Bulgarian')), + ('ca', _('Catalan')), + ('cs', _('Czech')), + ('da', _('Danish')), + ('nl', _('Dutch')), + ('en', _('English')), + ('fr', _('French')), + ('de', _('German')), + ('hu', _('Hungarian')), + ('it', _('Italian')), + ('lv', _('Latvian')), + ('nb', _('Norwegian ')), + ('pl', _('Polish')), + ('ru', _('Russian')), + ('es', _('Spanish')), + ('sv', _('Swedish')), +] # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.0/howto/static-files/ @@ -470,7 +541,13 @@ ACCOUNT_EMAIL_SUBJECT_PREFIX = os.getenv('ACCOUNT_EMAIL_SUBJECT_PREFIX', '[Tando ACCOUNT_FORMS = {'signup': 'cookbook.forms.AllAuthSignupForm', 'reset_password': 'cookbook.forms.CustomPasswordResetForm'} ACCOUNT_EMAIL_UNKNOWN_ACCOUNTS = False -ACCOUNT_RATE_LIMITS = {"change_password": "1/m/user", "reset_password": "1/m/ip,1/m/key", "reset_password_from_key": "1/m/ip", "signup": "5/m/ip", "login": "5/m/ip", } +ACCOUNT_RATE_LIMITS = { + "change_password": "1/m/user", + "reset_password": "1/m/ip,1/m/key", + "reset_password_from_key": "1/m/ip", + "signup": "5/m/ip", + "login": "5/m/ip", +} DISABLE_EXTERNAL_CONNECTORS = bool(int(os.getenv('DISABLE_EXTERNAL_CONNECTORS', False))) EXTERNAL_CONNECTORS_QUEUE_SIZE = int(os.getenv('EXTERNAL_CONNECTORS_QUEUE_SIZE', 100)) diff --git a/vue/package.json b/vue/package.json index 5615b558d..10a8e23c8 100644 --- a/vue/package.json +++ b/vue/package.json @@ -61,6 +61,7 @@ "babel-eslint": "^10.1.0", "eslint": "^8.46.0", "eslint-plugin-vue": "^8.7.1", + "prettier": "^3.2.5", "typescript": "~5.3.3", "vue-cli-plugin-i18n": "^2.3.2", "webpack-bundle-tracker": "3.0.1", @@ -102,6 +103,7 @@ "printWidth": 179, "trailingComma": "es5", "tabWidth": 2, - "semi": false + "semi": false, + "experimentalTernaries": true } } diff --git a/vue/yarn.lock b/vue/yarn.lock index 663c77a06..eed173f13 100644 --- a/vue/yarn.lock +++ b/vue/yarn.lock @@ -9136,6 +9136,11 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.2.5: + version "3.2.5" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" + integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== + pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" From ca5fda7927ff2d71b07043790c194345fde99a8e Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Wed, 10 Apr 2024 20:04:17 +0200 Subject: [PATCH 06/17] added property type delete admin --- cookbook/admin.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cookbook/admin.py b/cookbook/admin.py index 402d6f3f4..88a1cd79a 100644 --- a/cookbook/admin.py +++ b/cookbook/admin.py @@ -185,7 +185,7 @@ class StepAdmin(admin.ModelAdmin): @admin.display(description="Name") def recipe_and_name(obj): if not obj.recipe_set.exists(): - return f"Orphaned Step{'':s if not obj.name else f': {obj.name}'}" + return f"Orphaned Step{'' if not obj.name else f': {obj.name}'}" return f"{obj.recipe_set.first().name}: {obj.name}" if obj.name else obj.recipe_set.first().name @@ -376,10 +376,17 @@ class ShareLinkAdmin(admin.ModelAdmin): admin.site.register(ShareLink, ShareLinkAdmin) +@admin.action(description='Delete all properties with type') +def delete_properties_with_type(modeladmin, request, queryset): + for pt in queryset: + Property.objects.filter(property_type=pt).delete() + + class PropertyTypeAdmin(admin.ModelAdmin): - search_fields = ('space',) + search_fields = ('name',) list_display = ('id', 'space', 'name', 'fdc_id') + actions = [delete_properties_with_type] admin.site.register(PropertyType, PropertyTypeAdmin) From c33c4ed79b47d5fe65cf5438bbf1d028ebdbeecc Mon Sep 17 00:00:00 2001 From: smilerz Date: Thu, 11 Apr 2024 07:27:22 -0500 Subject: [PATCH 07/17] moved prettier configuration to .prettierrc --- .gitignore | 28 ++++++++++++---------------- .prettierignore | 13 +++++++++++++ .prettierrc | 7 +++++++ vue/package.json | 7 ------- 4 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.gitignore b/.gitignore index 143271c6c..c4d38e418 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,11 @@ docs/reports/** # Django stuff: *.log +mediafiles/ +*.sqlite3* +staticfiles/ +postgresql/ +data/ # Sphinx documentation docs/_build/ @@ -59,32 +64,23 @@ target/ \.idea/dataSources\.local\.xml -venv/ - -mediafiles/ - -*.sqlite3* - \.idea/workspace\.xml \.idea/misc\.xml # Deployment - \.env -staticfiles/ -postgresql/ -data/ - +cookbook/static/vue +vue/webpack-stats.json /docker-compose.override.yml vue/node_modules plugins -vetur.config.js -cookbook/static/vue -vue/webpack-stats.json +vue3/node_modules cookbook/templates/sw.js -.prettierignore vue/.yarn vue3/.vite -vue3/node_modules + +# Configs +vetur.config.js +venv/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..aea0c3a51 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,13 @@ +# generated files +api.ts +vue/src/apps/*.js +vue/node_modules +staticfiles/ +docs/reports/ +/vue3/src/openapi/ + +# ignored files - prettier interferes with django templates and github actions +*.html +*.yml +*.yaml + diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..956e17f3c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 179, + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "experimentalTernaries": true +} diff --git a/vue/package.json b/vue/package.json index 10a8e23c8..98d8f337b 100644 --- a/vue/package.json +++ b/vue/package.json @@ -98,12 +98,5 @@ "resolutions": { "@vue/cli-plugin-pwa/workbox-webpack-plugin": "^5.1.3", "coa": "2.0.2" - }, - "prettier": { - "printWidth": 179, - "trailingComma": "es5", - "tabWidth": 2, - "semi": false, - "experimentalTernaries": true } } From 714242b6dfbe4cb2c659e5904344913d77534121 Mon Sep 17 00:00:00 2001 From: smilerz Date: Thu, 11 Apr 2024 17:36:24 -0500 Subject: [PATCH 08/17] tests for pk only nested serializer --- .../tests/other/test_nested_serializer.py | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 cookbook/tests/other/test_nested_serializer.py diff --git a/cookbook/tests/other/test_nested_serializer.py b/cookbook/tests/other/test_nested_serializer.py new file mode 100644 index 000000000..9623551cc --- /dev/null +++ b/cookbook/tests/other/test_nested_serializer.py @@ -0,0 +1,69 @@ +import json + +import pytest +from django.urls import reverse +from django_scopes import scopes_disabled +from pytest_factoryboy import LazyFixture, register + +from cookbook.tests.factories import FoodFactory, KeywordFactory, UnitFactory + +RECIPE_URL = 'api:recipe-detail' +FOOD_URL = 'api:food-detail' + +register(FoodFactory, 'food_1', space=LazyFixture('space_1')) +register(FoodFactory, 'food_2', space=LazyFixture('space_1')) +register(KeywordFactory, 'keyword_1', space=LazyFixture('space_1')) +register(KeywordFactory, 'keyword_2', space=LazyFixture('space_1')) +register(UnitFactory, 'unit_1', space=LazyFixture('space_1')) + + +@pytest.mark.parametrize("arg", ['dict', 'pk']) +def test_unnested_serializer__single(arg, recipe_1_s1, food_1, u1_s1): + if arg == 'dict': + recipe = {'id': recipe_1_s1.id, 'name': recipe_1_s1.name, } + elif arg == 'pk': + recipe = recipe_1_s1.id + r = u1_s1.patch(reverse(FOOD_URL, args={food_1.id}), {'name': food_1.name, 'recipe': recipe}, content_type='application/json') + assert r.status_code == 200 + assert json.loads(r.content)['recipe']['id'] == recipe_1_s1.id + + +def test_nested_serializer_many(recipe_1_s1, food_1, food_2, keyword_1, keyword_2, unit_1, u1_s1): + with scopes_disabled(): + assert food_1 not in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] + assert food_2 not in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] + assert keyword_1 not in recipe_1_s1.keywords.all() + assert keyword_2 not in recipe_1_s1.keywords.all() + r = u1_s1.patch(reverse(RECIPE_URL, args={recipe_1_s1.id}), { + 'name': + recipe_1_s1.name, + 'steps': [{ + 'ingredients': [{ + 'amount': 1, + 'unit': { + 'id': unit_1.id, + 'name': unit_1.name + }, + 'food': { + 'id': food_1.id, + 'name': food_1.name + } + }, { + 'amount': 1, + 'unit': unit_1.id, + 'food': food_2.id + }] + }], + 'keywords': [{ + 'id': keyword_1.id, + 'name': keyword_1.name + }, keyword_2.id] + }, + content_type='application/json') + assert r.status_code == 200 + with scopes_disabled(): + # recipe_1_s1 = Recipe.objects.get(id=recipe_1_s1.id) + assert food_1 in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] + assert food_2 in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] + assert keyword_1 in recipe_1_s1.keywords.all() + assert keyword_2 in recipe_1_s1.keywords.all() From cc24964368ff2401e5b04218fed560172876da3b Mon Sep 17 00:00:00 2001 From: smilerz Date: Thu, 11 Apr 2024 18:24:44 -0500 Subject: [PATCH 09/17] Revert "moved prettier configuration to .prettierrc" This reverts commit c33c4ed79b47d5fe65cf5438bbf1d028ebdbeecc. --- .gitignore | 30 +++++++++++++++++------------- .prettierignore | 13 ------------- .prettierrc | 7 ------- vue/package.json | 7 +++++++ 4 files changed, 24 insertions(+), 33 deletions(-) delete mode 100644 .prettierignore delete mode 100644 .prettierrc diff --git a/.gitignore b/.gitignore index c4d38e418..143271c6c 100644 --- a/.gitignore +++ b/.gitignore @@ -47,11 +47,6 @@ docs/reports/** # Django stuff: *.log -mediafiles/ -*.sqlite3* -staticfiles/ -postgresql/ -data/ # Sphinx documentation docs/_build/ @@ -64,23 +59,32 @@ target/ \.idea/dataSources\.local\.xml +venv/ + +mediafiles/ + +*.sqlite3* + \.idea/workspace\.xml \.idea/misc\.xml # Deployment -\.env -cookbook/static/vue -vue/webpack-stats.json +\.env +staticfiles/ +postgresql/ +data/ + + /docker-compose.override.yml vue/node_modules plugins -vue3/node_modules +vetur.config.js +cookbook/static/vue +vue/webpack-stats.json cookbook/templates/sw.js +.prettierignore vue/.yarn vue3/.vite - -# Configs -vetur.config.js -venv/ +vue3/node_modules diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index aea0c3a51..000000000 --- a/.prettierignore +++ /dev/null @@ -1,13 +0,0 @@ -# generated files -api.ts -vue/src/apps/*.js -vue/node_modules -staticfiles/ -docs/reports/ -/vue3/src/openapi/ - -# ignored files - prettier interferes with django templates and github actions -*.html -*.yml -*.yaml - diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 956e17f3c..000000000 --- a/.prettierrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "printWidth": 179, - "trailingComma": "es5", - "tabWidth": 2, - "semi": false, - "experimentalTernaries": true -} diff --git a/vue/package.json b/vue/package.json index 98d8f337b..10a8e23c8 100644 --- a/vue/package.json +++ b/vue/package.json @@ -98,5 +98,12 @@ "resolutions": { "@vue/cli-plugin-pwa/workbox-webpack-plugin": "^5.1.3", "coa": "2.0.2" + }, + "prettier": { + "printWidth": 179, + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "experimentalTernaries": true } } From 6cb68612288a778b753841b647719d30947af8fd Mon Sep 17 00:00:00 2001 From: smilerz Date: Fri, 12 Apr 2024 07:02:42 -0500 Subject: [PATCH 10/17] Revert "Revert "moved prettier configuration to .prettierrc"" This reverts commit cc24964368ff2401e5b04218fed560172876da3b. --- .gitignore | 28 ++++++++++++---------------- .prettierignore | 13 +++++++++++++ .prettierrc | 7 +++++++ vue/package.json | 7 ------- 4 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc diff --git a/.gitignore b/.gitignore index 143271c6c..c4d38e418 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,11 @@ docs/reports/** # Django stuff: *.log +mediafiles/ +*.sqlite3* +staticfiles/ +postgresql/ +data/ # Sphinx documentation docs/_build/ @@ -59,32 +64,23 @@ target/ \.idea/dataSources\.local\.xml -venv/ - -mediafiles/ - -*.sqlite3* - \.idea/workspace\.xml \.idea/misc\.xml # Deployment - \.env -staticfiles/ -postgresql/ -data/ - +cookbook/static/vue +vue/webpack-stats.json /docker-compose.override.yml vue/node_modules plugins -vetur.config.js -cookbook/static/vue -vue/webpack-stats.json +vue3/node_modules cookbook/templates/sw.js -.prettierignore vue/.yarn vue3/.vite -vue3/node_modules + +# Configs +vetur.config.js +venv/ diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..aea0c3a51 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,13 @@ +# generated files +api.ts +vue/src/apps/*.js +vue/node_modules +staticfiles/ +docs/reports/ +/vue3/src/openapi/ + +# ignored files - prettier interferes with django templates and github actions +*.html +*.yml +*.yaml + diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..956e17f3c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "printWidth": 179, + "trailingComma": "es5", + "tabWidth": 2, + "semi": false, + "experimentalTernaries": true +} diff --git a/vue/package.json b/vue/package.json index 10a8e23c8..98d8f337b 100644 --- a/vue/package.json +++ b/vue/package.json @@ -98,12 +98,5 @@ "resolutions": { "@vue/cli-plugin-pwa/workbox-webpack-plugin": "^5.1.3", "coa": "2.0.2" - }, - "prettier": { - "printWidth": 179, - "trailingComma": "es5", - "tabWidth": 2, - "semi": false, - "experimentalTernaries": true } } From 975ad34672fe6c9fa84c9e67a0b95dcf8abe09cc Mon Sep 17 00:00:00 2001 From: smilerz Date: Fri, 12 Apr 2024 07:02:57 -0500 Subject: [PATCH 11/17] Revert "tests for pk only nested serializer" This reverts commit 714242b6dfbe4cb2c659e5904344913d77534121. --- .../tests/other/test_nested_serializer.py | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 cookbook/tests/other/test_nested_serializer.py diff --git a/cookbook/tests/other/test_nested_serializer.py b/cookbook/tests/other/test_nested_serializer.py deleted file mode 100644 index 9623551cc..000000000 --- a/cookbook/tests/other/test_nested_serializer.py +++ /dev/null @@ -1,69 +0,0 @@ -import json - -import pytest -from django.urls import reverse -from django_scopes import scopes_disabled -from pytest_factoryboy import LazyFixture, register - -from cookbook.tests.factories import FoodFactory, KeywordFactory, UnitFactory - -RECIPE_URL = 'api:recipe-detail' -FOOD_URL = 'api:food-detail' - -register(FoodFactory, 'food_1', space=LazyFixture('space_1')) -register(FoodFactory, 'food_2', space=LazyFixture('space_1')) -register(KeywordFactory, 'keyword_1', space=LazyFixture('space_1')) -register(KeywordFactory, 'keyword_2', space=LazyFixture('space_1')) -register(UnitFactory, 'unit_1', space=LazyFixture('space_1')) - - -@pytest.mark.parametrize("arg", ['dict', 'pk']) -def test_unnested_serializer__single(arg, recipe_1_s1, food_1, u1_s1): - if arg == 'dict': - recipe = {'id': recipe_1_s1.id, 'name': recipe_1_s1.name, } - elif arg == 'pk': - recipe = recipe_1_s1.id - r = u1_s1.patch(reverse(FOOD_URL, args={food_1.id}), {'name': food_1.name, 'recipe': recipe}, content_type='application/json') - assert r.status_code == 200 - assert json.loads(r.content)['recipe']['id'] == recipe_1_s1.id - - -def test_nested_serializer_many(recipe_1_s1, food_1, food_2, keyword_1, keyword_2, unit_1, u1_s1): - with scopes_disabled(): - assert food_1 not in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] - assert food_2 not in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] - assert keyword_1 not in recipe_1_s1.keywords.all() - assert keyword_2 not in recipe_1_s1.keywords.all() - r = u1_s1.patch(reverse(RECIPE_URL, args={recipe_1_s1.id}), { - 'name': - recipe_1_s1.name, - 'steps': [{ - 'ingredients': [{ - 'amount': 1, - 'unit': { - 'id': unit_1.id, - 'name': unit_1.name - }, - 'food': { - 'id': food_1.id, - 'name': food_1.name - } - }, { - 'amount': 1, - 'unit': unit_1.id, - 'food': food_2.id - }] - }], - 'keywords': [{ - 'id': keyword_1.id, - 'name': keyword_1.name - }, keyword_2.id] - }, - content_type='application/json') - assert r.status_code == 200 - with scopes_disabled(): - # recipe_1_s1 = Recipe.objects.get(id=recipe_1_s1.id) - assert food_1 in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] - assert food_2 in [i.food for i in recipe_1_s1.steps.all()[0].ingredients.all()] - assert keyword_1 in recipe_1_s1.keywords.all() - assert keyword_2 in recipe_1_s1.keywords.all() From ab9ea87549cede11d6adb284ca01aa721ef9f10a Mon Sep 17 00:00:00 2001 From: smilerz Date: Thu, 11 Apr 2024 18:38:51 -0500 Subject: [PATCH 12/17] upgrade recipe-scrapers --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 03574e211..a22048a42 100644 --- a/requirements.txt +++ b/requirements.txt @@ -30,7 +30,7 @@ Jinja2==3.1.3 django-webpack-loader==3.0.1 git+https://github.com/BITSOLVER/django-js-reverse@071e304fd600107bc64bbde6f2491f1fe049ec82 django-allauth==0.61.1 -recipe-scrapers==14.53.0 +recipe-scrapers==15.0.0-rc2 django-scopes==2.0.0 django-treebeard==4.7 django-cors-headers==4.3.1 From 7133249f4b5a7934c6ccf35e2510f8e263a88086 Mon Sep 17 00:00:00 2001 From: smilerz Date: Fri, 12 Apr 2024 08:11:02 -0500 Subject: [PATCH 13/17] update recipe_scrapers to use scrape_html scrape_me has been deprecated --- cookbook/helper/scrapers/scrapers.py | 2 +- cookbook/views/api.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cookbook/helper/scrapers/scrapers.py b/cookbook/helper/scrapers/scrapers.py index 7d6c08b15..0cf01333b 100644 --- a/cookbook/helper/scrapers/scrapers.py +++ b/cookbook/helper/scrapers/scrapers.py @@ -30,7 +30,7 @@ def text_scraper(text, url=None): html=None, url=None, ): - self.wild_mode = False + self.supported_only = False self.meta_http_equiv = False self.soup = BeautifulSoup(html, "html.parser") self.url = url diff --git a/cookbook/views/api.py b/cookbook/views/api.py index a0ceada12..f890caeaa 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -35,7 +35,7 @@ from django.utils.translation import gettext as _ from django_scopes import scopes_disabled from icalendar import Calendar, Event from oauth2_provider.models import AccessToken -from recipe_scrapers import scrape_me +from recipe_scrapers import scrape_html from recipe_scrapers._exceptions import NoSchemaFoundInWildMode from requests.exceptions import MissingSchema from rest_framework import decorators, status, viewsets @@ -1437,8 +1437,8 @@ class RecipeUrlImportView(APIView): else: try: if validators.url(url, public=True): - scrape = scrape_me(url_path=url, wild_mode=True) - + html = requests.get(url).content + scrape = scrape_html(org_url=url, html=html, supported_only=False) else: return Response({'error': True, 'msg': _('Invalid Url')}, status=status.HTTP_400_BAD_REQUEST) except NoSchemaFoundInWildMode: From 1700b9c5313df4f9b53cd11a8396cba00d8cc1de Mon Sep 17 00:00:00 2001 From: smilerz Date: Fri, 12 Apr 2024 09:20:56 -0500 Subject: [PATCH 14/17] change test_automations to use scrape_html remove reliance on custom text_scraper class changed url on test case to generic wildmode vs specific site --- cookbook/helper/recipe_url_import.py | 63 +++++++++++++----------- cookbook/tests/other/test_automations.py | 46 +++++++++-------- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/cookbook/helper/recipe_url_import.py b/cookbook/helper/recipe_url_import.py index aa0bb2d87..eca6813aa 100644 --- a/cookbook/helper/recipe_url_import.py +++ b/cookbook/helper/recipe_url_import.py @@ -15,12 +15,9 @@ from cookbook.models import Automation, Keyword, PropertyType def get_from_scraper(scrape, request): - # converting the scrape_me object to the existing json format based on ld+json + # converting the scrape_html object to the existing json format based on ld+json - recipe_json = { - 'steps': [], - 'internal': True - } + recipe_json = {'steps': [], 'internal': True} keywords = [] # assign source URL @@ -157,11 +154,18 @@ def get_from_scraper(scrape, request): # assign steps try: for i in parse_instructions(scrape.instructions()): - recipe_json['steps'].append({'instruction': i, 'ingredients': [], 'show_ingredients_table': request.user.userpreference.show_step_ingredients, }) + recipe_json['steps'].append({ + 'instruction': i, + 'ingredients': [], + 'show_ingredients_table': request.user.userpreference.show_step_ingredients, + }) except Exception: pass if len(recipe_json['steps']) == 0: - recipe_json['steps'].append({'instruction': '', 'ingredients': [], }) + recipe_json['steps'].append({ + 'instruction': '', + 'ingredients': [], + }) recipe_json['description'] = recipe_json['description'][:512] if len(recipe_json['description']) > 256: # split at 256 as long descriptions don't look good on recipe cards @@ -182,20 +186,20 @@ def get_from_scraper(scrape, request): 'original_text': x } if unit: - ingredient['unit'] = {'name': unit, } + ingredient['unit'] = { + 'name': unit, + } recipe_json['steps'][0]['ingredients'].append(ingredient) except Exception: - recipe_json['steps'][0]['ingredients'].append( - { - 'amount': 0, - 'unit': None, - 'food': { - 'name': x, - }, - 'note': '', - 'original_text': x - } - ) + recipe_json['steps'][0]['ingredients'].append({ + 'amount': 0, + 'unit': None, + 'food': { + 'name': x, + }, + 'note': '', + 'original_text': x + }) except Exception: pass @@ -248,14 +252,16 @@ def get_from_youtube_scraper(url, request): 'working_time': 0, 'waiting_time': 0, 'image': "", - 'keywords': [{'name': kw.name, 'label': kw.name, 'id': kw.pk}], + 'keywords': [{ + 'name': kw.name, + 'label': kw.name, + 'id': kw.pk + }], 'source_url': url, - 'steps': [ - { - 'ingredients': [], - 'instruction': '' - } - ] + 'steps': [{ + 'ingredients': [], + 'instruction': '' + }] } try: @@ -452,10 +458,7 @@ def normalize_string(string): def iso_duration_to_minutes(string): - match = re.match( - r'P((?P\d+)Y)?((?P\d+)M)?((?P\d+)W)?((?P\d+)D)?T((?P\d+)H)?((?P\d+)M)?((?P\d+)S)?', - string - ).groupdict() + match = re.match(r'P((?P\d+)Y)?((?P\d+)M)?((?P\d+)W)?((?P\d+)D)?T((?P\d+)H)?((?P\d+)M)?((?P\d+)S)?', string).groupdict() return int(match['days'] or 0) * 24 * 60 + int(match['hours'] or 0) * 60 + int(match['minutes'] or 0) diff --git a/cookbook/tests/other/test_automations.py b/cookbook/tests/other/test_automations.py index 8b7b5568f..810a73f74 100644 --- a/cookbook/tests/other/test_automations.py +++ b/cookbook/tests/other/test_automations.py @@ -4,10 +4,10 @@ import pytest from django.contrib import auth from django.test import RequestFactory from django_scopes import scope +from recipe_scrapers import scrape_html from cookbook.helper.automation_helper import AutomationEngine from cookbook.helper.recipe_url_import import get_from_scraper -from cookbook.helper.scrapers.scrapers import text_scraper from cookbook.models import Automation DATA_DIR = "cookbook/tests/other/test_data/" @@ -73,12 +73,14 @@ def test_unit_automation(u1_s1, arg): assert (automation.apply_unit_automation(arg[0]) == target_name) is True -@pytest.mark.parametrize("arg", [ - [[1, 'egg', 'white'], '', [1, '', 'egg', 'white']], - [[1, 'Egg', 'white'], '', [1, '', 'Egg', 'white']], - [[1, 'êgg', 'white'], '', [1, 'êgg', 'white']], - [[1, 'egg', 'white'], 'whole', [1, 'whole', 'egg', 'white']], -]) +@pytest.mark.parametrize( + "arg", [ + [[1, 'egg', 'white'], '', [1, '', 'egg', 'white']], + [[1, 'Egg', 'white'], '', [1, '', 'Egg', 'white']], + [[1, 'êgg', 'white'], '', [1, 'êgg', 'white']], + [[1, 'egg', 'white'], 'whole', [1, 'whole', 'egg', 'white']], + ] +) def test_never_unit_automation(u1_s1, arg): user = auth.get_user(u1_s1) space = user.userspace_set.first().space @@ -97,13 +99,15 @@ def test_never_unit_automation(u1_s1, arg): ['.*allrecipes.*', True], ['.*google.*', False], ]) -@pytest.mark.parametrize("arg", [ - [Automation.DESCRIPTION_REPLACE], - [Automation.INSTRUCTION_REPLACE], - [Automation.NAME_REPLACE], - [Automation.FOOD_REPLACE], - [Automation.UNIT_REPLACE], -]) +@pytest.mark.parametrize( + "arg", [ + [Automation.DESCRIPTION_REPLACE], + [Automation.INSTRUCTION_REPLACE], + [Automation.NAME_REPLACE], + [Automation.FOOD_REPLACE], + [Automation.UNIT_REPLACE], + ] +) def test_regex_automation(u1_s1, arg, source): user = auth.get_user(u1_s1) space = user.userspace_set.first().space @@ -124,11 +128,13 @@ def test_regex_automation(u1_s1, arg, source): assert (automation.apply_regex_replace_automation(fail, arg[0]) == target) == False -@pytest.mark.parametrize("arg", [ - ['second first', 'first second'], - ['longer string second first longer string', 'longer string first second longer string'], - ['second fails first', 'second fails first'], -]) +@pytest.mark.parametrize( + "arg", [ + ['second first', 'first second'], + ['longer string second first longer string', 'longer string first second longer string'], + ['second fails first', 'second fails first'], + ] +) def test_transpose_automation(u1_s1, arg): user = auth.get_user(u1_s1) space = user.userspace_set.first().space @@ -160,7 +166,7 @@ def test_url_import_regex_replace(u1_s1): else: test_file = os.path.join(os.getcwd(), 'cookbook', 'tests', 'other', 'test_data', recipe) with open(test_file, 'r', encoding='UTF-8') as d: - scrape = text_scraper(text=d.read(), url="https://www.allrecipes.com") + scrape = scrape_html(html=d.read(), org_url="https://testrecipe.test", supported_only=False) with scope(space=space): for t in types: Automation.objects.get_or_create(name=t, type=t, param_1='.*', param_2=find_text, param_3='', created_by=user, space=space) From 371d8a76b8e8d0c1618ebc70a9f7786e284507f0 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Sun, 14 Apr 2024 18:58:52 +0200 Subject: [PATCH 15/17] added flake8 watcher --- .idea/watcherTasks.xml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .idea/watcherTasks.xml diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 000000000..0976eb2bc --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,31 @@ + + + + + + + + \ No newline at end of file From 7ce2c042c3196259fa69396f042c31412ceddf10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 02:51:06 +0000 Subject: [PATCH 16/17] Bump gunicorn from 21.2.0 to 22.0.0 Bumps [gunicorn](https://github.com/benoitc/gunicorn) from 21.2.0 to 22.0.0. - [Release notes](https://github.com/benoitc/gunicorn/releases) - [Commits](https://github.com/benoitc/gunicorn/compare/21.2.0...22.0.0) --- updated-dependencies: - dependency-name: gunicorn dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a22048a42..44b668919 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,7 +10,7 @@ drf-writable-nested==0.7.0 django-oauth-toolkit==2.3.0 django-debug-toolbar==4.3.0 bleach==6.0.0 -gunicorn==21.2.0 +gunicorn==22.0.0 lxml==5.1.0 Markdown==3.5.1 Pillow==10.3.0 From fce57f7f0315adf64c6db97bec0c291846fca131 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:18:46 +0000 Subject: [PATCH 17/17] Bump aiohttp from 3.9.3 to 3.9.4 Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.3 to 3.9.4. - [Release notes](https://github.com/aio-libs/aiohttp/releases) - [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) - [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.3...v3.9.4) --- updated-dependencies: - dependency-name: aiohttp dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 44b668919..51189602f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,7 +43,7 @@ django-auth-ldap==4.6.0 pyppeteer==2.0.0 validators==0.20.0 pytube==15.0.0 -aiohttp==3.9.3 +aiohttp==3.9.4 # Development pytest==8.0.0