Merge branch 'TandoorRecipes:develop' into cookbookapp-images-import

This commit is contained in:
caffeinated-tech
2025-07-06 01:16:27 +01:00
committed by GitHub
1291 changed files with 238809 additions and 179996 deletions

View File

@@ -1,8 +1,10 @@
If you like this application and want it to give back, there are many ways to contribute.
<!-- prettier-ignore-start -->
!!! 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.
<!-- prettier-ignore-end -->
## Translations
@@ -11,23 +13,23 @@ 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
- Armenian
- Bulgarian
- Catalan
- Czech
- Danish
- Dutch
- English
- French
- German
- Hungarian
- Italian
- Latvian
- Norwegian
- Polish
- Russian
- Spanish
- Swedish
See [here](/docs/contribute/translations) for further information on how to contribute translation to Tandoor.

View File

@@ -1,10 +1,12 @@
If you want to contribute bug fixes or small tweaks then your pull requests are always welcome!
<!-- prettier-ignore-start -->
!!! 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.
<!-- prettier-ignore-end -->
## License
@@ -20,23 +22,29 @@ To contribute to the project you are required to use the following packages with
- isort
- prettier
<!-- prettier-ignore -->
!!! 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
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
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.
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.
<!-- prettier-ignore -->
!!! note "JAVA required"
The OpenAPI Generator is a Java project. You must have the java binary executable available on your PATH for this to work.
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.

View File

@@ -1,5 +1,7 @@
!!! 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.
<!-- prettier-ignore-start -->
!!! info "Development Setup"
The dev setup is a little messy as this application combines the best (at least in my opinion) of both Django and Vue.js.
<!-- prettier-ignore-end -->
### Devcontainer Setup
@@ -30,10 +32,17 @@ populated from default values.
### Vue.js
<!-- prettier-ignore-start -->
!!! warning "Feature Freeze"
With the exception of bug fixes, no changes will be accepted on the legacy `vue` front-end.
<!-- prettier-ignore-end -->
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.
In the `vue` folder run `yarn install` followed by `yarn build` to install and build the legacy front-end.
In the `vue3` folder run `yarn install` followed by `yarn build` to install and build the new front-end.
After that you can use `yarn serve` from the `vue3` folder 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

@@ -13,14 +13,14 @@ PyCharm can be configured to format and lint on save. Doing so requires some man
2. Click the '+' to add a new watcher.
3. Configure the watcher as below.
![flake8_watcher](assets/flake8_watcher.png)
![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)
![linting error](assets/linting_error.png)
## Setup isort
@@ -28,7 +28,7 @@ PyCharm can be configured to format and lint on save. Doing so requires some man
2. Click the '+' to add a new watcher.
3. Configure the watcher as below.
![yapf_watcher](assets/isort_watcher.png)
![yapf_watcher](assets/isort_watcher.png)
## Setup yapf
@@ -36,12 +36,16 @@ PyCharm can be configured to format and lint on save. Doing so requires some man
2. Click the '+' to add a new watcher.
3. Configure the watcher as below.
![yapf_watcher](assets/yapf_watcher.png)
![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
<!-- prettier-ignore -->
!!! note
In order to debug vue yarn and vite servers must be started before starting the django server.
## Setup prettier
1. Navigate to File -> Settings -> Tools -> File Watchers
@@ -50,13 +54,11 @@ PyCharm can be configured to format and lint on save. Doing so requires some man
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//*`
- Name: prettier
- Pattern: `file:vue/src//*||file:vue3/src//*||file:docs//*`
6. Configure the watcher as below.
![perttier_watcher](assets/prettier_watcher.png)
![perttier_watcher](assets/prettier_watcher.png)
- Arguments: `--cwd $ProjectFileDir$\vue prettier -w --config $ProjectFileDir$\.prettierrc $FilePath$`
## Setup Volar??
- Arguments: `--cwd $ProjectFileDir$\vue prettier -w --config $ProjectFileDir$\.prettierrc $FilePath$`

View File

@@ -7,10 +7,11 @@ You can simply register an account and then follow these steps to add translatio
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.
<!-- prettier-ignore -->
!!! 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.

View File

@@ -27,19 +27,23 @@ VS Marketplace Link: https://marketplace.visualstudio.com/items?itemName=esbenp.
<!-- 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
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
<!-- prettier-ignore -->
!!! note
In order to debug vue yarn and vite servers must be started before starting the django server.
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.
- `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.

View File

@@ -8,6 +8,7 @@ authentication providers.
They basically explain everything in their documentation, but the following is a short overview on how to get started.
<!-- prettier-ignore -->
!!! warning "Public Providers"
If you choose Google, Github or any other publicly available service as your authentication provider anyone
with an account on that site can create an account on your installation.
@@ -23,8 +24,9 @@ When at least one social provider is set up, the social login sign in buttons sh
SOCIAL_PROVIDERS=allauth.socialaccount.providers.openid_connect,allauth.socialaccount.providers.nextcloud
```
<!-- prettier-ignore -->
!!! warning "Formatting"
The exact formatting is important so make sure to follow the steps explained here!
The exact formatting is important so make sure to follow the steps explained here!
### Configuration, via environment
@@ -40,8 +42,8 @@ Take the example configuration from the allauth docs, fill in your settings and
(you can use a service like [www.freeformatter.com](https://www.freeformatter.com/json-formatter.html) for formatting).
Assign it to the additional `SOCIALACCOUNT_PROVIDERS` variable.
The example below is for a generic OIDC provider with PKCE enabled. Most values need to be customized for your specifics!
```ini
SOCIALACCOUNT_PROVIDERS = "{ 'openid_connect': { 'OAUTH_PKCE_ENABLED': True, 'APPS': [ { 'provider_id': 'oidc', 'name': 'My-IDM', 'client_id': 'my_client_id', 'secret': 'my_client_secret', 'settings': { 'server_url': 'https://idm.example.com/oidc/recipes' } } ] } }"
```
@@ -69,16 +71,19 @@ Use your superuser account to configure your authentication backend by opening t
Now the provider is configured and you should be able to sign up and sign in using the provider.
Use the superuser account to grant permissions to the newly created users, or enable default access via `SOCIAL_DEFAULT_ACCESS` & `SOCIAL_DEFAULT_GROUP`.
<!-- prettier-ignore -->
!!! info "WIP"
I do not have a ton of experience with using various single signon providers and also cannot test all of them.
If you have any Feedback or issues let me know.
### Third-party authentication example
Keycloak is a popular IAM solution and integration is straight forward thanks to Django Allauth. This example can also be used as reference for other third-party authentication solutions, as documented by Allauth.
At Keycloak, create a new client and assign a `Client-ID`, this client comes with a `Secret-Key`. Both values are required later on. Make sure to define the correct Redirection-URL for the service, for example `https://tandoor.example.com/*`. Depending on your Keycloak setup, you need to assign roles and groups to grant access to the service.
To enable Keycloak as a sign in option, set those variables to define the social provider and specify its configuration:
```ini
SOCIAL_PROVIDERS=allauth.socialaccount.providers.openid_connect
SOCIALACCOUNT_PROVIDERS='{"openid_connect":{"APPS":[{"provider_id":"keycloak","name":"Keycloak","client_id":"KEYCLOAK_CLIENT_ID","secret":"KEYCLOAK_CLIENT_SECRET","settings":{"server_url":"https://auth.example.org/realms/KEYCLOAK_REALM/.well-known/openid-configuration"}}]}}
@@ -96,13 +101,16 @@ Here you can also unlink your account if you no longer want to use a social logi
LDAP authentication can be enabled in the `.env` file by setting `LDAP_AUTH=1`.
If set, users listed in the LDAP instance will be able to sign in without signing up.
These variables must be set to configure the connection to the LDAP instance:
```
AUTH_LDAP_SERVER_URI=ldap://ldap.example.org:389
AUTH_LDAP_BIND_DN=uid=admin,ou=users,dc=example,dc=org
AUTH_LDAP_BIND_PASSWORD=adminpassword
AUTH_LDAP_USER_SEARCH_BASE_DN=ou=users,dc=example,dc=org
```
Additional optional variables:
```
AUTH_LDAP_USER_SEARCH_FILTER_STR=(uid=%(user)s)
AUTH_LDAP_USER_ATTR_MAP={'first_name': 'givenName', 'last_name': 'sn', 'email': 'mail'}
@@ -114,9 +122,11 @@ AUTH_LDAP_TLS_CACERTFILE=/etc/ssl/certs/own-ca.pem
## External Authentication
<!-- prettier-ignore -->
!!! warning "Security Impact"
If you just set `REMOTE_USER_AUTH=1` without any additional configuration, _anybody_ can authenticate with _any_ username!
<!-- prettier-ignore -->
!!! Info "Community Contributed Tutorial"
This tutorial was provided by a community member. We are not able to provide any support! Please only use, if you know what you are doing!
@@ -128,6 +138,7 @@ In order use external authentication (i.e. using a proxy auth like Authelia, Aut
Using any of the examples above will automatically generate a configuration file inside a docker volume.
Use `docker volume inspect recipes_nginx` to find out where your volume is stored.
<!-- prettier-ignore -->
!!! warning "Configuration File Volume"
The nginx config volume is generated when the container is first run. You can change the volume to a bind mount in the
`docker-compose.yml`, but then you will need to manually create it. See section `Volumes vs Bind Mounts` below

View File

@@ -1,7 +1,8 @@
<!-- prettier-ignore -->
!!! warning
Automations are currently in a beta stage. They work pretty stable but if I encounter any
issues while working on them, I might change how they work breaking existing automations.
I will try to avoid this and am pretty confident it won't happen.
Automations are currently in a beta stage. They work pretty stable but if I encounter any
issues while working on them, I might change how they work breaking existing automations.
I will try to avoid this and am pretty confident it won't happen.
Automations allow Tandoor to automatically perform certain tasks, especially when importing recipes, that
would otherwise have to be done manually. Currently, the following automations are supported.
@@ -45,10 +46,11 @@ ChatGPT and similiar LLMs are also useful for creating RegEx patterns:
`ChatGPT please create a Regex expression in the format of re.sub(<parameter 2>, <parameter 3>, <description>, count=1)
that will change the string <example string here> into the string <desired result here>`
<!-- prettier-ignore -->
!!! info
In order to prevent denial of service attacks on the RegEx engine the number of replace automations
and the length of the inputs that are processed are limited. Those limits should never be reached
during normal usage.
In order to prevent denial of service attacks on the RegEx engine the number of replace automations
and the length of the inputs that are processed are limited. Those limits should never be reached
during normal usage.
## Instruction Replace, Title Replace, Food Replace & Unit Replace

View File

@@ -1,3 +1,4 @@
<!-- prettier-ignore -->
!!! warning
Connectors are currently in a beta stage.
@@ -6,6 +7,7 @@
Connectors are a powerful add-on component to TandoorRecipes.
They allow for certain actions to be translated to api calls to external services.
<!-- prettier-ignore -->
!!! danger
In order for this application to push data to external providers it needs to store authentication information.
Please use read only/separate accounts or app passwords wherever possible.

View File

@@ -1,6 +1,7 @@
The original intend of this application was to provide a search interface to my large collection of PDF scans of recipes.
This feature is now called External recipes.
<!-- prettier-ignore -->
!!! info
Internal recipes are stored in a structured manner inside the database. They can be displayed using the standardized
interface and support features like shopping lists, scaling and steps.
@@ -12,76 +13,87 @@ Lastly you will need to sync with the external path and import recipes you desir
## Storage
<!-- prettier-ignore -->
!!! danger
In order for this application to retrieve data from external providers it needs to store authentication information.
Please use read only/separate accounts or app passwords wherever possible.
There are better ways to do this but they are currently not implemented
A `Storage Backend` is a remote storage location where files are **read** from.
To add a new backend click on `username >> External Recipes >> Manage External Storage >> the + next to Storage Backend List`.
To add a new backend click on `username >> External Recipes >> Manage External Storage >> the + next to Storage Backend List`.
There click the plus button.
The basic configuration is the same for all providers.
The basic configuration is the same for all providers.
| Field | Value |
|----------|-------|
| Name | Your identifier for this storage source, can be everything you want. |
| Method | The desired method. |
| Field | Value |
| ------ | -------------------------------------------------------------------- |
| Name | Your identifier for this storage source, can be everything you want. |
| Method | The desired method. |
<!-- prettier-ignore -->
!!! success
Only the providers listed below are currently implemented. If you need anything else feel free to open
an issue or pull request.
### Local
<!-- prettier-ignore -->
!!! info
There is currently no way to upload files through the webinterface. This is a feature that might be added later.
The local provider does not need any configuration (username, password, token or URL).
For the monitor you will need to define a valid path on your host system. (Path)
The Path depends on your setup and can be both relative and absolute.
For the monitor you will need to define a valid path on your host system. (Path)
The Path depends on your setup and can be both relative and absolute.
<!-- prettier-ignore -->
!!! warning "Volume"
By default no data other than the mediafiles and the database is persisted. If you use the local provider
make sure to mount the path you choose to monitor to your host system in order to keep it persistent.
#### Docker
If you use docker the default directory is `/opt/recipes/`.
add
```
- ./externalfiles:/opt/recipes/externalfiles
```
to your docker-compose.yml file under the `web_recipes >> volumes` section. This will create a folder in your docker directory named `externalfiles` under which you could choose to store external pdfs (you could of course store them anywhere, just change `./externalfiles` to your preferred location).
save the docker-compose.yml and restart your docker container.
### Dropbox
| Field | Value |
|----------|-------|
| Username | Dropbox username |
| Token | Dropbox API Token. Can be found [here](https://dropbox.github.io/dropbox-api-v2-explorer/#auth_token/from_oauth1)|
| Field | Value |
| -------- | ----------------------------------------------------------------------------------------------------------------- |
| Username | Dropbox username |
| Token | Dropbox API Token. Can be found [here](https://dropbox.github.io/dropbox-api-v2-explorer/#auth_token/from_oauth1) |
### Nextcloud
<!-- prettier-ignore -->
!!! warning "Path"
It appears that the correct webdav path varies from installation to installation (for whatever reason).
In the Nextcloud webinterface click the `Settings` button in the bottom left corner, there your WebDav Url will be displayed.
| Field | Value |
|----------|-------|
| Username | Nextcloud username |
| Password | Nextcloud app password |
| Url | Nextcloud Server URL (e.g. `https://cloud.mydomain.com`) |
| Field | Value |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| Username | Nextcloud username |
| Password | Nextcloud app password |
| Url | Nextcloud Server URL (e.g. `https://cloud.mydomain.com`) |
| Path | (optional) webdav path (e.g. `/remote.php/dav/files/vabene1111`). If no path is supplied `/remote.php/dav/files/` plus your username will be used. |
## Adding External Recipes
To add a new path from your Storage backend to the sync list, go to `username >> External Recipes` and
To add a new path from your Storage backend to the sync list, go to `username >> External Recipes` and
select the storage backend you want to use.
Then enter the path you want to monitor starting at the storage root (e.g. `/Folder/RecipesFolder`, or `/opt/recipes/externalfiles' in the docker example above) and save it.
## Syncing Data
To sync the recipes app with the storage backends press `Sync now` under `username >> External Recipes`
## Discovered Recipes
All files found by the sync can be found under `Manage Data >> Discovered recipes`.
All files found by the sync can be found under `Manage Data >> Discovered recipes`.
There you can either import all at once without modifying them or import one by one, adding tags while importing.

View File

@@ -132,6 +132,13 @@ This can either be a relative path from the applications base path or the url of
STATIC_URL=/static/
```
#### Static root
> default `<basedir>/staticfiles` - options `/some/other/media/path`.
Where staticfiles should be stored on disk. The default location is a
`staticfiles` subfolder at the root of the application directory.
#### Media URL
> default `/static/` - options: `/any/url/path/`, `https://any.domain.name/and/url/path`
@@ -293,6 +300,12 @@ PRIVACY_URL=
IMPRINT_URL=
```
#### Rate Limits
There are some rate limits that can be configured.
- RATELIMIT_URL_IMPORT_REQUESTS: limit the number of external URL import requests. Useful to prevent your server from being abused for malicious requests.
### Authentication
All configurable variables regarding authentication.
@@ -457,6 +470,20 @@ S3_ENDPOINT_URL= # when using a custom endpoint like minio
S3_CUSTOM_DOMAIN= # when using a CDN/proxy to S3 (see https://github.com/TandoorRecipes/recipes/issues/1943)
```
#### AI Integration
To use AI to perform different tasks you need to configure an API key and the AI provider. [LiteLLM](https://www.litellm.ai/) is used
to make a standardized request to different AI providers of your liking.
Configuring this via environment parameters is a temporary solution. In the future I plan on adding support for multiple AI providers per Tandoor instance
with the option to select them for various tasks. For now only gemini 2.0 flash has been tested but feel free to try out other models.
```
AI_API_KEY=
AI_MODEL_NAME=gemini/gemini-2.0-flash
AI_RATELIMIT=60/hour
```
#### FDC Api
The FDC Api is used to automatically load nutrition information from