Merge branch 'mealie-next' into feat-frontend-access-controll

This commit is contained in:
boc-the-git 2024-02-18 20:15:40 +11:00 committed by GitHub
commit ba4eddccd9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 1928 additions and 1004 deletions

View File

@ -22,7 +22,13 @@ jobs:
permissions: permissions:
contents: read contents: read
packages: write packages: write
# The id-token write permission is needed to connect to Depot.dev
# as part of the partial-builder.yml action. It needs to be declared
# in the parent action, as noted here:
# https://github.com/orgs/community/discussions/76409#discussioncomment-8131390
id-token: write
name: Build Tagged Release name: Build Tagged Release
if: github.repository == 'mealie-recipes/mealie'
uses: ./.github/workflows/partial-builder.yml uses: ./.github/workflows/partial-builder.yml
needs: needs:
- frontend-tests - frontend-tests
@ -35,6 +41,7 @@ jobs:
notify-discord: notify-discord:
name: Notify Discord name: Notify Discord
if: github.repository == 'mealie-recipes/mealie'
needs: needs:
- build-release - build-release
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -35,19 +35,16 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Override __init__.py - name: Override __init__.py
run: | run: |
echo "__version__ = \"${{ inputs.tag }}\"" > ./mealie/__init__.py echo "__version__ = \"${{ inputs.tag }}\"" > ./mealie/__init__.py
- name: Build and push Docker image - uses: depot/setup-action@v1
uses: docker/build-push-action@v5
- name: Build and push Docker image, via Depot.dev
uses: depot/build-push-action@v1
with: with:
project: srzjb6mhzm
file: ./docker/Dockerfile file: ./docker/Dockerfile
context: . context: .
platforms: linux/amd64,linux/arm64 platforms: linux/amd64,linux/arm64
@ -58,6 +55,3 @@ jobs:
${{ inputs.tags }} ${{ inputs.tags }}
build-args: | build-args: |
COMMIT=${{ github.sha }} COMMIT=${{ github.sha }}
# https://docs.docker.com/build/ci/github-actions/cache/#github-cache
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@ -17,6 +17,11 @@ jobs:
permissions: permissions:
contents: read contents: read
packages: write packages: write
# The id-token write permission is needed to connect to Depot.dev
# as part of the partial-builder.yml action. It needs to be declared
# in the parent action, as noted here:
# https://github.com/orgs/community/discussions/76409#discussioncomment-8131390
id-token: write
name: Build Tagged Release name: Build Tagged Release
uses: ./.github/workflows/partial-builder.yml uses: ./.github/workflows/partial-builder.yml
needs: needs:

View File

@ -71,12 +71,9 @@ Distributed under the AGPL License. See `LICENSE` for more information.
Huge thanks to all the sponsors of this project on [Github Sponsors](https://github.com/sponsors/hay-kot) and Buy Me a Coffee. Without you, this project would surely not be possible. Huge thanks to all the sponsors of this project on [Github Sponsors](https://github.com/sponsors/hay-kot) and Buy Me a Coffee. Without you, this project would surely not be possible.
Thanks to Linode for providing Hosting for the Demo, Beta, and Documentation sites! Another big thanks to JetBrains for providing their IDEs for development. Thanks to Depot for providing build instances for our Docker image builds.
<div align='center'> [![Built with Depot](https://depot.dev/badges/built-with-depot.svg)](https://depot.dev?utm_source=Mealie)
<img height="100" src="docs/docs/assets/img/sponsors-linode.svg" />
<img height="100" src="docs/docs/assets/img/sponsors-jetbrains.png" />
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 230 90" width="2500" height="978"><path d="M93.8 27.8l5.8-1.4v28c0 3.1.9 4.9 2.7 5.5-.9 1.7-2.4 2.6-4.6 2.6-2.6 0-4-1.8-4-5.5V27.8zM108.4 62V41.8h-3.2V37h9.1v25h-5.9zm3-34.6c.9 0 1.7.3 2.4 1s1 1.5 1 2.4c0 .9-.3 1.7-1 2.4s-1.5 1-2.4 1c-.9 0-1.7-.3-2.4-1s-1-1.5-1-2.4c0-.9.3-1.7 1-2.4s1.5-1 2.4-1zM137.1 62V47.6c0-2.1-.4-3.7-1.2-4.6-.8-1-2.1-1.5-4-1.5-.9 0-1.8.2-2.7.7-1 .5-1.7 1.1-2.3 1.8v18h-5.8V37.1h4.2l1.1 2.3c1.6-1.9 3.9-2.8 7-2.8 3 0 5.3.9 7 2.7 1.7 1.8 2.6 4.3 2.6 7.4V62h-5.9zM147.5 49.5c0-3.8 1.1-6.9 3.3-9.3 2.2-2.4 5.1-3.6 8.7-3.6 3.8 0 6.7 1.1 8.8 3.4 2.1 2.3 3.1 5.4 3.1 9.4s-1.1 7.1-3.2 9.5c-2.1 2.3-5 3.5-8.8 3.5-3.8 0-6.7-1.2-8.8-3.5-2-2.4-3.1-5.5-3.1-9.4zm6.1 0c0 5.5 2 8.2 5.9 8.2 1.8 0 3.2-.7 4.3-2.1 1.1-1.4 1.6-3.5 1.6-6.1 0-5.4-2-8.1-5.9-8.1-1.8 0-3.3.7-4.3 2.1-1.1 1.4-1.6 3.4-1.6 6zM192.1 62v-1.5c-.5.5-1.3 1-2.4 1.4-1.1.4-2.3.6-3.6.6-3.5 0-6.2-1.1-8.2-3.3-2-2.2-3-5.3-3-9.2 0-3.9 1.1-7.1 3.4-9.6s5.1-3.7 8.6-3.7c1.9 0 3.6.4 5.2 1.2v-10l5.8-1.4V62h-5.8zm0-19c-1.2-1-2.5-1.5-3.9-1.5-2.3 0-4.1.7-5.4 2.1-1.3 1.4-1.9 3.5-1.9 6.1 0 5.2 2.5 7.8 7.5 7.8.6 0 1.2-.2 2.1-.5.8-.3 1.3-.7 1.6-1V43zM226 51.3h-17.8c.1 2 .8 3.5 2 4.6 1.3 1.1 2.9 1.7 5.1 1.7 2.6 0 4.7-.7 6-2.1l2.3 4.4c-2 1.7-5.1 2.5-9.2 2.5-3.8 0-6.8-1.1-9-3.3-2.2-2.2-3.3-5.3-3.3-9.3 0-3.9 1.2-7.1 3.6-9.5 2.4-2.4 5.3-3.6 8.7-3.6 3.6 0 6.5 1.1 8.7 3.2 2.2 2.2 3.3 4.9 3.3 8.2.1.7-.1 1.7-.4 3.2zm-17.6-4.4h12.2c-.4-3.6-2.4-5.5-6-5.5-3.3.1-5.4 1.9-6.2 5.5z"/><g><path fill="#004712" d="M65.9 47.4l-1 11.5-3.3-2.3.4-5.8v-.1-.1l-.1-.1-.1-.1-7.1-4.7.1-5.1 11.1 6.8zM48.5 59.9L43.4 56v.9c0 .2-.1.4-.2.5L39.4 60l4.2 3.4.1.1v.2l.2 4 4.7 3.9-.1-11.7zm-32.1 5l2.4 11.5 9.9 10.5L27 75.3 16.4 64.9zm9.3 1.7l-2.4-16.1-12-10 3.2 15.6 11.2 10.5zm-3.8-26l-3.3-22.8L4.8 9.2l4.5 21.5 12.6 9.9z"/><path fill="#00B259" d="M75.7 41.2l-1.5 10.9-8.2 6.6 1-11.2 8.7-6.3zM49.6 59.9l.1 11.8 10.5-8.4.7-11.5-11.3 8.1zm-6.8 4.8L28 75.3l1.8 12.2 13.4-10.7-.4-12.1zm-.4-8l-.7-16-17.3 9.9 2.4 16.6 15.6-10.5zm-1.1-25.3l-.9-21.6-20.8 8L23 41l18.3-9.6z"/><path d="M76.9 40c0-.1 0-.1 0 0v-.2s0-.1-.1-.1c0 0-.1 0-.1-.1l-12-6.7c-.2-.1-.4-.1-.5 0L54 39.1h-.1v.6l-.1 5.4-4.1-2.7c-.2-.1-.4-.1-.6 0L43 45.8l-.3-6v-.1-.1-.1-.1-.1h-.1l-6.2-4.1 5.8-3c.2-.1.3-.3.3-.5L41.4 9v-.1s0-.1-.1-.1c0 0 0-.1-.1-.1L25.5 1.1c-.1-.1-.2-.1-.3-.1L3.9 7.6s-.1 0-.1.1c0 0-.1 0-.1.1v.6l4.7 22.9c0 .1.1.2.2.3l6.4 5-4.7 2.2s-.1 0-.1.1c0 0 0 .1-.1.1v.2l3.6 17.2c0 .1.1.2.2.3l4.5 4.2-3 1.8-.1.1s0 .1-.1.1V63.2L18 76.5c0 .1.1.2.1.3l10.9 12h.1s.1 0 .1.1h.5l14.4-11.5c.1-.1.2-.3.2-.4l-.3-7.9 4.8 4s.1 0 .1.1h.5L61 64c.1-.1.2-.2.2-.4l.4-5.8 3.5 2.4h.4s.1 0 .1-.1l9.4-7.5c.1-.1.2-.2.2-.3L76.9 40c0 .1 0 .1 0 0zM66 58.7l1-11.2 8.8-6.3-1.5 10.9-8.3 6.6zm-4.4-2.1l.4-5.8v-.1-.1l-.1-.1-.1-.1-7.1-4.7.1-5.1 11.1 6.9-1 11.5-3.3-2.4zm-1.5 6.7l-10.5 8.4-.1-11.8 11.3-8.1-.7 11.5zM43.3 76.8L29.8 87.5 28 75.3l14.7-10.5.6 12zm-24.6-.4l-2.4-11.5L27 75.3l1.7 11.6-10-10.5zm-.2-58.6l3.3 22.8-12.5-9.9L4.8 9.2l13.7 8.6zm21.9-8l.9 21.6L23 41l-3.4-23.2 20.8-8zm2 46.9L26.8 67.1l-2.4-16.6 17.3-9.9.7 16.1zm-19.1-6.1l2.4 16.1-11.2-10.6-3.2-15.6 12 10.1zm20.5 13.1v-.1-.1l-.1-.1-4.2-3.4 3.8-2.6c.2-.1.2-.3.2-.5V56l5.1 3.9.1 11.8-4.7-3.9-.2-4.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -133,7 +133,7 @@ export default defineComponent({
const domMadeThisForm = ref<VForm>(); const domMadeThisForm = ref<VForm>();
const newTimelineEvent = ref<RecipeTimelineEventIn>({ const newTimelineEvent = ref<RecipeTimelineEventIn>({
// @ts-expect-error - TS doesn't like the $auth global user attribute // @ts-expect-error - TS doesn't like the $auth global user attribute
subject: i18n.t("recipe.user-made-this", { user: $auth.user.fullName } as string), subject: i18n.tc("recipe.user-made-this", { user: $auth.user.fullName }),
eventType: "comment", eventType: "comment",
eventMessage: "", eventMessage: "",
timestamp: undefined, timestamp: undefined,

View File

@ -9,11 +9,11 @@
"database-url": "URL de base de datos", "database-url": "URL de base de datos",
"default-group": "Grupo Predeterminado", "default-group": "Grupo Predeterminado",
"demo": "Versión Demo", "demo": "Versión Demo",
"demo-status": "Estado Demo", "demo-status": "Modo Demo",
"development": "Desarrollo", "development": "Desarrollo",
"docs": "Documentación", "docs": "Documentación",
"download-log": "Descargar Log", "download-log": "Descargar Log",
"download-recipe-json": "Último JSON recuperado", "download-recipe-json": "Último JSON extraído",
"github": "Github", "github": "Github",
"log-lines": "Líneas de registro", "log-lines": "Líneas de registro",
"not-demo": "No Demo", "not-demo": "No Demo",
@ -33,7 +33,7 @@
"pdf": "PDF", "pdf": "PDF",
"recipe": "Receta", "recipe": "Receta",
"show-assets": "Mostrar recursos", "show-assets": "Mostrar recursos",
"error-submitting-form": "Se ha producido un error al enviar el formulario" "error-submitting-form": "Error al enviar el formulario"
}, },
"category": { "category": {
"categories": "Categorías", "categories": "Categorías",
@ -200,7 +200,7 @@
"created-on-date": "Creado el {0}", "created-on-date": "Creado el {0}",
"unsaved-changes": "Tienes cambios sin guardar. ¿Quieres guardar antes de salir? Aceptar para guardar, Cancelar para descartar cambios.", "unsaved-changes": "Tienes cambios sin guardar. ¿Quieres guardar antes de salir? Aceptar para guardar, Cancelar para descartar cambios.",
"clipboard-copy-failure": "No se pudo copiar al portapapeles.", "clipboard-copy-failure": "No se pudo copiar al portapapeles.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?" "confirm-delete-generic-items": "¿Estás seguro que quieres eliminar los siguientes elementos?"
}, },
"group": { "group": {
"are-you-sure-you-want-to-delete-the-group": "Por favor, confirma que deseas eliminar <b>{groupName}<b/>", "are-you-sure-you-want-to-delete-the-group": "Por favor, confirma que deseas eliminar <b>{groupName}<b/>",
@ -599,9 +599,9 @@
"import-summary": "Importar resumen", "import-summary": "Importar resumen",
"partial-backup": "Copia de seguridad parcial", "partial-backup": "Copia de seguridad parcial",
"unable-to-delete-backup": "No se puede eliminar la copia de seguridad.", "unable-to-delete-backup": "No se puede eliminar la copia de seguridad.",
"experimental-description": "Backups a total snapshots of the database and data directory of the site. This includes all data and cannot be set to exclude subsets of data. You can think off this as a snapshot of Mealie at a specific time. Currently, {not-crossed-version} (data migrations are not done automatically). These serve as a database agnostic way to export and import data or backup the site to an external location.", "experimental-description": "Las copias de seguridad son instantáneas completas de la base de datos y del directorio de datos del sitio. Esto incluye todos los datos y no se pueden configurar para excluir subconjuntos de datos. Puedes pensar en esto como una instantánea de Mealie en un momento específico. Estas sirven como una forma agnóstica de la base de datos para exportar e importar datos, o respaldar el sitio en una ubicación externa.",
"backup-restore": "Restaurar Copia de Seguridad", "backup-restore": "Restaurar Copia de Seguridad",
"back-restore-description": "Restoring this backup will overwrite all the current data in your database and in the data directory and replace them with the contents of this backup. {cannot-be-undone} If the restoration is successful, you will be logged out.", "back-restore-description": "Restaurar esta copia de seguridad sobrescribirá todos los datos actuales de su base de datos y del directorio de datos y los sustituirá por el contenido de esta copia. {cannot-be-undone} Si la restauración se realiza correctamente, se cerrará su sesión.",
"cannot-be-undone": "Esta acción no se puede deshacer, use con precaución.", "cannot-be-undone": "Esta acción no se puede deshacer, use con precaución.",
"postgresql-note": "Si estás usando PostGreSQL, por favor revisa el {backup-restore-process} antes de restaurar.", "postgresql-note": "Si estás usando PostGreSQL, por favor revisa el {backup-restore-process} antes de restaurar.",
"backup-restore-process-in-the-documentation": "copia de seguridad/proceso de restauración en la documentación", "backup-restore-process-in-the-documentation": "copia de seguridad/proceso de restauración en la documentación",
@ -723,7 +723,7 @@
"ldap-ready": "LDAP Listo", "ldap-ready": "LDAP Listo",
"ldap-ready-error-text": "No todos los valores LDAP están configurados. Esto puede ignorarse si no está usando autenticación LDAP.", "ldap-ready-error-text": "No todos los valores LDAP están configurados. Esto puede ignorarse si no está usando autenticación LDAP.",
"ldap-ready-success-text": "Las variables LDAP requeridas están todas definidas.", "ldap-ready-success-text": "Las variables LDAP requeridas están todas definidas.",
"build": "Compilar", "build": "Compilación",
"recipe-scraper-version": "Versión de Analizador de Recetas" "recipe-scraper-version": "Versión de Analizador de Recetas"
}, },
"shopping-list": { "shopping-list": {
@ -962,9 +962,9 @@
"settings-chosen-explanation": "Los ajustes seleccionados aquí, excluyendo la opción bloqueada, se aplicarán a todas las recetas seleccionadas.", "settings-chosen-explanation": "Los ajustes seleccionados aquí, excluyendo la opción bloqueada, se aplicarán a todas las recetas seleccionadas.",
"selected-length-recipe-s-settings-will-be-updated": "Se actualizarán los ajustes de {count} receta(s).", "selected-length-recipe-s-settings-will-be-updated": "Se actualizarán los ajustes de {count} receta(s).",
"recipe-data": "Datos de la receta", "recipe-data": "Datos de la receta",
"recipe-data-description": "Use this section to manage the data associated with your recipes. You can perform several bulk actions on your recipes including exporting, deleting, tagging, and assigning categories.", "recipe-data-description": "Utiliza esta sección para gestionar los datos asociados a tus recetas. Puedes realizar varias acciones de forma masiva en tus recetas, como exportar, eliminar, etiquetar y asignar categorías.",
"recipe-columns": "Recipe Columns", "recipe-columns": "Columnas de Recetas",
"data-exports-description": "This section provides links to available exports that are ready to download. These exports do expire, so be sure to grab them while they're still available.", "data-exports-description": "Esta sección proporciona enlaces a las exportaciones disponibles listas para descargar. Estas exportaciones caducan, así que asegúrate de descargarlas mientras estén disponibles.",
"data-exports": "Exportación de datos", "data-exports": "Exportación de datos",
"tag": "Etiqueta", "tag": "Etiqueta",
"categorize": "Clasificar", "categorize": "Clasificar",
@ -973,14 +973,14 @@
"categorize-recipes": "Categorizar recetas", "categorize-recipes": "Categorizar recetas",
"export-recipes": "Exportar recetas", "export-recipes": "Exportar recetas",
"delete-recipes": "Borrar Recetas", "delete-recipes": "Borrar Recetas",
"source-unit-will-be-deleted": "Source Unit will be deleted" "source-unit-will-be-deleted": "Se eliminará la unidad de origen"
}, },
"create-alias": "Crear un Alias", "create-alias": "Crear un Alias",
"manage-aliases": "Administrar Alias", "manage-aliases": "Administrar Alias",
"seed-data": "Datos de ejemplo", "seed-data": "Datos de ejemplo",
"seed": "Semilla", "seed": "Semilla",
"data-management": "Data Management", "data-management": "Gestión de Datos",
"data-management-description": "Select which data set you want to make changes to.", "data-management-description": "Selecciona el conjunto de datos al que deseas hacer cambios.",
"select-data": "Seleccionar datos", "select-data": "Seleccionar datos",
"select-language": "Seleccionar idioma", "select-language": "Seleccionar idioma",
"columns": "Columnas", "columns": "Columnas",
@ -1003,7 +1003,7 @@
}, },
"user-registration": { "user-registration": {
"user-registration": "Registro de usuario", "user-registration": "Registro de usuario",
"registration-success": "Registration Success", "registration-success": "Registrado con éxito",
"join-a-group": "Unirse a un grupo", "join-a-group": "Unirse a un grupo",
"create-a-new-group": "Crear un grupo nuevo", "create-a-new-group": "Crear un grupo nuevo",
"provide-registration-token-description": "Por favor, proporcione el token de registro asociado con el grupo al que desea unirse. Necesitará obtenerlo de un miembro del grupo.", "provide-registration-token-description": "Por favor, proporcione el token de registro asociado con el grupo al que desea unirse. Necesitará obtenerlo de un miembro del grupo.",
@ -1050,57 +1050,57 @@
}, },
"ocr-editor": { "ocr-editor": {
"ocr-editor": "Editor de OCR", "ocr-editor": "Editor de OCR",
"toolbar": "Toolbar", "toolbar": "Barra de Herramientas",
"selection-mode": "Modo de selección", "selection-mode": "Modo de selección",
"pan-and-zoom-picture": "Desplazar y hacer zoom en la imagen", "pan-and-zoom-picture": "Desplazar y hacer zoom en la imagen",
"split-text": "Split text", "split-text": "Dividir texto",
"preserve-line-breaks": "Preserve original line breaks", "preserve-line-breaks": "Mantener los saltos de línea originales",
"split-by-block": "Split by text block", "split-by-block": "División por bloques de texto",
"flatten": "Flatten regardless of original formating", "flatten": "Acoplar independientemente del formato original",
"help": { "help": {
"help": "Help", "help": "Ayuda",
"mouse-modes": "Mouse modes", "mouse-modes": "Modos de ratón",
"selection-mode": "Selection Mode (default)", "selection-mode": "Modo selección (por defecto)",
"selection-mode-desc": "The selection mode is the main mode that can be used to enter data:", "selection-mode-desc": "El modo de selección es el modo principal que puede utilizarse para introducir datos:",
"selection-mode-steps": { "selection-mode-steps": {
"draw": "Draw a rectangle on the text you want to select.", "draw": "Dibuja un rectángulo sobre el texto que deseas seleccionar.",
"click": "Click on any field on the right and then click back on the rectangle above the image.", "click": "Click on any field on the right and then click back on the rectangle above the image.",
"result": "The selected text will appear inside the previously selected field." "result": "The selected text will appear inside the previously selected field."
}, },
"pan-and-zoom-mode": "Pan and Zoom Mode", "pan-and-zoom-mode": "Modo Panorámico y Zoom",
"pan-and-zoom-desc": "Select pan and zoom by clicking the icon. This mode allows to zoom inside the image and move around to make using big images easier.", "pan-and-zoom-desc": "Select pan and zoom by clicking the icon. This mode allows to zoom inside the image and move around to make using big images easier.",
"split-text-mode": "Split Text modes", "split-text-mode": "Modos de división de texto",
"split-modes": { "split-modes": {
"line-mode": "Line mode (default)", "line-mode": "Modo de línea (por defecto)",
"line-mode-desc": "In line mode, the text will be propagated by keeping the original line breaks. This mode is useful when using bulk add on a list of ingredients where one ingredient is one line.", "line-mode-desc": "In line mode, the text will be propagated by keeping the original line breaks. This mode is useful when using bulk add on a list of ingredients where one ingredient is one line.",
"block-mode": "Block mode", "block-mode": "Modo en bloque",
"block-mode-desc": "In block mode, the text will be split in blocks. This mode is useful when bulk adding instructions that are usually written in paragraphs.", "block-mode-desc": "En el modo de bloque, el texto se dividirá en bloques. Este modo es útil cuando se agregan instrucciones que están escritas en párrafos.",
"flat-mode": "Flat mode", "flat-mode": "Modo texto sin formato",
"flat-mode-desc": "In flat mode, the text will be added to the selected recipe field with no line breaks." "flat-mode-desc": "En modo texto sin formato, el texto se añadirá al campo de la receta seleccionado sin saltos de línea."
} }
} }
}, },
"admin": { "admin": {
"maintenance": { "maintenance": {
"storage-details": "Storage Details", "storage-details": "Detalle del almacenamiento",
"page-title": "Site Maintenance", "page-title": "Mantenimiento del sitio",
"summary-title": "Summary", "summary-title": "Índice",
"button-label-get-summary": "Get Summary", "button-label-get-summary": "Obtener Resumen",
"button-label-open-details": "Detalles", "button-label-open-details": "Detalles",
"info-description-data-dir-size": "Data Directory Size", "info-description-data-dir-size": "Tamaño del directorio de datos",
"info-description-log-file-size": "Log File Size", "info-description-log-file-size": "Tamaño del archivo de registro",
"info-description-cleanable-directories": "Cleanable Directories", "info-description-cleanable-directories": "Directorios eliminables",
"info-description-cleanable-images": "Cleanable Images", "info-description-cleanable-images": "Imágenes eliminables",
"storage": { "storage": {
"title-temporary-directory": "Directorio temporal (.temp)", "title-temporary-directory": "Directorio temporal (.temp)",
"title-backups-directory": "Backups Directory (backups)", "title-backups-directory": "Directorio de Copias de Seguridad (respaldos)",
"title-groups-directory": "Groups Directory (groups)", "title-groups-directory": "Directorio de Grupos (grupos)",
"title-recipes-directory": "Recipes Directory (recipes)", "title-recipes-directory": "Directorio de Recetas (recetas)",
"title-user-directory": "User Directory (user)" "title-user-directory": "Directorio de usuario (usuario)"
}, },
"action-delete-log-files-name": "Delete Log Files", "action-delete-log-files-name": "Borrar archivos de registro",
"action-delete-log-files-description": "Deletes all the log files", "action-delete-log-files-description": "Elimina todos los archivos de registro",
"action-clean-directories-name": "Clean Directories", "action-clean-directories-name": "Limpiar directorios",
"action-clean-directories-description": "Removes all the recipe folders that are not valid UUIDs", "action-clean-directories-description": "Removes all the recipe folders that are not valid UUIDs",
"action-clean-temporary-files-name": "Eliminar archivos temporales", "action-clean-temporary-files-name": "Eliminar archivos temporales",
"action-clean-temporary-files-description": "Eliminar todos los archivos y carpetas del directorio .temp", "action-clean-temporary-files-description": "Eliminar todos los archivos y carpetas del directorio .temp",
@ -1119,8 +1119,8 @@
"ingredients-natural-language-processor": "Ingredients Natural Language Processor", "ingredients-natural-language-processor": "Ingredients Natural Language Processor",
"ingredients-natural-language-processor-explanation": "Mealie uses Conditional Random Fields (CRFs) for parsing and processing ingredients. The model used for ingredients is based off a data set of over 100,000 ingredients from a dataset compiled by the New York Times. Note that as the model is trained in English only, you may have varied results when using the model in other languages. This page is a playground for testing the model.", "ingredients-natural-language-processor-explanation": "Mealie uses Conditional Random Fields (CRFs) for parsing and processing ingredients. The model used for ingredients is based off a data set of over 100,000 ingredients from a dataset compiled by the New York Times. Note that as the model is trained in English only, you may have varied results when using the model in other languages. This page is a playground for testing the model.",
"ingredients-natural-language-processor-explanation-2": "It's not perfect, but it yields great results in general and is a good starting point for manually parsing ingredients into individual fields. Alternatively, you can also use the \"Brute\" processor that uses a pattern matching technique to identify ingredients.", "ingredients-natural-language-processor-explanation-2": "It's not perfect, but it yields great results in general and is a good starting point for manually parsing ingredients into individual fields. Alternatively, you can also use the \"Brute\" processor that uses a pattern matching technique to identify ingredients.",
"nlp": "NLP", "nlp": "PLN",
"brute": "Brute", "brute": "En bruto",
"show-individual-confidence": "Mostrar confianza individual", "show-individual-confidence": "Mostrar confianza individual",
"ingredient-text": "Texto del ingrediente", "ingredient-text": "Texto del ingrediente",
"average-confident": "{0} Confianza", "average-confident": "{0} Confianza",
@ -1148,31 +1148,31 @@
"user-settings-description": "Administrar preferencias, cambiar contraseña y actualizar correo electrónico", "user-settings-description": "Administrar preferencias, cambiar contraseña y actualizar correo electrónico",
"api-tokens-description": "Administra tus API Tokens para acceder desde aplicaciones externas", "api-tokens-description": "Administra tus API Tokens para acceder desde aplicaciones externas",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!", "group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings", "group-settings": "Ajustes de grupo",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.", "group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
"cookbooks-description": "Manage a collection of recipe categories and generate pages for them.", "cookbooks-description": "Manage a collection of recipe categories and generate pages for them.",
"members": "Members", "members": "Miembros",
"members-description": "See who's in your group and manage their permissions.", "members-description": "Ver quién está en tu grupo y administrar sus permisos.",
"webhooks-description": "Setup webhooks that trigger on days that you have have mealplan scheduled.", "webhooks-description": "Setup webhooks that trigger on days that you have have mealplan scheduled.",
"notifiers": "Notifiers", "notifiers": "Notificaciones",
"notifiers-description": "Setup email and push notifications that trigger on specific events.", "notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data", "manage-data": "Administrar datos",
"manage-data-description": "Manage your Food and Units (more options coming soon)", "manage-data-description": "Administra tu Comida y Unidades (próximamente más opciones)",
"data-migrations": "Data Migrations", "data-migrations": "Migración de datos",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown", "data-migrations-description": "Migrar tus datos existentes de otras aplicaciones como Nextcloud Recipes y Chowdown",
"email-sent": "Email Sent", "email-sent": "Email enviado",
"error-sending-email": "Error Sending Email", "error-sending-email": "Error enviando email",
"personal-information": "Personal Information", "personal-information": "Datos Personales",
"preferences": "Preferences", "preferences": "Preferencias",
"show-advanced-description": "Show advanced features (API Keys, Webhooks, and Data Management)", "show-advanced-description": "Mostrar características avanzadas (API Keys, Webhooks y Gestión de Datos)",
"back-to-profile": "Back to Profile", "back-to-profile": "Volver al perfil",
"looking-for-privacy-settings": "Looking for Privacy Settings?", "looking-for-privacy-settings": "¿Buscas los ajustes de privacidad?",
"manage-your-api-tokens": "Manage Your API Tokens", "manage-your-api-tokens": "Gestiona tus API tokens",
"manage-user-profile": "Manage User Profile", "manage-user-profile": "Administrar Perfil de Usuario",
"manage-cookbooks": "Manage Cookbooks", "manage-cookbooks": "Administrar Recetario",
"manage-members": "Gestionar miembros", "manage-members": "Gestionar miembros",
"manage-webhooks": "Manage Webhooks", "manage-webhooks": "Gestionar Webhooks",
"manage-notifiers": "Manage Notifiers", "manage-notifiers": "Administrar Notificadores",
"manage-data-migrations": "Administrar Migraciones de Datos" "manage-data-migrations": "Administrar Migraciones de Datos"
}, },
"cookbook": { "cookbook": {
@ -1187,7 +1187,7 @@
"require-all-tools": "Requiere todos los utensilios", "require-all-tools": "Requiere todos los utensilios",
"cookbook-name": "Nombre del recetario", "cookbook-name": "Nombre del recetario",
"cookbook-with-name": "Recetario {0}", "cookbook-with-name": "Recetario {0}",
"create-a-cookbook": "Create a Cookbook", "create-a-cookbook": "Crear Recetario",
"cookbook": "Cookbook" "cookbook": "Recetario"
} }
} }

View File

@ -28,7 +28,7 @@
"date-fns": "^2.29.3", "date-fns": "^2.29.3",
"fuse.js": "^6.6.2", "fuse.js": "^6.6.2",
"isomorphic-dompurify": "^1.0.0", "isomorphic-dompurify": "^1.0.0",
"nuxt": "^2.16.0", "nuxt": "^2.17.3",
"v-jsoneditor": "^1.4.5", "v-jsoneditor": "^1.4.5",
"vue-advanced-cropper": "^1.11.6", "vue-advanced-cropper": "^1.11.6",
"vuedraggable": "^2.24.3", "vuedraggable": "^2.24.3",
@ -56,8 +56,8 @@
}, },
"resolutions": { "resolutions": {
"@nuxtjs/i18n/**/ufo": "0.7.9", "@nuxtjs/i18n/**/ufo": "0.7.9",
"vue-template-compiler": "2.7.14",
"vue-demi": "^0.13.11", "vue-demi": "^0.13.11",
"vue-template-compiler": "2.7.16",
"postcss-preset-env": "^7.0.0", "postcss-preset-env": "^7.0.0",
"typescript": "^4.9.5" "typescript": "^4.9.5"
} }

View File

@ -48,46 +48,54 @@
</div> </div>
<v-expansion-panels v-model="panels" multiple> <v-expansion-panels v-model="panels" multiple>
<v-expansion-panel v-for="(ing, index) in parsedIng" :key="index"> <draggable
<v-expansion-panel-header class="my-0 py-0" disable-icon-rotate> v-if="parsedIng.length > 0"
<template #default="{ open }"> v-model="parsedIng"
<v-fade-transition> handle=".handle"
<span v-if="!open" key="0"> {{ ing.input }} </span> :style="{ width: '100%' }"
</v-fade-transition> ghost-class="ghost"
</template> >
<template #actions> <v-expansion-panel v-for="(ing, index) in parsedIng" :key="index">
<v-icon left :color="isError(ing) ? 'error' : 'success'"> <v-expansion-panel-header class="my-0 py-0" disable-icon-rotate>
{{ isError(ing) ? $globals.icons.alert : $globals.icons.check }} <template #default="{ open }">
</v-icon> <v-fade-transition>
<div class="my-auto" :color="isError(ing) ? 'error-text' : 'success-text'"> <span v-if="!open" key="0"> {{ ing.input }} </span>
{{ ing.confidence ? asPercentage(ing.confidence.average) : "" }} </v-fade-transition>
</div> </template>
</template> <template #actions>
</v-expansion-panel-header> <v-icon left :color="isError(ing) ? 'error' : 'success'">
<v-expansion-panel-content class="pb-0 mb-0"> {{ isError(ing) ? $globals.icons.alert : $globals.icons.check }}
<RecipeIngredientEditor v-model="parsedIng[index].ingredient" allow-insert-ingredient @insert-ingredient="insertIngredient(index)" @delete="deleteIngredient(index)" /> </v-icon>
{{ ing.input }} <div class="my-auto" :color="isError(ing) ? 'error-text' : 'success-text'">
<v-card-actions> {{ ing.confidence ? asPercentage(ing.confidence.average) : "" }}
<v-spacer /> </div>
<BaseButton </template>
v-if="errors[index].unitError && errors[index].unitErrorMessage !== ''" </v-expansion-panel-header>
color="warning" <v-expansion-panel-content class="pb-0 mb-0">
small <RecipeIngredientEditor v-model="parsedIng[index].ingredient" allow-insert-ingredient @insert-ingredient="insertIngredient(index)" @delete="deleteIngredient(index)" />
@click="createUnit(ing.ingredient.unit, index)" {{ ing.input }}
> <v-card-actions>
{{ errors[index].unitErrorMessage }} <v-spacer />
</BaseButton> <BaseButton
<BaseButton v-if="errors[index].unitError && errors[index].unitErrorMessage !== ''"
v-if="errors[index].foodError && errors[index].foodErrorMessage !== ''" color="warning"
color="warning" small
small @click="createUnit(ing.ingredient.unit, index)"
@click="createFood(ing.ingredient.food, index)" >
> {{ errors[index].unitErrorMessage }}
{{ errors[index].foodErrorMessage }} </BaseButton>
</BaseButton> <BaseButton
</v-card-actions> v-if="errors[index].foodError && errors[index].foodErrorMessage !== ''"
</v-expansion-panel-content> color="warning"
</v-expansion-panel> small
@click="createFood(ing.ingredient.food, index)"
>
{{ errors[index].foodErrorMessage }}
</BaseButton>
</v-card-actions>
</v-expansion-panel-content>
</v-expansion-panel>
</draggable>
</v-expansion-panels> </v-expansion-panels>
</v-container> </v-container>
</v-container> </v-container>
@ -96,6 +104,7 @@
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, ref, useContext, useRoute, useRouter } from "@nuxtjs/composition-api"; import { computed, defineComponent, ref, useContext, useRoute, useRouter } from "@nuxtjs/composition-api";
import { invoke, until } from "@vueuse/core"; import { invoke, until } from "@vueuse/core";
import draggable from "vuedraggable";
import { import {
CreateIngredientFood, CreateIngredientFood,
CreateIngredientUnit, CreateIngredientUnit,
@ -122,6 +131,7 @@ interface Error {
export default defineComponent({ export default defineComponent({
components: { components: {
RecipeIngredientEditor, RecipeIngredientEditor,
draggable
}, },
middleware: ["auth", "group-only"], middleware: ["auth", "group-only"],
setup() { setup() {

View File

@ -39,6 +39,7 @@
:recipe-id="mealplan.recipe ? mealplan.recipe.id : ''" :recipe-id="mealplan.recipe ? mealplan.recipe.id : ''"
class="mb-2" class="mb-2"
:route="mealplan.recipe ? true : false" :route="mealplan.recipe ? true : false"
:rating="mealplan.recipe ? mealplan.recipe.rating : 0"
:slug="mealplan.recipe ? mealplan.recipe.slug : mealplan.title" :slug="mealplan.recipe ? mealplan.recipe.slug : mealplan.title"
:description="mealplan.recipe ? mealplan.recipe.description : mealplan.text" :description="mealplan.recipe ? mealplan.recipe.description : mealplan.text"
:name="mealplan.recipe ? mealplan.recipe.name : mealplan.title" :name="mealplan.recipe ? mealplan.recipe.name : mealplan.title"

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
import os
from collections.abc import Callable from collections.abc import Callable
from pathlib import Path from pathlib import Path
from time import sleep from time import sleep
@ -87,7 +88,12 @@ def main():
if max_retry == 0: if max_retry == 0:
raise ConnectionError("Database connection failed - exiting application.") raise ConnectionError("Database connection failed - exiting application.")
alembic_cfg = Config(str(PROJECT_DIR / "alembic.ini")) alembic_cfg_path = os.getenv("ALEMBIC_CONFIG_FILE", default=str(PROJECT_DIR / "alembic.ini"))
if not os.path.isfile(alembic_cfg_path):
raise Exception("Provided alembic config path doesn't exist")
alembic_cfg = Config(alembic_cfg_path)
if db_is_at_head(alembic_cfg): if db_is_at_head(alembic_cfg):
logger.debug("Migration not needed.") logger.debug("Migration not needed.")
else: else:

View File

@ -33,12 +33,12 @@
"generic-deleted": "{name} wurde gelöscht" "generic-deleted": "{name} wurde gelöscht"
}, },
"datetime": { "datetime": {
"year": "year|years", "year": "jahr|jahre",
"day": "day|days", "day": "tag|tage",
"hour": "hour|hours", "hour": "stunde|stunden",
"minute": "minute|minutes", "minute": "minute|minuten",
"second": "second|seconds", "second": "sekunde|sekunden",
"millisecond": "millisecond|milliseconds", "millisecond": "millisekunde|millisekunden",
"microsecond": "microsecond|microseconds" "microsecond": "mikrosekunde|mikrosekunden"
} }
} }

View File

@ -33,12 +33,12 @@
"generic-deleted": "Se ha eliminado {name}" "generic-deleted": "Se ha eliminado {name}"
}, },
"datetime": { "datetime": {
"year": "year|years", "year": "año|años",
"day": "day|days", "day": "día|días",
"hour": "hour|hours", "hour": "hora|horas",
"minute": "minute|minutes", "minute": "minuto|minutos",
"second": "second|seconds", "second": "segundo|segundos",
"millisecond": "millisecond|milliseconds", "millisecond": "milisegundo|milisegundos",
"microsecond": "microsecond|microseconds" "microsecond": "microsegundo|microsegundos"
} }
} }

View File

@ -140,7 +140,11 @@ class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
if isinstance(i, UUID): if isinstance(i, UUID):
ids.append(i) ids.append(i)
else: else:
slugs.append(i) try:
i_as_uuid = UUID(i)
ids.append(i_as_uuid)
except ValueError:
slugs.append(i)
additional_ids = self.session.execute(select(model.id).filter(model.slug.in_(slugs))).scalars().all() additional_ids = self.session.execute(select(model.id).filter(model.slug.in_(slugs))).scalars().all()
return ids + additional_ids return ids + additional_ids

View File

@ -1,3 +1,4 @@
import os
import subprocess import subprocess
import tempfile import tempfile
from fractions import Fraction from fractions import Fraction
@ -13,7 +14,7 @@ from . import utils
from .pre_processor import pre_process_string from .pre_processor import pre_process_string
CWD = Path(__file__).parent CWD = Path(__file__).parent
MODEL_PATH = CWD / "model.crfmodel" MODEL_PATH = os.getenv("CRF_MODEL_PATH", default=CWD / "model.crfmodel")
class CRFConfidence(BaseModel): class CRFConfidence(BaseModel):

197
poetry.lock generated
View File

@ -1359,61 +1359,61 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
[[package]] [[package]]
name = "orjson" name = "orjson"
version = "3.9.13" version = "3.9.14"
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "orjson-3.9.13-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:fa6b67f8bef277c2a4aadd548d58796854e7d760964126c3209b19bccc6a74f1"}, {file = "orjson-3.9.14-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:793f6c9448ab6eb7d4974b4dde3f230345c08ca6c7995330fbceeb43a5c8aa5e"},
{file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b812417199eeb169c25f67815cfb66fd8de7ff098bf57d065e8c1943a7ba5c8f"}, {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bc7928d161840096adc956703494b5c0193ede887346f028216cac0af87500"},
{file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ccd5bd222e5041069ad9d9868ab59e6dbc53ecde8d8c82b919954fbba43b46b"}, {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:58b36f54da759602d8e2f7dad958752d453dfe2c7122767bc7f765e17dc59959"},
{file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaaf80957c38e9d3f796f355a80fad945e72cd745e6b64c210e635b7043b673e"}, {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abcda41ecdc950399c05eff761c3de91485d9a70d8227cb599ad3a66afe93bcc"},
{file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:60da7316131185d0110a1848e9ad15311e6c8938ee0b5be8cbd7261e1d80ee8f"}, {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df76ecd17b1b3627bddfd689faaf206380a1a38cc9f6c4075bd884eaedcf46c2"},
{file = "orjson-3.9.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b98cd948372f0eb219bc309dee4633db1278687161e3280d9e693b6076951d2"}, {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d450a8e0656efb5d0fcb062157b918ab02dcca73278975b4ee9ea49e2fcf5bd5"},
{file = "orjson-3.9.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3869d65561f10071d3e7f35ae58fd377056f67d7aaed5222f318390c3ad30339"}, {file = "orjson-3.9.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:95c03137b0cf66517c8baa65770507a756d3a89489d8ecf864ea92348e1beabe"},
{file = "orjson-3.9.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:43fd6036b16bb6742d03dae62f7bdf8214d06dea47e4353cde7e2bd1358d186f"}, {file = "orjson-3.9.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20837e10835c98973673406d6798e10f821e7744520633811a5a3d809762d8cc"},
{file = "orjson-3.9.13-cp310-none-win32.whl", hash = "sha256:0d3ba9d88e20765335260d7b25547d7c571eee2b698200f97afa7d8c7cd668fc"}, {file = "orjson-3.9.14-cp310-none-win32.whl", hash = "sha256:1f7b6f3ef10ae8e3558abb729873d033dbb5843507c66b1c0767e32502ba96bb"},
{file = "orjson-3.9.13-cp310-none-win_amd64.whl", hash = "sha256:6e47153db080f5e87e8ba638f1a8b18995eede6b0abb93964d58cf11bcea362f"}, {file = "orjson-3.9.14-cp310-none-win_amd64.whl", hash = "sha256:ea890e6dc1711aeec0a33b8520e395c2f3d59ead5b4351a788e06bf95fc7ba81"},
{file = "orjson-3.9.13-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4584e8eb727bc431baaf1bf97e35a1d8a0109c924ec847395673dfd5f4ef6d6f"}, {file = "orjson-3.9.14-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c19009ff37f033c70acd04b636380379499dac2cba27ae7dfc24f304deabbc81"},
{file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f37f0cdd026ef777a4336e599d8194c8357fc14760c2a5ddcfdf1965d45504b"}, {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19cdea0664aec0b7f385be84986d4defd3334e9c3c799407686ee1c26f7b8251"},
{file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d714595d81efab11b42bccd119977d94b25d12d3a806851ff6bfd286a4bce960"}, {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:135d518f73787ce323b1a5e21fb854fe22258d7a8ae562b81a49d6c7f826f2a3"},
{file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9171e8e1a1f221953e38e84ae0abffe8759002fd8968106ee379febbb5358b33"}, {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2cf1d0557c61c75e18cf7d69fb689b77896e95553e212c0cc64cf2087944b84"},
{file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ab9dbdec3f13f3ea6f937564ce21651844cfbf2725099f2f490426acf683c23"}, {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7c11667421df2d8b18b021223505dcc3ee51be518d54e4dc49161ac88ac2b87"},
{file = "orjson-3.9.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:811ac076855e33e931549340288e0761873baf29276ad00f221709933c644330"}, {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eefc41ba42e75ed88bc396d8fe997beb20477f3e7efa000cd7a47eda452fbb2"},
{file = "orjson-3.9.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:860d0f5b42d0c0afd73fa4177709f6e1b966ba691fcd72175affa902052a81d6"}, {file = "orjson-3.9.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:917311d6a64d1c327c0dfda1e41f3966a7fb72b11ca7aa2e7a68fcccc7db35d9"},
{file = "orjson-3.9.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:838b898e8c1f26eb6b8d81b180981273f6f5110c76c22c384979aca854194f1b"}, {file = "orjson-3.9.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4dc1c132259b38d12c6587d190cd09cd76e3b5273ce71fe1372437b4cbc65f6f"},
{file = "orjson-3.9.13-cp311-none-win32.whl", hash = "sha256:d3222db9df629ef3c3673124f2e05fb72bc4a320c117e953fec0d69dde82e36d"}, {file = "orjson-3.9.14-cp311-none-win32.whl", hash = "sha256:6f39a10408478f4c05736a74da63727a1ae0e83e3533d07b19443400fe8591ca"},
{file = "orjson-3.9.13-cp311-none-win_amd64.whl", hash = "sha256:978117122ca4cc59b28af5322253017f6c5fc03dbdda78c7f4b94ae984c8dd43"}, {file = "orjson-3.9.14-cp311-none-win_amd64.whl", hash = "sha256:26280a7fcb62d8257f634c16acebc3bec626454f9ab13558bbf7883b9140760e"},
{file = "orjson-3.9.13-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:031df1026c7ea8303332d78711f180231e3ae8b564271fb748a03926587c5546"}, {file = "orjson-3.9.14-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:08e722a8d06b13b67a51f247a24938d1a94b4b3862e40e0eef3b2e98c99cd04c"},
{file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fd9a2101d04e85086ea6198786a3f016e45475f800712e6833e14bf9ce2832f"}, {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2591faa0c031cf3f57e5bce1461cfbd6160f3f66b5a72609a130924917cb07d"},
{file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:446d9ad04204e79229ae19502daeea56479e55cbc32634655d886f5a39e91b44"}, {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2450d87dd7b4f277f4c5598faa8b49a0c197b91186c47a2c0b88e15531e4e3e"},
{file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b57c0954a9fdd2b05b9cec0f5a12a0bdce5bf021a5b3b09323041613972481ab"}, {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90903d2908158a2c9077a06f11e27545de610af690fb178fd3ba6b32492d4d1c"},
{file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:266e55c83f81248f63cc93d11c5e3a53df49a5d2598fa9e9db5f99837a802d5d"}, {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce6f095eef0026eae76fc212f20f786011ecf482fc7df2f4c272a8ae6dd7b1ef"},
{file = "orjson-3.9.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31372ba3a9fe8ad118e7d22fba46bbc18e89039e3bfa89db7bc8c18ee722dca8"}, {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:751250a31fef2bac05a2da2449aae7142075ea26139271f169af60456d8ad27a"},
{file = "orjson-3.9.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e3b0c4da61f39899561e08e571f54472a09fa71717d9797928af558175ae5243"}, {file = "orjson-3.9.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9a1af21160a38ee8be3f4fcf24ee4b99e6184cadc7f915d599f073f478a94d2c"},
{file = "orjson-3.9.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2cc03a35bfc71c8ebf96ce49b82c2a7be6af4b3cd3ac34166fdb42ac510bbfff"}, {file = "orjson-3.9.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:449bf090b2aa4e019371d7511a6ea8a5a248139205c27d1834bb4b1e3c44d936"},
{file = "orjson-3.9.13-cp312-none-win_amd64.whl", hash = "sha256:49b7e3fe861cb246361825d1a238f2584ed8ea21e714bf6bb17cebb86772e61c"}, {file = "orjson-3.9.14-cp312-none-win_amd64.whl", hash = "sha256:a603161318ff699784943e71f53899983b7dee571b4dd07c336437c9c5a272b0"},
{file = "orjson-3.9.13-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:62e9a99879c4d5a04926ac2518a992134bfa00d546ea5a4cae4b9be454d35a22"}, {file = "orjson-3.9.14-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:814f288c011efdf8f115c5ebcc1ab94b11da64b207722917e0ceb42f52ef30a3"},
{file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d92a3e835a5100f1d5b566fff79217eab92223ca31900dba733902a182a35ab0"}, {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a88cafb100af68af3b9b29b5ccd09fdf7a48c63327916c8c923a94c336d38dd3"},
{file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23f21faf072ed3b60b5954686f98157e073f6a8068eaa58dbde83e87212eda84"}, {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ba3518b999f88882ade6686f1b71e207b52e23546e180499be5bbb63a2f9c6e6"},
{file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:828c502bb261588f7de897e06cb23c4b122997cb039d2014cb78e7dabe92ef0c"}, {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:978f416bbff9da8d2091e3cf011c92da68b13f2c453dcc2e8109099b2a19d234"},
{file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16946d095212a3dec552572c5d9bca7afa40f3116ad49695a397be07d529f1fa"}, {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75fc593cf836f631153d0e21beaeb8d26e144445c73645889335c2247fcd71a0"},
{file = "orjson-3.9.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3deadd8dc0e9ff844b5b656fa30a48dbee1c3b332d8278302dd9637f6b09f627"}, {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d1528db3c7554f9d6eeb09df23cb80dd5177ec56eeb55cc5318826928de506"},
{file = "orjson-3.9.13-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9b1b5adc5adf596c59dca57156b71ad301d73956f5bab4039b0e34dbf50b9fa0"}, {file = "orjson-3.9.14-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:7183cc68ee2113b19b0b8714221e5e3b07b3ba10ca2bb108d78fd49cefaae101"},
{file = "orjson-3.9.13-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:ddc089315d030c54f0f03fb38286e2667c05009a78d659f108a8efcfbdf2e585"}, {file = "orjson-3.9.14-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:df3266d54246cb56b8bb17fa908660d2a0f2e3f63fbc32451ffc1b1505051d07"},
{file = "orjson-3.9.13-cp38-none-win32.whl", hash = "sha256:ae77275a28667d9c82d4522b681504642055efa0368d73108511647c6499b31c"}, {file = "orjson-3.9.14-cp38-none-win32.whl", hash = "sha256:7913079b029e1b3501854c9a78ad938ed40d61fe09bebab3c93e60ff1301b189"},
{file = "orjson-3.9.13-cp38-none-win_amd64.whl", hash = "sha256:730385fdb99a21fce9bb84bb7fcbda72c88626facd74956bda712834b480729d"}, {file = "orjson-3.9.14-cp38-none-win_amd64.whl", hash = "sha256:29512eb925b620e5da2fd7585814485c67cc6ba4fe739a0a700c50467a8a8065"},
{file = "orjson-3.9.13-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7e8e4a571d958910272af8d53a9cbe6599f9f5fd496a1bc51211183bb2072cbd"}, {file = "orjson-3.9.14-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5bf597530544db27a8d76aced49cfc817ee9503e0a4ebf0109cd70331e7bbe0c"},
{file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfad553a36548262e7da0f3a7464270e13900b898800fb571a5d4b298c3f8356"}, {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac650d49366fa41fe702e054cb560171a8634e2865537e91f09a8d05ea5b1d37"},
{file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0d691c44604941945b00e0a13b19a7d9c1a19511abadf0080f373e98fdeb6b31"}, {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:236230433a9a4968ab895140514c308fdf9f607cb8bee178a04372b771123860"},
{file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8c83718346de08d68b3cb1105c5d91e5fc39885d8610fdda16613d4e3941459"}, {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3014ccbda9be0b1b5f8ea895121df7e6524496b3908f4397ff02e923bcd8f6dd"},
{file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63ef57a53bfc2091a7cd50a640d9ae866bd7d92a5225a1bab6baa60ef62583f2"}, {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ac0c7eae7ad3a223bde690565442f8a3d620056bd01196f191af8be58a5248e1"},
{file = "orjson-3.9.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9156b96afa38db71344522f5517077eaedf62fcd2c9148392ff93d801128809c"}, {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fca33fdd0b38839b01912c57546d4f412ba7bfa0faf9bf7453432219aec2df07"},
{file = "orjson-3.9.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31fb66b41fb2c4c817d9610f0bc7d31345728d7b5295ac78b63603407432a2b2"}, {file = "orjson-3.9.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f75823cc1674a840a151e999a7dfa0d86c911150dd6f951d0736ee9d383bf415"},
{file = "orjson-3.9.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:8a730bf07feacb0863974e67b206b7c503a62199de1cece2eb0d4c233ec29c11"}, {file = "orjson-3.9.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f52ac2eb49e99e7373f62e2a68428c6946cda52ce89aa8fe9f890c7278e2d3a"},
{file = "orjson-3.9.13-cp39-none-win32.whl", hash = "sha256:5ef58869f3399acbbe013518d8b374ee9558659eef14bca0984f67cb1fbd3c37"}, {file = "orjson-3.9.14-cp39-none-win32.whl", hash = "sha256:0572f174f50b673b7df78680fb52cd0087a8585a6d06d295a5f790568e1064c6"},
{file = "orjson-3.9.13-cp39-none-win_amd64.whl", hash = "sha256:9bcf56efdb83244cde070e82a69c0f03c47c235f0a5cb6c81d9da23af7fbaae4"}, {file = "orjson-3.9.14-cp39-none-win_amd64.whl", hash = "sha256:ab90c02cb264250b8a58cedcc72ed78a4a257d956c8d3c8bebe9751b818dfad8"},
{file = "orjson-3.9.13.tar.gz", hash = "sha256:fc6bc65b0cf524ee042e0bc2912b9206ef242edfba7426cf95763e4af01f527a"}, {file = "orjson-3.9.14.tar.gz", hash = "sha256:06fb40f8e49088ecaa02f1162581d39e2cf3fd9dbbfe411eb2284147c99bad79"},
] ]
[[package]] [[package]]
@ -1439,16 +1439,17 @@ files = [
[[package]] [[package]]
name = "paho-mqtt" name = "paho-mqtt"
version = "1.6.1" version = "2.0.0"
description = "MQTT version 5.0/3.1.1 client class" description = "MQTT version 5.0/3.1.1 client class"
optional = false optional = false
python-versions = "*" python-versions = ">=3.7"
files = [ files = [
{file = "paho-mqtt-1.6.1.tar.gz", hash = "sha256:2a8291c81623aec00372b5a85558a372c747cbca8e9934dfe218638b8eefc26f"}, {file = "paho_mqtt-2.0.0-py3-none-any.whl", hash = "sha256:2ef745073dfc9aa68bfec30d0b9b6f0304ea75182bae85a7c77a80cefce1eff5"},
{file = "paho_mqtt-2.0.0.tar.gz", hash = "sha256:13b205f29251e4f2c66a6c923c31fc4fd780561e03b2d775cff8e4f2915cf947"},
] ]
[package.extras] [package.extras]
proxy = ["PySocks"] proxy = ["pysocks"]
[[package]] [[package]]
name = "pathspec" name = "pathspec"
@ -1563,13 +1564,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-
[[package]] [[package]]
name = "pluggy" name = "pluggy"
version = "1.0.0" version = "1.4.0"
description = "plugin and hook calling mechanisms for python" description = "plugin and hook calling mechanisms for python"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.8"
files = [ files = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
] ]
[package.extras] [package.extras]
@ -1578,13 +1579,13 @@ testing = ["pytest", "pytest-benchmark"]
[[package]] [[package]]
name = "pre-commit" name = "pre-commit"
version = "3.6.0" version = "3.6.1"
description = "A framework for managing and maintaining multi-language pre-commit hooks." description = "A framework for managing and maintaining multi-language pre-commit hooks."
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.9"
files = [ files = [
{file = "pre_commit-3.6.0-py2.py3-none-any.whl", hash = "sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376"}, {file = "pre_commit-3.6.1-py2.py3-none-any.whl", hash = "sha256:9fe989afcf095d2c4796ce7c553cf28d4d4a9b9346de3cda079bcf40748454a4"},
{file = "pre_commit-3.6.0.tar.gz", hash = "sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d"}, {file = "pre_commit-3.6.1.tar.gz", hash = "sha256:c90961d8aa706f75d60935aba09469a6b0bcb8345f127c3fbee4bdc5f114cf4b"},
] ]
[package.dependencies] [package.dependencies]
@ -1812,19 +1813,23 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
[[package]] [[package]]
name = "pydantic-settings" name = "pydantic-settings"
version = "2.1.0" version = "2.2.0"
description = "Settings management using Pydantic" description = "Settings management using Pydantic"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "pydantic_settings-2.1.0-py3-none-any.whl", hash = "sha256:7621c0cb5d90d1140d2f0ef557bdf03573aac7035948109adf2574770b77605a"}, {file = "pydantic_settings-2.2.0-py3-none-any.whl", hash = "sha256:5f7bcaf9ad4419559dc5ac155c0324a9aeb2547c60471ee7c7d026f467a6b515"},
{file = "pydantic_settings-2.1.0.tar.gz", hash = "sha256:26b1492e0a24755626ac5e6d715e9077ab7ad4fb5f19a8b7ed7011d52f36141c"}, {file = "pydantic_settings-2.2.0.tar.gz", hash = "sha256:648d0a76673e69c51278979cba2e83cf16a23d57519bfd7e553d1c3f37db5560"},
] ]
[package.dependencies] [package.dependencies]
pydantic = ">=2.3.0" pydantic = ">=2.3.0"
python-dotenv = ">=0.21.0" python-dotenv = ">=0.21.0"
[package.extras]
toml = ["tomlkit (>=0.12)"]
yaml = ["pyyaml (>=6.0.1)"]
[[package]] [[package]]
name = "pydantic-to-typescript" name = "pydantic-to-typescript"
version = "1.0.10" version = "1.0.10"
@ -1946,13 +1951,13 @@ rdflib = "*"
[[package]] [[package]]
name = "pytest" name = "pytest"
version = "7.4.4" version = "8.0.1"
description = "pytest: simple powerful testing with Python" description = "pytest: simple powerful testing with Python"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, {file = "pytest-8.0.1-py3-none-any.whl", hash = "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca"},
{file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, {file = "pytest-8.0.1.tar.gz", hash = "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae"},
] ]
[package.dependencies] [package.dependencies]
@ -1960,7 +1965,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""}
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*" iniconfig = "*"
packaging = "*" packaging = "*"
pluggy = ">=0.12,<2.0" pluggy = ">=1.3.0,<2.0"
tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
[package.extras] [package.extras]
@ -1968,17 +1973,17 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no
[[package]] [[package]]
name = "pytest-asyncio" name = "pytest-asyncio"
version = "0.23.4" version = "0.23.5"
description = "Pytest support for asyncio" description = "Pytest support for asyncio"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "pytest-asyncio-0.23.4.tar.gz", hash = "sha256:2143d9d9375bf372a73260e4114541485e84fca350b0b6b92674ca56ff5f7ea2"}, {file = "pytest-asyncio-0.23.5.tar.gz", hash = "sha256:3a048872a9c4ba14c3e90cc1aa20cbc2def7d01c7c8db3777ec281ba9c057675"},
{file = "pytest_asyncio-0.23.4-py3-none-any.whl", hash = "sha256:b0079dfac14b60cd1ce4691fbfb1748fe939db7d0234b5aba97197d10fbe0fef"}, {file = "pytest_asyncio-0.23.5-py3-none-any.whl", hash = "sha256:4e7093259ba018d58ede7d5315131d21923a60f8a6e9ee266ce1589685c89eac"},
] ]
[package.dependencies] [package.dependencies]
pytest = ">=7.0.0,<8" pytest = ">=7.0.0,<9"
[package.extras] [package.extras]
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
@ -2465,28 +2470,28 @@ pyasn1 = ">=0.1.3"
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.2.1" version = "0.2.2"
description = "An extremely fast Python linter and code formatter, written in Rust." description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:dd81b911d28925e7e8b323e8d06951554655021df8dd4ac3045d7212ac4ba080"}, {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0a9efb032855ffb3c21f6405751d5e147b0c6b631e3ca3f6b20f917572b97eb6"},
{file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:dc586724a95b7d980aa17f671e173df00f0a2eef23f8babbeee663229a938fec"}, {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d450b7fbff85913f866a5384d8912710936e2b96da74541c82c1b458472ddb39"},
{file = "ruff-0.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c92db7101ef5bfc18e96777ed7bc7c822d545fa5977e90a585accac43d22f18a"}, {file = "ruff-0.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecd46e3106850a5c26aee114e562c329f9a1fbe9e4821b008c4404f64ff9ce73"},
{file = "ruff-0.2.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13471684694d41ae0f1e8e3a7497e14cd57ccb7dd72ae08d56a159d6c9c3e30e"}, {file = "ruff-0.2.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e22676a5b875bd72acd3d11d5fa9075d3a5f53b877fe7b4793e4673499318ba"},
{file = "ruff-0.2.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a11567e20ea39d1f51aebd778685582d4c56ccb082c1161ffc10f79bebe6df35"}, {file = "ruff-0.2.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1695700d1e25a99d28f7a1636d85bafcc5030bba9d0578c0781ba1790dbcf51c"},
{file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:00a818e2db63659570403e44383ab03c529c2b9678ba4ba6c105af7854008105"}, {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b0c232af3d0bd8f521806223723456ffebf8e323bd1e4e82b0befb20ba18388e"},
{file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be60592f9d218b52f03384d1325efa9d3b41e4c4d55ea022cd548547cc42cd2b"}, {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f63d96494eeec2fc70d909393bcd76c69f35334cdbd9e20d089fb3f0640216ca"},
{file = "ruff-0.2.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbd2288890b88e8aab4499e55148805b58ec711053588cc2f0196a44f6e3d855"}, {file = "ruff-0.2.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a61ea0ff048e06de273b2e45bd72629f470f5da8f71daf09fe481278b175001"},
{file = "ruff-0.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ef052283da7dec1987bba8d8733051c2325654641dfe5877a4022108098683"}, {file = "ruff-0.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1439c8f407e4f356470e54cdecdca1bd5439a0673792dbe34a2b0a551a2fe3"},
{file = "ruff-0.2.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7022d66366d6fded4ba3889f73cd791c2d5621b2ccf34befc752cb0df70f5fad"}, {file = "ruff-0.2.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:940de32dc8853eba0f67f7198b3e79bc6ba95c2edbfdfac2144c8235114d6726"},
{file = "ruff-0.2.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0a725823cb2a3f08ee743a534cb6935727d9e47409e4ad72c10a3faf042ad5ba"}, {file = "ruff-0.2.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c126da55c38dd917621552ab430213bdb3273bb10ddb67bc4b761989210eb6e"},
{file = "ruff-0.2.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0034d5b6323e6e8fe91b2a1e55b02d92d0b582d2953a2b37a67a2d7dedbb7acc"}, {file = "ruff-0.2.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3b65494f7e4bed2e74110dac1f0d17dc8e1f42faaa784e7c58a98e335ec83d7e"},
{file = "ruff-0.2.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e5cb5526d69bb9143c2e4d2a115d08ffca3d8e0fddc84925a7b54931c96f5c02"}, {file = "ruff-0.2.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1ec49be4fe6ddac0503833f3ed8930528e26d1e60ad35c2446da372d16651ce9"},
{file = "ruff-0.2.1-py3-none-win32.whl", hash = "sha256:6b95ac9ce49b4fb390634d46d6ece32ace3acdd52814671ccaf20b7f60adb232"}, {file = "ruff-0.2.2-py3-none-win32.whl", hash = "sha256:d920499b576f6c68295bc04e7b17b6544d9d05f196bb3aac4358792ef6f34325"},
{file = "ruff-0.2.1-py3-none-win_amd64.whl", hash = "sha256:e3affdcbc2afb6f5bd0eb3130139ceedc5e3f28d206fe49f63073cb9e65988e0"}, {file = "ruff-0.2.2-py3-none-win_amd64.whl", hash = "sha256:cc9a91ae137d687f43a44c900e5d95e9617cb37d4c989e462980ba27039d239d"},
{file = "ruff-0.2.1-py3-none-win_arm64.whl", hash = "sha256:efababa8e12330aa94a53e90a81eb6e2d55f348bc2e71adbf17d9cad23c03ee6"}, {file = "ruff-0.2.2-py3-none-win_arm64.whl", hash = "sha256:c9d15fc41e6054bfc7200478720570078f0b41c9ae4f010bcc16bd6f4d1aacdd"},
{file = "ruff-0.2.1.tar.gz", hash = "sha256:3b42b5d8677cd0c72b99fcaf068ffc62abb5a19e71b4a3b9cfa50658a0af02f1"}, {file = "ruff-0.2.2.tar.gz", hash = "sha256:e62ed7f36b3068a30ba39193a14274cd706bc486fad521276458022f7bccb31d"},
] ]
[[package]] [[package]]
@ -2764,13 +2769,13 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]] [[package]]
name = "uvicorn" name = "uvicorn"
version = "0.27.0" version = "0.27.1"
description = "The lightning-fast ASGI server." description = "The lightning-fast ASGI server."
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "uvicorn-0.27.0-py3-none-any.whl", hash = "sha256:890b00f6c537d58695d3bb1f28e23db9d9e7a17cbcc76d7457c499935f933e24"}, {file = "uvicorn-0.27.1-py3-none-any.whl", hash = "sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4"},
{file = "uvicorn-0.27.0.tar.gz", hash = "sha256:c855578045d45625fd027367f7653d249f7c49f9361ba15cf9624186b26b8eb6"}, {file = "uvicorn-0.27.1.tar.gz", hash = "sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a"},
] ]
[package.dependencies] [package.dependencies]
@ -3028,4 +3033,4 @@ pgsql = ["psycopg2-binary"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "02c2f99d7ead3339de5c02e9b3ec3ac33fc4a7204130b9cd404e749d995e9a7b" content-hash = "b8a0c715906337427ee8f676d2dfbc49be273118818823a19766412766e66a5c"

View File

@ -44,7 +44,7 @@ isodate = "^0.6.1"
text-unidecode = "^1.3" text-unidecode = "^1.3"
rapidfuzz = "^3.2.0" rapidfuzz = "^3.2.0"
html2text = "^2020.1.16" html2text = "^2020.1.16"
paho-mqtt = "^1.6.1" paho-mqtt = "^2.0.0"
pydantic-settings = "^2.1.0" pydantic-settings = "^2.1.0"
[tool.poetry.group.postgres.dependencies] [tool.poetry.group.postgres.dependencies]
@ -59,7 +59,7 @@ mypy = "^1.5.1"
pre-commit = "^3.3.3" pre-commit = "^3.3.3"
pydantic-to-typescript = "^1.0.7" pydantic-to-typescript = "^1.0.7"
pylint = "^3.0.0" pylint = "^3.0.0"
pytest = "^7.2.0" pytest = "^8.0.0"
pytest-asyncio = "^0.23.0" pytest-asyncio = "^0.23.0"
rich = "^13.5.2" rich = "^13.5.2"
ruff = "^0.2.0" ruff = "^0.2.0"

View File

@ -17,8 +17,10 @@ from recipe_scrapers._schemaorg import SchemaOrg
from slugify import slugify from slugify import slugify
from mealie.repos.repository_factory import AllRepositories from mealie.repos.repository_factory import AllRepositories
from mealie.schema.recipe.recipe import RecipeCategory, RecipeSummary, RecipeTag from mealie.schema.recipe.recipe import Recipe, RecipeCategory, RecipeSummary, RecipeTag
from mealie.schema.recipe.recipe_category import CategorySave, TagSave
from mealie.schema.recipe.recipe_notes import RecipeNote from mealie.schema.recipe.recipe_notes import RecipeNote
from mealie.schema.recipe.recipe_tool import RecipeToolSave
from mealie.services.recipe.recipe_data_service import RecipeDataService from mealie.services.recipe.recipe_data_service import RecipeDataService
from mealie.services.scraper.recipe_scraper import DEFAULT_SCRAPER_STRATEGIES from mealie.services.scraper.recipe_scraper import DEFAULT_SCRAPER_STRATEGIES
from tests import data, utils from tests import data, utils
@ -740,6 +742,70 @@ def test_get_recipe_by_slug_or_id(api_client: TestClient, unique_user: utils.Tes
assert recipe_data["id"] == recipe_id assert recipe_data["id"] == recipe_id
@pytest.mark.parametrize("organizer_type", ["tags", "categories", "tools"])
def test_get_recipes_organizer_filter(
api_client: TestClient, unique_user: utils.TestUser, organizer_type: str, database: AllRepositories
):
# create recipes with different organizers
tags = database.tags.by_group(unique_user.group_id).create_many(
[TagSave(name=random_string(), group_id=unique_user.group_id) for _ in range(3)]
)
categories = database.categories.by_group(unique_user.group_id).create_many(
[CategorySave(name=random_string(), group_id=unique_user.group_id) for _ in range(3)]
)
tools = database.tools.by_group(unique_user.group_id).create_many(
[RecipeToolSave(name=random_string(), group_id=unique_user.group_id) for _ in range(3)]
)
new_recipes_data: list[dict] = []
for i in range(40):
name = random_string()
new_recipes_data.append(
Recipe(
id=uuid4(),
user_id=unique_user.user_id,
group_id=unique_user.group_id,
name=name,
slug=name,
tags=[random.choice(tags)] if i % 2 else [],
recipe_category=[random.choice(categories)] if i % 2 else [],
tools=[random.choice(tools)] if i % 2 else [],
)
)
recipes = database.recipes.by_group(unique_user.group_id).create_many(new_recipes_data) # type: ignore
# get recipes by organizer
if organizer_type == "tags":
organizer = random.choice(tags)
expected_recipe_ids = set(
str(recipe.id) for recipe in recipes if organizer.id in [tag.id for tag in recipe.tags or []]
)
elif organizer_type == "categories":
organizer = random.choice(categories)
expected_recipe_ids = set(
str(recipe.id)
for recipe in recipes
if organizer.id in [category.id for category in recipe.recipe_category or []]
)
elif organizer_type == "tools":
organizer = random.choice(tools)
expected_recipe_ids = set(
str(recipe.id) for recipe in recipes if organizer.id in [tool.id for tool in recipe.tools or []]
)
else:
raise ValueError(f"Unknown organizer type: {organizer_type}")
query_params = {organizer_type: str(organizer.id)}
response = api_client.get(api_routes.recipes, params=query_params, headers=unique_user.token)
assert response.status_code == 200
response_json = response.json()
assert len(response_json["items"]) == len(expected_recipe_ids)
fetched_recipes_ids = [recipe["id"] for recipe in response_json["items"]]
assert set(fetched_recipes_ids) == expected_recipe_ids
def test_get_random_order(api_client: TestClient, unique_user: utils.TestUser): def test_get_random_order(api_client: TestClient, unique_user: utils.TestUser):
# Create more recipes for stable random ordering # Create more recipes for stable random ordering
slugs = [random_string(10) for _ in range(7)] slugs = [random_string(10) for _ in range(7)]