Merge branch 'develop' into feature/vue3

# Conflicts:
#	.gitignore
#	docs/contribute.md
#	recipes/settings.py
#	requirements.txt
This commit is contained in:
vabene1111
2024-04-11 18:00:42 +02:00
29 changed files with 528 additions and 213 deletions

22
.flake8 Normal file
View File

@@ -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

23
.gitignore vendored
View File

@@ -47,6 +47,11 @@ docs/reports/**
# Django stuff:
*.log
mediafiles/
*.sqlite3*
staticfiles/
postgresql/
data/
# Sphinx documentation
docs/_build/
@@ -59,24 +64,15 @@ 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
/recipes/plugins
@@ -85,7 +81,10 @@ 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

13
.prettierignore Normal file
View File

@@ -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

7
.prettierrc Normal file
View File

@@ -0,0 +1,7 @@
{
"printWidth": 179,
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"experimentalTernaries": true
}

11
.vscode/settings.json vendored
View File

@@ -3,5 +3,12 @@
"cookbook/tests"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
"python.testing.pytestEnabled": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[python]": {
"editor.defaultFormatter": "eeyore.yapf",
},
"yapf.args": [],
"isort.args": []
}

View File

@@ -6,8 +6,6 @@ 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
@@ -35,12 +33,6 @@ 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

17
boot.sh
View File

@@ -67,21 +67,12 @@ echo "Migrating database"
python manage.py migrate
if [[ "${DOCKER}" == "true" ]]; then
echo "Copying cached static files from docker build"
echo "Generating static files"
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
python manage.py collectstatic_js_reverse
python manage.py collectstatic --noinput
echo "Done"
fi
echo "Done"
chmod -R 755 /opt/recipes/mediafiles

View File

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

View File

@@ -1,117 +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.
### 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 `vue3` 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 `vue3/src/openapi`.
Generate the schema using `openapi-generator-cli generate -g typescript-fetch -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 <language_code> -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.

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -0,0 +1,55 @@
If you like this application and want it to give back, there are many ways to contribute.
!!! 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.
## Translations
If you know any foreign languages you can:
Improve the translations for any of the existing languages.
Add a new language to the long list of existing translations.
- Armenian
- Bulgarian
- Catalan
- Czech
- Danish
- Dutch
- English
- French
- German
- Hungarian
- Italian
- Latvian
- Norwegian
- Polish
- Russian
- Spanish
- Swedish
See [here](/contribute/translations) for further information on how to contribute translation to Tandoor.
## Issues and Feature Requests
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.
## Documentation
Helping improve the documentation for Tandoor is one of the easiest ways to give back and doesn't even require deep technical knowledge.
You can write guides on how to install and configure Tandoor expanding our repository of non-standard configuations.
Or you can write how-to guides using some of Tandoor's advanced features such as authentication or automation.
See [here](/contribute/documentation) for more information on how to add documentation to Tandoor.
## Contributing Code
For the truly ambitious, you can help write code to fix issues, add additional features, or write your own scripts using
Tandoor's extensive API and share your work with the community.
Before writing any code, please make sure that you review [contribution guidelines](/contribute/guidelines) and
[VSCode](/contribute/vscode) or [PyCharm](/contribute/pycharm) specific configurations.

View File

@@ -0,0 +1,26 @@
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, there are a couple of methods that you can use.
## Directly on GitHub
You can fork the develop repository and edit the markdown files directly on the GitHub website.
## With an IDE
You can fork the develop repository and edit the markdown files from your favorite IDE such as VSCode or PyCharm.
One advantage of using as IDE is that you can preview your changes by:
### Installing mkdocs
Now install mkdocs and dependencies: `pip install mkdocs-material mkdocs-include-markdown-plugin`.
### Serving Documetation
If you want to test the documentation, locally run `mkdocs serve` from the project root.
## Super Low Tech
Create your documentation in any work processor (or even create a video!) and [open a feature request](https://github.com/vabene1111/recipes/issues)
attaching your document and requesting that someone add the documentation to Tandoor.

View File

@@ -0,0 +1,63 @@
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.
## License
Contributing to Tandoor requires signing a Contributor License Agreement. You can review the CLA [here](https://cla-assistant.io/TandoorRecipes/recipes).
## Linting & Formatting
Tandoor uses a number of libraries to maintain style and formatting consistency.
To contribute to the project you are required to use the following packages with the project defined configurations:
- flake8
- yapf
- isort
- prettier
!!! tip "Manual Formatting"
It is possible to run formatting manually, but it is recommended to setup your IDE to format on save.
``` bash
flake8 file.py --ignore=E501 | isort -q file.py | yapf -i file.py
prettier --write file.vue
```
## Testing
Django uses pytest-django to implement a full suite of testing. If you make any functional changes, please implment the appropriate
tests.
Tandoor is also actively soliciting contribors willing to setup vue3 testing. If you have knowledge in this area it would be greatly appreciated.
## API Client
Tandoor uses [django-rest-framework](https://www.django-rest-framework.org/) for API implementation. Making contributions that impact the API requires an understanding of
Viewsets and Serializers.
Also double check that your changes are actively reflected in the schema so that client apis are generated accurately.
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`.)
### Vue
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.)
### Vue3
Navigate to `vue3/src/openapi`.
Generate the schema using `openapi-generator-cli generate -g typescript-fetch -i http://127.0.0.1:8000/openapi/`. (Replace your dev server url if required.)
## Install and Configuration
Instructions for [VSCode](/contribute/vscode)
Instructions for [PyCharm](/contribute/pycharm)

View File

@@ -0,0 +1,39 @@
!!! 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`.
### 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.

View File

@@ -0,0 +1,62 @@
PyCharm can be configured to format and lint on save. Doing so requires some manual configuration as outlined below.
## Setup File Watchers
1. Navigate to File -> 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)
<!-- prettier-ignore -->
!!! 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??

View File

@@ -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.

View File

@@ -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 <language_code> -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.

45
docs/contribute/vscode.md Normal file
View File

@@ -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
<!-- prettier-ignore -->
!!! 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.

View File

@@ -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).

View File

@@ -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

12
pyproject.toml Normal file
View File

@@ -0,0 +1,12 @@
[tool.yapf]
column_limit = 179
based_on_style = "pep8"
DISABLE_ENDING_COMMA_HEURISTIC = false
COALESCE_BRACKETS = true
DEDENT_CLOSING_BRACKETS = true
FORCE_MULTILINE_DICT = false
[tool.isort]
multi_line_output = 5
skip = [".gitignore", ".dockerignore"]
line_length = 179

View File

@@ -210,10 +210,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:
@@ -244,7 +252,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',
@@ -271,7 +283,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))
@@ -285,15 +300,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')
@@ -358,17 +378,23 @@ SPECTACULAR_SETTINGS = {
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'
@@ -439,7 +465,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')
@@ -502,9 +533,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/
@@ -562,7 +609,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))

View File

@@ -56,4 +56,6 @@ pytest-factoryboy==2.6.0
pytest-html==4.1.1
pytest-asyncio==0.23.5
pytest-xdist==3.5.0
django-vite==3.0.3
autopep8==2.0.4
flake8==6.1.0
yapf==0.40.2

View File

@@ -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",

View File

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