Merge remote-tracking branch 'upstream/mealie-next' into feat/remove-food-flag

This commit is contained in:
Michael Genson 2025-07-29 13:48:06 +00:00
commit 53748ea65f
27 changed files with 840 additions and 770 deletions

View file

@ -12,7 +12,7 @@ repos:
exclude: ^tests/data/ exclude: ^tests/data/
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version. # Ruff version.
rev: v0.12.4 rev: v0.12.5
hooks: hooks:
- id: ruff - id: ruff
- id: ruff-format - id: ruff-format

View file

@ -3,7 +3,10 @@
<v-expand-transition> <v-expand-transition>
<v-card <v-card
:ripple="false" :ripple="false"
:class="isFlat ? 'mx-auto flat' : 'mx-auto'" :class="[
isFlat ? 'mx-auto flat' : 'mx-auto',
{ 'disable-highlight': disableHighlight },
]"
:style="{ cursor }" :style="{ cursor }"
hover hover
height="100%" height="100%"
@ -181,6 +184,10 @@ export default defineNuxtComponent({
type: [Number], type: [Number],
default: 150, default: 150,
}, },
disableHighlight: {
type: Boolean,
default: false,
},
}, },
emits: ["selected", "delete"], emits: ["selected", "delete"],
setup(props) { setup(props) {
@ -241,4 +248,8 @@ export default defineNuxtComponent({
box-shadow: none !important; box-shadow: none !important;
background-color: transparent !important; background-color: transparent !important;
} }
.disable-highlight :deep(.v-card__overlay) {
opacity: 0 !important;
}
</style> </style>

View file

@ -81,7 +81,7 @@
</v-card> </v-card>
<WakelockSwitch /> <WakelockSwitch />
<RecipePageComments <RecipePageComments
v-if="!recipe.settings.disableComments && !isEditForm && !isCookMode" v-if="!recipe.settings?.disableComments && !isEditForm && !isCookMode"
v-model="recipe" v-model="recipe"
class="px-1 my-4 d-print-none" class="px-1 my-4 d-print-none"
/> />
@ -277,7 +277,7 @@ async function deleteRecipe() {
* View Preferences * View Preferences
*/ */
const landscape = computed(() => { const landscape = computed(() => {
const preferLandscape = recipe.value.settings.landscapeView; const preferLandscape = recipe.value.settings?.landscapeView;
const smallScreen = !$vuetify.display.smAndUp.value; const smallScreen = !$vuetify.display.smAndUp.value;
if (preferLandscape) { if (preferLandscape) {

View file

@ -29,33 +29,31 @@
{{ activeText }} {{ activeText }}
</p> </p>
<v-divider class="mb-4" /> <v-divider class="mb-4" />
<v-checkbox <v-checkbox-btn
v-for="ing in unusedIngredients" v-for="ing in unusedIngredients"
:key="ing.referenceId" :key="ing.referenceId"
v-model="activeRefs" v-model="activeRefs"
:value="ing.referenceId" :value="ing.referenceId"
class="mb-n2 mt-n2"
> >
<template #label> <template #label>
<RecipeIngredientHtml :markup="parseIngredientText(ing)" /> <RecipeIngredientHtml :markup="parseIngredientText(ing)" />
</template> </template>
</v-checkbox> </v-checkbox-btn>
<template v-if="usedIngredients.length > 0"> <template v-if="usedIngredients.length > 0">
<h4 class="py-3 ml-1"> <h4 class="py-3 ml-1">
{{ $t("recipe.linked-to-other-step") }} {{ $t("recipe.linked-to-other-step") }}
</h4> </h4>
<v-checkbox <v-checkbox-btn
v-for="ing in usedIngredients" v-for="ing in usedIngredients"
:key="ing.referenceId" :key="ing.referenceId"
v-model="activeRefs" v-model="activeRefs"
:value="ing.referenceId" :value="ing.referenceId"
class="mb-n2 mt-n2"
> >
<template #label> <template #label>
<RecipeIngredientHtml :markup="parseIngredientText(ing)" /> <RecipeIngredientHtml :markup="parseIngredientText(ing)" />
</template> </template>
</v-checkbox> </v-checkbox-btn>
</template> </template>
</v-card-text> </v-card-text>

View file

@ -66,12 +66,12 @@
<v-card-text class="mt-n5"> <v-card-text class="mt-n5">
<div class="mt-4 d-flex align-center"> <div class="mt-4 d-flex align-center">
<v-text-field <v-text-field
:model-value="yieldQuantityEditorValue" :model-value="yieldQuantity"
type="number" type="number"
:min="0" :min="0"
variant="underlined" variant="underlined"
hide-spin-buttons hide-spin-buttons
@update:model-value="recalculateScale(yieldQuantityEditorValue)" @update:model-value="recalculateScale(parseFloat($event) || 0)"
/> />
<v-tooltip <v-tooltip
end end
@ -81,6 +81,7 @@
<v-btn <v-btn
v-bind="props" v-bind="props"
icon icon
flat
class="mx-1" class="mx-1"
size="small" size="small"
@click="scale = 1" @click="scale = 1"
@ -178,21 +179,8 @@ export default defineNuxtComponent({
: ""; : "";
}); });
// only update yield quantity when the menu opens, so we don't override the user's input
const yieldQuantityEditorValue = ref(recipeYieldAmount.value.scaledAmount);
watch(
() => menu.value,
() => {
if (!menu.value) {
return;
}
yieldQuantityEditorValue.value = recipeYieldAmount.value.scaledAmount;
},
);
const disableDecrement = computed(() => { const disableDecrement = computed(() => {
return recipeYieldAmount.value.scaledAmount <= 1; return yieldQuantity.value <= 1;
}); });
return { return {
@ -202,7 +190,6 @@ export default defineNuxtComponent({
recalculateScale, recalculateScale,
yieldDisplay, yieldDisplay,
yieldQuantity, yieldQuantity,
yieldQuantityEditorValue,
disableDecrement, disableDecrement,
}; };
}, },

View file

@ -242,28 +242,28 @@ export default defineNuxtComponent({
alert.success(i18n.t("events.event-deleted") as string); alert.success(i18n.t("events.event-deleted") as string);
}; };
async function getRecipe(recipeId: string): Promise<Recipe | null> { async function getRecipes(recipeIds: string[]): Promise<Recipe[]> {
const { data } = await api.recipes.getOne(recipeId); const qf = "id IN [" + recipeIds.map(id => `"${id}"`).join(", ") + "]";
return data; const { data } = await api.recipes.getAll(1, -1, { queryFilter: qf });
return data?.items || [];
}; };
async function updateRecipes(events: RecipeTimelineEventOut[]) { async function updateRecipes(events: RecipeTimelineEventOut[]) {
const recipePromises: Promise<Recipe | null>[] = []; const recipeIds: string[] = [];
const seenRecipeIds: string[] = [];
events.forEach((event) => { events.forEach((event) => {
if (seenRecipeIds.includes(event.recipeId) || recipes.has(event.recipeId)) { if (recipeIds.includes(event.recipeId) || recipes.has(event.recipeId)) {
return; return;
} }
seenRecipeIds.push(event.recipeId); recipeIds.push(event.recipeId);
recipePromises.push(getRecipe(event.recipeId));
}); });
const results = await Promise.all(recipePromises); const results = await getRecipes(recipeIds);
results.forEach((result) => { results.forEach((result) => {
if (result && result.id) { if (!result?.id) {
recipes.set(result.id, result); return;
} }
recipes.set(result.id, result);
}); });
} }

View file

@ -53,6 +53,7 @@
<v-row :class="useMobileFormat ? 'py-3 mx-0' : 'py-3 mx-0'" style="max-width: 100%"> <v-row :class="useMobileFormat ? 'py-3 mx-0' : 'py-3 mx-0'" style="max-width: 100%">
<v-col align-self="center" class="pa-0"> <v-col align-self="center" class="pa-0">
<RecipeCardMobile <RecipeCardMobile
disable-highlight
:vertical="useMobileFormat" :vertical="useMobileFormat"
:name="recipe.name" :name="recipe.name"
:slug="recipe.slug" :slug="recipe.slug"

View file

@ -8,21 +8,23 @@
class="flex-nowrap align-center" class="flex-nowrap align-center"
> >
<v-col :cols="itemLabelCols"> <v-col :cols="itemLabelCols">
<v-checkbox <div class="d-flex align-center flex-nowrap">
v-model="listItem.checked" <v-checkbox
class="mt-0" v-model="listItem.checked"
color="null" hide-details
hide-details density="compact"
density="compact" class="mt-0"
:label="listItem.note!" color="null"
@change="$emit('checked', listItem)" @change="$emit('checked', listItem)"
> />
<template #label> <div
<div :class="listItem.checked ? 'strike-through' : ''"> class="ml-2 text-truncate"
<RecipeIngredientListItem :ingredient="listItem" /> :class="listItem.checked ? 'strike-through' : ''"
</div> style="min-width: 0;"
</template> >
</v-checkbox> <RecipeIngredientListItem :ingredient="listItem" />
</div>
</div>
</v-col> </v-col>
<v-spacer /> <v-spacer />
<v-col <v-col

View file

@ -22,10 +22,9 @@
<v-card> <v-card>
<v-card-text> <v-card-text>
<v-checkbox <v-checkbox
v-for="itemValue in headers" v-for="itemValue in localHeaders"
:key="itemValue.text + itemValue.show" :key="itemValue.text + itemValue.show"
v-model="filteredHeaders" v-model="itemValue.show"
:value="itemValue.value"
density="compact" density="compact"
flat flat
inset inset
@ -172,12 +171,20 @@ export default defineNuxtComponent({
// =========================================================== // ===========================================================
// Reactive Headers // Reactive Headers
// Create a local reactive copy of headers that we can modify
const localHeaders = ref([...props.headers]);
// Watch for changes in props.headers and update local copy
watch(() => props.headers, (newHeaders) => {
localHeaders.value = [...newHeaders];
}, { deep: true });
const filteredHeaders = computed<string[]>(() => { const filteredHeaders = computed<string[]>(() => {
return props.headers.filter(header => header.show).map(header => header.value); return localHeaders.value.filter(header => header.show).map(header => header.value);
}); });
const headersWithoutActions = computed(() => const headersWithoutActions = computed(() =>
props.headers localHeaders.value
.filter(header => filteredHeaders.value.includes(header.value)) .filter(header => filteredHeaders.value.includes(header.value))
.map(header => ({ .map(header => ({
...header, ...header,
@ -214,6 +221,7 @@ export default defineNuxtComponent({
return { return {
sortBy, sortBy,
selected, selected,
localHeaders,
filteredHeaders, filteredHeaders,
headersWithoutActions, headersWithoutActions,
activeHeaders, activeHeaders,

View file

@ -26,10 +26,10 @@ export default defineComponent({
}, },
}, },
emits: ["update:modelValue"], emits: ["update:modelValue"],
setup(_, { emit }) { setup(props, { emit }) {
function parseEvent(event: any): object { function parseEvent(event: any): object {
if (!event) { if (!event) {
return {}; return props.modelValue || {};
} }
try { try {
if (event.json) { if (event.json) {
@ -43,11 +43,14 @@ export default defineComponent({
} }
} }
catch { catch {
return {}; return props.modelValue || {};
} }
} }
function onChange(event: any) { function onChange(event: any) {
emit("update:modelValue", parseEvent(event)); const parsed = parseEvent(event);
if (parsed !== props.modelValue) {
emit("update:modelValue", parsed);
}
} }
return { return {
onChange, onChange,

View file

@ -38,7 +38,7 @@ export const useGroupWebhooks = function () {
loading.value = true; loading.value = true;
const payload = { const payload = {
enabled: false, enabled: true,
name: "New Webhook", name: "New Webhook",
url: "", url: "",
scheduledTime: "00:00", scheduledTime: "00:00",

View file

@ -3,13 +3,13 @@ export const LOCALES = [
{ {
name: "繁體中文 (Chinese traditional)", name: "繁體中文 (Chinese traditional)",
value: "zh-TW", value: "zh-TW",
progress: 8, progress: 9,
dir: "ltr", dir: "ltr",
}, },
{ {
name: "简体中文 (Chinese simplified)", name: "简体中文 (Chinese simplified)",
value: "zh-CN", value: "zh-CN",
progress: 33, progress: 35,
dir: "ltr", dir: "ltr",
}, },
{ {
@ -33,7 +33,7 @@ export const LOCALES = [
{ {
name: "Svenska (Swedish)", name: "Svenska (Swedish)",
value: "sv-SE", value: "sv-SE",
progress: 47, progress: 50,
dir: "ltr", dir: "ltr",
}, },
{ {
@ -87,13 +87,13 @@ export const LOCALES = [
{ {
name: "Norsk (Norwegian)", name: "Norsk (Norwegian)",
value: "no-NO", value: "no-NO",
progress: 38, progress: 39,
dir: "ltr", dir: "ltr",
}, },
{ {
name: "Nederlands (Dutch)", name: "Nederlands (Dutch)",
value: "nl-NL", value: "nl-NL",
progress: 44, progress: 45,
dir: "ltr", dir: "ltr",
}, },
{ {
@ -147,7 +147,7 @@ export const LOCALES = [
{ {
name: "עברית (Hebrew)", name: "עברית (Hebrew)",
value: "he-IL", value: "he-IL",
progress: 45, progress: 67,
dir: "rtl", dir: "rtl",
}, },
{ {
@ -213,7 +213,7 @@ export const LOCALES = [
{ {
name: "Deutsch (German)", name: "Deutsch (German)",
value: "de-DE", value: "de-DE",
progress: 63, progress: 64,
dir: "ltr", dir: "ltr",
}, },
{ {
@ -225,7 +225,7 @@ export const LOCALES = [
{ {
name: "Čeština (Czech)", name: "Čeština (Czech)",
value: "cs-CZ", value: "cs-CZ",
progress: 40, progress: 39,
dir: "ltr", dir: "ltr",
}, },
{ {

View file

@ -579,10 +579,10 @@
"made-this": "Jag lagade den här", "made-this": "Jag lagade den här",
"how-did-it-turn-out": "Hur blev rätten?", "how-did-it-turn-out": "Hur blev rätten?",
"user-made-this": "{user} lagade detta", "user-made-this": "{user} lagade detta",
"added-to-timeline": "Added to timeline", "added-to-timeline": "Lagt till i tidslinjen",
"failed-to-add-to-timeline": "Failed to add to timeline", "failed-to-add-to-timeline": "Kunde inte lägga till i tidslinjen",
"failed-to-update-recipe": "Failed to update recipe", "failed-to-update-recipe": "Kunde inte uppdatera receptet",
"added-to-timeline-but-failed-to-add-image": "Added to timeline, but failed to add image", "added-to-timeline-but-failed-to-add-image": "Lagt till i tidslinjen men kunde inte lägga till bild",
"api-extras-description": "Recept API-tillägg är en viktig funktion i Mealie's API. Med hjälp av dem kan du skapa anpassade JSON-nyckel/värdepar i ett recept, som du kan referera till från tredjepartsapplikationer. Du kan använda dessa nycklar för att tillhandahålla information, till exempel för att trigga automatiseringar eller anpassade meddelanden som ska vidarebefordras till önskad enhet.", "api-extras-description": "Recept API-tillägg är en viktig funktion i Mealie's API. Med hjälp av dem kan du skapa anpassade JSON-nyckel/värdepar i ett recept, som du kan referera till från tredjepartsapplikationer. Du kan använda dessa nycklar för att tillhandahålla information, till exempel för att trigga automatiseringar eller anpassade meddelanden som ska vidarebefordras till önskad enhet.",
"message-key": "Meddelandenyckel", "message-key": "Meddelandenyckel",
"parse": "Läs in", "parse": "Läs in",

View file

@ -16,7 +16,10 @@
{{ $t("recipe.group-global-timeline", { groupName }) }} {{ $t("recipe.group-global-timeline", { groupName }) }}
</template> </template>
</BasePageTitle> </BasePageTitle>
<v-sheet :class="$vuetify.display.smAndDown ? 'pa-0' : 'px-3 py-0'"> <v-sheet
:class="$vuetify.display.smAndDown ? 'pa-0' : 'px-3 py-0'"
style="background-color: transparent;"
>
<RecipeTimeline <RecipeTimeline
v-if="queryFilter" v-if="queryFilter"
v-model="ready" v-model="ready"

View file

@ -65,6 +65,7 @@
:title="$t('general.confirm')" :title="$t('general.confirm')"
:icon="$globals.icons.alertCircle" :icon="$globals.icons.alertCircle"
color="error" color="error"
can-confirm
@confirm="deleteSelected" @confirm="deleteSelected"
> >
<v-card-text> <v-card-text>

View file

@ -73,6 +73,7 @@
:title="$t('general.confirm')" :title="$t('general.confirm')"
:icon="$globals.icons.alertCircle" :icon="$globals.icons.alertCircle"
color="error" color="error"
can-confirm
@confirm="deleteSelected" @confirm="deleteSelected"
> >
<v-card-text> <v-card-text>

View file

@ -4135,8 +4135,8 @@
"country style rib": { "country style rib": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "country style rib", "name": "Rippe nach Landhausart",
"plural_name": "country style ribs" "plural_name": "Rippchen nach Landhausart"
}, },
"black forest ham": { "black forest ham": {
"aliases": [], "aliases": [],
@ -4189,8 +4189,8 @@
"hard salami": { "hard salami": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "hard salami", "name": "Hartsalami",
"plural_name": "hard salamis" "plural_name": "Hartsalamis"
}, },
"back bacon": { "back bacon": {
"aliases": [], "aliases": [],
@ -4238,19 +4238,19 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "Getrocknetes Rindfleisch", "name": "Getrocknetes Rindfleisch",
"plural_name": "dried beefs" "plural_name": "Trockenfleisch"
}, },
"gammon joint": { "gammon joint": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "gammon joint", "name": "Geräucherter Schweineschinken",
"plural_name": "gammon joints" "plural_name": "Geräucherte Schweineschinken"
}, },
"boneless beef short rib": { "boneless beef short rib": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "boneless beef short rib", "name": "Ausgelöste Rinderrippe",
"plural_name": "boneless beef short ribs" "plural_name": "Ausgelöste Rinderrippchen"
}, },
"country ham": { "country ham": {
"aliases": [], "aliases": [],

View file

@ -16,8 +16,8 @@
"bell pepper": { "bell pepper": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "bell pepper", "name": "στρογγυλή πιπεριά",
"plural_name": "bell peppers" "plural_name": "στρογγυλές πιπεριές"
}, },
"carrot": { "carrot": {
"aliases": [], "aliases": [],
@ -168,20 +168,20 @@
"arugula": { "arugula": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "arugula", "name": "ρόκα",
"plural_name": "arugulas" "plural_name": "ρόκα"
}, },
"leek": { "leek": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "leek", "name": "πράσο",
"plural_name": "leeks" "plural_name": "πράσα"
}, },
"eggplant": { "eggplant": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "eggplant", "name": "μελιτζάνα",
"plural_name": "eggplants" "plural_name": "μελιτζάνες"
}, },
"lettuce": { "lettuce": {
"aliases": [], "aliases": [],
@ -198,8 +198,8 @@
"romaine": { "romaine": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "romaine", "name": "μαρούλι",
"plural_name": "romaines" "plural_name": "μαρούλια"
}, },
"beetroot": { "beetroot": {
"aliases": [], "aliases": [],
@ -210,48 +210,48 @@
"brussels sprout": { "brussels sprout": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "brussels sprout", "name": "λαχανάκι Βρυξελλών",
"plural_name": "brussels sprouts" "plural_name": "λαχανάκια Βρυξελλών"
}, },
"fennel": { "fennel": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "fennel", "name": "μάραθος",
"plural_name": "fennels" "plural_name": "μάραθος"
}, },
"sun dried tomato": { "sun dried tomato": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sun dried tomato", "name": "αποξηραμένη ντομάτα",
"plural_name": "sun dried tomatoes" "plural_name": "αποξηραμένες ντομάτες"
}, },
"radish": { "radish": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "radish", "name": "ραπανάκι",
"plural_name": "radishes" "plural_name": "ραπανάκια"
}, },
"red cabbage": { "red cabbage": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "red cabbage", "name": "κόκκινο λάχανο",
"plural_name": "red cabbages" "plural_name": "κόκκινα λάχανα"
}, },
"artichoke": { "artichoke": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "artichoke", "name": "αγκινάρα",
"plural_name": "artichokes" "plural_name": "αγκινάρες"
}, },
"new potato": { "new potato": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "new potato", "name": "φρέσια πατάτα",
"plural_name": "new potatoes" "plural_name": "φρέσκες πατάτες"
}, },
"summer squash": { "summer squash": {
"aliases": [ "aliases": [
"courgette", "κολοκυθάκι",
"gem squash" "gem squash"
], ],
"description": "", "description": "",
@ -261,8 +261,8 @@
"mixed green": { "mixed green": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mixed green", "name": "ανάμικτη πρασινάδα",
"plural_name": "mixed greens" "plural_name": "ανάμικτη πρασινάδα"
}, },
"parsnip": { "parsnip": {
"aliases": [], "aliases": [],
@ -273,14 +273,14 @@
"baby carrot": { "baby carrot": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "baby carrot", "name": "καρότο μπέιμπι",
"plural_name": "baby carrots" "plural_name": "καρότα μπέιμπι"
}, },
"mixed vegetable": { "mixed vegetable": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mixed vegetable", "name": "μιξ λαχανικού",
"plural_name": "mixed vegetables" "plural_name": "μιξ λαχανικών"
}, },
"poblano pepper": { "poblano pepper": {
"aliases": [], "aliases": [],
@ -291,8 +291,8 @@
"sweet pepper": { "sweet pepper": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sweet pepper", "name": "γλυκιά πιπεριά",
"plural_name": "sweet peppers" "plural_name": "γλυκές πιπεριές "
}, },
"serrano pepper": { "serrano pepper": {
"aliases": [], "aliases": [],
@ -628,93 +628,93 @@
"foods": { "foods": {
"tomato": { "tomato": {
"aliases": [], "aliases": [],
"description": "Yes they are a fruit", "description": "Σωστά, είναι φρούτο",
"name": "tomato", "name": "ντομάτα",
"plural_name": "tomatoes" "plural_name": "ντομάτες"
}, },
"lemon": { "lemon": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "lemon", "name": "λεμόνι",
"plural_name": "lemons" "plural_name": "λεμόνια"
}, },
"lime": { "lime": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "lime", "name": "λάιμ",
"plural_name": "limes" "plural_name": "λάιμ"
}, },
"apple": { "apple": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "apple", "name": "μήλο",
"plural_name": "μήλα" "plural_name": "μήλα"
}, },
"banana": { "banana": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "banana", "name": "μπανάνα",
"plural_name": "bananas" "plural_name": "μπανάνες"
}, },
"orange": { "orange": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "orange", "name": "πορτοκάλι",
"plural_name": "oranges" "plural_name": "πορτοκάλια"
}, },
"raisin": { "raisin": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "raisin", "name": "σταφίδα",
"plural_name": "raisins" "plural_name": "σταφίδες"
}, },
"pineapple": { "pineapple": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pineapple", "name": "ανανάς",
"plural_name": "pineapples" "plural_name": "ανανάδες"
}, },
"mango": { "mango": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mango", "name": "μάνγκο",
"plural_name": "mangoes" "plural_name": "μάνγκο"
}, },
"peach": { "peach": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "peach", "name": "ροδάκινο",
"plural_name": "peaches" "plural_name": "ροδάκινα"
}, },
"date": { "date": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "date", "name": "χουρμάς",
"plural_name": "dates" "plural_name": "χουρμάδες"
}, },
"coconut": { "coconut": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "coconut", "name": "καρύδα",
"plural_name": "coconuts" "plural_name": "καρύδες"
}, },
"craisin": { "craisin": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "craisin", "name": "αποξηραμένο κράνμπερι",
"plural_name": "craisins" "plural_name": "αποξηραμένα κράνμπερι"
}, },
"pear": { "pear": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pear", "name": "αχλάδι",
"plural_name": "pears" "plural_name": "αχλάδια"
}, },
"grape": { "grape": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "grape", "name": "σταφύλι",
"plural_name": "grapes" "plural_name": "σταφύλια"
}, },
"pomegranate": { "pomegranate": {
"aliases": [], "aliases": [],
@ -725,8 +725,8 @@
"watermelon": { "watermelon": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "watermelon", "name": "καρπούζι",
"plural_name": "watermelons" "plural_name": "καρπούζια"
}, },
"rhubarb": { "rhubarb": {
"aliases": [], "aliases": [],
@ -743,8 +743,8 @@
"kiwi": { "kiwi": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "kiwi", "name": "ακτινίδιο",
"plural_name": "kiwis" "plural_name": "ακτινίδια"
}, },
"grapefruit": { "grapefruit": {
"aliases": [], "aliases": [],
@ -821,8 +821,8 @@
"nectarine": { "nectarine": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "nectarine", "name": "νεκταρίνι",
"plural_name": "nectarines" "plural_name": "νεκταρίνια"
}, },
"dried fig": { "dried fig": {
"aliases": [], "aliases": [],
@ -1251,14 +1251,14 @@
"portobello mushroom": { "portobello mushroom": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "portobello mushroom", "name": "μανιτάρι πορτομπέλο",
"plural_name": "portobello mushrooms" "plural_name": "μανιτάρια πορτομπέλο"
}, },
"wild mushroom": { "wild mushroom": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "wild mushroom", "name": "άγριο μανιτάρι",
"plural_name": "wild mushrooms" "plural_name": "άγρια μανιτάρια "
}, },
"porcini": { "porcini": {
"aliases": [], "aliases": [],
@ -1269,8 +1269,8 @@
"mixed mushroom": { "mixed mushroom": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mixed mushroom", "name": "μιξ μανιτάρι",
"plural_name": "mixed mushrooms" "plural_name": "μιξ μανιταριών"
}, },
"oyster mushroom": { "oyster mushroom": {
"aliases": [], "aliases": [],
@ -2009,14 +2009,14 @@
"cheddars" "cheddars"
], ],
"description": "", "description": "",
"name": "cheddar cheese", "name": "τυρί τσένταρ",
"plural_name": "cheddar cheeses" "plural_name": "τυριά τσένταρ"
}, },
"cream cheese": { "cream cheese": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "cream cheese", "name": "cream cheese",
"plural_name": "cream cheeses" "plural_name": "τυρί κρέμα"
}, },
"sharp cheddar": { "sharp cheddar": {
"aliases": [], "aliases": [],
@ -2027,20 +2027,20 @@
"cheese": { "cheese": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "cheese", "name": "τυρί",
"plural_name": "cheeses" "plural_name": "τυριά"
}, },
"mozzarella": { "mozzarella": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mozzarella", "name": "μοτσαρέλα",
"plural_name": "mozzarellas" "plural_name": "μοτσαρέλες"
}, },
"feta": { "feta": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "feta", "name": "φέτα",
"plural_name": "fetas" "plural_name": "φέτες"
}, },
"ricotta": { "ricotta": {
"aliases": [], "aliases": [],
@ -2063,32 +2063,32 @@
"blue cheese": { "blue cheese": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "blue cheese", "name": "ροκφόρ τυρί ",
"plural_name": "blue cheeses" "plural_name": "ροκφόρ τυριά"
}, },
"goat cheese": { "goat cheese": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "goat cheese", "name": "κατσικίσιο τυρί ",
"plural_name": "goat cheeses" "plural_name": "κατσικίσια τυριά"
}, },
"fresh mozzarella": { "fresh mozzarella": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "fresh mozzarella", "name": "φρέσκια μοτσαρέλα",
"plural_name": "fresh mozzarellas" "plural_name": "φρέσκιες μοτσαρέλες"
}, },
"swiss cheese": { "swiss cheese": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "swiss cheese", "name": "ελβετικό τυρί ",
"plural_name": "swiss cheeses" "plural_name": "ελβετικά τυριά "
}, },
"pecorino": { "pecorino": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pecorino", "name": "πεκορίνο",
"plural_name": "pecorinoes" "plural_name": "πεκορίνο"
}, },
"gruyere": { "gruyere": {
"aliases": [], "aliases": [],
@ -2099,8 +2099,8 @@
"mascarpone": { "mascarpone": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mascarpone", "name": "μασκαρπόνε",
"plural_name": "mascarpones" "plural_name": "μασκαρπόνε "
}, },
"cottage cheese": { "cottage cheese": {
"aliases": [], "aliases": [],
@ -2118,7 +2118,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "provolone", "name": "provolone",
"plural_name": "provolones" "plural_name": "provolone"
}, },
"mexican cheese blend": { "mexican cheese blend": {
"aliases": [], "aliases": [],

View file

@ -14515,8 +14515,8 @@
"rum": { "rum": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "rum", "name": "rhum",
"plural_name": "rums" "plural_name": "rhums"
}, },
"vodka": { "vodka": {
"aliases": [], "aliases": [],
@ -14581,8 +14581,8 @@
"white rum": { "white rum": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "white rum", "name": "rhum blanc",
"plural_name": "white rums" "plural_name": "rhums blancs"
}, },
"coffee liqueur": { "coffee liqueur": {
"aliases": [], "aliases": [],

File diff suppressed because it is too large Load diff

View file

@ -2453,20 +2453,20 @@
"hard goat cheese": { "hard goat cheese": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "hard goat cheese", "name": "harde geiten kaas",
"plural_name": "hard goat cheeses" "plural_name": "harde geiten kazen"
}, },
"kashkaval": { "kashkaval": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "kashkaval", "name": "kashkaval",
"plural_name": "kashkavals" "plural_name": "schapen kaas"
}, },
"sheep cheese": { "sheep cheese": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sheep cheese", "name": "schapen kaas",
"plural_name": "sheep cheeses" "plural_name": "schapen kazen"
}, },
"amul cheese": { "amul cheese": {
"aliases": [], "aliases": [],

View file

@ -8540,8 +8540,8 @@
"rice": { "rice": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "rice", "name": "ris",
"plural_name": "rices" "plural_name": "ris"
}, },
"Rice Krispie Cereal": { "Rice Krispie Cereal": {
"aliases": [ "aliases": [
@ -8555,13 +8555,13 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "quinoa", "name": "quinoa",
"plural_name": "quinoas" "plural_name": "quinoa"
}, },
"basmati rice": { "basmati rice": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "basmati rice", "name": "basmatiris",
"plural_name": "basmati rices" "plural_name": "basmatiris"
}, },
"brown rice": { "brown rice": {
"aliases": [], "aliases": [],
@ -8578,26 +8578,26 @@
"breakfast cereal": { "breakfast cereal": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "breakfast cereal", "name": "frukostflinga",
"plural_name": "breakfast cereals" "plural_name": "frukostflingor"
}, },
"risotto rice": { "risotto rice": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "risotto rice", "name": "risottoris",
"plural_name": "risotto rices" "plural_name": "risottoris"
}, },
"couscou": { "couscou": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "couscou", "name": "couscous",
"plural_name": "couscous" "plural_name": "couscous"
}, },
"rice cereal": { "rice cereal": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "rice cereal", "name": "risflinga",
"plural_name": "rice cereals" "plural_name": "risflingor"
}, },
"wild rice": { "wild rice": {
"aliases": [], "aliases": [],
@ -8614,14 +8614,14 @@
"jasmine rice": { "jasmine rice": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "jasmine rice", "name": "jasminris",
"plural_name": "jasmine rices" "plural_name": "jasminris"
}, },
"polenta": { "polenta": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "polenta", "name": "polenta",
"plural_name": "polentas" "plural_name": "polenta"
}, },
"granola cereal": { "granola cereal": {
"aliases": [], "aliases": [],
@ -8633,7 +8633,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "bulgur", "name": "bulgur",
"plural_name": "bulgurs" "plural_name": "bulgur"
}, },
"pearl barley": { "pearl barley": {
"aliases": [], "aliases": [],
@ -8686,8 +8686,8 @@
"sushi rice": { "sushi rice": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sushi rice", "name": "sushiris",
"plural_name": "sushi rices" "plural_name": "sushiris"
}, },
"glutinous rice": { "glutinous rice": {
"aliases": [], "aliases": [],
@ -8764,8 +8764,8 @@
"muesli": { "muesli": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "muesli", "name": "müsli",
"plural_name": "mueslis" "plural_name": "müsli"
}, },
"amaranth": { "amaranth": {
"aliases": [], "aliases": [],
@ -8812,8 +8812,8 @@
"paella rice": { "paella rice": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "paella rice", "name": "paellaris",
"plural_name": "paella rices" "plural_name": "paellaris"
}, },
"sorghum": { "sorghum": {
"aliases": [], "aliases": [],
@ -8986,8 +8986,8 @@
"gluten-free breakfast cereal": { "gluten-free breakfast cereal": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "gluten-free breakfast cereal", "name": "glutenfri frukostflinga",
"plural_name": "gluten-free breakfast cereals" "plural_name": "glutenfria frukostflingor"
}, },
"puffed amaranth": { "puffed amaranth": {
"aliases": [], "aliases": [],
@ -9092,8 +9092,8 @@
"pea": { "pea": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pea", "name": "ärta",
"plural_name": "peas" "plural_name": "ärtor"
}, },
"green bean": { "green bean": {
"aliases": [], "aliases": [],
@ -9104,8 +9104,8 @@
"chickpea": { "chickpea": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "chickpea", "name": "kikärta",
"plural_name": "chickpeas" "plural_name": "kikärtor"
}, },
"black bean": { "black bean": {
"aliases": [], "aliases": [],
@ -9116,20 +9116,20 @@
"kidney bean": { "kidney bean": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "kidney bean", "name": "kidneyböna",
"plural_name": "kidney beans" "plural_name": "kidneybönor"
}, },
"white bean": { "white bean": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "white bean", "name": "vit böna",
"plural_name": "white beans" "plural_name": "vita bönor"
}, },
"lentil": { "lentil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "lentil", "name": "lins",
"plural_name": "lentils" "plural_name": "linser"
}, },
"pinto bean": { "pinto bean": {
"aliases": [], "aliases": [],
@ -9152,8 +9152,8 @@
"red lentil": { "red lentil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "red lentil", "name": "röd lins",
"plural_name": "red lentils" "plural_name": "röda linser"
}, },
"cannellini bean": { "cannellini bean": {
"aliases": [], "aliases": [],
@ -9170,14 +9170,14 @@
"edamame": { "edamame": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "edamame", "name": "edamameböna",
"plural_name": "edamames" "plural_name": "edamamebönor"
}, },
"green lentil": { "green lentil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "green lentil", "name": "grön lins",
"plural_name": "green lentils" "plural_name": "gröna linser"
}, },
"urad dal": { "urad dal": {
"aliases": [], "aliases": [],
@ -9188,8 +9188,8 @@
"lima bean": { "lima bean": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "lima bean", "name": "limaböna",
"plural_name": "lima beans" "plural_name": "limabönor"
}, },
"chana dal": { "chana dal": {
"aliases": [], "aliases": [],
@ -9296,8 +9296,8 @@
"yellow lentil": { "yellow lentil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "yellow lentil", "name": "gul lins",
"plural_name": "yellow lentils" "plural_name": "gula linser"
}, },
"mixed bean": { "mixed bean": {
"aliases": [], "aliases": [],
@ -9428,8 +9428,8 @@
"golden wax bean": { "golden wax bean": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "golden wax bean", "name": "gul vaxböna",
"plural_name": "golden wax beans" "plural_name": "gula vaxbönor"
}, },
"moth bean": { "moth bean": {
"aliases": [], "aliases": [],
@ -9782,8 +9782,8 @@
"instant noodle": { "instant noodle": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "instant noodle", "name": "snabbnudel",
"plural_name": "instant noodles" "plural_name": "snabbnudlar"
}, },
"somen noodle": { "somen noodle": {
"aliases": [], "aliases": [],
@ -10042,8 +10042,8 @@
"panko": { "panko": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "panko", "name": "pankosmula",
"plural_name": "pankoes" "plural_name": "pankosmulor"
}, },
"flour tortilla": { "flour tortilla": {
"aliases": [], "aliases": [],
@ -10114,14 +10114,14 @@
"crouton": { "crouton": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "crouton", "name": "krutong",
"plural_name": "croutons" "plural_name": "krutonger"
}, },
"whole-wheat tortilla": { "whole-wheat tortilla": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "whole-wheat tortilla", "name": "fullkornstortilla",
"plural_name": "whole-wheat tortillas" "plural_name": "fullkornstortilla"
}, },
"english muffin": { "english muffin": {
"aliases": [], "aliases": [],
@ -10144,8 +10144,8 @@
"rye bread": { "rye bread": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "rye bread", "name": "rågbröd",
"plural_name": "rye breads" "plural_name": "rågbröd"
}, },
"flatbread": { "flatbread": {
"aliases": [], "aliases": [],
@ -10156,14 +10156,14 @@
"dry-roasted peanut": { "dry-roasted peanut": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "dry-roasted peanut", "name": "torrostad jordnöt",
"plural_name": "dry-roasted peanuts" "plural_name": "torrostade jordnötter"
}, },
"potato chip": { "potato chip": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "potato chip", "name": "potatischips",
"plural_name": "potato chips" "plural_name": "potatischips"
}, },
"naan": { "naan": {
"aliases": [], "aliases": [],
@ -10282,8 +10282,8 @@
"gluten-free bread crumb": { "gluten-free bread crumb": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "gluten-free bread crumb", "name": "glutenfri brödsmula",
"plural_name": "gluten-free bread crumbs" "plural_name": "glutenfria brödsmulor"
}, },
"tostada shell": { "tostada shell": {
"aliases": [], "aliases": [],
@ -10336,8 +10336,8 @@
"rice cake": { "rice cake": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "rice cake", "name": "riskaka",
"plural_name": "rice cakes" "plural_name": "riskakor"
}, },
"panettone": { "panettone": {
"aliases": [], "aliases": [],
@ -10348,8 +10348,8 @@
"sweet potato fry": { "sweet potato fry": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sweet potato fry", "name": "sötpotatispommes",
"plural_name": "sweet potato fries" "plural_name": "sötpotatispommes"
}, },
"sev": { "sev": {
"aliases": [], "aliases": [],
@ -10658,8 +10658,8 @@
"coconut oil": { "coconut oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "coconut oil", "name": "kokosnötsolja",
"plural_name": "coconut oils" "plural_name": "kokosnötsoljor"
}, },
"cooking spray": { "cooking spray": {
"aliases": [], "aliases": [],
@ -10670,20 +10670,20 @@
"sesame oil": { "sesame oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sesame oil", "name": "sesamolja",
"plural_name": "sesame oils" "plural_name": "sesamoljor"
}, },
"frying oil": { "frying oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "frying oil", "name": "frityrolja",
"plural_name": "frying oils" "plural_name": "frityroljor"
}, },
"sunflower oil": { "sunflower oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sunflower oil", "name": "solrosolja",
"plural_name": "sunflower oils" "plural_name": "solrosoljor"
}, },
"avocado oil": { "avocado oil": {
"aliases": [], "aliases": [],
@ -10700,8 +10700,8 @@
"peanut oil": { "peanut oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "peanut oil", "name": "jordnötsolja",
"plural_name": "peanut oils" "plural_name": "jordnötsoljor"
}, },
"grapeseed oil": { "grapeseed oil": {
"aliases": [ "aliases": [
@ -10756,8 +10756,8 @@
"truffle oil": { "truffle oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "truffle oil", "name": "tryffelolja",
"plural_name": "truffle oils" "plural_name": "tryffeloljor"
}, },
"bacon grease": { "bacon grease": {
"aliases": [], "aliases": [],
@ -10786,8 +10786,8 @@
"duck fat": { "duck fat": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "duck fat", "name": "ankfett",
"plural_name": "duck fats" "plural_name": "ankfett"
}, },
"rice bran oil": { "rice bran oil": {
"aliases": [], "aliases": [],
@ -10822,8 +10822,8 @@
"white truffle oil": { "white truffle oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "white truffle oil", "name": "vit tryffelolja",
"plural_name": "white truffle oils" "plural_name": "vit tryffeloljor"
}, },
"pumpkin seed oil": { "pumpkin seed oil": {
"aliases": [], "aliases": [],
@ -10870,14 +10870,14 @@
"palm oil": { "palm oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "palm oil", "name": "palmolja",
"plural_name": "palm oils" "plural_name": "palmoljor"
}, },
"basil oil": { "basil oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "basil oil", "name": "basilikaolja",
"plural_name": "basil oils" "plural_name": "basilikaoljor"
}, },
"pork fat": { "pork fat": {
"aliases": [], "aliases": [],
@ -11078,44 +11078,44 @@
"mayonnaise": { "mayonnaise": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mayonnaise", "name": "majonnäs",
"plural_name": "mayonnaises" "plural_name": "majonnäser"
}, },
"apple cider vinegar": { "apple cider vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "apple cider vinegar", "name": "äppelcidervinäger",
"plural_name": "apple cider vinegars" "plural_name": "äppelcidervinäger"
}, },
"balsamic vinegar": { "balsamic vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "balsamic vinegar", "name": "balsamvinäger",
"plural_name": "balsamic vinegars" "plural_name": "balsamvinäger"
}, },
"vinegar": { "vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "vinegar", "name": "vinäger",
"plural_name": "vinegars" "plural_name": "vinäger"
}, },
"red wine vinegar": { "red wine vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "red wine vinegar", "name": "rödvinsvinäger",
"plural_name": "red wine vinegars" "plural_name": "rödvinsvinäger"
}, },
"rice wine vinegar": { "rice wine vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "rice wine vinegar", "name": "risvinsvinäger",
"plural_name": "rice wine vinegars" "plural_name": "risvinsvinäger"
}, },
"white wine vinegar": { "white wine vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "white wine vinegar", "name": "vitvinsvinäger",
"plural_name": "white wine vinegars" "plural_name": "vitvinsvinäger"
}, },
"ranch dressing": { "ranch dressing": {
"aliases": [], "aliases": [],
@ -11150,8 +11150,8 @@
"white balsamic vinegar": { "white balsamic vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "white balsamic vinegar", "name": "vit balsamvinäger",
"plural_name": "white balsamic vinegars" "plural_name": "vit balsamvinäger"
}, },
"champagne vinegar": { "champagne vinegar": {
"aliases": [], "aliases": [],
@ -11210,8 +11210,8 @@
"raspberry vinegar": { "raspberry vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "raspberry vinegar", "name": "hallonvinäger",
"plural_name": "raspberry vinegars" "plural_name": "hallonvinäger"
}, },
"japanese mayonnaise": { "japanese mayonnaise": {
"aliases": [], "aliases": [],
@ -11222,8 +11222,8 @@
"tarragon vinegar": { "tarragon vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "tarragon vinegar", "name": "dragonvinäger",
"plural_name": "tarragon vinegars" "plural_name": "dragonvinäger"
}, },
"greek vinaigrette": { "greek vinaigrette": {
"aliases": [], "aliases": [],
@ -11246,8 +11246,8 @@
"aioli sauce": { "aioli sauce": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "aioli sauce", "name": "aioli",
"plural_name": "aioli sauces" "plural_name": "aioli"
}, },
"french dressing": { "french dressing": {
"aliases": [], "aliases": [],
@ -11420,8 +11420,8 @@
"honey vinegar": { "honey vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "honey vinegar", "name": "honungsvinäger",
"plural_name": "honey vinegars" "plural_name": "honungsvinäger"
}, },
"tandoori mayonnaise": { "tandoori mayonnaise": {
"aliases": [], "aliases": [],
@ -11432,8 +11432,8 @@
"chili vinegar": { "chili vinegar": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "chili vinegar", "name": "chillivinäger",
"plural_name": "chili vinegars" "plural_name": "chillivinäger"
}, },
"chili-lime dressing": { "chili-lime dressing": {
"aliases": [], "aliases": [],
@ -11490,14 +11490,14 @@
"soy sauce": { "soy sauce": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "soy sauce", "name": "soja",
"plural_name": "soy sauces" "plural_name": "soja"
}, },
"dijon mustard": { "dijon mustard": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "dijon mustard", "name": "dijonsenap",
"plural_name": "dijon mustards" "plural_name": "dijonsenap"
}, },
"worcestershire": { "worcestershire": {
"aliases": [], "aliases": [],
@ -11521,13 +11521,13 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "ketchup", "name": "ketchup",
"plural_name": "ketchups" "plural_name": "ketchup"
}, },
"mustard": { "mustard": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mustard", "name": "senap",
"plural_name": "mustards" "plural_name": "senap"
}, },
"fish sauce": { "fish sauce": {
"aliases": [], "aliases": [],
@ -11550,8 +11550,8 @@
"wholegrain mustard": { "wholegrain mustard": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "wholegrain mustard", "name": "grov senap",
"plural_name": "wholegrain mustards" "plural_name": "grov senap"
}, },
"tamari": { "tamari": {
"aliases": [], "aliases": [],
@ -11610,8 +11610,8 @@
"dark soy sauce": { "dark soy sauce": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "dark soy sauce", "name": "mörk soja",
"plural_name": "dark soy sauces" "plural_name": "mörk soja"
}, },
"coconut amino": { "coconut amino": {
"aliases": [], "aliases": [],
@ -11665,19 +11665,19 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "wasabi", "name": "wasabi",
"plural_name": "wasabis" "plural_name": "wasabi"
}, },
"honey mustard": { "honey mustard": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "honey mustard", "name": "honungssenap",
"plural_name": "honey mustards" "plural_name": "honungssenap"
}, },
"mango chutney": { "mango chutney": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "mango chutney", "name": "mango chutney",
"plural_name": "mango chutneys" "plural_name": "mango chutney"
}, },
"english mustard": { "english mustard": {
"aliases": [], "aliases": [],
@ -11689,7 +11689,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sambal oelek", "name": "sambal oelek",
"plural_name": "sambal oeleks" "plural_name": "sambal oelek"
}, },
"preserved lemon": { "preserved lemon": {
"aliases": [], "aliases": [],
@ -11712,8 +11712,8 @@
"shrimp paste": { "shrimp paste": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "shrimp paste", "name": "räkpasta",
"plural_name": "shrimp pastes" "plural_name": "räkpasta"
}, },
"picante sauce": { "picante sauce": {
"aliases": [], "aliases": [],
@ -11880,8 +11880,8 @@
"hp sauce": { "hp sauce": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "hp sauce", "name": "HP-sås",
"plural_name": "hp sauces" "plural_name": "HP-såser"
}, },
"duck sauce": { "duck sauce": {
"aliases": [], "aliases": [],
@ -12012,8 +12012,8 @@
"remoulade": { "remoulade": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "remoulade", "name": "remoulad",
"plural_name": "remoulades" "plural_name": "remoulad"
}, },
"white bbq sauce": { "white bbq sauce": {
"aliases": [], "aliases": [],
@ -12106,26 +12106,26 @@
"caper": { "caper": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "caper", "name": "kapris",
"plural_name": "capers" "plural_name": "kapris"
}, },
"green olive": { "green olive": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "green olive", "name": "grön oliv",
"plural_name": "green olives" "plural_name": "gröna oliver"
}, },
"canned chickpea": { "canned chickpea": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned chickpea", "name": "konserverad kikärta",
"plural_name": "canned chickpeas" "plural_name": "konserverade kikärtor"
}, },
"black olive": { "black olive": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "black olive", "name": "svart oliv",
"plural_name": "black olives" "plural_name": "svarta oliver"
}, },
"canned black bean": { "canned black bean": {
"aliases": [], "aliases": [],
@ -12142,14 +12142,14 @@
"kalamata olive": { "kalamata olive": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "kalamata olive", "name": "kalamataoliv",
"plural_name": "kalamata olives" "plural_name": "kalamataoliver"
}, },
"canned tuna": { "canned tuna": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned tuna", "name": "konserverad tonfisk",
"plural_name": "canned tuna" "plural_name": "konserverade tonfiskar"
}, },
"pickle": { "pickle": {
"aliases": [], "aliases": [],
@ -12160,8 +12160,8 @@
"canned pineapple": { "canned pineapple": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned pineapple", "name": "konserverad ananas",
"plural_name": "canned pineapples" "plural_name": "konserverade ananaser"
}, },
"chipotle in adobo": { "chipotle in adobo": {
"aliases": [], "aliases": [],
@ -12226,8 +12226,8 @@
"canned whole tomato": { "canned whole tomato": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned whole tomato", "name": "konserverad hel tomat",
"plural_name": "canned whole tomatoes" "plural_name": "konserverade hela tomater"
}, },
"sweet pickle relish": { "sweet pickle relish": {
"aliases": [], "aliases": [],
@ -12238,8 +12238,8 @@
"sauerkraut": { "sauerkraut": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sauerkraut", "name": "surkål",
"plural_name": "sauerkrauts" "plural_name": "surkål"
}, },
"creamed corn": { "creamed corn": {
"aliases": [], "aliases": [],
@ -12274,14 +12274,14 @@
"sun-dried tomato in oil": { "sun-dried tomato in oil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sun-dried tomato in oil", "name": "soltorkad tomat i olja",
"plural_name": "sun-dried tomatoes in oil" "plural_name": "soltorkade tomater i olja"
}, },
"kimchi": { "kimchi": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "kimchi", "name": "kimchi",
"plural_name": "kimchis" "plural_name": "kimchi"
}, },
"canned mandarin orange": { "canned mandarin orange": {
"aliases": [], "aliases": [],
@ -12304,14 +12304,14 @@
"bamboo shoot": { "bamboo shoot": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "bamboo shoot", "name": "bambuskott",
"plural_name": "bamboo shoots" "plural_name": "bambuskott"
}, },
"canned mushroom": { "canned mushroom": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned mushroom", "name": "konserverad champinjon",
"plural_name": "canned mushrooms" "plural_name": "konserverade champinjoner"
}, },
"baked bean": { "baked bean": {
"aliases": [], "aliases": [],
@ -12400,20 +12400,20 @@
"canned lentil": { "canned lentil": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned lentil", "name": "konserverad lins",
"plural_name": "canned lentils" "plural_name": "konserverade linser"
}, },
"canned pea": { "canned pea": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned pea", "name": "konserverad ärta",
"plural_name": "canned peas" "plural_name": "konserverade ärtor"
}, },
"pickled red onion": { "pickled red onion": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pickled red onion", "name": "picklad rödlök",
"plural_name": "pickled red onions" "plural_name": "picklade rödlökar"
}, },
"pimiento-stuffed green olive": { "pimiento-stuffed green olive": {
"aliases": [], "aliases": [],
@ -12436,8 +12436,8 @@
"canned cherry tomato": { "canned cherry tomato": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned cherry tomato", "name": "konserverad körsbärstomat",
"plural_name": "canned cherry tomatoes" "plural_name": "konserverade körsbärstomater"
}, },
"bread & butter pickle": { "bread & butter pickle": {
"aliases": [], "aliases": [],
@ -12460,8 +12460,8 @@
"canned pear": { "canned pear": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned pear", "name": "konserverat päron",
"plural_name": "canned pears" "plural_name": "konserverade päron"
}, },
"peppadew pepper": { "peppadew pepper": {
"aliases": [], "aliases": [],
@ -12484,8 +12484,8 @@
"canned baby corn": { "canned baby corn": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned baby corn", "name": "konserverad minimajs",
"plural_name": "canned baby corns" "plural_name": "konserverade minimajs"
}, },
"mexican-style corn": { "mexican-style corn": {
"aliases": [], "aliases": [],
@ -12520,8 +12520,8 @@
"canned carrot": { "canned carrot": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned carrot", "name": "konserverad morot",
"plural_name": "canned carrots" "plural_name": "konserverade morötter"
}, },
"banana pepper ring": { "banana pepper ring": {
"aliases": [], "aliases": [],
@ -12586,8 +12586,8 @@
"canned asparagu": { "canned asparagu": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned asparagu", "name": "konserverad sparris",
"plural_name": "canned asparagus" "plural_name": "konserverade sparris"
}, },
"fire-roasted green chile": { "fire-roasted green chile": {
"aliases": [], "aliases": [],
@ -12622,8 +12622,8 @@
"canned mackerel": { "canned mackerel": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned mackerel", "name": "konserverad makrill",
"plural_name": "canned mackerel" "plural_name": "konserverade makrillar"
}, },
"pickled cherry pepper": { "pickled cherry pepper": {
"aliases": [], "aliases": [],
@ -12652,8 +12652,8 @@
"canned potato": { "canned potato": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "canned potato", "name": "konserverad potatis",
"plural_name": "canned potatoes" "plural_name": "konserverade potatisar"
}, },
"okra pickle": { "okra pickle": {
"aliases": [], "aliases": [],
@ -12704,14 +12704,14 @@
"peanut butter": { "peanut butter": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "peanut butter", "name": "jordnötssmör",
"plural_name": "peanut butters" "plural_name": "jordnötssmör"
}, },
"tomato paste": { "tomato paste": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "tomato paste", "name": "tomatpuré",
"plural_name": "tomato pastes" "plural_name": "tomatpuréer"
}, },
"tomato sauce": { "tomato sauce": {
"aliases": [], "aliases": [],
@ -12735,7 +12735,7 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "pesto", "name": "pesto",
"plural_name": "pestoes" "plural_name": "pesto"
}, },
"marinara sauce": { "marinara sauce": {
"aliases": [ "aliases": [
@ -12773,12 +12773,12 @@
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "guacamole", "name": "guacamole",
"plural_name": "guacamoles" "plural_name": "guacamole"
}, },
"hummu": { "hummu": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "hummu", "name": "hummus",
"plural_name": "hummus" "plural_name": "hummus"
}, },
"enchilada sauce": { "enchilada sauce": {
@ -12844,8 +12844,8 @@
"taco sauce": { "taco sauce": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "taco sauce", "name": "tacosås",
"plural_name": "taco sauces" "plural_name": "tacosåser"
}, },
"beef gravy": { "beef gravy": {
"aliases": [], "aliases": [],
@ -12856,8 +12856,8 @@
"sun-dried tomato pesto": { "sun-dried tomato pesto": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "sun-dried tomato pesto", "name": "pesto på soltorkad tomat",
"plural_name": "sun-dried tomato pestoes" "plural_name": "pesto på soltorkad tomat"
}, },
"béchamel sauce": { "béchamel sauce": {
"aliases": [], "aliases": [],
@ -12880,8 +12880,8 @@
"garlic butter": { "garlic butter": {
"aliases": [], "aliases": [],
"description": "", "description": "",
"name": "garlic butter", "name": "vitlökssmör",
"plural_name": "garlic butter" "plural_name": "vitlökssmör"
}, },
"hollandaise sauce": { "hollandaise sauce": {
"aliases": [], "aliases": [],

View file

@ -10,7 +10,7 @@ from mealie.routes._base.mixins import HttpRepo
from mealie.schema import mapper from mealie.schema import mapper
from mealie.schema.household.webhook import CreateWebhook, ReadWebhook, SaveWebhook, WebhookPagination from mealie.schema.household.webhook import CreateWebhook, ReadWebhook, SaveWebhook, WebhookPagination
from mealie.schema.response.pagination import PaginationQuery from mealie.schema.response.pagination import PaginationQuery
from mealie.services.scheduler.tasks.post_webhooks import post_group_webhooks, post_single_webhook from mealie.services.scheduler.tasks.post_webhooks import post_group_webhooks, post_test_webhook
router = APIRouter(prefix="/households/webhooks", tags=["Households: Webhooks"]) router = APIRouter(prefix="/households/webhooks", tags=["Households: Webhooks"])
@ -55,7 +55,7 @@ class ReadWebhookController(BaseUserController):
@router.post("/{item_id}/test") @router.post("/{item_id}/test")
def test_one(self, item_id: UUID4, bg_tasks: BackgroundTasks): def test_one(self, item_id: UUID4, bg_tasks: BackgroundTasks):
webhook = self.mixins.get_one(item_id) webhook = self.mixins.get_one(item_id)
bg_tasks.add_task(post_single_webhook, webhook, "Test Webhook") bg_tasks.add_task(post_test_webhook, webhook, "Test Webhook")
@router.put("/{item_id}", response_model=ReadWebhook) @router.put("/{item_id}", response_model=ReadWebhook)
def update_one(self, item_id: UUID4, data: CreateWebhook): def update_one(self, item_id: UUID4, data: CreateWebhook):

View file

@ -3,7 +3,6 @@ import json
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import Generator from collections.abc import Generator
from datetime import UTC, datetime from datetime import UTC, datetime
from typing import cast
from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit
from fastapi.encoders import jsonable_encoder from fastapi.encoders import jsonable_encoder
@ -148,15 +147,24 @@ class WebhookEventListener(EventListenerBase):
def publish_to_subscribers(self, event: Event, subscribers: list[ReadWebhook]) -> None: def publish_to_subscribers(self, event: Event, subscribers: list[ReadWebhook]) -> None:
with self.ensure_repos(self.group_id, self.household_id) as repos: with self.ensure_repos(self.group_id, self.household_id) as repos:
if event.document_data.document_type == EventDocumentType.mealplan: if not isinstance(event.document_data, EventWebhookData):
webhook_data = cast(EventWebhookData, event.document_data) return
meal_repo = repos.meals
meal_data = meal_repo.get_meals_by_date_range( match event.document_data.document_type:
webhook_data.webhook_start_dt, webhook_data.webhook_end_dt case EventDocumentType.mealplan:
) meal_repo = repos.meals
if meal_data: meal_data = meal_repo.get_meals_by_date_range(
webhook_data.webhook_body = meal_data event.document_data.webhook_start_dt, event.document_data.webhook_end_dt
self.publisher.publish(event, [webhook.url for webhook in subscribers]) )
event.document_data.webhook_body = meal_data or None
case _:
if event.event_type is EventTypes.test_message:
# make sure the webhook has a valid body so it gets sent
event.document_data.webhook_body = event.document_data.webhook_body or []
# Only publish to subscribers if we have a webhook body to send
if event.document_data.webhook_body is not None:
self.publisher.publish(event, [webhook.url for webhook in subscribers])
def get_scheduled_webhooks(self, start_dt: datetime, end_dt: datetime) -> list[ReadWebhook]: def get_scheduled_webhooks(self, start_dt: datetime, end_dt: datetime) -> list[ReadWebhook]:
"""Fetches all scheduled webhooks from the database""" """Fetches all scheduled webhooks from the database"""

View file

@ -79,12 +79,12 @@ def post_group_webhooks(
) )
def post_single_webhook(webhook: ReadWebhook, message: str = "") -> None: def post_test_webhook(webhook: ReadWebhook, message: str = "") -> None:
dt = datetime.min.replace(tzinfo=UTC) dt = datetime.min.replace(tzinfo=UTC)
event_type = EventTypes.webhook_task event_type = EventTypes.test_message
event_document_data = EventWebhookData( event_document_data = EventWebhookData(
document_type=EventDocumentType.mealplan, document_type=EventDocumentType.generic,
operation=EventOperation.info, operation=EventOperation.info,
webhook_start_dt=dt, webhook_start_dt=dt,
webhook_end_dt=dt, webhook_end_dt=dt,

178
poetry.lock generated
View file

@ -478,100 +478,100 @@ markers = {main = "platform_system == \"Windows\" or sys_platform == \"win32\""}
[[package]] [[package]]
name = "coverage" name = "coverage"
version = "7.10.0" version = "7.10.1"
description = "Code coverage measurement for Python" description = "Code coverage measurement for Python"
optional = false optional = false
python-versions = ">=3.9" python-versions = ">=3.9"
groups = ["dev"] groups = ["dev"]
files = [ files = [
{file = "coverage-7.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cbd823f7ea5286c26406ad9e54268544d82f3d1cadb6d4f3b85e9877f0cab1ef"}, {file = "coverage-7.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1c86eb388bbd609d15560e7cc0eb936c102b6f43f31cf3e58b4fd9afe28e1372"},
{file = "coverage-7.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ab3f7a5dbaab937df0b9e9e8ec6eab235ba9a6f29d71fd3b24335affaed886cc"}, {file = "coverage-7.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6b4ba0f488c1bdb6bd9ba81da50715a372119785458831c73428a8566253b86b"},
{file = "coverage-7.10.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8c63aaf850523d8cbe3f5f1a5c78f689b223797bef902635f2493ab43498f36c"}, {file = "coverage-7.10.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:083442ecf97d434f0cb3b3e3676584443182653da08b42e965326ba12d6b5f2a"},
{file = "coverage-7.10.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4c3133ce3fa84023f7c6921c4dca711be0b658784c5a51a797168229eae26172"}, {file = "coverage-7.10.1-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c1a40c486041006b135759f59189385da7c66d239bad897c994e18fd1d0c128f"},
{file = "coverage-7.10.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3747d1d0af85b17d3a156cd30e4bbacf893815e846dc6c07050e9769da2b138e"}, {file = "coverage-7.10.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3beb76e20b28046989300c4ea81bf690df84ee98ade4dc0bbbf774a28eb98440"},
{file = "coverage-7.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:241923b350437f6a7cb343d9df72998305ef940c3c40009f06e05029a047677c"}, {file = "coverage-7.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bc265a7945e8d08da28999ad02b544963f813a00f3ed0a7a0ce4165fd77629f8"},
{file = "coverage-7.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13e82e499309307104d58ac66f9eed237f7aaceab4325416645be34064d9a2be"}, {file = "coverage-7.10.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:47c91f32ba4ac46f1e224a7ebf3f98b4b24335bad16137737fe71a5961a0665c"},
{file = "coverage-7.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bf73cdde4f6c9cd4457b00bf1696236796ac3a241f859a55e0f84a4c58326a7f"}, {file = "coverage-7.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1a108dd78ed185020f66f131c60078f3fae3f61646c28c8bb4edd3fa121fc7fc"},
{file = "coverage-7.10.0-cp310-cp310-win32.whl", hash = "sha256:2396e13275b37870a3345f58bce8b15a7e0a985771d13a4b16ce9129954e07d6"}, {file = "coverage-7.10.1-cp310-cp310-win32.whl", hash = "sha256:7092cc82382e634075cc0255b0b69cb7cada7c1f249070ace6a95cb0f13548ef"},
{file = "coverage-7.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:9d45c7c71fb3d2da92ab893602e3f28f2d1560cec765a27e1824a6e0f7e92cfd"}, {file = "coverage-7.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:ac0c5bba938879c2fc0bc6c1b47311b5ad1212a9dcb8b40fe2c8110239b7faed"},
{file = "coverage-7.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4abc01843581a6f9dd72d4d15761861190973a2305416639435ef509288f7a04"}, {file = "coverage-7.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b45e2f9d5b0b5c1977cb4feb5f594be60eb121106f8900348e29331f553a726f"},
{file = "coverage-7.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2093297773111d7d748fe4a99b68747e57994531fb5c57bbe439af17c11c169"}, {file = "coverage-7.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a7a4d74cb0f5e3334f9aa26af7016ddb94fb4bfa11b4a573d8e98ecba8c34f1"},
{file = "coverage-7.10.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:58240e27815bf105bd975c2fd42e700839f93d5aad034ef976411193ca32dbfd"}, {file = "coverage-7.10.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d4b0aab55ad60ead26159ff12b538c85fbab731a5e3411c642b46c3525863437"},
{file = "coverage-7.10.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d019eac999b40ad48521ea057958b07a9f549c0c6d257a20e5c7c4ba91af8d1c"}, {file = "coverage-7.10.1-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:dcc93488c9ebd229be6ee1f0d9aad90da97b33ad7e2912f5495804d78a3cd6b7"},
{file = "coverage-7.10.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35e0a1f5454bc80faf4ceab10d1d48f025f92046c9c0f3bec2e1a9dda55137f8"}, {file = "coverage-7.10.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa309df995d020f3438407081b51ff527171cca6772b33cf8f85344b8b4b8770"},
{file = "coverage-7.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a93dd7759c416dd1cc754123b926d065055cb9a33b6699e64a1e5bdfae1ff459"}, {file = "coverage-7.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cfb8b9d8855c8608f9747602a48ab525b1d320ecf0113994f6df23160af68262"},
{file = "coverage-7.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7b3d737266048368a6ffd68f1ecd662c54de56535c82eb8f98a55ac216a72cbd"}, {file = "coverage-7.10.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:320d86da829b012982b414c7cdda65f5d358d63f764e0e4e54b33097646f39a3"},
{file = "coverage-7.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:93227c2707cb0effd9163cd0d8f0d9ab628982f7a3e915d6d64c7107867b9a07"}, {file = "coverage-7.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dc60ddd483c556590da1d9482a4518292eec36dd0e1e8496966759a1f282bcd0"},
{file = "coverage-7.10.0-cp311-cp311-win32.whl", hash = "sha256:69270af3014ab3058ad6108c6d0e218166f568b5a7a070dc3d62c0a63aca1c4d"}, {file = "coverage-7.10.1-cp311-cp311-win32.whl", hash = "sha256:4fcfe294f95b44e4754da5b58be750396f2b1caca8f9a0e78588e3ef85f8b8be"},
{file = "coverage-7.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:43c16bbb661a7b4dafac0ab69e44d6dbcc6a64c4d93aefd89edc6f8911b6ab4a"}, {file = "coverage-7.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:efa23166da3fe2915f8ab452dde40319ac84dc357f635737174a08dbd912980c"},
{file = "coverage-7.10.0-cp311-cp311-win_arm64.whl", hash = "sha256:14e7c23fcb74ed808efb4eb48fcd25a759f0e20f685f83266d1df174860e4733"}, {file = "coverage-7.10.1-cp311-cp311-win_arm64.whl", hash = "sha256:d12b15a8c3759e2bb580ffa423ae54be4f184cf23beffcbd641f4fe6e1584293"},
{file = "coverage-7.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a2adcfdaf3b4d69b0c64ad024fe9dd6996782b52790fb6033d90f36f39e287df"}, {file = "coverage-7.10.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6b7dc7f0a75a7eaa4584e5843c873c561b12602439d2351ee28c7478186c4da4"},
{file = "coverage-7.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d7b27c2c0840e8eeff3f1963782bd9d3bc767488d2e67a31de18d724327f9f6"}, {file = "coverage-7.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:607f82389f0ecafc565813aa201a5cade04f897603750028dd660fb01797265e"},
{file = "coverage-7.10.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0ed50429786e935517570b08576a661fd79032e6060985ab492b9d39ba8e66ee"}, {file = "coverage-7.10.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f7da31a1ba31f1c1d4d5044b7c5813878adae1f3af8f4052d679cc493c7328f4"},
{file = "coverage-7.10.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7171c139ab6571d70460ecf788b1dcaf376bfc75a42e1946b8c031d062bbbad4"}, {file = "coverage-7.10.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:51fe93f3fe4f5d8483d51072fddc65e717a175490804e1942c975a68e04bf97a"},
{file = "coverage-7.10.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a726aac7e6e406e403cdee4c443a13aed3ea3d67d856414c5beacac2e70c04e"}, {file = "coverage-7.10.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3e59d00830da411a1feef6ac828b90bbf74c9b6a8e87b8ca37964925bba76dbe"},
{file = "coverage-7.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2886257481a14e953e96861a00c0fe7151117a523f0470a51e392f00640bba03"}, {file = "coverage-7.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:924563481c27941229cb4e16eefacc35da28563e80791b3ddc5597b062a5c386"},
{file = "coverage-7.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:536578b79521e59c385a2e0a14a5dc2a8edd58761a966d79368413e339fc9535"}, {file = "coverage-7.10.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ca79146ee421b259f8131f153102220b84d1a5e6fb9c8aed13b3badfd1796de6"},
{file = "coverage-7.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77fae95558f7804a9ceefabf3c38ad41af1da92b39781b87197c6440dcaaa967"}, {file = "coverage-7.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2b225a06d227f23f386fdc0eab471506d9e644be699424814acc7d114595495f"},
{file = "coverage-7.10.0-cp312-cp312-win32.whl", hash = "sha256:97803e14736493eb029558e1502fe507bd6a08af277a5c8eeccf05c3e970cb84"}, {file = "coverage-7.10.1-cp312-cp312-win32.whl", hash = "sha256:5ba9a8770effec5baaaab1567be916c87d8eea0c9ad11253722d86874d885eca"},
{file = "coverage-7.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:4c73ab554e54ffd38d114d6bc4a7115fb0c840cf6d8622211bee3da26e4bd25d"}, {file = "coverage-7.10.1-cp312-cp312-win_amd64.whl", hash = "sha256:9eb245a8d8dd0ad73b4062135a251ec55086fbc2c42e0eb9725a9b553fba18a3"},
{file = "coverage-7.10.0-cp312-cp312-win_arm64.whl", hash = "sha256:3ae95d5a9aedab853641026b71b2ddd01983a0a7e9bf870a20ef3c8f5d904699"}, {file = "coverage-7.10.1-cp312-cp312-win_arm64.whl", hash = "sha256:7718060dd4434cc719803a5e526838a5d66e4efa5dc46d2b25c21965a9c6fcc4"},
{file = "coverage-7.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d883fee92b9245c0120fa25b5d36de71ccd4cfc29735906a448271e935d8d86d"}, {file = "coverage-7.10.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ebb08d0867c5a25dffa4823377292a0ffd7aaafb218b5d4e2e106378b1061e39"},
{file = "coverage-7.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c87e59e88268d30e33d3665ede4fbb77b513981a2df0059e7c106ca3de537586"}, {file = "coverage-7.10.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f32a95a83c2e17422f67af922a89422cd24c6fa94041f083dd0bb4f6057d0bc7"},
{file = "coverage-7.10.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f669d969f669a11d6ceee0b733e491d9a50573eb92a71ffab13b15f3aa2665d4"}, {file = "coverage-7.10.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c4c746d11c8aba4b9f58ca8bfc6fbfd0da4efe7960ae5540d1a1b13655ee8892"},
{file = "coverage-7.10.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9582bd6c6771300a847d328c1c4204e751dbc339a9e249eecdc48cada41f72e6"}, {file = "coverage-7.10.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7f39edd52c23e5c7ed94e0e4bf088928029edf86ef10b95413e5ea670c5e92d7"},
{file = "coverage-7.10.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91f97e9637dc7977842776fdb7ad142075d6fa40bc1b91cb73685265e0d31d32"}, {file = "coverage-7.10.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ab6e19b684981d0cd968906e293d5628e89faacb27977c92f3600b201926b994"},
{file = "coverage-7.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ae4fa92b6601a62367c6c9967ad32ad4e28a89af54b6bb37d740946b0e0534dd"}, {file = "coverage-7.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5121d8cf0eacb16133501455d216bb5f99899ae2f52d394fe45d59229e6611d0"},
{file = "coverage-7.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3a5cc8b97473e7b3623dd17a42d2194a2b49de8afecf8d7d03c8987237a9552c"}, {file = "coverage-7.10.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:df1c742ca6f46a6f6cbcaef9ac694dc2cb1260d30a6a2f5c68c5f5bcfee1cfd7"},
{file = "coverage-7.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc1cbb7f623250e047c32bd7aa1bb62ebc62608d5004d74df095e1059141ac88"}, {file = "coverage-7.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:40f9a38676f9c073bf4b9194707aa1eb97dca0e22cc3766d83879d72500132c7"},
{file = "coverage-7.10.0-cp313-cp313-win32.whl", hash = "sha256:1380cc5666d778e77f1587cd88cc317158111f44d54c0dd3975f0936993284e0"}, {file = "coverage-7.10.1-cp313-cp313-win32.whl", hash = "sha256:2348631f049e884839553b9974f0821d39241c6ffb01a418efce434f7eba0fe7"},
{file = "coverage-7.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:bf03cf176af098ee578b754a03add4690b82bdfe070adfb5d192d0b1cd15cf82"}, {file = "coverage-7.10.1-cp313-cp313-win_amd64.whl", hash = "sha256:4072b31361b0d6d23f750c524f694e1a417c1220a30d3ef02741eed28520c48e"},
{file = "coverage-7.10.0-cp313-cp313-win_arm64.whl", hash = "sha256:8041c78cd145088116db2329b2fb6e89dc338116c962fbe654b7e9f5d72ab957"}, {file = "coverage-7.10.1-cp313-cp313-win_arm64.whl", hash = "sha256:3e31dfb8271937cab9425f19259b1b1d1f556790e98eb266009e7a61d337b6d4"},
{file = "coverage-7.10.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37cc2c06052771f48651160c080a86431884db9cd62ba622cab71049b90a95b3"}, {file = "coverage-7.10.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1c4f679c6b573a5257af6012f167a45be4c749c9925fd44d5178fd641ad8bf72"},
{file = "coverage-7.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:91f37270b16178b05fa107d85713d29bf21606e37b652d38646eef5f2dfbd458"}, {file = "coverage-7.10.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:871ebe8143da284bd77b84a9136200bd638be253618765d21a1fce71006d94af"},
{file = "coverage-7.10.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f9b0b0168864d09bcb9a3837548f75121645c4cfd0efce0eb994c221955c5b10"}, {file = "coverage-7.10.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:998c4751dabf7d29b30594af416e4bf5091f11f92a8d88eb1512c7ba136d1ed7"},
{file = "coverage-7.10.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:df0be435d3b616e7d3ee3f9ebbc0d784a213986fe5dff9c6f1042ee7cfd30157"}, {file = "coverage-7.10.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:780f750a25e7749d0af6b3631759c2c14f45de209f3faaa2398312d1c7a22759"},
{file = "coverage-7.10.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:35e9aba1c4434b837b1d567a533feba5ce205e8e91179c97974b28a14c23d3a0"}, {file = "coverage-7.10.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:590bdba9445df4763bdbebc928d8182f094c1f3947a8dc0fc82ef014dbdd8324"},
{file = "coverage-7.10.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a0b0c481e74dfad631bdc2c883e57d8b058e5c90ba8ef087600995daf7bbec18"}, {file = "coverage-7.10.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b2df80cb6a2af86d300e70acb82e9b79dab2c1e6971e44b78dbfc1a1e736b53"},
{file = "coverage-7.10.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8aec1b7c8922808a433c13cd44ace6fceac0609f4587773f6c8217a06102674b"}, {file = "coverage-7.10.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d6a558c2725bfb6337bf57c1cd366c13798bfd3bfc9e3dd1f4a6f6fc95a4605f"},
{file = "coverage-7.10.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:04ec59ceb3a594af0927f2e0d810e1221212abd9a2e6b5b917769ff48760b460"}, {file = "coverage-7.10.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e6150d167f32f2a54690e572e0a4c90296fb000a18e9b26ab81a6489e24e78dd"},
{file = "coverage-7.10.0-cp313-cp313t-win32.whl", hash = "sha256:b6871e62d29646eb9b3f5f92def59e7575daea1587db21f99e2b19561187abda"}, {file = "coverage-7.10.1-cp313-cp313t-win32.whl", hash = "sha256:d946a0c067aa88be4a593aad1236493313bafaa27e2a2080bfe88db827972f3c"},
{file = "coverage-7.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff99cff2be44f78920b76803f782e91ffb46ccc7fa89eccccc0da3ca94285b64"}, {file = "coverage-7.10.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e37c72eaccdd5ed1130c67a92ad38f5b2af66eeff7b0abe29534225db2ef7b18"},
{file = "coverage-7.10.0-cp313-cp313t-win_arm64.whl", hash = "sha256:3246b63501348fe47299d12c47a27cfc221cfbffa1c2d857bcc8151323a4ae4f"}, {file = "coverage-7.10.1-cp313-cp313t-win_arm64.whl", hash = "sha256:89ec0ffc215c590c732918c95cd02b55c7d0f569d76b90bb1a5e78aa340618e4"},
{file = "coverage-7.10.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:1f628d91f941a375b4503cb486148dbeeffb48e17bc080e0f0adfee729361574"}, {file = "coverage-7.10.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:166d89c57e877e93d8827dac32cedae6b0277ca684c6511497311249f35a280c"},
{file = "coverage-7.10.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3a0e101d5af952d233557e445f42ebace20b06b4ceb615581595ced5386caa78"}, {file = "coverage-7.10.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bed4a2341b33cd1a7d9ffc47df4a78ee61d3416d43b4adc9e18b7d266650b83e"},
{file = "coverage-7.10.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ec4c1abbcc53f9f650acb14ea71725d88246a9e14ed42f8dd1b4e1b694e9d842"}, {file = "coverage-7.10.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ddca1e4f5f4c67980533df01430184c19b5359900e080248bbf4ed6789584d8b"},
{file = "coverage-7.10.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9c95f3a7f041b4cc68a8e3fecfa6366170c13ac773841049f1cd19c8650094e0"}, {file = "coverage-7.10.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:37b69226001d8b7de7126cad7366b0778d36777e4d788c66991455ba817c5b41"},
{file = "coverage-7.10.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a2cd597b69c16d24e310611f2ed6fcfb8f09429316038c03a57e7b4f5345244"}, {file = "coverage-7.10.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2f22102197bcb1722691296f9e589f02b616f874e54a209284dd7b9294b0b7f"},
{file = "coverage-7.10.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5e18591906a40c2b3609196c9879136aa4a47c5405052ca6b065ab10cb0b71d0"}, {file = "coverage-7.10.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1e0c768b0f9ac5839dac5cf88992a4bb459e488ee8a1f8489af4cb33b1af00f1"},
{file = "coverage-7.10.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:485c55744252ed3f300cc1a0f5f365e684a0f2651a7aed301f7a67125906b80e"}, {file = "coverage-7.10.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:991196702d5e0b120a8fef2664e1b9c333a81d36d5f6bcf6b225c0cf8b0451a2"},
{file = "coverage-7.10.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4dabea1516e5b0e9577282b149c8015e4dceeb606da66fb8d9d75932d5799bf5"}, {file = "coverage-7.10.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae8e59e5f4fd85d6ad34c2bb9d74037b5b11be072b8b7e9986beb11f957573d4"},
{file = "coverage-7.10.0-cp314-cp314-win32.whl", hash = "sha256:ac455f0537af22333fdc23b824cff81110dff2d47300bb2490f947b7c9a16017"}, {file = "coverage-7.10.1-cp314-cp314-win32.whl", hash = "sha256:042125c89cf74a074984002e165d61fe0e31c7bd40ebb4bbebf07939b5924613"},
{file = "coverage-7.10.0-cp314-cp314-win_amd64.whl", hash = "sha256:b3c94b532f52f95f36fbfde3e178510a4d04eea640b484b2fe8f1491338dc653"}, {file = "coverage-7.10.1-cp314-cp314-win_amd64.whl", hash = "sha256:a22c3bfe09f7a530e2c94c87ff7af867259c91bef87ed2089cd69b783af7b84e"},
{file = "coverage-7.10.0-cp314-cp314-win_arm64.whl", hash = "sha256:2f807f2c3a9da99c80dfa73f09ef5fc3bd21e70c73ba1c538f23396a3a772252"}, {file = "coverage-7.10.1-cp314-cp314-win_arm64.whl", hash = "sha256:ee6be07af68d9c4fca4027c70cea0c31a0f1bc9cb464ff3c84a1f916bf82e652"},
{file = "coverage-7.10.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0a889ef25215990f65073c32cadf37483363a6a22914186dedc15a6b1a597d50"}, {file = "coverage-7.10.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d24fb3c0c8ff0d517c5ca5de7cf3994a4cd559cde0315201511dbfa7ab528894"},
{file = "coverage-7.10.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:39c638ecf3123805bacbf71aff8091e93af490c676fca10ab4e442375076e483"}, {file = "coverage-7.10.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1217a54cfd79be20512a67ca81c7da3f2163f51bbfd188aab91054df012154f5"},
{file = "coverage-7.10.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f2f2c0df0cbcf7dffa14f88a99c530cdef3f4fcfe935fa4f95d28be2e7ebc570"}, {file = "coverage-7.10.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:51f30da7a52c009667e02f125737229d7d8044ad84b79db454308033a7808ab2"},
{file = "coverage-7.10.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:048d19a5d641a2296745ab59f34a27b89a08c48d6d432685f22aac0ec1ea447f"}, {file = "coverage-7.10.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ed3718c757c82d920f1c94089066225ca2ad7f00bb904cb72b1c39ebdd906ccb"},
{file = "coverage-7.10.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1209b65d302d7a762004be37ab9396cbd8c99525ed572bdf455477e3a9449e06"}, {file = "coverage-7.10.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc452481e124a819ced0c25412ea2e144269ef2f2534b862d9f6a9dae4bda17b"},
{file = "coverage-7.10.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e44aa79a36a7a0aec6ea109905a4a7c28552d90f34e5941b36217ae9556657d5"}, {file = "coverage-7.10.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9d6f494c307e5cb9b1e052ec1a471060f1dea092c8116e642e7a23e79d9388ea"},
{file = "coverage-7.10.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:96124be864b89395770c9a14652afcddbcdafb99466f53a9281c51d1466fb741"}, {file = "coverage-7.10.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:fc0e46d86905ddd16b85991f1f4919028092b4e511689bbdaff0876bd8aab3dd"},
{file = "coverage-7.10.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aad222e841f94b42bd1d6be71737fade66943853f0807cf87887c88f70883a2a"}, {file = "coverage-7.10.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:80b9ccd82e30038b61fc9a692a8dc4801504689651b281ed9109f10cc9fe8b4d"},
{file = "coverage-7.10.0-cp314-cp314t-win32.whl", hash = "sha256:0eed5354d28caa5c8ad60e07e938f253e4b2810ea7dd56784339b6ce98b6f104"}, {file = "coverage-7.10.1-cp314-cp314t-win32.whl", hash = "sha256:e58991a2b213417285ec866d3cd32db17a6a88061a985dbb7e8e8f13af429c47"},
{file = "coverage-7.10.0-cp314-cp314t-win_amd64.whl", hash = "sha256:3da35f9980058acb960b2644527cc3911f1e00f94d309d704b309fa984029109"}, {file = "coverage-7.10.1-cp314-cp314t-win_amd64.whl", hash = "sha256:e88dd71e4ecbc49d9d57d064117462c43f40a21a1383507811cf834a4a620651"},
{file = "coverage-7.10.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cb9e138dfa8a4b5c52c92a537651e2ca4f2ca48d8cb1bc01a2cbe7a5773c2426"}, {file = "coverage-7.10.1-cp314-cp314t-win_arm64.whl", hash = "sha256:1aadfb06a30c62c2eb82322171fe1f7c288c80ca4156d46af0ca039052814bab"},
{file = "coverage-7.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cf283ec9c6878826291b17442eb5c32d3d252dc77d25e082b460b2d2ea67ba3c"}, {file = "coverage-7.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:57b6e8789cbefdef0667e4a94f8ffa40f9402cee5fc3b8e4274c894737890145"},
{file = "coverage-7.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8a83488c9fc6fff487f2ab551f9b64c70672357b8949f0951b0cd778b3ed8165"}, {file = "coverage-7.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:85b22a9cce00cb03156334da67eb86e29f22b5e93876d0dd6a98646bb8a74e53"},
{file = "coverage-7.10.0-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b86df3a7494d12338c11e59f210a0498d6109bbc3a4037f44de517ebb30a9c6b"}, {file = "coverage-7.10.1-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:97b6983a2f9c76d345ca395e843a049390b39652984e4a3b45b2442fa733992d"},
{file = "coverage-7.10.0-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6de9b460809e5e4787b742e786a36ae2346a53982e2be317cdcb7a33c56412fb"}, {file = "coverage-7.10.1-cp39-cp39-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ddf2a63b91399a1c2f88f40bc1705d5a7777e31c7e9eb27c602280f477b582ba"},
{file = "coverage-7.10.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de5ef8a5954d63fa26a6aaa4600e48f885ce70fe495e8fce2c43aa9241fc9434"}, {file = "coverage-7.10.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:47ab6dbbc31a14c5486420c2c1077fcae692097f673cf5be9ddbec8cdaa4cdbc"},
{file = "coverage-7.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f178fe5e96f1e057527d5d0b20ab76b8616e0410169c33716cc226118eaf2c4f"}, {file = "coverage-7.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:21eb7d8b45d3700e7c2936a736f732794c47615a20f739f4133d5230a6512a88"},
{file = "coverage-7.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4a38c42f0182a012fa9ec25bc6057e51114c1ba125be304f3f776d6d283cb303"}, {file = "coverage-7.10.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:283005bb4d98ae33e45f2861cd2cde6a21878661c9ad49697f6951b358a0379b"},
{file = "coverage-7.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bf09beb5c1785cb36aad042455c0afab561399b74bb8cdaf6e82b7d77322df99"}, {file = "coverage-7.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:fefe31d61d02a8b2c419700b1fade9784a43d726de26495f243b663cd9fe1513"},
{file = "coverage-7.10.0-cp39-cp39-win32.whl", hash = "sha256:cb8dfbb5d3016cb8d1940444c0c69b40cdc6c8bde724b07716ee5ea47b5273c6"}, {file = "coverage-7.10.1-cp39-cp39-win32.whl", hash = "sha256:e8ab8e4c7ec7f8a55ac05b5b715a051d74eac62511c6d96d5bb79aaafa3b04cf"},
{file = "coverage-7.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:58ff22653cd93d563110d1ff2aef958f5f21be9e917762f8124d0e36f80f172a"}, {file = "coverage-7.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:c36baa0ecde742784aa76c2b816466d3ea888d5297fda0edbac1bf48fa94688a"},
{file = "coverage-7.10.0-py3-none-any.whl", hash = "sha256:310a786330bb0463775c21d68e26e79973839b66d29e065c5787122b8dd4489f"}, {file = "coverage-7.10.1-py3-none-any.whl", hash = "sha256:fa2a258aa6bf188eb9a8948f7102a83da7c430a0dce918dbd8b60ef8fcb772d7"},
{file = "coverage-7.10.0.tar.gz", hash = "sha256:2768885aef484b5dcde56262cbdfba559b770bfc46994fe9485dc3614c7a5867"}, {file = "coverage-7.10.1.tar.gz", hash = "sha256:ae2b4856f29ddfe827106794f3589949a57da6f0d38ab01e24ec35107979ba57"},
] ]
[package.extras] [package.extras]

View file

@ -3,6 +3,8 @@ from datetime import UTC, datetime
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from mealie.schema.household.webhook import ReadWebhook
from mealie.services.scheduler.tasks.post_webhooks import post_test_webhook
from tests.utils import api_routes, assert_deserialize, jsonify from tests.utils import api_routes, assert_deserialize, jsonify
from tests.utils.fixture_schemas import TestUser from tests.utils.fixture_schemas import TestUser
@ -84,3 +86,48 @@ def test_delete_webhook(api_client: TestClient, webhook_data, unique_user: TestU
response = api_client.get(api_routes.households_webhooks_item_id(item_id), headers=unique_user.token) response = api_client.get(api_routes.households_webhooks_item_id(item_id), headers=unique_user.token)
assert response.status_code == 404 assert response.status_code == 404
def test_post_test_webhook(
monkeypatch: pytest.MonkeyPatch, api_client: TestClient, unique_user: TestUser, webhook_data
):
# Mock the requests.post to avoid actual HTTP calls
class MockResponse:
status_code = 200
mock_calls = []
def mock_post(*args, **kwargs):
mock_calls.append((args, kwargs))
return MockResponse()
monkeypatch.setattr("mealie.services.event_bus_service.publisher.requests.post", mock_post)
# Create a webhook and post it
response = api_client.post(
api_routes.households_webhooks,
json=jsonify(webhook_data),
headers=unique_user.token,
)
webhook_dict = assert_deserialize(response, 201)
webhook = ReadWebhook(
id=webhook_dict["id"],
name=webhook_dict["name"],
url=webhook_dict["url"],
scheduled_time=webhook_dict["scheduledTime"],
enabled=webhook_dict["enabled"],
group_id=webhook_dict["groupId"],
household_id=webhook_dict["householdId"],
)
test_message = "This is a test webhook message"
post_test_webhook(webhook, test_message)
# Verify that requests.post was called with the correct parameters
assert len(mock_calls) == 1
args, kwargs = mock_calls[0]
assert kwargs["json"]["message"]["body"] == test_message
assert kwargs["timeout"] == 15
assert args[0] == webhook.url