From b1820f9b233e52de7ab12ac1f4583a35a768b69b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 17 Sep 2024 08:13:13 +0200 Subject: [PATCH 01/28] fix(deps): update dependency openai to v1.45.1 (#4215) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- poetry.lock | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 61db97af40a..198e9e8a7f9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1580,13 +1580,13 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openai" -version = "1.45.0" +version = "1.45.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.45.0-py3-none-any.whl", hash = "sha256:2f1f7b7cf90f038a9f1c24f0d26c0f1790c102ec5acd07ffd70a9b7feac1ff4e"}, - {file = "openai-1.45.0.tar.gz", hash = "sha256:731207d10637335413aa3c0955f8f8df30d7636a4a0f9c381f2209d32cf8de97"}, + {file = "openai-1.45.1-py3-none-any.whl", hash = "sha256:4a6cce402aec803ae57ae7eff4b5b94bf6c0e1703a8d85541c27243c2adeadf8"}, + {file = "openai-1.45.1.tar.gz", hash = "sha256:f79e384916b219ab2f028bbf9c778e81291c61eb0645ccfa1828a4b18b55d534"}, ] [package.dependencies] @@ -2935,13 +2935,17 @@ files = [ {file = "SQLAlchemy-2.0.35-cp312-cp312-win32.whl", hash = "sha256:0f9f3f9a3763b9c4deb8c5d09c4cc52ffe49f9876af41cc1b2ad0138878453cf"}, {file = "SQLAlchemy-2.0.35-cp312-cp312-win_amd64.whl", hash = "sha256:25b0f63e7fcc2a6290cb5f7f5b4fc4047843504983a28856ce9b35d8f7de03cc"}, {file = "SQLAlchemy-2.0.35-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f021d334f2ca692523aaf7bbf7592ceff70c8594fad853416a81d66b35e3abf9"}, + {file = "SQLAlchemy-2.0.35-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05c3f58cf91683102f2f0265c0db3bd3892e9eedabe059720492dbaa4f922da1"}, {file = "SQLAlchemy-2.0.35-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:032d979ce77a6c2432653322ba4cbeabf5a6837f704d16fa38b5a05d8e21fa00"}, + {file = "SQLAlchemy-2.0.35-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:2e795c2f7d7249b75bb5f479b432a51b59041580d20599d4e112b5f2046437a3"}, {file = "SQLAlchemy-2.0.35-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:cc32b2990fc34380ec2f6195f33a76b6cdaa9eecf09f0c9404b74fc120aef36f"}, {file = "SQLAlchemy-2.0.35-cp37-cp37m-win32.whl", hash = "sha256:9509c4123491d0e63fb5e16199e09f8e262066e58903e84615c301dde8fa2e87"}, {file = "SQLAlchemy-2.0.35-cp37-cp37m-win_amd64.whl", hash = "sha256:3655af10ebcc0f1e4e06c5900bb33e080d6a1fa4228f502121f28a3b1753cde5"}, {file = "SQLAlchemy-2.0.35-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4c31943b61ed8fdd63dfd12ccc919f2bf95eefca133767db6fbbd15da62078ec"}, {file = "SQLAlchemy-2.0.35-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a62dd5d7cc8626a3634208df458c5fe4f21200d96a74d122c83bc2015b333bc1"}, + {file = "SQLAlchemy-2.0.35-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0630774b0977804fba4b6bbea6852ab56c14965a2b0c7fc7282c5f7d90a1ae72"}, {file = "SQLAlchemy-2.0.35-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d625eddf7efeba2abfd9c014a22c0f6b3796e0ffb48f5d5ab106568ef01ff5a"}, + {file = "SQLAlchemy-2.0.35-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ada603db10bb865bbe591939de854faf2c60f43c9b763e90f653224138f910d9"}, {file = "SQLAlchemy-2.0.35-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c41411e192f8d3ea39ea70e0fae48762cd11a2244e03751a98bd3c0ca9a4e936"}, {file = "SQLAlchemy-2.0.35-cp38-cp38-win32.whl", hash = "sha256:d299797d75cd747e7797b1b41817111406b8b10a4f88b6e8fe5b5e59598b43b0"}, {file = "SQLAlchemy-2.0.35-cp38-cp38-win_amd64.whl", hash = "sha256:0375a141e1c0878103eb3d719eb6d5aa444b490c96f3fedab8471c7f6ffe70ee"}, @@ -2951,6 +2955,7 @@ files = [ {file = "SQLAlchemy-2.0.35-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b76d63495b0508ab9fc23f8152bac63205d2a704cd009a2b0722f4c8e0cba8e0"}, {file = "SQLAlchemy-2.0.35-cp39-cp39-win32.whl", hash = "sha256:69683e02e8a9de37f17985905a5eca18ad651bf592314b4d3d799029797d0eb3"}, {file = "SQLAlchemy-2.0.35-cp39-cp39-win_amd64.whl", hash = "sha256:aee110e4ef3c528f3abbc3c2018c121e708938adeeff9006428dd7c8555e9b3f"}, + {file = "SQLAlchemy-2.0.35-py3-none-any.whl", hash = "sha256:2ab3f0336c0387662ce6221ad30ab3a5e6499aab01b9790879b6578fd9b8faa1"}, {file = "sqlalchemy-2.0.35.tar.gz", hash = "sha256:e11d7ea4d24f0a262bccf9a7cd6284c976c5369dac21db237cff59586045ab9f"}, ] From fd0257c1b87f1aaa0ec2a47b8b15bf031e18e33e Mon Sep 17 00:00:00 2001 From: Michael Genson <71845777+michael-genson@users.noreply.github.com> Date: Tue, 17 Sep 2024 10:48:14 -0500 Subject: [PATCH 02/28] feat: Additional Household Permissions (#4158) Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com> --- ...dded_household_recipe_lock_setting_and_.py | 75 +++++++++ .../Household/HouseholdPreferencesEditor.vue | 109 +++++++++--- .../components/Domain/Recipe/RecipeCard.vue | 2 +- .../Domain/Recipe/RecipeCardMobile.vue | 2 +- .../RecipePageParts/RecipePageHeader.vue | 13 +- .../recipes/use-recipe-permissions.test.ts | 66 ++++++-- .../recipes/use-recipe-permissions.ts | 62 ++++--- frontend/composables/use-households.ts | 2 + frontend/composables/use-users/user-form.ts | 6 + frontend/lang/messages/en-US.json | 8 +- frontend/lib/api/types/admin.ts | 1 + frontend/lib/api/types/household.ts | 5 + frontend/lib/api/types/openai.ts | 155 ++++++++++++++++++ frontend/lib/api/types/user.ts | 4 + frontend/lib/api/user/groups.ts | 7 +- .../middleware/can-manage-household-only.ts | 11 ++ .../pages/admin/manage/households/_id.vue | 7 +- frontend/pages/household/index.vue | 88 ++++------ frontend/pages/household/members.vue | 13 ++ frontend/pages/user/profile/index.vue | 13 +- mealie/db/models/household/preferences.py | 1 + mealie/db/models/users/users.py | 9 +- mealie/routes/_base/checks.py | 5 + .../groups/controller_group_self_service.py | 13 +- .../controller_household_self_service.py | 3 + .../schema/household/household_permissions.py | 1 + .../schema/household/household_preferences.py | 1 + mealie/schema/openai/__init__.py | 5 + mealie/schema/user/user.py | 1 + mealie/services/recipe/recipe_service.py | 45 ++--- .../user_services/registration_service.py | 1 + .../test_admin_household_actions.py | 1 + .../test_group_self_service.py | 30 +++- .../test_household_perferences.py | 24 ++- .../test_household_permissions.py | 3 +- .../test_recipe_cross_household.py | 70 ++++++-- tests/utils/api_routes/__init__.py | 5 + 37 files changed, 686 insertions(+), 181 deletions(-) create mode 100644 alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py create mode 100644 frontend/middleware/can-manage-household-only.ts diff --git a/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py b/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py new file mode 100644 index 00000000000..83f2e55186a --- /dev/null +++ b/alembic/versions/2024-09-02-21.39.49_be568e39ffdf_added_household_recipe_lock_setting_and_.py @@ -0,0 +1,75 @@ +"""added household recipe lock setting and household management user permission + +Revision ID: be568e39ffdf +Revises: feecc8ffb956 +Create Date: 2024-09-02 21:39:49.210355 + +""" + +from textwrap import dedent + +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision = "be568e39ffdf" +down_revision = "feecc8ffb956" +branch_labels: str | tuple[str, ...] | None = None +depends_on: str | tuple[str, ...] | None = None + + +def populate_defaults(): + if op.get_context().dialect.name == "postgresql": + TRUE = "TRUE" + FALSE = "FALSE" + else: + TRUE = "1" + FALSE = "0" + + op.execute( + dedent( + f""" + UPDATE household_preferences + SET lock_recipe_edits_from_other_households = {TRUE} + WHERE lock_recipe_edits_from_other_households IS NULL + """ + ) + ) + op.execute( + dedent( + f""" + UPDATE users + SET can_manage_household = {FALSE} + WHERE can_manage_household IS NULL AND admin = {FALSE} + """ + ) + ) + op.execute( + dedent( + f""" + UPDATE users + SET can_manage_household = {TRUE} + WHERE can_manage_household IS NULL AND admin = {TRUE} + """ + ) + ) + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "household_preferences", + sa.Column("lock_recipe_edits_from_other_households", sa.Boolean(), nullable=True), + ) + op.add_column("users", sa.Column("can_manage_household", sa.Boolean(), nullable=True)) + # ### end Alembic commands ### + + populate_defaults() + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("users", "can_manage_household") + op.drop_column("household_preferences", "lock_recipe_edits_from_other_households") + # ### end Alembic commands ### diff --git a/frontend/components/Domain/Household/HouseholdPreferencesEditor.vue b/frontend/components/Domain/Household/HouseholdPreferencesEditor.vue index ab6b8833f5b..e5c8899384d 100644 --- a/frontend/components/Domain/Household/HouseholdPreferencesEditor.vue +++ b/frontend/components/Domain/Household/HouseholdPreferencesEditor.vue @@ -1,7 +1,33 @@ - diff --git a/frontend/components/Domain/Recipe/RecipeCard.vue b/frontend/components/Domain/Recipe/RecipeCard.vue index aa22437e3e5..b6c627c60d3 100644 --- a/frontend/components/Domain/Recipe/RecipeCard.vue +++ b/frontend/components/Domain/Recipe/RecipeCard.vue @@ -50,7 +50,7 @@ :recipe-id="recipeId" :use-items="{ delete: false, - edit: true, + edit: false, download: true, mealplanner: true, shoppingList: true, diff --git a/frontend/components/Domain/Recipe/RecipeCardMobile.vue b/frontend/components/Domain/Recipe/RecipeCardMobile.vue index 6fa5b8354e8..3d064126948 100644 --- a/frontend/components/Domain/Recipe/RecipeCardMobile.vue +++ b/frontend/components/Domain/Recipe/RecipeCardMobile.vue @@ -62,7 +62,7 @@ :recipe-id="recipeId" :use-items="{ delete: false, - edit: true, + edit: false, download: true, mealplanner: true, shoppingList: true, diff --git a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue index 18915641ae2..69853821a79 100644 --- a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue +++ b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageHeader.vue @@ -69,7 +69,8 @@ import RecipeRating from "~/components/Domain/Recipe/RecipeRating.vue"; import RecipeLastMade from "~/components/Domain/Recipe/RecipeLastMade.vue"; import RecipeActionMenu from "~/components/Domain/Recipe/RecipeActionMenu.vue"; import RecipeTimeCard from "~/components/Domain/Recipe/RecipeTimeCard.vue"; -import { useStaticRoutes } from "~/composables/api"; +import { useStaticRoutes, useUserApi } from "~/composables/api"; +import { HouseholdSummary } from "~/lib/api/types/household"; import { Recipe } from "~/lib/api/types/recipe"; import { NoUndefinedField } from "~/lib/api/types/non-generated"; import { usePageState, usePageUser, PageMode, EditorMode } from "~/composables/recipe-page/shared-state"; @@ -100,7 +101,15 @@ export default defineComponent({ const { imageKey, pageMode, editMode, setMode, toggleEditMode, isEditMode } = usePageState(props.recipe.slug); const { user } = usePageUser(); const { isOwnGroup } = useLoggedInState(); - const { canEditRecipe } = useRecipePermissions(props.recipe, user); + + const recipeHousehold = ref(); + if (user) { + const userApi = useUserApi(); + userApi.groups.fetchHousehold(props.recipe.householdId).then(({ data }) => { + recipeHousehold.value = data || undefined; + }); + } + const { canEditRecipe } = useRecipePermissions(props.recipe, recipeHousehold, user); function printRecipe() { window.print(); diff --git a/frontend/composables/recipes/use-recipe-permissions.test.ts b/frontend/composables/recipes/use-recipe-permissions.test.ts index 6dedeb32b37..a962d7af34d 100644 --- a/frontend/composables/recipes/use-recipe-permissions.test.ts +++ b/frontend/composables/recipes/use-recipe-permissions.test.ts @@ -1,5 +1,7 @@ import { describe, test, expect } from "vitest"; +import { ref, Ref } from "@nuxtjs/composition-api"; import { useRecipePermissions } from "./use-recipe-permissions"; +import { HouseholdSummary } from "~/lib/api/types/household"; import { Recipe } from "~/lib/api/types/recipe"; import { UserOut } from "~/lib/api/types/user"; @@ -32,35 +34,76 @@ describe("test use recipe permissions", () => { ...overrides, }); + const createRecipeHousehold = (overrides: Partial, lockRecipeEdits = false): Ref => ( + ref({ + id: commonHouseholdId, + groupId: commonGroupId, + name: "My Household", + slug: "my-household", + preferences: { + id: "my-household-preferences-id", + lockRecipeEditsFromOtherHouseholds: lockRecipeEdits, + }, + ...overrides, + }) + ); + test("when user is null, cannot edit", () => { - const result = useRecipePermissions(createRecipe({}), null); + const result = useRecipePermissions(createRecipe({}), createRecipeHousehold({}), null); expect(result.canEditRecipe.value).toBe(false); }); test("when user is recipe owner, can edit", () => { - const result = useRecipePermissions(createRecipe({}), createUser({})); + const result = useRecipePermissions(createRecipe({}), ref(), createUser({})); expect(result.canEditRecipe.value).toBe(true); }); - test("when user is not recipe owner, is correct group and household, and recipe is unlocked, can edit", () => { + test( + "when user is not recipe owner, is correct group and household, recipe is unlocked, and household is unlocked, can edit", + () => { + const result = useRecipePermissions( + createRecipe({}), + createRecipeHousehold({}), + createUser({ id: "other-user-id" }), + ); + expect(result.canEditRecipe.value).toBe(true); + } + ); + + test( + "when user is not recipe owner, is correct group and household, recipe is unlocked, but household is locked, can edit", + () => { + const result = useRecipePermissions( + createRecipe({}), + createRecipeHousehold({}, true), + createUser({ id: "other-user-id" }), + ); + expect(result.canEditRecipe.value).toBe(true); + } + ); + + test("when user is not recipe owner, and user is other group, cannot edit", () => { const result = useRecipePermissions( createRecipe({}), - createUser({ id: "other-user-id" }), + createRecipeHousehold({}), + createUser({ id: "other-user-id", groupId: "other-group-id"}), ); - expect(result.canEditRecipe.value).toBe(true); + expect(result.canEditRecipe.value).toBe(false); }); - test("when user is not recipe owner, and user is other group, cannot edit", () => { + test("when user is not recipe owner, and user is other household, and household is unlocked, can edit", () => { const result = useRecipePermissions( createRecipe({}), - createUser({ id: "other-user-id", groupId: "other-group-id"}), + createRecipeHousehold({}), + createUser({ id: "other-user-id", householdId: "other-household-id" }), ); - expect(result.canEditRecipe.value).toBe(false); + expect(result.canEditRecipe.value).toBe(true); }); - test("when user is not recipe owner, and user is other household, cannot edit", () => { + test("when user is not recipe owner, and user is other household, and household is locked, cannot edit", () => { const result = useRecipePermissions( createRecipe({}), + createRecipeHousehold({}, true), createUser({ id: "other-user-id", householdId: "other-household-id" }), ); expect(result.canEditRecipe.value).toBe(false); @@ -69,13 +112,14 @@ describe("test use recipe permissions", () => { test("when user is not recipe owner, and recipe is locked, cannot edit", () => { const result = useRecipePermissions( createRecipe({}, true), + createRecipeHousehold({}), createUser({ id: "other-user-id"}), ); expect(result.canEditRecipe.value).toBe(false); }); - test("when user is recipe owner, and recipe is locked, can edit", () => { - const result = useRecipePermissions(createRecipe({}, true), createUser({})); + test("when user is recipe owner, and recipe is locked, and household is locked, can edit", () => { + const result = useRecipePermissions(createRecipe({}, true), createRecipeHousehold({}, true), createUser({})); expect(result.canEditRecipe.value).toBe(true); }); }); diff --git a/frontend/composables/recipes/use-recipe-permissions.ts b/frontend/composables/recipes/use-recipe-permissions.ts index bd3af98dca1..d4efbfd058b 100644 --- a/frontend/composables/recipes/use-recipe-permissions.ts +++ b/frontend/composables/recipes/use-recipe-permissions.ts @@ -1,34 +1,44 @@ -import { computed } from "@nuxtjs/composition-api"; +import { computed, Ref } from "@nuxtjs/composition-api"; import { Recipe } from "~/lib/api/types/recipe"; +import { HouseholdSummary } from "~/lib/api/types/household"; import { UserOut } from "~/lib/api/types/user"; -export function useRecipePermissions(recipe: Recipe, user: UserOut | null) { - const canEditRecipe = computed(() => { - // Check recipe owner - if (!user?.id) { - return false; - } - if (user.id === recipe.userId) { - return true; - } +export function useRecipePermissions( + recipe: Recipe, + recipeHousehold: Ref, + user: UserOut | null, +) { + const canEditRecipe = computed(() => { + // Check recipe owner + if (!user?.id) { + return false; + } + if (user.id === recipe.userId) { + return true; + } - // Check group and household - if (user.groupId !== recipe.groupId) { - return false; - } - if (user.householdId !== recipe.householdId) { - return false; - } + // Check group and household + if (user.groupId !== recipe.groupId) { + return false; + } + if (user.householdId !== recipe.householdId) { + if (!recipeHousehold.value?.preferences) { + return false; + } + if (recipeHousehold.value?.preferences.lockRecipeEditsFromOtherHouseholds) { + return false; + } + } - // Check recipe - if (recipe.settings?.locked) { - return false; - } + // Check recipe + if (recipe.settings?.locked) { + return false; + } - return true; - }); + return true; + }); - return { - canEditRecipe, - } + return { + canEditRecipe, + } } diff --git a/frontend/composables/use-households.ts b/frontend/composables/use-households.ts index 618ab75636f..44f9caf8f4e 100644 --- a/frontend/composables/use-households.ts +++ b/frontend/composables/use-households.ts @@ -36,6 +36,8 @@ export const useHouseholdSelf = function () { if (data) { householdSelfRef.value.preferences = data; } + + return data || undefined; }, }; diff --git a/frontend/composables/use-users/user-form.ts b/frontend/composables/use-users/user-form.ts index 387f56f49c4..79b889f3f0f 100644 --- a/frontend/composables/use-users/user-form.ts +++ b/frontend/composables/use-users/user-form.ts @@ -65,6 +65,12 @@ export const useUserForm = () => { type: fieldTypes.BOOLEAN, rules: ["required"], }, + { + label: i18n.tc("user.user-can-manage-household"), + varName: "canManageHousehold", + type: fieldTypes.BOOLEAN, + rules: ["required"], + }, { label: i18n.tc("user.enable-advanced-features"), varName: "advanced", diff --git a/frontend/lang/messages/en-US.json b/frontend/lang/messages/en-US.json index 0ee1fadc316..382aa53aca0 100644 --- a/frontend/lang/messages/en-US.json +++ b/frontend/lang/messages/en-US.json @@ -241,13 +241,14 @@ "manage-members": "Manage Members", "manage-members-description": "Manage the permissions of the members in your household. {manage} allows the user to access the data-management page, and {invite} allows the user to generate invitation links for other users. Group owners cannot change their own permissions.", "manage": "Manage", + "manage-household": "Manage Household", "invite": "Invite", "looking-to-update-your-profile": "Looking to Update Your Profile?", "default-recipe-preferences-description": "These are the default settings when a new recipe is created in your group. These can be changed for individual recipes in the recipe settings menu.", "default-recipe-preferences": "Default Recipe Preferences", "group-preferences": "Group Preferences", "private-group": "Private Group", - "private-group-description": "Setting your group to private will default all public view options to default. This overrides any individual households or recipes public view settings.", + "private-group-description": "Setting your group to private will disable all public view options. This overrides any individual public view settings", "enable-public-access": "Enable Public Access", "enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in", "allow-users-outside-of-your-group-to-see-your-recipes": "Allow users outside of your group to see your recipes", @@ -285,7 +286,9 @@ "admin-household-management-text": "Changes to this household will be reflected immediately.", "household-id-value": "Household Id: {0}", "private-household": "Private Household", - "private-household-description": "Setting your household to private will default all public view options to default. This overrides any individual recipes public view settings.", + "private-household-description": "Setting your household to private will disable all public view options. This overrides any individual public view settings", + "lock-recipe-edits-from-other-households": "Lock recipe edits from other households", + "lock-recipe-edits-from-other-households-description": "When enabled only users in your household can edit recipes created by your household", "household-recipe-preferences": "Household Recipe Preferences", "default-recipe-preferences-description": "These are the default settings when a new recipe is created in your household. These can be changed for individual recipes in the recipe settings menu.", "allow-users-outside-of-your-household-to-see-your-recipes": "Allow users outside of your household to see your recipes", @@ -987,6 +990,7 @@ "administrator": "Administrator", "user-can-invite-other-to-group": "User can invite others to group", "user-can-manage-group": "User can manage group", + "user-can-manage-household": "User can manage household", "user-can-organize-group-data": "User can organize group data", "enable-advanced-features": "Enable advanced features", "it-looks-like-this-is-your-first-time-logging-in": "It looks like this is your first time logging in.", diff --git a/frontend/lib/api/types/admin.ts b/frontend/lib/api/types/admin.ts index 88bf0f22f21..6f42b40d443 100644 --- a/frontend/lib/api/types/admin.ts +++ b/frontend/lib/api/types/admin.ts @@ -16,6 +16,7 @@ export interface AdminAboutInfo { oidcRedirect: boolean; oidcProviderName: string; enableOpenai: boolean; + enableOpenaiImageServices: boolean; versionLatest: string; apiPort: number; apiDocs: boolean; diff --git a/frontend/lib/api/types/household.ts b/frontend/lib/api/types/household.ts index 7841bd3861f..79b1a7ffaf5 100644 --- a/frontend/lib/api/types/household.ts +++ b/frontend/lib/api/types/household.ts @@ -15,6 +15,7 @@ export interface CreateGroupRecipeAction { } export interface CreateHouseholdPreferences { privateHousehold?: boolean; + lockRecipeEditsFromOtherHouseholds?: boolean; firstDayOfWeek?: number; recipePublic?: boolean; recipeShowNutrition?: boolean; @@ -185,6 +186,7 @@ export interface HouseholdInDB { } export interface ReadHouseholdPreferences { privateHousehold?: boolean; + lockRecipeEditsFromOtherHouseholds?: boolean; firstDayOfWeek?: number; recipePublic?: boolean; recipeShowNutrition?: boolean; @@ -241,6 +243,7 @@ export interface SaveGroupRecipeAction { } export interface SaveHouseholdPreferences { privateHousehold?: boolean; + lockRecipeEditsFromOtherHouseholds?: boolean; firstDayOfWeek?: number; recipePublic?: boolean; recipeShowNutrition?: boolean; @@ -267,6 +270,7 @@ export interface SaveWebhook { } export interface SetPermissions { userId: string; + canManageHousehold?: boolean; canManage?: boolean; canInvite?: boolean; canOrganize?: boolean; @@ -649,6 +653,7 @@ export interface UpdateHouseholdAdmin { } export interface UpdateHouseholdPreferences { privateHousehold?: boolean; + lockRecipeEditsFromOtherHouseholds?: boolean; firstDayOfWeek?: number; recipePublic?: boolean; recipeShowNutrition?: boolean; diff --git a/frontend/lib/api/types/openai.ts b/frontend/lib/api/types/openai.ts index ac4a29bd998..f1a358ae084 100644 --- a/frontend/lib/api/types/openai.ts +++ b/frontend/lib/api/types/openai.ts @@ -62,4 +62,159 @@ export interface OpenAIIngredient { export interface OpenAIIngredients { ingredients?: OpenAIIngredient[]; } +export interface OpenAIRecipe { + /** + * + * The name or title of the recipe. If you're unable to determine the name of the recipe, you should + * make your best guess based upon the ingredients and instructions provided. + * + */ + name: string; + /** + * + * A long description of the recipe. This should be a string that describes the recipe in a few words + * or sentences. If the recipe doesn't have a description, you should return None. + * + */ + description: string | null; + /** + * + * The yield of the recipe. For instance, if the recipe makes 12 cookies, the yield is "12 cookies". + * If the recipe makes 2 servings, the yield is "2 servings". Typically yield consists of a number followed + * by the word "serving" or "servings", but it can be any string that describes the yield. If the yield + * isn't specified, you should return None. + * + */ + recipe_yield?: string | null; + /** + * + * The total time it takes to make the recipe. This should be a string that describes a duration of time, + * such as "1 hour and 30 minutes", "90 minutes", or "1.5 hours". If the recipe has multiple times, choose + * the longest time. If the recipe doesn't specify a total time or duration, or it specifies a prep time or + * perform time but not a total time, you should return None. Do not duplicate times between total time, prep + * time and perform time. + * + */ + total_time?: string | null; + /** + * + * The time it takes to prepare the recipe. This should be a string that describes a duration of time, + * such as "30 minutes", "1 hour", or "1.5 hours". If the recipe has a total time, the prep time should be + * less than the total time. If the recipe doesn't specify a prep time, you should return None. If the recipe + * supplies only one time, it should be the total time. Do not duplicate times between total time, prep + * time and coperformok time. + * + */ + prep_time?: string | null; + /** + * + * The time it takes to cook the recipe. This should be a string that describes a duration of time, + * such as "30 minutes", "1 hour", or "1.5 hours". If the recipe has a total time, the perform time should be + * less than the total time. If the recipe doesn't specify a perform time, you should return None. If the + * recipe specifies a cook time, active time, or other time besides total or prep, you should use that + * time as the perform time. If the recipe supplies only one time, it should be the total time, and not the + * perform time. Do not duplicate times between total time, prep time and perform time. + * + */ + perform_time?: string | null; + /** + * + * A list of ingredients used in the recipe. Ingredients should be inserted in the order they appear in the + * recipe. If the recipe has no ingredients, you should return an empty list. + * + * Often times, but not always, ingredients are separated by line breaks. Use these as a guide to + * separate ingredients. + * + */ + ingredients?: OpenAIRecipeIngredient[]; + /** + * + * A list of ingredients used in the recipe. Ingredients should be inserted in the order they appear in the + * recipe. If the recipe has no ingredients, you should return an empty list. + * + * Often times, but not always, instructions are separated by line breaks and/or separated by paragraphs. + * Use these as a guide to separate instructions. They also may be separated by numbers or words, such as + * "1.", "2.", "Step 1", "Step 2", "First", "Second", etc. + * + */ + instructions?: OpenAIRecipeInstruction[]; + /** + * + * A list of notes found in the recipe. Notes should be inserted in the order they appear in the recipe. + * They may appear anywhere on the recipe, though they are typically found under the instructions. + * + */ + notes?: OpenAIRecipeNotes[]; +} +export interface OpenAIRecipeIngredient { + /** + * + * The title of the section of the recipe that the ingredient is found in. Recipes may not specify + * ingredient sections, in which case this should be left blank. + * Only the first item in the section should have this set, + * whereas subsuquent items should have their titles left blank (unless they start a new section). + * + */ + title?: string | null; + /** + * + * The text of the ingredient. This should represent the entire ingredient, such as "1 cup of flour" or + * "2 cups of onions, chopped". If the ingredient is completely blank, skip it and do not add the ingredient, + * since this field is required. + * + * If the ingredient has no text, but has a title, include the title on the + * next ingredient instead. + * + */ + text: string; +} +export interface OpenAIRecipeInstruction { + /** + * + * The title of the section of the recipe that the instruction is found in. Recipes may not specify + * instruction sections, in which case this should be left blank. + * Only the first instruction in the section should have this set, + * whereas subsuquent instructions should have their titles left blank (unless they start a new section). + * + */ + title?: string | null; + /** + * + * The text of the instruction. This represents one step in the recipe, such as "Preheat the oven to 350", + * or "Sauté the onions for 20 minutes". Sometimes steps can be longer, such as "Bring a large pot of lightly + * salted water to a boil. Add ditalini pasta and cook for 8 minutes or until al dente; drain.". + * + * Sometimes, but not always, recipes will include their number in front of the text, such as + * "1.", "2.", or "Step 1", "Step 2", or "First", "Second". In the case where they are directly numbered + * ("1.", "2.", "Step one", "Step 1", "Step two", "Step 2", etc.), you should not include the number in + * the text. However, if they use words ("First", "Second", etc.), then those should be included. + * + * If the instruction is completely blank, skip it and do not add the instruction, since this field is + * required. If the ingredient has no text, but has a title, include the title on the next + * instruction instead. + * + */ + text: string; +} +export interface OpenAIRecipeNotes { + /** + * + * The title of the note. Notes may not specify a title, and just have a body of text. In this case, + * title should be left blank, and all content should go in the note text. If the note title is just + * "note" or "info", you should ignore it and leave the title blank. + * + */ + title?: string | null; + /** + * + * The text of the note. This should represent the entire note, such as "This recipe is great for + * a summer picnic" or "This recipe is a family favorite". They may also include additional prep + * instructions such as "to make this recipe gluten free, use gluten free flour", or "you may prepare + * the dough the night before and refrigerate it until ready to bake". + * + * If the note is completely blank, skip it and do not add the note, since this field is required. + * + */ + text: string; +} export interface OpenAIBase {} diff --git a/frontend/lib/api/types/user.ts b/frontend/lib/api/types/user.ts index 8b2218f0015..81fd6a7014c 100644 --- a/frontend/lib/api/types/user.ts +++ b/frontend/lib/api/types/user.ts @@ -114,6 +114,7 @@ export interface PrivateUser { advanced?: boolean; canInvite?: boolean; canManage?: boolean; + canManageHousehold?: boolean; canOrganize?: boolean; groupId: string; groupSlug: string; @@ -189,6 +190,7 @@ export interface UserBase { advanced?: boolean; canInvite?: boolean; canManage?: boolean; + canManageHousehold?: boolean; canOrganize?: boolean; } export interface UserIn { @@ -203,6 +205,7 @@ export interface UserIn { advanced?: boolean; canInvite?: boolean; canManage?: boolean; + canManageHousehold?: boolean; canOrganize?: boolean; password: string; } @@ -218,6 +221,7 @@ export interface UserOut { advanced?: boolean; canInvite?: boolean; canManage?: boolean; + canManageHousehold?: boolean; canOrganize?: boolean; groupId: string; groupSlug: string; diff --git a/frontend/lib/api/user/groups.ts b/frontend/lib/api/user/groups.ts index a43063988ce..5dc85110abb 100644 --- a/frontend/lib/api/user/groups.ts +++ b/frontend/lib/api/user/groups.ts @@ -15,7 +15,8 @@ const routes = { groupsSelf: `${prefix}/groups/self`, preferences: `${prefix}/groups/preferences`, storage: `${prefix}/groups/storage`, - households: `${prefix}/households`, + households: `${prefix}/groups/households`, + householdsId: (id: string | number) => `${prefix}/groups/households/${id}`, membersHouseholdId: (householdId: string | number | null) => { return householdId ? `${prefix}/households/members?householdId=${householdId}` : @@ -50,6 +51,10 @@ export class GroupAPI extends BaseCRUDAPI(routes.households); } + async fetchHousehold(householdId: string | number) { + return await this.requests.get(routes.householdsId(householdId)); + } + async storage() { return await this.requests.get(routes.storage); } diff --git a/frontend/middleware/can-manage-household-only.ts b/frontend/middleware/can-manage-household-only.ts new file mode 100644 index 00000000000..0e4509e9e86 --- /dev/null +++ b/frontend/middleware/can-manage-household-only.ts @@ -0,0 +1,11 @@ +interface CanManageRedirectParams { + $auth: any + redirect: (path: string) => void +} +export default function ({ $auth, redirect }: CanManageRedirectParams) { + // If the user is not allowed to manage group settings redirect to the home page + if (!$auth.user?.canManageHousehold) { + console.warn("User is not allowed to manage household settings"); + return redirect("/"); + } +} diff --git a/frontend/pages/admin/manage/households/_id.vue b/frontend/pages/admin/manage/households/_id.vue index 174ab7c1b10..3e897cff2b1 100644 --- a/frontend/pages/admin/manage/households/_id.vue +++ b/frontend/pages/admin/manage/households/_id.vue @@ -53,7 +53,7 @@ import { VForm } from "~/types/vuetify"; export default defineComponent({ components: { - HouseholdPreferencesEditor, + HouseholdPreferencesEditor, }, layout: "admin", setup() { @@ -94,11 +94,8 @@ export default defineComponent({ const { response, data } = await userApi.households.updateOne(household.value.id, household.value); if (response?.status === 200 && data) { - if (household.value.slug !== data.slug) { - // the slug updated, which invalidates the nav URLs - window.location.reload(); - } household.value = data; + alert.success(i18n.tc("settings.settings-updated")); } else { alert.error(i18n.tc("settings.settings-update-failed")); } diff --git a/frontend/pages/household/index.vue b/frontend/pages/household/index.vue index 3e40b173ed6..0416a2bbad3 100644 --- a/frontend/pages/household/index.vue +++ b/frontend/pages/household/index.vue @@ -1,5 +1,5 @@ - + {{ child.icon }} {{ child.title }} - diff --git a/frontend/lang/messages/en-US.json b/frontend/lang/messages/en-US.json index 2dd9dcee3c2..72ec75defa9 100644 --- a/frontend/lang/messages/en-US.json +++ b/frontend/lang/messages/en-US.json @@ -1246,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/layouts/admin.vue b/frontend/layouts/admin.vue index 16547f9cd21..41633791984 100644 --- a/frontend/layouts/admin.vue +++ b/frontend/layouts/admin.vue @@ -92,10 +92,23 @@ export default defineComponent({ restricted: true, }, { - icon: $globals.icons.slotMachine, - to: "/admin/parser", - title: i18n.tc("sidebar.parser"), + icon: $globals.icons.robot, + title: i18n.tc("recipe.debug"), restricted: true, + children: [ + { + icon: $globals.icons.robot, + to: "/admin/debug/openai", + title: i18n.tc("admin.openai"), + restricted: true, + }, + { + icon: $globals.icons.slotMachine, + to: "/admin/debug/parser", + title: i18n.tc("sidebar.parser"), + restricted: true, + }, + ] }, ]; diff --git a/frontend/lib/api/admin/admin-debug.ts b/frontend/lib/api/admin/admin-debug.ts new file mode 100644 index 00000000000..bfbc4cbc4a2 --- /dev/null +++ b/frontend/lib/api/admin/admin-debug.ts @@ -0,0 +1,21 @@ +import { BaseAPI } from "../base/base-clients"; +import { DebugResponse } from "~/lib/api/types/admin"; + +const prefix = "/api"; + +const routes = { + openai: `${prefix}/admin/debug/openai`, +}; + +export class AdminDebugAPI extends BaseAPI { + async debugOpenAI(fileObject: Blob | File | undefined = undefined, fileName = "") { + let formData: FormData | null = null; + if (fileObject) { + formData = new FormData(); + formData.append("image", fileObject); + formData.append("extension", fileName.split(".").pop() ?? ""); + } + + return await this.requests.post(routes.openai, formData); + } +} diff --git a/frontend/lib/api/client-admin.ts b/frontend/lib/api/client-admin.ts index bf151d390ed..27463043084 100644 --- a/frontend/lib/api/client-admin.ts +++ b/frontend/lib/api/client-admin.ts @@ -5,6 +5,7 @@ import { AdminGroupsApi } from "./admin/admin-groups"; import { AdminBackupsApi } from "./admin/admin-backups"; import { AdminMaintenanceApi } from "./admin/admin-maintenance"; import { AdminAnalyticsApi } from "./admin/admin-analytics"; +import { AdminDebugAPI } from "./admin/admin-debug"; import { ApiRequestInstance } from "~/lib/api/types/non-generated"; export class AdminAPI { @@ -15,6 +16,7 @@ export class AdminAPI { public backups: AdminBackupsApi; public maintenance: AdminMaintenanceApi; public analytics: AdminAnalyticsApi; + public debug: AdminDebugAPI; constructor(requests: ApiRequestInstance) { this.about = new AdminAboutAPI(requests); @@ -24,6 +26,7 @@ export class AdminAPI { this.backups = new AdminBackupsApi(requests); this.maintenance = new AdminMaintenanceApi(requests); this.analytics = new AdminAnalyticsApi(requests); + this.debug = new AdminDebugAPI(requests); Object.freeze(this); } diff --git a/frontend/lib/api/types/admin.ts b/frontend/lib/api/types/admin.ts index 6f42b40d443..4f02f2d527c 100644 --- a/frontend/lib/api/types/admin.ts +++ b/frontend/lib/api/types/admin.ts @@ -173,6 +173,10 @@ export interface CustomPageOut { categories?: RecipeCategoryResponse[]; id: number; } +export interface DebugResponse { + success: boolean; + response?: string | null; +} export interface EmailReady { ready: boolean; } diff --git a/frontend/pages/admin/debug/openai.vue b/frontend/pages/admin/debug/openai.vue new file mode 100644 index 00000000000..522cea20fc6 --- /dev/null +++ b/frontend/pages/admin/debug/openai.vue @@ -0,0 +1,127 @@ + + + diff --git a/frontend/pages/admin/parser.vue b/frontend/pages/admin/debug/parser.vue similarity index 100% rename from frontend/pages/admin/parser.vue rename to frontend/pages/admin/debug/parser.vue diff --git a/mealie/core/settings/settings.py b/mealie/core/settings/settings.py index 0b33f5a88cb..0e73ee51d76 100644 --- a/mealie/core/settings/settings.py +++ b/mealie/core/settings/settings.py @@ -3,7 +3,7 @@ import secrets from datetime import datetime, timezone from pathlib import Path -from typing import NamedTuple +from typing import Any, NamedTuple from dateutil.tz import tzlocal from pydantic import field_validator @@ -305,6 +305,10 @@ def OIDC_READY(self) -> bool: """Your OpenAI API key. Required to enable OpenAI features""" OPENAI_MODEL: str = "gpt-4o" """Which OpenAI model to send requests to. Leave this unset for most usecases""" + OPENAI_CUSTOM_HEADERS: dict[str, str] = {} + """Custom HTTP headers to send with each OpenAI request""" + OPENAI_CUSTOM_PARAMS: dict[str, Any] = {} + """Custom HTTP parameters to send with each OpenAI request""" OPENAI_ENABLE_IMAGE_SERVICES: bool = True """Whether to enable image-related features in OpenAI""" OPENAI_WORKERS: int = 2 diff --git a/mealie/routes/admin/__init__.py b/mealie/routes/admin/__init__.py index c0a9839e47f..c0ef59a9dcc 100644 --- a/mealie/routes/admin/__init__.py +++ b/mealie/routes/admin/__init__.py @@ -3,6 +3,7 @@ from . import ( admin_about, admin_backups, + admin_debug, admin_email, admin_maintenance, admin_management_groups, @@ -19,3 +20,4 @@ router.include_router(admin_email.router, tags=["Admin: Email"]) router.include_router(admin_backups.router, tags=["Admin: Backups"]) router.include_router(admin_maintenance.router, tags=["Admin: Maintenance"]) +router.include_router(admin_debug.router, tags=["Admin: Debug"]) diff --git a/mealie/routes/admin/admin_debug.py b/mealie/routes/admin/admin_debug.py new file mode 100644 index 00000000000..65bb654904f --- /dev/null +++ b/mealie/routes/admin/admin_debug.py @@ -0,0 +1,52 @@ +import os +import shutil + +from fastapi import APIRouter, File, UploadFile + +from mealie.core.dependencies.dependencies import get_temporary_path +from mealie.routes._base import BaseAdminController, controller +from mealie.schema.admin.debug import DebugResponse +from mealie.services.openai import OpenAILocalImage, OpenAIService + +router = APIRouter(prefix="/debug") + + +@controller(router) +class AdminDebugController(BaseAdminController): + @router.post("/openai", response_model=DebugResponse) + async def debug_openai(self, image: UploadFile | None = File(None)): + if not self.settings.OPENAI_ENABLED: + return DebugResponse(success=False, response="OpenAI is not enabled") + if image and not self.settings.OPENAI_ENABLE_IMAGE_SERVICES: + return DebugResponse( + success=False, response="Image was provided, but OpenAI image services are not enabled" + ) + + with get_temporary_path() as temp_path: + if image: + with temp_path.joinpath(image.filename).open("wb") as buffer: + shutil.copyfileobj(image.file, buffer) + local_image_path = temp_path.joinpath(image.filename) + local_images = [OpenAILocalImage(filename=os.path.basename(local_image_path), path=local_image_path)] + else: + local_images = None + + try: + openai_service = OpenAIService() + prompt = openai_service.get_prompt("debug") + + message = "Hello, checking to see if I can reach you." + if local_images: + message = f"{message} Here is an image to test with:" + + response = await openai_service.get_response( + prompt, message, images=local_images, force_json_response=False + ) + return DebugResponse(success=True, response=f'OpenAI is working. Response: "{response}"') + + except Exception as e: + self.logger.exception(e) + return DebugResponse( + success=False, + response=f'OpenAI request failed. Full error has been logged. {e.__class__.__name__}: "{e}"', + ) diff --git a/mealie/schema/admin/__init__.py b/mealie/schema/admin/__init__.py index 85d33599605..b399d46f8e9 100644 --- a/mealie/schema/admin/__init__.py +++ b/mealie/schema/admin/__init__.py @@ -1,6 +1,7 @@ # This file is auto-generated by gen_schema_exports.py from .about import AdminAboutInfo, AppInfo, AppStartupInfo, AppStatistics, AppTheme, CheckAppConfig, OIDCInfo from .backup import AllBackups, BackupFile, BackupOptions, CreateBackup, ImportJob +from .debug import DebugResponse from .email import EmailReady, EmailSuccess, EmailTest from .maintenance import MaintenanceLogs, MaintenanceStorageDetails, MaintenanceSummary from .migration import ChowdownURL, MigrationFile, MigrationImport, Migrations @@ -49,4 +50,5 @@ "EmailReady", "EmailSuccess", "EmailTest", + "DebugResponse", ] diff --git a/mealie/schema/admin/debug.py b/mealie/schema/admin/debug.py new file mode 100644 index 00000000000..e653a2bb628 --- /dev/null +++ b/mealie/schema/admin/debug.py @@ -0,0 +1,6 @@ +from mealie.schema._mealie import MealieModel + + +class DebugResponse(MealieModel): + success: bool + response: str | None = None diff --git a/mealie/services/openai/openai.py b/mealie/services/openai/openai.py index 64cd4180eb6..09c391d56b8 100644 --- a/mealie/services/openai/openai.py +++ b/mealie/services/openai/openai.py @@ -90,6 +90,8 @@ def __init__(self) -> None: base_url=settings.OPENAI_BASE_URL, api_key=settings.OPENAI_API_KEY, timeout=settings.OPENAI_REQUEST_TIMEOUT, + default_headers=settings.OPENAI_CUSTOM_HEADERS, + default_query=settings.OPENAI_CUSTOM_PARAMS, ) super().__init__() @@ -176,6 +178,5 @@ async def get_response( if not response.choices: return None return response.choices[0].message.content - except Exception: - self.logger.exception("OpenAI Request Failed") - return None + except Exception as e: + raise Exception(f"OpenAI Request Failed. {e.__class__.__name__}: {e}") from e diff --git a/mealie/services/openai/prompts/debug.txt b/mealie/services/openai/prompts/debug.txt new file mode 100644 index 00000000000..c6fb0bdb173 --- /dev/null +++ b/mealie/services/openai/prompts/debug.txt @@ -0,0 +1 @@ +You are a simple chatbot being used for debugging purposes. diff --git a/mealie/services/parser_services/openai/parser.py b/mealie/services/parser_services/openai/parser.py index 77e1c022935..0e01931bef5 100644 --- a/mealie/services/parser_services/openai/parser.py +++ b/mealie/services/parser_services/openai/parser.py @@ -80,10 +80,20 @@ async def _parse(self, ingredients: list[str]) -> OpenAIIngredients: tasks.append(service.get_response(prompt, message, force_json_response=True)) # re-combine chunks into one response - responses_json = await asyncio.gather(*tasks) - responses = [ - OpenAIIngredients.parse_openai_response(response_json) for response_json in responses_json if responses_json - ] + try: + responses_json = await asyncio.gather(*tasks) + except Exception as e: + raise Exception("Failed to call OpenAI services") from e + + try: + responses = [ + OpenAIIngredients.parse_openai_response(response_json) + for response_json in responses_json + if responses_json + ] + except Exception as e: + raise Exception("Failed to parse OpenAI response") from e + if not responses: raise Exception("No response from OpenAI") diff --git a/mealie/services/recipe/recipe_service.py b/mealie/services/recipe/recipe_service.py index d9efbaca87e..b420216c73f 100644 --- a/mealie/services/recipe/recipe_service.py +++ b/mealie/services/recipe/recipe_service.py @@ -487,7 +487,13 @@ async def build_recipe_from_images(self, images: list[Path], translate_language: if translate_language: message += f" Please translate the recipe to {translate_language}." - response = await openai_service.get_response(prompt, message, images=openai_images, force_json_response=True) + try: + response = await openai_service.get_response( + prompt, message, images=openai_images, force_json_response=True + ) + except Exception as e: + raise Exception("Failed to call OpenAI services") from e + try: openai_recipe = OpenAIRecipe.parse_openai_response(response) recipe = self._convert_recipe(openai_recipe) diff --git a/tests/utils/api_routes/__init__.py b/tests/utils/api_routes/__init__.py index 587ca4abef3..dc096b387e7 100644 --- a/tests/utils/api_routes/__init__.py +++ b/tests/utils/api_routes/__init__.py @@ -11,6 +11,8 @@ """`/api/admin/backups`""" admin_backups_upload = "/api/admin/backups/upload" """`/api/admin/backups/upload`""" +admin_debug_openai = "/api/admin/debug/openai" +"""`/api/admin/debug/openai`""" admin_email = "/api/admin/email" """`/api/admin/email`""" admin_groups = "/api/admin/groups" From 13522a04026f32cb14198692ad69ec3cf316c200 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Mon, 23 Sep 2024 05:31:17 -0500 Subject: [PATCH 23/28] chore(l10n): New Crowdin updates (#4256) --- frontend/lang/messages/af-ZA.json | 7 ++++++- frontend/lang/messages/ar-SA.json | 7 ++++++- frontend/lang/messages/bg-BG.json | 7 ++++++- frontend/lang/messages/ca-ES.json | 7 ++++++- frontend/lang/messages/cs-CZ.json | 7 ++++++- frontend/lang/messages/da-DK.json | 7 ++++++- frontend/lang/messages/de-DE.json | 7 ++++++- frontend/lang/messages/el-GR.json | 7 ++++++- frontend/lang/messages/en-GB.json | 7 ++++++- frontend/lang/messages/es-ES.json | 7 ++++++- frontend/lang/messages/fi-FI.json | 7 ++++++- frontend/lang/messages/fr-BE.json | 19 ++++++++++++------- frontend/lang/messages/fr-CA.json | 19 ++++++++++++------- frontend/lang/messages/fr-FR.json | 7 ++++++- frontend/lang/messages/gl-ES.json | 7 ++++++- frontend/lang/messages/he-IL.json | 7 ++++++- frontend/lang/messages/hr-HR.json | 7 ++++++- frontend/lang/messages/hu-HU.json | 7 ++++++- frontend/lang/messages/is-IS.json | 7 ++++++- frontend/lang/messages/it-IT.json | 7 ++++++- frontend/lang/messages/ja-JP.json | 7 ++++++- frontend/lang/messages/ko-KR.json | 7 ++++++- frontend/lang/messages/lt-LT.json | 7 ++++++- frontend/lang/messages/lv-LV.json | 7 ++++++- frontend/lang/messages/nl-NL.json | 7 ++++++- frontend/lang/messages/no-NO.json | 7 ++++++- frontend/lang/messages/pl-PL.json | 7 ++++++- frontend/lang/messages/pt-BR.json | 7 ++++++- frontend/lang/messages/pt-PT.json | 7 ++++++- frontend/lang/messages/ro-RO.json | 7 ++++++- frontend/lang/messages/ru-RU.json | 7 ++++++- frontend/lang/messages/sk-SK.json | 7 ++++++- frontend/lang/messages/sl-SI.json | 7 ++++++- frontend/lang/messages/sr-SP.json | 7 ++++++- frontend/lang/messages/sv-SE.json | 7 ++++++- frontend/lang/messages/tr-TR.json | 7 ++++++- frontend/lang/messages/uk-UA.json | 7 ++++++- frontend/lang/messages/vi-VN.json | 7 ++++++- frontend/lang/messages/zh-CN.json | 7 ++++++- frontend/lang/messages/zh-TW.json | 7 ++++++- 40 files changed, 252 insertions(+), 52 deletions(-) diff --git a/frontend/lang/messages/af-ZA.json b/frontend/lang/messages/af-ZA.json index 9fe7e648aab..ca048e2377a 100644 --- a/frontend/lang/messages/af-ZA.json +++ b/frontend/lang/messages/af-ZA.json @@ -652,6 +652,7 @@ "or": "Of", "has-any": "Het een van", "has-all": "Bevat alles", + "clear-selection": "Clear Selection", "results": "Resultate", "search": "Soek", "search-mealie": "Soek in Mealie (druk /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/ar-SA.json b/frontend/lang/messages/ar-SA.json index 7ce0f32e213..9767d807d40 100644 --- a/frontend/lang/messages/ar-SA.json +++ b/frontend/lang/messages/ar-SA.json @@ -652,6 +652,7 @@ "or": "Or", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "Results", "search": "Search", "search-mealie": "Search Mealie (press /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/bg-BG.json b/frontend/lang/messages/bg-BG.json index bd063274a78..9e333fbd1ac 100644 --- a/frontend/lang/messages/bg-BG.json +++ b/frontend/lang/messages/bg-BG.json @@ -652,6 +652,7 @@ "or": "Или", "has-any": "Има някое", "has-all": "Има всички", + "clear-selection": "Clear Selection", "results": "Резултати", "search": "Търсене", "search-mealie": "Търсене в Mealie (Натисни /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Ето няколко неща, които ще Ви помогнат да започнете с Mealie", "restore-from-v1-backup": "Имате резервно копие от предишна инстанция на Mealie v1? Можете да го възстановите тук.", "manage-profile-or-get-invite-link": "Управлявайте собствения си профил или вземете връзка за покана, която да споделите с други." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Добре дошъл(а), {0}!", diff --git a/frontend/lang/messages/ca-ES.json b/frontend/lang/messages/ca-ES.json index 4a763230e03..ef2e38cbda5 100644 --- a/frontend/lang/messages/ca-ES.json +++ b/frontend/lang/messages/ca-ES.json @@ -652,6 +652,7 @@ "or": "O", "has-any": "Conté qualsevol", "has-all": "Ho conté tot", + "clear-selection": "Clear Selection", "results": "Resultats", "search": "Cerca", "search-mealie": "Cerca a Melie (prem /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Aquí hi ha unes quantes coses per ajudar-te a posar Mealie en marxa", "restore-from-v1-backup": "Tens una còpia de seguretat d'una instància prèvia de Mealie v1? Pots restaurar-la aquí.", "manage-profile-or-get-invite-link": "Gestiona el teu propi perfil, o agafa un enllaç d'invitació per compartir amb altres." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Benvingut/Benvinguda, {0}!", diff --git a/frontend/lang/messages/cs-CZ.json b/frontend/lang/messages/cs-CZ.json index 426daabaccb..dcbb74bfeba 100644 --- a/frontend/lang/messages/cs-CZ.json +++ b/frontend/lang/messages/cs-CZ.json @@ -652,6 +652,7 @@ "or": "Nebo", "has-any": "Má nějaké", "has-all": "Má všechny", + "clear-selection": "Clear Selection", "results": "Výsledky", "search": "Hledat", "search-mealie": "Hledat v Mealie (stiskněte /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/da-DK.json b/frontend/lang/messages/da-DK.json index 5cb397532c9..e1ca629c1ff 100644 --- a/frontend/lang/messages/da-DK.json +++ b/frontend/lang/messages/da-DK.json @@ -652,6 +652,7 @@ "or": "Eller", "has-any": "Har Nogen", "has-all": "Har Alle", + "clear-selection": "Clear Selection", "results": "Resultater", "search": "Søg", "search-mealie": "Søg Mealie (tryk /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Her er et par ting, der kan hjælpe dig i gang med Mealie", "restore-from-v1-backup": "Har du en sikkerhedskopi fra en tidligere udgave af Mealie v1? Du kan gendanne den her.", "manage-profile-or-get-invite-link": "Administrer din egen profil, eller tag et invitationslink til at dele med andre." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Velkommen, {0}!", diff --git a/frontend/lang/messages/de-DE.json b/frontend/lang/messages/de-DE.json index f010b5dcd7c..752a14b9312 100644 --- a/frontend/lang/messages/de-DE.json +++ b/frontend/lang/messages/de-DE.json @@ -652,6 +652,7 @@ "or": "Oder", "has-any": "Irgendeines enthalten", "has-all": "Alle enthalten", + "clear-selection": "Clear Selection", "results": "Ergebnisse", "search": "Suchen", "search-mealie": "Mealie durchsuchen (/ drücken)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Hier sind einige Funktionen, die dich beim Start mit Mealie unterstützen", "restore-from-v1-backup": "Hast du ein Backup von einer früheren v1 Instanz von Mealie? Hier kannst du es wiederherstellen.", "manage-profile-or-get-invite-link": "Verwalte dein eigenes Profil oder erstelle einen Einladungslink, den du an andere weitergeben kannst." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Willkommen, {0}!", diff --git a/frontend/lang/messages/el-GR.json b/frontend/lang/messages/el-GR.json index d9a8461c5c0..fe95db2a2e8 100644 --- a/frontend/lang/messages/el-GR.json +++ b/frontend/lang/messages/el-GR.json @@ -652,6 +652,7 @@ "or": "Ή", "has-any": "Περιέχει", "has-all": "Περιέχει τα πάντα", + "clear-selection": "Απαλοιφή επιλογής", "results": "Αποτελέσματα", "search": "Αναζήτηση", "search-mealie": "Αναζήτηση στο Mealie (πατήστε /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Εδώ είναι μερικά πράγματα που θα σας βοηθήσουν να ξεκινήσετε με το Mealie", "restore-from-v1-backup": "Εχετε ένα αντίγραφο ασφαλείας από μια προηγούμενη υπόσταση του Mealie v1; Μπορείτε να το επαναφέρετε εδώ.", "manage-profile-or-get-invite-link": "Διαχειριστείτε το δικό σας προφίλ, ή λάβετε έναν σύνδεσμο πρόσκλησης για να μοιραστείτε με άλλους." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Καλώς ορίσατε, {0}!", diff --git a/frontend/lang/messages/en-GB.json b/frontend/lang/messages/en-GB.json index abfa465404b..0b38e746e06 100644 --- a/frontend/lang/messages/en-GB.json +++ b/frontend/lang/messages/en-GB.json @@ -652,6 +652,7 @@ "or": "Or", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "Results", "search": "Search", "search-mealie": "Search Mealie (press /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/es-ES.json b/frontend/lang/messages/es-ES.json index fbe6c630c15..93bfc1f6bf0 100644 --- a/frontend/lang/messages/es-ES.json +++ b/frontend/lang/messages/es-ES.json @@ -652,6 +652,7 @@ "or": "O", "has-any": "Tiene alguna", "has-all": "Tiene todo", + "clear-selection": "Clear Selection", "results": "Resultados", "search": "Buscar", "search-mealie": "Buscar Mealie (presione /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Aquí hay algunas cosas para ayudarte a empezar con Mealie", "restore-from-v1-backup": "¿Tienes una copia de seguridad de Mealie v1? Puedes restaurarla aquí.", "manage-profile-or-get-invite-link": "Gestiona tu perfil, o usa un enlace de invitación para compartir con otros." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 ¡Bienvenido, {0}!", diff --git a/frontend/lang/messages/fi-FI.json b/frontend/lang/messages/fi-FI.json index 18a0a321319..65b17904775 100644 --- a/frontend/lang/messages/fi-FI.json +++ b/frontend/lang/messages/fi-FI.json @@ -652,6 +652,7 @@ "or": "Tai", "has-any": "On Mikä Tahansa", "has-all": "On Kaikki", + "clear-selection": "Clear Selection", "results": "Tulokset", "search": "Hae", "search-mealie": "Hae Mealiestä (paina /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Näillä muutamilla asioilla pääset alkuun", "restore-from-v1-backup": "Onko sinulla varmuuskopio aiemmasta Mealie v1 -instanssista? Palauta se tästä.", "manage-profile-or-get-invite-link": "Hallitse profiiliasi tai hanki kutsulinkki muille." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Tervetuloa, {0}!", diff --git a/frontend/lang/messages/fr-BE.json b/frontend/lang/messages/fr-BE.json index 106b0e67e48..f7aa5878771 100644 --- a/frontend/lang/messages/fr-BE.json +++ b/frontend/lang/messages/fr-BE.json @@ -241,14 +241,14 @@ "manage-members": "Gestion des membres", "manage-members-description": "Gérez les permissions des membres de votre foyer. {manage} donne l’accès à la page de gestion des données à l’utilisateur, et {invite} lui permet de générer des liens d’invitation pour d’autres utilisateurs. Les propriétaires de groupe ne peuvent pas changer leurs propres permissions.", "manage": "Gérer", - "manage-household": "Manage Household", + "manage-household": "Gérer le foyer", "invite": "Inviter", "looking-to-update-your-profile": "Vous cherchez à mettre à jour votre profil ?", "default-recipe-preferences-description": "Ce sont les paramètres par défaut lorsqu'une nouvelle recette est créée dans votre groupe. Elles peuvent être modifiées individuellement dans le menu de configuration des recettes.", "default-recipe-preferences": "Préférences de recette par défaut", "group-preferences": "Préférences du groupe", "private-group": "Groupe privé", - "private-group-description": "Setting your group to private will disable all public view options. This overrides any individual public view settings", + "private-group-description": "Rendre votre groupe privé va désactiver toutes les options de vue publique. Cela écrase les paramètres de vue publique", "enable-public-access": "Activer l’accès public", "enable-public-access-description": "Les recettes de groupes deviennent publiques par défaut, cela permet aux visiteurs de les voir sans s’identifier", "allow-users-outside-of-your-group-to-see-your-recipes": "Autoriser les utilisateurs en dehors de votre groupe à voir vos recettes", @@ -286,9 +286,9 @@ "admin-household-management-text": "Les changements apportés à ce foyer seront immédiatement pris en compte.", "household-id-value": "Identifiant du foyer : {0}", "private-household": "Foyer privé", - "private-household-description": "Setting your household to private will disable all public view options. This overrides any individual public view settings", - "lock-recipe-edits-from-other-households": "Lock recipe edits from other households", - "lock-recipe-edits-from-other-households-description": "When enabled only users in your household can edit recipes created by your household", + "private-household-description": "Rendre votre foyer privé va désactiver toutes les options de vue publique. Cela écrase les paramètres de vue publique", + "lock-recipe-edits-from-other-households": "Verrouiller les éditions de recettes de la part des autres foyers", + "lock-recipe-edits-from-other-households-description": "Si activé, seuls les utilisateurs de votre foyer peuvent modifier les recettes créé par votre foyer", "household-recipe-preferences": "Préférences de recette du foyer", "default-recipe-preferences-description": "Ce sont les paramètres par défaut utilisés pour la création d’une nouvelle recette dans votre foyer. Ils peuvent être modifiés individuellement dans le menu de configuration des recettes.", "allow-users-outside-of-your-household-to-see-your-recipes": "Autoriser les utilisateurs en dehors de votre foyer à voir vos recettes", @@ -652,6 +652,7 @@ "or": "Ou", "has-any": "Requiert au moins", "has-all": "Requiert tout", + "clear-selection": "Effacer la sélection", "results": "Résultats", "search": "Rechercher", "search-mealie": "Rechercher dans Mealie (appuyez sur /)", @@ -990,7 +991,7 @@ "administrator": "Administrateur", "user-can-invite-other-to-group": "L’utilisateur peut inviter d’autres personnes dans le groupe", "user-can-manage-group": "L'utilisateur peut gérer le groupe", - "user-can-manage-household": "User can manage household", + "user-can-manage-household": "L’utilisateur peut gérer le foyer", "user-can-organize-group-data": "L'utilisateur peut organiser des données de groupe", "enable-advanced-features": "Activer les fonctions avancées", "it-looks-like-this-is-your-first-time-logging-in": "Il semble que ce soit votre première connexion.", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Voici quelques trucs pour vous aider à commencer avec Mealie", "restore-from-v1-backup": "Vous avez une sauvegarde d’une précédente instance de Mealie v1 ? Vous pouvez la restaurer ici.", "manage-profile-or-get-invite-link": "Gérez votre propre profil, ou récupérez un lien d’invitation à partager avec d’autres." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Bienvenue, {0} !", diff --git a/frontend/lang/messages/fr-CA.json b/frontend/lang/messages/fr-CA.json index 53b10e6988b..c4ac016a152 100644 --- a/frontend/lang/messages/fr-CA.json +++ b/frontend/lang/messages/fr-CA.json @@ -241,14 +241,14 @@ "manage-members": "Gestion des membres", "manage-members-description": "Gérer les permissions des membres de votre foyer. {manage} permet à l'utilisateur d'accéder à la page de gestion des données, et {invite} permet à l'utilisateur de générer des liens d'invitation pour d'autres utilisateurs. Les propriétaires du groupe ne peuvent pas modifier leurs propres permissions.", "manage": "Gérer", - "manage-household": "Manage Household", + "manage-household": "Gérer le foyer", "invite": "Inviter", "looking-to-update-your-profile": "Vous cherchez à mettre à jour votre profil ?", "default-recipe-preferences-description": "Ce sont les paramètres par défaut lorsqu'une nouvelle recette est créée dans votre groupe. Elles peuvent être modifiées individuellement dans le menu de configuration des recettes.", "default-recipe-preferences": "Préférences de recette par défaut", "group-preferences": "Préférences du groupe", "private-group": "Groupe privé", - "private-group-description": "Setting your group to private will disable all public view options. This overrides any individual public view settings", + "private-group-description": "Rendre votre groupe privé va désactiver toutes les options de vue publique. Cela écrase les paramètres de vue publique", "enable-public-access": "Permettre l'accès public", "enable-public-access-description": "Les recettes de groupes deviennent publiques par défaut, cela permet aux visiteurs de les voir sans s’identifier", "allow-users-outside-of-your-group-to-see-your-recipes": "Autoriser les utilisateurs en dehors de votre groupe à voir vos recettes", @@ -286,9 +286,9 @@ "admin-household-management-text": "Les changements apportés à ce foyer seront appliqués immédiatement.", "household-id-value": "Identifiant du foyer : {0}", "private-household": "Foyer privé", - "private-household-description": "Setting your household to private will disable all public view options. This overrides any individual public view settings", - "lock-recipe-edits-from-other-households": "Lock recipe edits from other households", - "lock-recipe-edits-from-other-households-description": "When enabled only users in your household can edit recipes created by your household", + "private-household-description": "Rendre votre foyer privé va désactiver toutes les options de vue publique. Cela écrase les paramètres de vue publique", + "lock-recipe-edits-from-other-households": "Verrouiller les éditions de recettes de la part des autres foyers", + "lock-recipe-edits-from-other-households-description": "Si activé, seuls les utilisateurs de votre foyer peuvent modifier les recettes créé par votre foyer", "household-recipe-preferences": "Préférences de recette du foyer", "default-recipe-preferences-description": "Ce sont les paramètres par défaut utilisés pour la création d’une nouvelle recette dans votre foyer. Ils peuvent être modifiés individuellement dans le menu de configuration des recettes.", "allow-users-outside-of-your-household-to-see-your-recipes": "Autoriser les utilisateurs en dehors de votre foyer à voir vos recettes", @@ -652,6 +652,7 @@ "or": "Ou", "has-any": "A n'importe quel", "has-all": "A tout", + "clear-selection": "Effacer la sélection", "results": "Résultats", "search": "Rechercher", "search-mealie": "Rechercher dans Mealie (appuyez sur /)", @@ -990,7 +991,7 @@ "administrator": "Administrateur", "user-can-invite-other-to-group": "L’utilisateur peut inviter d’autres personnes dans le groupe", "user-can-manage-group": "L'utilisateur peut gérer le groupe", - "user-can-manage-household": "User can manage household", + "user-can-manage-household": "L’utilisateur peut gérer le foyer", "user-can-organize-group-data": "L'utilisateur peut organiser des données de groupe", "enable-advanced-features": "Activer les fonctions avancées", "it-looks-like-this-is-your-first-time-logging-in": "Il semble que ce soit votre première connexion.", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Voici quelques trucs pour vous aider à commencer avec Mealie", "restore-from-v1-backup": "Vous avez une sauvegarde d’une précédente instance de Mealie v1 ? Vous pouvez la restaurer ici.", "manage-profile-or-get-invite-link": "Gérez votre propre profil, ou récupérez un lien d’invitation à partager avec d’autres." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Bienvenue, {0}!", diff --git a/frontend/lang/messages/fr-FR.json b/frontend/lang/messages/fr-FR.json index e0498b0b94d..f7aa5878771 100644 --- a/frontend/lang/messages/fr-FR.json +++ b/frontend/lang/messages/fr-FR.json @@ -652,6 +652,7 @@ "or": "Ou", "has-any": "Requiert au moins", "has-all": "Requiert tout", + "clear-selection": "Effacer la sélection", "results": "Résultats", "search": "Rechercher", "search-mealie": "Rechercher dans Mealie (appuyez sur /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Voici quelques trucs pour vous aider à commencer avec Mealie", "restore-from-v1-backup": "Vous avez une sauvegarde d’une précédente instance de Mealie v1 ? Vous pouvez la restaurer ici.", "manage-profile-or-get-invite-link": "Gérez votre propre profil, ou récupérez un lien d’invitation à partager avec d’autres." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Bienvenue, {0} !", diff --git a/frontend/lang/messages/gl-ES.json b/frontend/lang/messages/gl-ES.json index 2ded2419508..fc37d526840 100644 --- a/frontend/lang/messages/gl-ES.json +++ b/frontend/lang/messages/gl-ES.json @@ -652,6 +652,7 @@ "or": "Or", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "Results", "search": "Search", "search-mealie": "Search Mealie (press /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/he-IL.json b/frontend/lang/messages/he-IL.json index 45cac7c67f6..683fd8e8c5d 100644 --- a/frontend/lang/messages/he-IL.json +++ b/frontend/lang/messages/he-IL.json @@ -652,6 +652,7 @@ "or": "או", "has-any": "מכיל חלק", "has-all": "מכיל הכול", + "clear-selection": "Clear Selection", "results": "תוצאות", "search": "חיפוש", "search-mealie": "חיפוש במילי (לחץ /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/hr-HR.json b/frontend/lang/messages/hr-HR.json index 4780bbc8bd7..d9866a2b11a 100644 --- a/frontend/lang/messages/hr-HR.json +++ b/frontend/lang/messages/hr-HR.json @@ -652,6 +652,7 @@ "or": "Ili", "has-any": "Sadrži dio", "has-all": "Sadrži sve", + "clear-selection": "Clear Selection", "results": "Rezultati", "search": "Traži", "search-mealie": "Pretraži Mealie (pritisnite /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/hu-HU.json b/frontend/lang/messages/hu-HU.json index 01e60cabe98..72ca172c3e9 100644 --- a/frontend/lang/messages/hu-HU.json +++ b/frontend/lang/messages/hu-HU.json @@ -652,6 +652,7 @@ "or": "Vagy", "has-any": "Bármely", "has-all": "Mind", + "clear-selection": "Clear Selection", "results": "Találatok", "search": "Keresés", "search-mealie": "Keresés a Mealie-ben (/ gombbal)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Itt van egy pár dolog ami segíthet a kezdésben a Mealie-vel", "restore-from-v1-backup": "Van egy korábbi Mealie v1 biztonsági másolatod? Itt visszaállíthatod.", "manage-profile-or-get-invite-link": "Alakítsa a profilját vagy szerezze meg a meghívó link-jét hogy megoszthassa másokkal." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Üdvözöljük, {0}!", diff --git a/frontend/lang/messages/is-IS.json b/frontend/lang/messages/is-IS.json index 382aa53aca0..72ec75defa9 100644 --- a/frontend/lang/messages/is-IS.json +++ b/frontend/lang/messages/is-IS.json @@ -652,6 +652,7 @@ "or": "Or", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "Results", "search": "Search", "search-mealie": "Search Mealie (press /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/it-IT.json b/frontend/lang/messages/it-IT.json index d02f4af5407..9f4130a5a79 100644 --- a/frontend/lang/messages/it-IT.json +++ b/frontend/lang/messages/it-IT.json @@ -652,6 +652,7 @@ "or": "O", "has-any": "Una Delle Scelte", "has-all": "Tutte Le Scelte", + "clear-selection": "Clear Selection", "results": "Risultati", "search": "Cerca", "search-mealie": "Cerca Mealie (premi /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Qui ci sono alcune cose per aiutarvi a iniziare con Mealie", "restore-from-v1-backup": "Hai un backup da un'istanza precedente di Mealie v1? Puoi ripristinarlo qui.", "manage-profile-or-get-invite-link": "Gestisci il tuo profilo, o parti da un link di invito per condividere con gli altri." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Benvenutǝ, {0}!", diff --git a/frontend/lang/messages/ja-JP.json b/frontend/lang/messages/ja-JP.json index 2c33d1aa3ef..6a943eea0eb 100644 --- a/frontend/lang/messages/ja-JP.json +++ b/frontend/lang/messages/ja-JP.json @@ -652,6 +652,7 @@ "or": "または", "has-any": "いずれかの", "has-all": "すべての", + "clear-selection": "Clear Selection", "results": "検索結果", "search": "検索", "search-mealie": "Mealieを検索 (/キーを押す)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Mealieを始めるのに役立つことがいくつかあります", "restore-from-v1-backup": "Mealie v1以前のインスタンスからのバックアップはありますか?ここで復元できます。", "manage-profile-or-get-invite-link": "自分のプロフィールを管理するか、招待リンクを取得して他の人と共有します。" - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 ようこそ, {0}!", diff --git a/frontend/lang/messages/ko-KR.json b/frontend/lang/messages/ko-KR.json index eabbf2cc7f8..43efd844165 100644 --- a/frontend/lang/messages/ko-KR.json +++ b/frontend/lang/messages/ko-KR.json @@ -652,6 +652,7 @@ "or": "Or", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "Results", "search": "검색", "search-mealie": "Search Mealie (press /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/lt-LT.json b/frontend/lang/messages/lt-LT.json index 6db99f5e48a..b61940adce5 100644 --- a/frontend/lang/messages/lt-LT.json +++ b/frontend/lang/messages/lt-LT.json @@ -652,6 +652,7 @@ "or": "Arba", "has-any": "Bet kuris", "has-all": "Visi", + "clear-selection": "Clear Selection", "results": "Rezultatai", "search": "Ieškoti", "search-mealie": "Pradėti ieškoti \"Mealie\" (spauskite /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/lv-LV.json b/frontend/lang/messages/lv-LV.json index ffdfd75d07a..5976ca8f866 100644 --- a/frontend/lang/messages/lv-LV.json +++ b/frontend/lang/messages/lv-LV.json @@ -652,6 +652,7 @@ "or": "Or", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "Results", "search": "Search", "search-mealie": "Search Mealie (press /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/nl-NL.json b/frontend/lang/messages/nl-NL.json index 274f8bdc8b5..da9174975bd 100644 --- a/frontend/lang/messages/nl-NL.json +++ b/frontend/lang/messages/nl-NL.json @@ -652,6 +652,7 @@ "or": "Of", "has-any": "Heeft een van", "has-all": "Bevat alles", + "clear-selection": "Selectie wissen", "results": "Resultaten", "search": "Zoek", "search-mealie": "Zoek in Mealie (druk /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Hier zijn een aantal dingen om je op weg te helpen met Mealie", "restore-from-v1-backup": "Heb je een back-up van een vorig exemplaar van Mealie v1? Deze kan je hier terugzetten.", "manage-profile-or-get-invite-link": "Beheer je eigen profiel, of gebruik een uitnodigingslink om te delen met anderen." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welkom, {0}!", diff --git a/frontend/lang/messages/no-NO.json b/frontend/lang/messages/no-NO.json index 7c28c842cb5..f98775fa6d1 100644 --- a/frontend/lang/messages/no-NO.json +++ b/frontend/lang/messages/no-NO.json @@ -652,6 +652,7 @@ "or": "Eller", "has-any": "Har enhver", "has-all": "Har alle", + "clear-selection": "Clear Selection", "results": "Resultater", "search": "Søk", "search-mealie": "Søk i Mealie (trykk /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Her er noen ting som kan hjelpe deg å komme i gang med Mealie", "restore-from-v1-backup": "Har du en sikkerhetskopi fra en tidligere forekomst av Mealie v1? Du kan gjenopprette den her.", "manage-profile-or-get-invite-link": "Administrer din egen profil, eller hent en invitasjonslenke for å dele med andre." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "Velkommen, {0}!", diff --git a/frontend/lang/messages/pl-PL.json b/frontend/lang/messages/pl-PL.json index c8bac2d4582..4f0a8c74f38 100644 --- a/frontend/lang/messages/pl-PL.json +++ b/frontend/lang/messages/pl-PL.json @@ -652,6 +652,7 @@ "or": "Lub", "has-any": "Ma dowolny", "has-all": "Ma wszystkie", + "clear-selection": "Clear Selection", "results": "Wyniki", "search": "Szukaj", "search-mealie": "Przeszukaj Mealie (naciśnij /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/pt-BR.json b/frontend/lang/messages/pt-BR.json index 8807e89554b..bfe7f9059c8 100644 --- a/frontend/lang/messages/pt-BR.json +++ b/frontend/lang/messages/pt-BR.json @@ -652,6 +652,7 @@ "or": "Ou", "has-any": "Tem alguma", "has-all": "Tem todos", + "clear-selection": "Clear Selection", "results": "Resultados", "search": "Pesquisar", "search-mealie": "Pesquisar no Mealie (pressione /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Aqui há algumas coisas para ajudá-lo a começar com o Mealie", "restore-from-v1-backup": "Tem uma cópia de segurança de uma instância anterior do Mealie v1? Você pode restaurá-la aqui.", "manage-profile-or-get-invite-link": "Gerencie seu próprio perfil, ou pegue um link de convite para compartilhar." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Bem-vindo(a), {0}!", diff --git a/frontend/lang/messages/pt-PT.json b/frontend/lang/messages/pt-PT.json index 6e248e0ebf0..6eb7bb57158 100644 --- a/frontend/lang/messages/pt-PT.json +++ b/frontend/lang/messages/pt-PT.json @@ -652,6 +652,7 @@ "or": "Ou", "has-any": "Tem algum", "has-all": "Tem todos", + "clear-selection": "Clear Selection", "results": "Resultados", "search": "Pesquisar", "search-mealie": "Procurar no Mealie (prima /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Aqui estão algumas coisas para ajudar a começar com o Mealie", "restore-from-v1-backup": "Tem uma cópia de segurança de uma instância do Mealie v1? Pode restaurá-la aqui.", "manage-profile-or-get-invite-link": "Gira o seu próprio perfil ou pegue num convite para partilhar com outros." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Bem-vindo, {0}!", diff --git a/frontend/lang/messages/ro-RO.json b/frontend/lang/messages/ro-RO.json index 34d8b5cde3f..bf70e62f5d0 100644 --- a/frontend/lang/messages/ro-RO.json +++ b/frontend/lang/messages/ro-RO.json @@ -652,6 +652,7 @@ "or": "Sau", "has-any": "Are orice", "has-all": "Are toate", + "clear-selection": "Clear Selection", "results": "Rezultate", "search": "Caută", "search-mealie": "Căutare Mealie (apasă /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/ru-RU.json b/frontend/lang/messages/ru-RU.json index 12cc5865674..3c2f2fa9ec4 100644 --- a/frontend/lang/messages/ru-RU.json +++ b/frontend/lang/messages/ru-RU.json @@ -652,6 +652,7 @@ "or": "Или", "has-any": "Включает любое", "has-all": "Включает все", + "clear-selection": "Clear Selection", "results": "Результаты", "search": "Поиск", "search-mealie": "Поиск Mealie (нажмите /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Добро пожаловать, {0}!", diff --git a/frontend/lang/messages/sk-SK.json b/frontend/lang/messages/sk-SK.json index 10dd514b98f..44fd3d58afc 100644 --- a/frontend/lang/messages/sk-SK.json +++ b/frontend/lang/messages/sk-SK.json @@ -652,6 +652,7 @@ "or": "Alebo", "has-any": "Obsahuje ktorýkoľvek", "has-all": "Obsahuje všetky", + "clear-selection": "Clear Selection", "results": "Výsledky", "search": "Vyhľadať", "search-mealie": "Prehľadať Mealie (stlač /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Tu je niekoľko bodov, ktoré vám pomôžu na začiatku v Mealie", "restore-from-v1-backup": "Máte zálohu z predchádzajúcej inštalácie Mealie v1? Tu ju môžete obnoviť.", "manage-profile-or-get-invite-link": "Spravujte svoj profil ako súkromný alebo ho s pomocou pozývacieho linku zdieľajte s ostatnými." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Vitajte, {0}!", diff --git a/frontend/lang/messages/sl-SI.json b/frontend/lang/messages/sl-SI.json index 0cada85795f..dd93f02cfb9 100644 --- a/frontend/lang/messages/sl-SI.json +++ b/frontend/lang/messages/sl-SI.json @@ -652,6 +652,7 @@ "or": "Ali", "has-any": "Ima enega izmed", "has-all": "Ima vse", + "clear-selection": "Clear Selection", "results": "Rezultati", "search": "Iskanje", "search-mealie": "Išči po Mealie (pritisni /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Par stvari, ki to bodo pomagale začeti z Mealie", "restore-from-v1-backup": "Imaš varnostno kopijo iz predhodnje instance Mealie v1? Obnoviš jo lahko tule.", "manage-profile-or-get-invite-link": "Upravljaj s svojim profilom ali skopiraj povezavo z vabilom in jo deli z drugimi." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Živjo, {0}!", diff --git a/frontend/lang/messages/sr-SP.json b/frontend/lang/messages/sr-SP.json index 5d32c588838..de199099af0 100644 --- a/frontend/lang/messages/sr-SP.json +++ b/frontend/lang/messages/sr-SP.json @@ -652,6 +652,7 @@ "or": "Или", "has-any": "Садржи било који", "has-all": "Садржи све", + "clear-selection": "Clear Selection", "results": "Резултати", "search": "Претрага", "search-mealie": "Претражи Мили (стисни /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/sv-SE.json b/frontend/lang/messages/sv-SE.json index 6dea9485914..5c15d06ed60 100644 --- a/frontend/lang/messages/sv-SE.json +++ b/frontend/lang/messages/sv-SE.json @@ -652,6 +652,7 @@ "or": "Eller", "has-any": "Har någon", "has-all": "Har alla", + "clear-selection": "Clear Selection", "results": "Resultat", "search": "Sök", "search-mealie": "Sök Mealie (tryck /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Här är några saker som hjälper dig att komma igång med Mealie", "restore-from-v1-backup": "Har du en säkerhetskopia från en tidigare instans av Mealie v1? Du kan återställa den här.", "manage-profile-or-get-invite-link": "Hantera din egen profil eller hämta en inbjudningslänk för att dela med andra." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Välkommen, {0}!", diff --git a/frontend/lang/messages/tr-TR.json b/frontend/lang/messages/tr-TR.json index bd32f7c8f71..660cd4f424a 100644 --- a/frontend/lang/messages/tr-TR.json +++ b/frontend/lang/messages/tr-TR.json @@ -652,6 +652,7 @@ "or": "Veya", "has-any": "Herhangi biri var", "has-all": "Hepsi var", + "clear-selection": "Clear Selection", "results": "Sonuçlar", "search": "Ara", "search-mealie": "Mealie'de Ara (/ tuşuna basın)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Mealie'yi kullanmaya başlamanıza yardımcı olacak birkaç şey", "restore-from-v1-backup": "Mealie v1'in önceki örneğinden bir yedeğiniz mi var? Buradan geri yükleyebilirsiniz.", "manage-profile-or-get-invite-link": "Kendi profilinizi yönetin veya başkalarıyla paylaşmak için bir davet bağlantısı alın." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Hoşgeldin, {0}!", diff --git a/frontend/lang/messages/uk-UA.json b/frontend/lang/messages/uk-UA.json index 80feb67bc82..603e5caf65a 100644 --- a/frontend/lang/messages/uk-UA.json +++ b/frontend/lang/messages/uk-UA.json @@ -652,6 +652,7 @@ "or": "Або", "has-any": "Є будь-яке", "has-all": "Є всі", + "clear-selection": "Clear Selection", "results": "Результати", "search": "Пошук", "search-mealie": "Пошук по Mealie (натисніть /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Ось кілька речей, які допоможуть вам почати з Mealie", "restore-from-v1-backup": "Маєте резервну копію з попереднього екземпляра Меаліе v1? Ви можете використати його тут.", "manage-profile-or-get-invite-link": "Керуйте вашим власним профілем, або отримайте посилання-запрошення щоб поділитися з іншими." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Ласкаво просимо, {0}!", diff --git a/frontend/lang/messages/vi-VN.json b/frontend/lang/messages/vi-VN.json index f522cb3318f..d6dafdd4a21 100644 --- a/frontend/lang/messages/vi-VN.json +++ b/frontend/lang/messages/vi-VN.json @@ -652,6 +652,7 @@ "or": "Or", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "Results", "search": "Search", "search-mealie": "Search Mealie (press /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", diff --git a/frontend/lang/messages/zh-CN.json b/frontend/lang/messages/zh-CN.json index 7ccb94d8093..6eee3de9d1b 100644 --- a/frontend/lang/messages/zh-CN.json +++ b/frontend/lang/messages/zh-CN.json @@ -652,6 +652,7 @@ "or": "或", "has-any": "包含任意", "has-all": "包含所有", + "clear-selection": "Clear Selection", "results": "结果", "search": "搜索", "search-mealie": "搜索Mealie (按 /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "以下这些可以帮助你开始使用Mealie", "restore-from-v1-backup": "有之前Mealie v1实例的备份数据?你可以在这里恢复它们。", "manage-profile-or-get-invite-link": "管理你自己的个人资料,或者获取邀请链接分享给其他人。" - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 欢迎,{0}!", diff --git a/frontend/lang/messages/zh-TW.json b/frontend/lang/messages/zh-TW.json index 639315d6633..0924d8bc92e 100644 --- a/frontend/lang/messages/zh-TW.json +++ b/frontend/lang/messages/zh-TW.json @@ -652,6 +652,7 @@ "or": "或", "has-any": "Has Any", "has-all": "Has All", + "clear-selection": "Clear Selection", "results": "結果", "search": "搜尋", "search-mealie": "搜尋Mealie (按 /)", @@ -1245,7 +1246,11 @@ "here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie", "restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.", "manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others." - } + }, + "debug-openai-services": "Debug OpenAI Services", + "debug-openai-services-description": "Use this page to debug OpenAI services. You can test your OpenAI connection and see the results here. If you have image services enabled, you can also provide an image.", + "run-test": "Run Test", + "test-results": "Test Results" }, "profile": { "welcome-user": "👋 Welcome, {0}!", From 1d4ff66824cffd69a9f853d750d2e18259671f8a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:49:46 +0000 Subject: [PATCH 24/28] chore(auto): Update pre-commit hooks (#4255) Co-authored-by: boc-the-git <3479092+boc-the-git@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6413e3b0562..fb14874f0e0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: exclude: ^tests/data/ - repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.6.5 + rev: v0.6.7 hooks: - id: ruff - id: ruff-format From 02a36509b6cb28d48599634debabad2583c23bdf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 10:18:26 -0500 Subject: [PATCH 25/28] fix(deps): update dependency rapidfuzz to v3.10.0 (#4257) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- poetry.lock | 202 +++++++++++++++++++++++----------------------------- 1 file changed, 91 insertions(+), 111 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3cb908e0dd1..bc31fd840dc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2514,123 +2514,103 @@ pyyaml = "*" [[package]] name = "rapidfuzz" -version = "3.9.7" +version = "3.10.0" description = "rapid fuzzy string matching" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "rapidfuzz-3.9.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ccf68e30b80e903f2309f90a438dbd640dd98e878eeb5ad361a288051ee5b75c"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:696a79018ef989bf1c9abd9005841cee18005ccad4748bad8a4c274c47b6241a"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4eebf6c93af0ae866c22b403a84747580bb5c10f0d7b51c82a87f25405d4dcb"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e9125377fa3d21a8abd4fbdbcf1c27be73e8b1850f0b61b5b711364bf3b59db"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c12d180b17a22d107c8747de9c68d0b9c1d15dcda5445ff9bf9f4ccfb67c3e16"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c1318d42610c26dcd68bd3279a1bf9e3605377260867c9a8ed22eafc1bd93a7c"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5fa6e3c6e0333051c1f3a49f0807b3366f4131c8d6ac8c3e05fd0d0ce3755c"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fcf79b686962d7bec458a0babc904cb4fa319808805e036b9d5a531ee6b9b835"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8b01153c7466d0bad48fba77a303d5a768e66f24b763853469f47220b3de4661"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:94baaeea0b4f8632a6da69348b1e741043eba18d4e3088d674d3f76586b6223d"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6c5b32875646cb7f60c193ade99b2e4b124f19583492115293cd00f6fb198b17"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:110b6294396bc0a447648627479c9320f095c2034c0537f687592e0f58622638"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-win32.whl", hash = "sha256:3445a35c4c8d288f2b2011eb61bce1227c633ce85a3154e727170f37c0266bb2"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-win_amd64.whl", hash = "sha256:0d1415a732ee75e74a90af12020b77a0b396b36c60afae1bde3208a78cd2c9fc"}, - {file = "rapidfuzz-3.9.7-cp310-cp310-win_arm64.whl", hash = "sha256:836f4d88b8bd0fff2ebe815dcaab8aa6c8d07d1d566a7e21dd137cf6fe11ed5b"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d098ce6162eb5e48fceb0745455bc950af059df6113eec83e916c129fca11408"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:048d55d36c02c6685a2b2741688503c3d15149694506655b6169dcfd3b6c2585"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c33211cfff9aec425bb1bfedaf94afcf337063aa273754f22779d6dadebef4c2"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6d9db2fa4e9be171e9bb31cf2d2575574774966b43f5b951062bb2e67885852"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4e049d5ad61448c9a020d1061eba20944c4887d720c4069724beb6ea1692507"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cfa74aac64c85898b93d9c80bb935a96bf64985e28d4ee0f1a3d1f3bf11a5106"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:965693c2e9efd425b0f059f5be50ef830129f82892fa1858e220e424d9d0160f"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8501000a5eb8037c4b56857724797fe5a8b01853c363de91c8d0d0ad56bef319"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d92c552c6b7577402afdd547dcf5d31ea6c8ae31ad03f78226e055cfa37f3c6"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1ee2086f490cb501d86b7e386c1eb4e3a0ccbb0c99067089efaa8c79012c8952"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1de91e7fd7f525e10ea79a6e62c559d1b0278ec097ad83d9da378b6fab65a265"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4da514d13f4433e16960a17f05b67e0af30ac771719c9a9fb877e5004f74477"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-win32.whl", hash = "sha256:a40184c67db8252593ec518e17fb8a6e86d7259dc9f2d6c0bf4ff4db8cf1ad4b"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-win_amd64.whl", hash = "sha256:c4f28f1930b09a2c300357d8465b388cecb7e8b2f454a5d5425561710b7fd07f"}, - {file = "rapidfuzz-3.9.7-cp311-cp311-win_arm64.whl", hash = "sha256:675b75412a943bb83f1f53e2e54fd18c80ef15ed642dc6eb0382d1949419d904"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1ef6a1a8f0b12f8722f595f15c62950c9a02d5abc64742561299ffd49f6c6944"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:32532af1d70c6ec02ea5ac7ee2766dfff7c8ae8c761abfe8da9e527314e634e8"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae1a38bade755aa9dd95a81cda949e1bf9cd92b79341ccc5e2189c9e7bdfc5ec"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d73ee2df41224c87336448d279b5b6a3a75f36e41dd3dcf538c0c9cce36360d8"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be3a1fc3e2ab3bdf93dc0c83c00acca8afd2a80602297d96cf4a0ba028333cdf"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:603f48f621272a448ff58bb556feb4371252a02156593303391f5c3281dfaeac"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:268f8e1ca50fc61c0736f3fe9d47891424adf62d96ed30196f30f4bd8216b41f"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f8bf3f0d02935751d8660abda6044821a861f6229f7d359f98bcdcc7e66c39b"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b997ff3b39d4cee9fb025d6c46b0a24bd67595ce5a5b652a97fb3a9d60beb651"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ca66676c8ef6557f9b81c5b2b519097817a7c776a6599b8d6fcc3e16edd216fe"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:35d3044cb635ca6b1b2b7b67b3597bd19f34f1753b129eb6d2ae04cf98cd3945"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a93c9e60904cb76e7aefef67afffb8b37c4894f81415ed513db090f29d01101"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-win32.whl", hash = "sha256:579d107102c0725f7c79b4e79f16d3cf4d7c9208f29c66b064fa1fd4641d5155"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-win_amd64.whl", hash = "sha256:953b3780765c8846866faf891ee4290f6a41a6dacf4fbcd3926f78c9de412ca6"}, - {file = "rapidfuzz-3.9.7-cp312-cp312-win_arm64.whl", hash = "sha256:7c20c1474b068c4bd45bf2fd0ad548df284f74e9a14a68b06746c56e3aa8eb70"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fde81b1da9a947f931711febe2e2bee694e891f6d3e6aa6bc02c1884702aea19"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:47e92c155a14f44511ea8ebcc6bc1535a1fe8d0a7d67ad3cc47ba61606df7bcf"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8772b745668260c5c4d069c678bbaa68812e6c69830f3771eaad521af7bc17f8"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578302828dd97ee2ba507d2f71d62164e28d2fc7bc73aad0d2d1d2afc021a5d5"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc3e6081069eea61593f1d6839029da53d00c8c9b205c5534853eaa3f031085c"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0b1c2d504eddf97bc0f2eba422c8915576dbf025062ceaca2d68aecd66324ad9"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb76e5a21034f0307c51c5a2fc08856f698c53a4c593b17d291f7d6e9d09ca3"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d4ba2318ef670ce505f42881a5d2af70f948124646947341a3c6ccb33cd70369"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:057bb03f39e285047d7e9412e01ecf31bb2d42b9466a5409d715d587460dd59b"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a8feac9006d5c9758438906f093befffc4290de75663dbb2098461df7c7d28dd"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95b8292383e717e10455f2c917df45032b611141e43d1adf70f71b1566136b11"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e9fbf659537d246086d0297628b3795dc3e4a384101ecc01e5791c827b8d7345"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-win32.whl", hash = "sha256:1dc516ac6d32027be2b0196bedf6d977ac26debd09ca182376322ad620460feb"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-win_amd64.whl", hash = "sha256:b4f86e09d3064dca0b014cd48688964036a904a2d28048f00c8f4640796d06a8"}, - {file = "rapidfuzz-3.9.7-cp313-cp313-win_arm64.whl", hash = "sha256:19c64d8ddb2940b42a4567b23f1681af77f50a5ff6c9b8e85daba079c210716e"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fbda3dd68d8b28ccb20ffb6f756fefd9b5ba570a772bedd7643ed441f5793308"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2379e0b2578ad3ac7004f223251550f08bca873ff76c169b09410ec562ad78d8"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d1eff95362f993b0276fd3839aee48625b09aac8938bb0c23b40d219cba5dc5"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd9360e30041690912525a210e48a897b49b230768cc8af1c702e5395690464f"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a93cd834b3c315ab437f0565ee3a2f42dd33768dc885ccbabf9710b131cf70d2"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff196996240db7075f62c7bc4506f40a3c80cd4ae3ab0e79ac6892283a90859"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948dcee7aaa1cd14358b2a7ef08bf0be42bf89049c3a906669874a715fc2c937"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d95751f505a301af1aaf086c19f34536056d6c8efa91b2240de532a3db57b543"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:90db86fa196eecf96cb6db09f1083912ea945c50c57188039392d810d0b784e1"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:3171653212218a162540a3c8eb8ae7d3dcc8548540b69eaecaf3b47c14d89c90"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:36dd6e820379c37a1ffefc8a52b648758e867cd9d78ee5b5dc0c9a6a10145378"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:7b702de95666a1f7d5c6b47eacadfe2d2794af3742d63d2134767d13e5d1c713"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-win32.whl", hash = "sha256:9030e7238c0df51aed5c9c5ed8eee2bdd47a2ae788e562c1454af2851c3d1906"}, - {file = "rapidfuzz-3.9.7-cp38-cp38-win_amd64.whl", hash = "sha256:f847fb0fbfb72482b1c05c59cbb275c58a55b73708a7f77a83f8035ee3c86497"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:97f2ce529d2a70a60c290f6ab269a2bbf1d3b47b9724dccc84339b85f7afb044"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e2957fdad10bb83b1982b02deb3604a3f6911a5e545f518b59c741086f92d152"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d5262383634626eb45c536017204b8163a03bc43bda880cf1bdd7885db9a163"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:364587827d7cbd41afa0782adc2d2d19e3f07d355b0750a02a8e33ad27a9c368"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ecc24af7f905f3d6efb371a01680116ffea8d64e266618fb9ad1602a9b4f7934"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dc86aa6b29d174713c5f4caac35ffb7f232e3e649113e8d13812b35ab078228"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3dcfbe7266e74a707173a12a7b355a531f2dcfbdb32f09468e664330da14874"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b23806fbdd6b510ba9ac93bb72d503066263b0fba44b71b835be9f063a84025f"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:5551d68264c1bb6943f542da83a4dc8940ede52c5847ef158698799cc28d14f5"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:13d8675a1fa7e2b19650ca7ef9a6ec01391d4bb12ab9e0793e8eb024538b4a34"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9b6a5de507b9be6de688dae40143b656f7a93b10995fb8bd90deb555e7875c60"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:111a20a3c090cf244d9406e60500b6c34b2375ba3a5009e2b38fd806fe38e337"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-win32.whl", hash = "sha256:22589c0b8ccc6c391ce7f776c93a8c92c96ab8d34e1a19f1bd2b12a235332632"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-win_amd64.whl", hash = "sha256:6f83221db5755b8f34222e40607d87f1176a8d5d4dbda4a55a0f0b67d588a69c"}, - {file = "rapidfuzz-3.9.7-cp39-cp39-win_arm64.whl", hash = "sha256:3665b92e788578c3bb334bd5b5fa7ee1a84bafd68be438e3110861d1578c63a0"}, - {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:d7df9c2194c7ec930b33c991c55dbd0c10951bd25800c0b7a7b571994ebbced5"}, - {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:68bd888eafd07b09585dcc8bc2716c5ecdb7eed62827470664d25588982b2873"}, - {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1230e0f9026851a6a432beaa0ce575dda7b39fe689b576f99a0704fbb81fc9c"}, - {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3b36e1c61b796ae1777f3e9e11fd39898b09d351c9384baf6e3b7e6191d8ced"}, - {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dba13d86806fcf3fe9c9919f58575e0090eadfb89c058bde02bcc7ab24e4548"}, - {file = "rapidfuzz-3.9.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1f1a33e84056b7892c721d84475d3bde49a145126bc4c6efe0d6d0d59cb31c29"}, - {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3492c7a42b7fa9f0051d7fcce9893e95ed91c97c9ec7fb64346f3e070dd318ed"}, - {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:ece45eb2af8b00f90d10f7419322e8804bd42fb1129026f9bfe712c37508b514"}, - {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcd14cf4876f04b488f6e54a7abd3e9b31db5f5a6aba0ce90659917aaa8c088"}, - {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:521c58c72ed8a612b25cda378ff10dee17e6deb4ee99a070b723519a345527b9"}, - {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18669bb6cdf7d40738526d37e550df09ba065b5a7560f3d802287988b6cb63cf"}, - {file = "rapidfuzz-3.9.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7abe2dbae81120a64bb4f8d3fcafe9122f328c9f86d7f327f174187a5af4ed86"}, - {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:a3c0783910911f4f24655826d007c9f4360f08107410952c01ee3df98c713eb2"}, - {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:03126f9a040ff21d2a110610bfd6b93b79377ce8b4121edcb791d61b7df6eec5"}, - {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:591908240f4085e2ade5b685c6e8346e2ed44932cffeaac2fb32ddac95b55c7f"}, - {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9012d86c6397edbc9da4ac0132de7f8ee9d6ce857f4194d5684c4ddbcdd1c5c"}, - {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df596ddd3db38aa513d4c0995611267b3946e7cbe5a8761b50e9306dfec720ee"}, - {file = "rapidfuzz-3.9.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3ed5adb752f4308fcc8f4fb6f8eb7aa4082f9d12676fda0a74fa5564242a8107"}, - {file = "rapidfuzz-3.9.7.tar.gz", hash = "sha256:f1c7296534c1afb6f495aa95871f14ccdc197c6db42965854e483100df313030"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:884453860de029380dded8f3c1918af2d8eb5adf8010261645c7e5c88c2b5428"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718c9bd369288aca5fa929df6dbf66fdbe9768d90940a940c0b5cdc96ade4309"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a68e3724b7dab761c01816aaa64b0903734d999d5589daf97c14ef5cc0629a8e"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1af60988d47534246d9525f77288fdd9de652608a4842815d9018570b959acc6"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3084161fc3e963056232ef8d937449a2943852e07101f5a136c8f3cfa4119217"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6cd67d3d017296d98ff505529104299f78433e4b8af31b55003d901a62bbebe9"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b11a127ac590fc991e8a02c2d7e1ac86e8141c92f78546f18b5c904064a0552c"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aadce42147fc09dcef1afa892485311e824c050352e1aa6e47f56b9b27af4cf0"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b54853c2371bf0e38d67da379519deb6fbe70055efb32f6607081641af3dc752"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ce19887268e90ee81a3957eef5e46a70ecc000713796639f83828b950343f49e"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f39a2a5ded23b9b9194ec45740dce57177b80f86c6d8eba953d3ff1a25c97766"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:0ec338d5f4ad8d9339a88a08db5c23e7f7a52c2b2a10510c48a0cef1fb3f0ddc"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-win32.whl", hash = "sha256:56fd15ea8f4c948864fa5ebd9261c67cf7b89a1c517a0caef4df75446a7af18c"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:43dfc5e733808962a822ff6d9c29f3039a3cfb3620706f5953e17cfe4496724c"}, + {file = "rapidfuzz-3.10.0-cp310-cp310-win_arm64.whl", hash = "sha256:ae7966f205b5a7fde93b44ca8fed37c1c8539328d7f179b1197de34eceaceb5f"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb0013795b40db5cf361e6f21ee7cda09627cf294977149b50e217d7fe9a2f03"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:69ef5b363afff7150a1fbe788007e307b9802a2eb6ad92ed51ab94e6ad2674c6"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c582c46b1bb0b19f1a5f4c1312f1b640c21d78c371a6615c34025b16ee56369b"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:288f6f6e7410cacb115fb851f3f18bf0e4231eb3f6cb5bd1cec0e7b25c4d039d"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e29a13d2fd9be3e7d8c26c7ef4ba60b5bc7efbc9dbdf24454c7e9ebba31768"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea2da0459b951ee461bd4e02b8904890bd1c4263999d291c5cd01e6620177ad4"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:457827ba82261aa2ae6ac06a46d0043ab12ba7216b82d87ae1434ec0f29736d6"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5d350864269d56f51ab81ab750c9259ae5cad3152c0680baef143dcec92206a1"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a9b8f51e08c3f983d857c3889930af9ddecc768453822076683664772d87e374"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7f3a6aa6e70fc27e4ff5c479f13cc9fc26a56347610f5f8b50396a0d344c5f55"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:803f255f10d63420979b1909ef976e7d30dec42025c9b067fc1d2040cc365a7e"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2026651761bf83a0f31495cc0f70840d5c0d54388f41316e3f9cb51bd85e49a5"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-win32.whl", hash = "sha256:4df75b3ebbb8cfdb9bf8b213b168620b88fd92d0c16a8bc9f9234630b282db59"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:f9f0bbfb6787b97c51516f3ccf97737d504db5d239ad44527673b81f598b84ab"}, + {file = "rapidfuzz-3.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:10fdad800441b9c97d471a937ba7d42625f1b530db05e572f1cb7d401d95c893"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7dc87073ba3a40dd65591a2100aa71602107443bf10770579ff9c8a3242edb94"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a425a0a868cf8e9c6e93e1cda4b758cdfd314bb9a4fc916c5742c934e3613480"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a86d5d1d75e61df060c1e56596b6b0a4422a929dff19cc3dbfd5eee762c86b61"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34f213d59219a9c3ca14e94a825f585811a68ac56b4118b4dc388b5b14afc108"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96ad46f5f56f70fab2be9e5f3165a21be58d633b90bf6e67fc52a856695e4bcf"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9178277f72d144a6c7704d7ae7fa15b7b86f0f0796f0e1049c7b4ef748a662ef"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76a35e9e19a7c883c422ffa378e9a04bc98cb3b29648c5831596401298ee51e6"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a6405d34c394c65e4f73a1d300c001f304f08e529d2ed6413b46ee3037956eb"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bd393683129f446a75d8634306aed7e377627098a1286ff3af2a4f1736742820"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b0445fa9880ead81f5a7d0efc0b9c977a947d8052c43519aceeaf56eabaf6843"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:c50bc308fa29767ed8f53a8d33b7633a9e14718ced038ed89d41b886e301da32"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e89605afebbd2d4b045bccfdc12a14b16fe8ccbae05f64b4b4c64a97dad1c891"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-win32.whl", hash = "sha256:2db9187f3acf3cd33424ecdbaad75414c298ecd1513470df7bda885dcb68cc15"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:50e3d0c72ea15391ba9531ead7f2068a67c5b18a6a365fef3127583aaadd1725"}, + {file = "rapidfuzz-3.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:9eac95b4278bd53115903d89118a2c908398ee8bdfd977ae844f1bd2b02b917c"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fe5231e8afd069c742ac5b4f96344a0fe4aff52df8e53ef87faebf77f827822c"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:886882367dbc985f5736356105798f2ae6e794e671fc605476cbe2e73838a9bb"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b33e13e537e3afd1627d421a142a12bbbe601543558a391a6fae593356842f6e"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:094c26116d55bf9c53abd840d08422f20da78ec4c4723e5024322321caedca48"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:545fc04f2d592e4350f59deb0818886c1b444ffba3bec535b4fbb97191aaf769"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:916a6abf3632e592b937c3d04c00a6efadd8fd30539cdcd4e6e4d92be7ca5d90"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb6ec40cef63b1922083d33bfef2f91fc0b0bc07b5b09bfee0b0f1717d558292"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c77a7330dd15c7eb5fd3631dc646fc96327f98db8181138766bd14d3e905f0ba"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:949b5e9eeaa4ecb4c7e9c2a4689dddce60929dd1ff9c76a889cdbabe8bbf2171"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b5363932a5aab67010ae1a6205c567d1ef256fb333bc23c27582481606be480c"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:5dd6eec15b13329abe66cc241b484002ecb0e17d694491c944a22410a6a9e5e2"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e7f98525b60b3c14524e0a4e1fedf7654657b6e02eb25f1be897ab097706f3"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-win32.whl", hash = "sha256:d29d1b9857c65f8cb3a29270732e1591b9bacf89de9d13fa764f79f07d8f1fd2"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:fa9720e56663cc3649d62b4b5f3145e94b8f5611e8a8e1b46507777249d46aad"}, + {file = "rapidfuzz-3.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:eda4c661e68dddd56c8fbfe1ca35e40dd2afd973f7ebb1605f4d151edc63dff8"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cffbc50e0767396ed483900900dd58ce4351bc0d40e64bced8694bd41864cc71"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c038b9939da3035afb6cb2f465f18163e8f070aba0482923ecff9443def67178"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca366c2e2a54e2f663f4529b189fdeb6e14d419b1c78b754ec1744f3c01070d4"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c4c82b1689b23b1b5e6a603164ed2be41b6f6de292a698b98ba2381e889eb9d"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98f6ebe28831a482981ecfeedc8237047878424ad0c1add2c7f366ba44a20452"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4bd1a7676ee2a4c8e2f7f2550bece994f9f89e58afb96088964145a83af7408b"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9139baa3f85b65adc700eafa03ed04995ca8533dd56c924f0e458ffec044ab"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:26de93e6495078b6af4c4d93a42ca067b16cc0e95699526c82ab7d1025b4d3bf"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f3a0bda83c18195c361b5500377d0767749f128564ca95b42c8849fd475bb327"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:63e4c175cbce8c3adc22dca5e6154588ae673f6c55374d156f3dac732c88d7de"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4dd3d8443970eaa02ab5ae45ce584b061f2799cd9f7e875190e2617440c1f9d4"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e5ddb2388610799fc46abe389600625058f2a73867e63e20107c5ad5ffa57c47"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-win32.whl", hash = "sha256:2e9be5d05cd960914024412b5406fb75a82f8562f45912ff86255acbfdbfb78e"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:47aca565a39c9a6067927871973ca827023e8b65ba6c5747f4c228c8d7ddc04f"}, + {file = "rapidfuzz-3.10.0-cp39-cp39-win_arm64.whl", hash = "sha256:b0732343cdc4273b5921268026dd7266f75466eb21873cb7635a200d9d9c3fac"}, + {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f744b5eb1469bf92dd143d36570d2bdbbdc88fe5cb0b5405e53dd34f479cbd8a"}, + {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b67cc21a14327a0eb0f47bc3d7e59ec08031c7c55220ece672f9476e7a8068d3"}, + {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fe5783676f0afba4a522c80b15e99dbf4e393c149ab610308a8ef1f04c6bcc8"}, + {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4688862f957c8629d557d084f20b2d803f8738b6c4066802a0b1cc472e088d9"}, + {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20bd153aacc244e4c907d772c703fea82754c4db14f8aa64d75ff81b7b8ab92d"}, + {file = "rapidfuzz-3.10.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:50484d563f8bfa723c74c944b0bb15b9e054db9c889348c8c307abcbee75ab92"}, + {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5897242d455461f2c5b82d7397b29341fd11e85bf3608a522177071044784ee8"}, + {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:116c71a81e046ba56551d8ab68067ca7034d94b617545316d460a452c5c3c289"}, + {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0a547e4350d1fa32624d3eab51eff8cf329f4cae110b4ea0402486b1da8be40"}, + {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:399b9b79ccfcf50ca3bad7692bc098bb8eade88d7d5e15773b7f866c91156d0c"}, + {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7947a425d1be3e744707ee58c6cb318b93a56e08f080722dcc0347e0b7a1bb9a"}, + {file = "rapidfuzz-3.10.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:94c48b4a2a4b1d22246f48e2b11cae01ec7d23f0c9123f8bb822839ad79d0a88"}, + {file = "rapidfuzz-3.10.0.tar.gz", hash = "sha256:6b62af27e65bb39276a66533655a2fa3c60a487b03935721c45b7809527979be"}, ] [package.extras] -full = ["numpy"] +all = ["numpy"] [[package]] name = "rdflib" From eb640ac270913958c62ebfbe996dea9339e6a53c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 15:31:05 +0000 Subject: [PATCH 26/28] fix(deps): update dependency alembic to v1.13.3 (#4258) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index bc31fd840dc..2264b89a9c7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,13 +13,13 @@ files = [ [[package]] name = "alembic" -version = "1.13.2" +version = "1.13.3" description = "A database migration tool for SQLAlchemy." optional = false python-versions = ">=3.8" files = [ - {file = "alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953"}, - {file = "alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef"}, + {file = "alembic-1.13.3-py3-none-any.whl", hash = "sha256:908e905976d15235fae59c9ac42c4c5b75cfcefe3d27c0fbf7ae15a37715d80e"}, + {file = "alembic-1.13.3.tar.gz", hash = "sha256:203503117415561e203aa14541740643a611f641517f0209fcae63e9fa09f1a2"}, ] [package.dependencies] From f393c05d6dade9fb77f6acffdc6e95ddfc239cdd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 10:50:48 -0500 Subject: [PATCH 27/28] fix(deps): update dependency openai to v1.47.1 (#4259) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2264b89a9c7..cc712471d2c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1580,13 +1580,13 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openai" -version = "1.47.0" +version = "1.47.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.47.0-py3-none-any.whl", hash = "sha256:9ccc8737dfa791f7bd903db4758c176b8544a8cd89d3a3d2add3cea02a34c3a0"}, - {file = "openai-1.47.0.tar.gz", hash = "sha256:6e14d6f77c8cf546646afcd87a2ef752505b3710d2564a2e433e17307dfa86a0"}, + {file = "openai-1.47.1-py3-none-any.whl", hash = "sha256:34277583bf268bb2494bc03f48ac123788c5e2a914db1d5a23d5edc29d35c825"}, + {file = "openai-1.47.1.tar.gz", hash = "sha256:62c8f5f478f82ffafc93b33040f8bb16a45948306198bd0cba2da2ecd9cf7323"}, ] [package.dependencies] From 7922e4d2c1a5686968489055d9b47c6069d666a4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 21:42:44 +0200 Subject: [PATCH 28/28] fix(deps): update dependency tzdata to v2024.2 (#4261) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index cc712471d2c..d642f79e2dc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3110,13 +3110,13 @@ files = [ [[package]] name = "tzdata" -version = "2024.1" +version = "2024.2" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" files = [ - {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, - {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, + {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, + {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, ] [[package]]