mirror of
https://github.com/hay-kot/mealie.git
synced 2025-08-22 06:23:34 -07:00
fix: Remove Recipes From Cookbook API (#5899)
This commit is contained in:
parent
fd966e5843
commit
1c23d855ae
31 changed files with 169 additions and 237 deletions
|
@ -71,6 +71,7 @@ tasks:
|
||||||
desc: run code generators
|
desc: run code generators
|
||||||
cmds:
|
cmds:
|
||||||
- poetry run python dev/code-generation/main.py {{ .CLI_ARGS }}
|
- poetry run python dev/code-generation/main.py {{ .CLI_ARGS }}
|
||||||
|
- task: docs:gen
|
||||||
- task: py:format
|
- task: py:format
|
||||||
|
|
||||||
dev:services:
|
dev:services:
|
||||||
|
|
|
@ -8,8 +8,8 @@ from utils import log
|
||||||
# ============================================================
|
# ============================================================
|
||||||
|
|
||||||
template = """// This Code is auto generated by gen_ts_types.py
|
template = """// This Code is auto generated by gen_ts_types.py
|
||||||
{% for name in global %}import {{ name }} from "@/components/global/{{ name }}.vue";
|
{% for name in global %}import type {{ name }} from "@/components/global/{{ name }}.vue";
|
||||||
{% endfor %}{% for name in layout %}import {{ name }} from "@/components/layout/{{ name }}.vue";
|
{% endfor %}{% for name in layout %}import type {{ name }} from "@/components/layout/{{ name }}.vue";
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
declare module "vue" {
|
declare module "vue" {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -70,7 +70,7 @@ import RecipeCardSection from "@/components/Domain/Recipe/RecipeCardSection.vue"
|
||||||
import { useCookbookStore } from "~/composables/store/use-cookbook-store";
|
import { useCookbookStore } from "~/composables/store/use-cookbook-store";
|
||||||
import { useCookbook } from "~/composables/use-group-cookbooks";
|
import { useCookbook } from "~/composables/use-group-cookbooks";
|
||||||
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
import { useLoggedInState } from "~/composables/use-logged-in-state";
|
||||||
import type { RecipeCookBook } from "~/lib/api/types/cookbook";
|
import type { ReadCookBook } from "~/lib/api/types/cookbook";
|
||||||
import CookbookEditor from "~/components/Domain/Cookbook/CookbookEditor.vue";
|
import CookbookEditor from "~/components/Domain/Cookbook/CookbookEditor.vue";
|
||||||
|
|
||||||
const $auth = useMealieAuth();
|
const $auth = useMealieAuth();
|
||||||
|
@ -100,7 +100,7 @@ const dialogStates = reactive({
|
||||||
edit: false,
|
edit: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const editTarget = ref<RecipeCookBook | null>(null);
|
const editTarget = ref<ReadCookBook | null>(null);
|
||||||
function handleEditCookbook() {
|
function handleEditCookbook() {
|
||||||
dialogStates.edit = true;
|
dialogStates.edit = true;
|
||||||
editTarget.value = book.value;
|
editTarget.value = book.value;
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import type { Composer } from "vue-i18n";
|
import type { Composer } from "vue-i18n";
|
||||||
import { useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
import { useReadOnlyStore, useStore } from "../partials/use-store-factory";
|
||||||
import type { RecipeCookBook } from "~/lib/api/types/cookbook";
|
import type { ReadCookBook } from "~/lib/api/types/cookbook";
|
||||||
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
import { usePublicExploreApi, useUserApi } from "~/composables/api";
|
||||||
|
|
||||||
const store: Ref<RecipeCookBook[]> = ref([]);
|
const store: Ref<ReadCookBook[]> = ref([]);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const publicLoading = ref(false);
|
const publicLoading = ref(false);
|
||||||
|
|
||||||
export const useCookbookStore = function (i18n?: Composer) {
|
export const useCookbookStore = function (i18n?: Composer) {
|
||||||
const api = useUserApi(i18n);
|
const api = useUserApi(i18n);
|
||||||
return useStore<RecipeCookBook>(store, loading, api.cookbooks);
|
return useStore<ReadCookBook>(store, loading, api.cookbooks);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const usePublicCookbookStore = function (groupSlug: string, i18n?: Composer) {
|
export const usePublicCookbookStore = function (groupSlug: string, i18n?: Composer) {
|
||||||
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
const api = usePublicExploreApi(groupSlug, i18n).explore;
|
||||||
return useReadOnlyStore<RecipeCookBook>(store, publicLoading, api.cookbooks);
|
return useReadOnlyStore<ReadCookBook>(store, publicLoading, api.cookbooks);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { BaseCRUDAPIReadOnly } from "~/lib/api/base/base-clients";
|
import { BaseCRUDAPIReadOnly } from "~/lib/api/base/base-clients";
|
||||||
import { RecipeCookBook } from "~/lib/api/types/cookbook";
|
import { ReadCookBook } from "~/lib/api/types/cookbook";
|
||||||
import { ApiRequestInstance } from "~/lib/api/types/non-generated";
|
import { ApiRequestInstance } from "~/lib/api/types/non-generated";
|
||||||
|
|
||||||
const prefix = "/api";
|
const prefix = "/api";
|
||||||
|
@ -10,7 +10,7 @@ const routes = {
|
||||||
cookbooksGroupSlugCookbookId: (groupSlug: string | number, cookbookId: string | number) => `${exploreGroupSlug(groupSlug)}/cookbooks/${cookbookId}`,
|
cookbooksGroupSlugCookbookId: (groupSlug: string | number, cookbookId: string | number) => `${exploreGroupSlug(groupSlug)}/cookbooks/${cookbookId}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class PublicCookbooksApi extends BaseCRUDAPIReadOnly<RecipeCookBook> {
|
export class PublicCookbooksApi extends BaseCRUDAPIReadOnly<ReadCookBook> {
|
||||||
constructor(requests: ApiRequestInstance, groupSlug: string) {
|
constructor(requests: ApiRequestInstance, groupSlug: string) {
|
||||||
super(
|
super(
|
||||||
requests,
|
requests,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
@ -38,67 +39,6 @@ export interface QueryFilterJSONPart {
|
||||||
attributeName?: string | null;
|
attributeName?: string | null;
|
||||||
relationalOperator?: RelationalKeyword | RelationalOperator | null;
|
relationalOperator?: RelationalKeyword | RelationalOperator | null;
|
||||||
value?: string | string[] | null;
|
value?: string | string[] | null;
|
||||||
}
|
|
||||||
export interface RecipeCookBook {
|
|
||||||
name: string;
|
|
||||||
description?: string;
|
|
||||||
slug?: string | null;
|
|
||||||
position?: number;
|
|
||||||
public?: boolean;
|
|
||||||
queryFilterString?: string;
|
|
||||||
groupId: string;
|
|
||||||
householdId: string;
|
|
||||||
id: string;
|
|
||||||
queryFilter?: QueryFilterJSON;
|
|
||||||
recipes: RecipeSummary[];
|
|
||||||
}
|
|
||||||
export interface RecipeSummary {
|
|
||||||
id?: string | null;
|
|
||||||
userId?: string;
|
|
||||||
householdId?: string;
|
|
||||||
groupId?: string;
|
|
||||||
name?: string | null;
|
|
||||||
slug?: string;
|
|
||||||
image?: unknown;
|
|
||||||
recipeServings?: number;
|
|
||||||
recipeYieldQuantity?: number;
|
|
||||||
recipeYield?: string | null;
|
|
||||||
totalTime?: string | null;
|
|
||||||
prepTime?: string | null;
|
|
||||||
cookTime?: string | null;
|
|
||||||
performTime?: string | null;
|
|
||||||
description?: string | null;
|
|
||||||
recipeCategory?: RecipeCategory[] | null;
|
|
||||||
tags?: RecipeTag[] | null;
|
|
||||||
tools?: RecipeTool[];
|
|
||||||
rating?: number | null;
|
|
||||||
orgURL?: string | null;
|
|
||||||
dateAdded?: string | null;
|
|
||||||
dateUpdated?: string | null;
|
|
||||||
createdAt?: string | null;
|
|
||||||
updatedAt?: string | null;
|
|
||||||
lastMade?: string | null;
|
|
||||||
}
|
|
||||||
export interface RecipeCategory {
|
|
||||||
id?: string | null;
|
|
||||||
groupId?: string | null;
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
[k: string]: unknown;
|
|
||||||
}
|
|
||||||
export interface RecipeTag {
|
|
||||||
id?: string | null;
|
|
||||||
groupId?: string | null;
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
[k: string]: unknown;
|
|
||||||
}
|
|
||||||
export interface RecipeTool {
|
|
||||||
id: string;
|
|
||||||
groupId?: string | null;
|
|
||||||
name: string;
|
|
||||||
slug: string;
|
|
||||||
householdsWithTool?: string[];
|
|
||||||
[k: string]: unknown;
|
[k: string]: unknown;
|
||||||
}
|
}
|
||||||
export interface SaveCookBook {
|
export interface SaveCookBook {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
/**
|
/**
|
||||||
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
/* This file was automatically generated from pydantic models by running pydantic2ts.
|
||||||
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
/* Do not modify it by hand - just update the pydantic models and then re-run the script
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { BaseCRUDAPI } from "../base/base-clients";
|
import { BaseCRUDAPI } from "../base/base-clients";
|
||||||
import type { CreateCookBook, RecipeCookBook, UpdateCookBook } from "~/lib/api/types/cookbook";
|
import type { CreateCookBook, ReadCookBook, UpdateCookBook } from "~/lib/api/types/cookbook";
|
||||||
|
|
||||||
const prefix = "/api";
|
const prefix = "/api";
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ const routes = {
|
||||||
cookbooksId: (id: number) => `${prefix}/households/cookbooks/${id}`,
|
cookbooksId: (id: number) => `${prefix}/households/cookbooks/${id}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class CookbookAPI extends BaseCRUDAPI<CreateCookBook, RecipeCookBook, UpdateCookBook> {
|
export class CookbookAPI extends BaseCRUDAPI<CreateCookBook, ReadCookBook, UpdateCookBook> {
|
||||||
baseRoute: string = routes.cookbooks;
|
baseRoute: string = routes.cookbooks;
|
||||||
itemRoute = routes.cookbooksId;
|
itemRoute = routes.cookbooksId;
|
||||||
|
|
||||||
|
|
2
frontend/types/components.d.ts
vendored
2
frontend/types/components.d.ts
vendored
|
@ -81,4 +81,4 @@ declare module "vue" {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { };
|
export {};
|
||||||
|
|
|
@ -5,7 +5,7 @@ from pydantic import UUID4
|
||||||
|
|
||||||
from mealie.routes._base import controller
|
from mealie.routes._base import controller
|
||||||
from mealie.routes._base.base_controllers import BasePublicHouseholdExploreController
|
from mealie.routes._base.base_controllers import BasePublicHouseholdExploreController
|
||||||
from mealie.schema.cookbook.cookbook import ReadCookBook, RecipeCookBook
|
from mealie.schema.cookbook.cookbook import ReadCookBook
|
||||||
from mealie.schema.make_dependable import make_dependable
|
from mealie.schema.make_dependable import make_dependable
|
||||||
from mealie.schema.response.pagination import PaginationBase, PaginationQuery
|
from mealie.schema.response.pagination import PaginationBase, PaginationQuery
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ class PublicCookbooksController(BasePublicHouseholdExploreController):
|
||||||
response.set_pagination_guides(self.get_explore_url_path(router.url_path_for("get_all")), q.model_dump())
|
response.set_pagination_guides(self.get_explore_url_path(router.url_path_for("get_all")), q.model_dump())
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@router.get("/{item_id}", response_model=RecipeCookBook)
|
@router.get("/{item_id}", response_model=ReadCookBook)
|
||||||
def get_one(self, item_id: UUID4 | str) -> RecipeCookBook:
|
def get_one(self, item_id: UUID4 | str) -> ReadCookBook:
|
||||||
NOT_FOUND_EXCEPTION = HTTPException(404, "cookbook not found")
|
NOT_FOUND_EXCEPTION = HTTPException(404, "cookbook not found")
|
||||||
if isinstance(item_id, UUID):
|
if isinstance(item_id, UUID):
|
||||||
match_attr = "id"
|
match_attr = "id"
|
||||||
|
@ -58,13 +58,4 @@ class PublicCookbooksController(BasePublicHouseholdExploreController):
|
||||||
if not household or household.preferences.private_household:
|
if not household or household.preferences.private_household:
|
||||||
raise NOT_FOUND_EXCEPTION
|
raise NOT_FOUND_EXCEPTION
|
||||||
|
|
||||||
cross_household_recipes = self.cross_household_repos.recipes
|
return cookbook
|
||||||
recipes = cross_household_recipes.page_all(
|
|
||||||
PaginationQuery(
|
|
||||||
page=1,
|
|
||||||
per_page=-1,
|
|
||||||
query_filter="settings.public = TRUE AND household.preferences.privateHousehold = FALSE",
|
|
||||||
),
|
|
||||||
cookbook=cookbook,
|
|
||||||
)
|
|
||||||
return cookbook.cast(RecipeCookBook, recipes=recipes.items)
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ from mealie.routes._base import BaseCrudController, controller
|
||||||
from mealie.routes._base.mixins import HttpRepo
|
from mealie.routes._base.mixins import HttpRepo
|
||||||
from mealie.routes._base.routers import MealieCrudRoute
|
from mealie.routes._base.routers import MealieCrudRoute
|
||||||
from mealie.schema import mapper
|
from mealie.schema import mapper
|
||||||
from mealie.schema.cookbook import CreateCookBook, ReadCookBook, RecipeCookBook, SaveCookBook, UpdateCookBook
|
from mealie.schema.cookbook import CreateCookBook, ReadCookBook, SaveCookBook, UpdateCookBook
|
||||||
from mealie.schema.cookbook.cookbook import CookBookPagination
|
from mealie.schema.cookbook.cookbook import CookBookPagination
|
||||||
from mealie.schema.response.pagination import PaginationQuery
|
from mealie.schema.response.pagination import PaginationQuery
|
||||||
from mealie.services.event_bus_service.event_types import (
|
from mealie.services.event_bus_service.event_types import (
|
||||||
|
@ -101,7 +101,7 @@ class GroupCookbookController(BaseCrudController):
|
||||||
|
|
||||||
return all_updated
|
return all_updated
|
||||||
|
|
||||||
@router.get("/{item_id}", response_model=RecipeCookBook)
|
@router.get("/{item_id}", response_model=ReadCookBook)
|
||||||
def get_one(self, item_id: UUID4 | str):
|
def get_one(self, item_id: UUID4 | str):
|
||||||
if isinstance(item_id, UUID):
|
if isinstance(item_id, UUID):
|
||||||
match_attr = "id"
|
match_attr = "id"
|
||||||
|
@ -114,12 +114,10 @@ class GroupCookbookController(BaseCrudController):
|
||||||
|
|
||||||
# Allow fetching other households' cookbooks
|
# Allow fetching other households' cookbooks
|
||||||
cookbook = self.group_cookbooks.get_one(item_id, match_attr)
|
cookbook = self.group_cookbooks.get_one(item_id, match_attr)
|
||||||
|
|
||||||
if cookbook is None:
|
if cookbook is None:
|
||||||
raise HTTPException(status_code=404)
|
raise HTTPException(status_code=404)
|
||||||
|
|
||||||
recipe_pagination = self.repos.recipes.page_all(PaginationQuery(page=1, per_page=-1, cookbook=cookbook))
|
return cookbook
|
||||||
return cookbook.cast(RecipeCookBook, recipes=recipe_pagination.items)
|
|
||||||
|
|
||||||
@router.put("/{item_id}", response_model=ReadCookBook)
|
@router.put("/{item_id}", response_model=ReadCookBook)
|
||||||
def update_one(self, item_id: str, data: CreateCookBook):
|
def update_one(self, item_id: str, data: CreateCookBook):
|
||||||
|
|
|
@ -3,11 +3,11 @@ from .datetime_parse import DateError, DateTimeError, DurationError, TimeError
|
||||||
from .mealie_model import HasUUID, MealieModel, SearchType
|
from .mealie_model import HasUUID, MealieModel, SearchType
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"HasUUID",
|
|
||||||
"MealieModel",
|
|
||||||
"SearchType",
|
|
||||||
"DateError",
|
"DateError",
|
||||||
"DateTimeError",
|
"DateTimeError",
|
||||||
"DurationError",
|
"DurationError",
|
||||||
"TimeError",
|
"TimeError",
|
||||||
|
"HasUUID",
|
||||||
|
"MealieModel",
|
||||||
|
"SearchType",
|
||||||
]
|
]
|
||||||
|
|
|
@ -18,10 +18,28 @@ from .restore import (
|
||||||
from .settings import CustomPageBase, CustomPageOut
|
from .settings import CustomPageBase, CustomPageOut
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"MaintenanceLogs",
|
||||||
|
"MaintenanceStorageDetails",
|
||||||
|
"MaintenanceSummary",
|
||||||
"ChowdownURL",
|
"ChowdownURL",
|
||||||
"MigrationFile",
|
"MigrationFile",
|
||||||
"MigrationImport",
|
"MigrationImport",
|
||||||
"Migrations",
|
"Migrations",
|
||||||
|
"CustomPageBase",
|
||||||
|
"CustomPageOut",
|
||||||
|
"CommentImport",
|
||||||
|
"CustomPageImport",
|
||||||
|
"GroupImport",
|
||||||
|
"ImportBase",
|
||||||
|
"NotificationImport",
|
||||||
|
"RecipeImport",
|
||||||
|
"SettingsImport",
|
||||||
|
"UserImport",
|
||||||
|
"AllBackups",
|
||||||
|
"BackupFile",
|
||||||
|
"BackupOptions",
|
||||||
|
"CreateBackup",
|
||||||
|
"ImportJob",
|
||||||
"AdminAboutInfo",
|
"AdminAboutInfo",
|
||||||
"AppInfo",
|
"AppInfo",
|
||||||
"AppStartupInfo",
|
"AppStartupInfo",
|
||||||
|
@ -31,23 +49,5 @@ __all__ = [
|
||||||
"EmailReady",
|
"EmailReady",
|
||||||
"EmailSuccess",
|
"EmailSuccess",
|
||||||
"EmailTest",
|
"EmailTest",
|
||||||
"CustomPageBase",
|
|
||||||
"CustomPageOut",
|
|
||||||
"AllBackups",
|
|
||||||
"BackupFile",
|
|
||||||
"BackupOptions",
|
|
||||||
"CreateBackup",
|
|
||||||
"ImportJob",
|
|
||||||
"MaintenanceLogs",
|
|
||||||
"MaintenanceStorageDetails",
|
|
||||||
"MaintenanceSummary",
|
|
||||||
"DebugResponse",
|
"DebugResponse",
|
||||||
"CommentImport",
|
|
||||||
"CustomPageImport",
|
|
||||||
"GroupImport",
|
|
||||||
"ImportBase",
|
|
||||||
"NotificationImport",
|
|
||||||
"RecipeImport",
|
|
||||||
"SettingsImport",
|
|
||||||
"UserImport",
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
# This file is auto-generated by gen_schema_exports.py
|
# This file is auto-generated by gen_schema_exports.py
|
||||||
from .cookbook import CookBookPagination, CreateCookBook, ReadCookBook, RecipeCookBook, SaveCookBook, UpdateCookBook
|
from .cookbook import CookBookPagination, CreateCookBook, ReadCookBook, SaveCookBook, UpdateCookBook
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"CookBookPagination",
|
"CookBookPagination",
|
||||||
"CreateCookBook",
|
"CreateCookBook",
|
||||||
"ReadCookBook",
|
"ReadCookBook",
|
||||||
"RecipeCookBook",
|
|
||||||
"SaveCookBook",
|
"SaveCookBook",
|
||||||
"UpdateCookBook",
|
"UpdateCookBook",
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,7 +7,6 @@ from slugify import slugify
|
||||||
from mealie.core.root_logger import get_logger
|
from mealie.core.root_logger import get_logger
|
||||||
from mealie.db.models.recipe import RecipeModel
|
from mealie.db.models.recipe import RecipeModel
|
||||||
from mealie.schema._mealie import MealieModel
|
from mealie.schema._mealie import MealieModel
|
||||||
from mealie.schema.recipe.recipe import RecipeSummary
|
|
||||||
from mealie.schema.response.pagination import PaginationBase
|
from mealie.schema.response.pagination import PaginationBase
|
||||||
from mealie.schema.response.query_filter import QueryFilterBuilder, QueryFilterJSON
|
from mealie.schema.response.query_filter import QueryFilterBuilder, QueryFilterJSON
|
||||||
|
|
||||||
|
@ -84,10 +83,3 @@ class ReadCookBook(UpdateCookBook):
|
||||||
|
|
||||||
class CookBookPagination(PaginationBase):
|
class CookBookPagination(PaginationBase):
|
||||||
items: list[ReadCookBook]
|
items: list[ReadCookBook]
|
||||||
|
|
||||||
|
|
||||||
class RecipeCookBook(ReadCookBook):
|
|
||||||
group_id: UUID4
|
|
||||||
household_id: UUID4
|
|
||||||
recipes: list[RecipeSummary]
|
|
||||||
model_config = ConfigDict(from_attributes=True)
|
|
||||||
|
|
|
@ -7,13 +7,13 @@ from .group_seeder import SeederConfig
|
||||||
from .group_statistics import GroupStorage
|
from .group_statistics import GroupStorage
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"GroupAdminUpdate",
|
|
||||||
"GroupStorage",
|
|
||||||
"GroupDataExport",
|
"GroupDataExport",
|
||||||
"SeederConfig",
|
|
||||||
"CreateGroupPreferences",
|
"CreateGroupPreferences",
|
||||||
"ReadGroupPreferences",
|
"ReadGroupPreferences",
|
||||||
"UpdateGroupPreferences",
|
"UpdateGroupPreferences",
|
||||||
|
"GroupStorage",
|
||||||
"DataMigrationCreate",
|
"DataMigrationCreate",
|
||||||
"SupportedMigrations",
|
"SupportedMigrations",
|
||||||
|
"SeederConfig",
|
||||||
|
"GroupAdminUpdate",
|
||||||
]
|
]
|
||||||
|
|
|
@ -70,6 +70,49 @@ from .invite_token import CreateInviteToken, EmailInitationResponse, EmailInvita
|
||||||
from .webhook import CreateWebhook, ReadWebhook, SaveWebhook, WebhookPagination, WebhookType
|
from .webhook import CreateWebhook, ReadWebhook, SaveWebhook, WebhookPagination, WebhookType
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"GroupEventNotifierCreate",
|
||||||
|
"GroupEventNotifierOptions",
|
||||||
|
"GroupEventNotifierOptionsOut",
|
||||||
|
"GroupEventNotifierOptionsSave",
|
||||||
|
"GroupEventNotifierOut",
|
||||||
|
"GroupEventNotifierPrivate",
|
||||||
|
"GroupEventNotifierSave",
|
||||||
|
"GroupEventNotifierUpdate",
|
||||||
|
"GroupEventPagination",
|
||||||
|
"CreateGroupRecipeAction",
|
||||||
|
"GroupRecipeActionOut",
|
||||||
|
"GroupRecipeActionPagination",
|
||||||
|
"GroupRecipeActionPayload",
|
||||||
|
"GroupRecipeActionType",
|
||||||
|
"SaveGroupRecipeAction",
|
||||||
|
"CreateWebhook",
|
||||||
|
"ReadWebhook",
|
||||||
|
"SaveWebhook",
|
||||||
|
"WebhookPagination",
|
||||||
|
"WebhookType",
|
||||||
|
"CreateHouseholdPreferences",
|
||||||
|
"ReadHouseholdPreferences",
|
||||||
|
"SaveHouseholdPreferences",
|
||||||
|
"UpdateHouseholdPreferences",
|
||||||
|
"HouseholdCreate",
|
||||||
|
"HouseholdInDB",
|
||||||
|
"HouseholdPagination",
|
||||||
|
"HouseholdRecipeBase",
|
||||||
|
"HouseholdRecipeCreate",
|
||||||
|
"HouseholdRecipeOut",
|
||||||
|
"HouseholdRecipeSummary",
|
||||||
|
"HouseholdRecipeUpdate",
|
||||||
|
"HouseholdSave",
|
||||||
|
"HouseholdSummary",
|
||||||
|
"HouseholdUserSummary",
|
||||||
|
"UpdateHousehold",
|
||||||
|
"UpdateHouseholdAdmin",
|
||||||
|
"HouseholdStatistics",
|
||||||
|
"CreateInviteToken",
|
||||||
|
"EmailInitationResponse",
|
||||||
|
"EmailInvitation",
|
||||||
|
"ReadInviteToken",
|
||||||
|
"SaveInviteToken",
|
||||||
"ShoppingListAddRecipeParams",
|
"ShoppingListAddRecipeParams",
|
||||||
"ShoppingListAddRecipeParamsBulk",
|
"ShoppingListAddRecipeParamsBulk",
|
||||||
"ShoppingListCreate",
|
"ShoppingListCreate",
|
||||||
|
@ -93,48 +136,5 @@ __all__ = [
|
||||||
"ShoppingListSave",
|
"ShoppingListSave",
|
||||||
"ShoppingListSummary",
|
"ShoppingListSummary",
|
||||||
"ShoppingListUpdate",
|
"ShoppingListUpdate",
|
||||||
"GroupEventNotifierCreate",
|
|
||||||
"GroupEventNotifierOptions",
|
|
||||||
"GroupEventNotifierOptionsOut",
|
|
||||||
"GroupEventNotifierOptionsSave",
|
|
||||||
"GroupEventNotifierOut",
|
|
||||||
"GroupEventNotifierPrivate",
|
|
||||||
"GroupEventNotifierSave",
|
|
||||||
"GroupEventNotifierUpdate",
|
|
||||||
"GroupEventPagination",
|
|
||||||
"CreateGroupRecipeAction",
|
|
||||||
"GroupRecipeActionOut",
|
|
||||||
"GroupRecipeActionPagination",
|
|
||||||
"GroupRecipeActionPayload",
|
|
||||||
"GroupRecipeActionType",
|
|
||||||
"SaveGroupRecipeAction",
|
|
||||||
"CreateHouseholdPreferences",
|
|
||||||
"ReadHouseholdPreferences",
|
|
||||||
"SaveHouseholdPreferences",
|
|
||||||
"UpdateHouseholdPreferences",
|
|
||||||
"SetPermissions",
|
"SetPermissions",
|
||||||
"CreateInviteToken",
|
|
||||||
"EmailInitationResponse",
|
|
||||||
"EmailInvitation",
|
|
||||||
"ReadInviteToken",
|
|
||||||
"SaveInviteToken",
|
|
||||||
"HouseholdStatistics",
|
|
||||||
"CreateWebhook",
|
|
||||||
"ReadWebhook",
|
|
||||||
"SaveWebhook",
|
|
||||||
"WebhookPagination",
|
|
||||||
"WebhookType",
|
|
||||||
"HouseholdCreate",
|
|
||||||
"HouseholdInDB",
|
|
||||||
"HouseholdPagination",
|
|
||||||
"HouseholdRecipeBase",
|
|
||||||
"HouseholdRecipeCreate",
|
|
||||||
"HouseholdRecipeOut",
|
|
||||||
"HouseholdRecipeSummary",
|
|
||||||
"HouseholdRecipeUpdate",
|
|
||||||
"HouseholdSave",
|
|
||||||
"HouseholdSummary",
|
|
||||||
"HouseholdUserSummary",
|
|
||||||
"UpdateHousehold",
|
|
||||||
"UpdateHouseholdAdmin",
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -12,6 +12,9 @@ from .plan_rules import PlanRulesCreate, PlanRulesDay, PlanRulesOut, PlanRulesPa
|
||||||
from .shopping_list import ListItem, ShoppingListIn, ShoppingListOut
|
from .shopping_list import ListItem, ShoppingListIn, ShoppingListOut
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"ListItem",
|
||||||
|
"ShoppingListIn",
|
||||||
|
"ShoppingListOut",
|
||||||
"CreatePlanEntry",
|
"CreatePlanEntry",
|
||||||
"CreateRandomEntry",
|
"CreateRandomEntry",
|
||||||
"PlanEntryPagination",
|
"PlanEntryPagination",
|
||||||
|
@ -19,9 +22,6 @@ __all__ = [
|
||||||
"ReadPlanEntry",
|
"ReadPlanEntry",
|
||||||
"SavePlanEntry",
|
"SavePlanEntry",
|
||||||
"UpdatePlanEntry",
|
"UpdatePlanEntry",
|
||||||
"ListItem",
|
|
||||||
"ShoppingListIn",
|
|
||||||
"ShoppingListOut",
|
|
||||||
"PlanRulesCreate",
|
"PlanRulesCreate",
|
||||||
"PlanRulesDay",
|
"PlanRulesDay",
|
||||||
"PlanRulesOut",
|
"PlanRulesOut",
|
||||||
|
|
|
@ -89,6 +89,35 @@ from .recipe_tool import RecipeToolCreate, RecipeToolOut, RecipeToolResponse, Re
|
||||||
from .request_helpers import RecipeDuplicate, RecipeSlug, RecipeZipTokenResponse, SlugResponse, UpdateImageResponse
|
from .request_helpers import RecipeDuplicate, RecipeSlug, RecipeZipTokenResponse, SlugResponse, UpdateImageResponse
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"IngredientReferences",
|
||||||
|
"RecipeStep",
|
||||||
|
"RecipeNote",
|
||||||
|
"CategoryBase",
|
||||||
|
"CategoryIn",
|
||||||
|
"CategoryOut",
|
||||||
|
"CategorySave",
|
||||||
|
"RecipeCategoryResponse",
|
||||||
|
"RecipeTagResponse",
|
||||||
|
"TagBase",
|
||||||
|
"TagIn",
|
||||||
|
"TagOut",
|
||||||
|
"TagSave",
|
||||||
|
"RecipeAsset",
|
||||||
|
"RecipeTimelineEventCreate",
|
||||||
|
"RecipeTimelineEventIn",
|
||||||
|
"RecipeTimelineEventOut",
|
||||||
|
"RecipeTimelineEventPagination",
|
||||||
|
"RecipeTimelineEventUpdate",
|
||||||
|
"TimelineEventImage",
|
||||||
|
"TimelineEventType",
|
||||||
|
"RecipeSuggestionQuery",
|
||||||
|
"RecipeSuggestionResponse",
|
||||||
|
"RecipeSuggestionResponseItem",
|
||||||
|
"Nutrition",
|
||||||
|
"RecipeShareToken",
|
||||||
|
"RecipeShareTokenCreate",
|
||||||
|
"RecipeShareTokenSave",
|
||||||
|
"RecipeShareTokenSummary",
|
||||||
"CreateIngredientFood",
|
"CreateIngredientFood",
|
||||||
"CreateIngredientFoodAlias",
|
"CreateIngredientFoodAlias",
|
||||||
"CreateIngredientUnit",
|
"CreateIngredientUnit",
|
||||||
|
@ -111,27 +140,13 @@ __all__ = [
|
||||||
"SaveIngredientFood",
|
"SaveIngredientFood",
|
||||||
"SaveIngredientUnit",
|
"SaveIngredientUnit",
|
||||||
"UnitFoodBase",
|
"UnitFoodBase",
|
||||||
"RecipeTimelineEventCreate",
|
|
||||||
"RecipeTimelineEventIn",
|
|
||||||
"RecipeTimelineEventOut",
|
|
||||||
"RecipeTimelineEventPagination",
|
|
||||||
"RecipeTimelineEventUpdate",
|
|
||||||
"TimelineEventImage",
|
|
||||||
"TimelineEventType",
|
|
||||||
"Nutrition",
|
|
||||||
"AssignCategories",
|
|
||||||
"AssignSettings",
|
|
||||||
"AssignTags",
|
|
||||||
"DeleteRecipes",
|
|
||||||
"ExportBase",
|
|
||||||
"ExportRecipes",
|
|
||||||
"ExportTypes",
|
|
||||||
"RecipeCommentCreate",
|
"RecipeCommentCreate",
|
||||||
"RecipeCommentOut",
|
"RecipeCommentOut",
|
||||||
"RecipeCommentPagination",
|
"RecipeCommentPagination",
|
||||||
"RecipeCommentSave",
|
"RecipeCommentSave",
|
||||||
"RecipeCommentUpdate",
|
"RecipeCommentUpdate",
|
||||||
"UserBase",
|
"UserBase",
|
||||||
|
"RecipeSettings",
|
||||||
"CreateRecipe",
|
"CreateRecipe",
|
||||||
"CreateRecipeBulk",
|
"CreateRecipeBulk",
|
||||||
"CreateRecipeByUrlBulk",
|
"CreateRecipeByUrlBulk",
|
||||||
|
@ -145,40 +160,25 @@ __all__ = [
|
||||||
"RecipeTagPagination",
|
"RecipeTagPagination",
|
||||||
"RecipeTool",
|
"RecipeTool",
|
||||||
"RecipeToolPagination",
|
"RecipeToolPagination",
|
||||||
"IngredientReferences",
|
"ScrapeRecipe",
|
||||||
"RecipeStep",
|
"ScrapeRecipeBase",
|
||||||
"RecipeNote",
|
"ScrapeRecipeData",
|
||||||
"RecipeSuggestionQuery",
|
"ScrapeRecipeTest",
|
||||||
"RecipeSuggestionResponse",
|
"AssignCategories",
|
||||||
"RecipeSuggestionResponseItem",
|
"AssignSettings",
|
||||||
"RecipeSettings",
|
"AssignTags",
|
||||||
"RecipeShareToken",
|
"DeleteRecipes",
|
||||||
"RecipeShareTokenCreate",
|
"ExportBase",
|
||||||
"RecipeShareTokenSave",
|
"ExportRecipes",
|
||||||
"RecipeShareTokenSummary",
|
"ExportTypes",
|
||||||
"RecipeAsset",
|
"RecipeToolCreate",
|
||||||
|
"RecipeToolOut",
|
||||||
|
"RecipeToolResponse",
|
||||||
|
"RecipeToolSave",
|
||||||
|
"RecipeImageTypes",
|
||||||
"RecipeDuplicate",
|
"RecipeDuplicate",
|
||||||
"RecipeSlug",
|
"RecipeSlug",
|
||||||
"RecipeZipTokenResponse",
|
"RecipeZipTokenResponse",
|
||||||
"SlugResponse",
|
"SlugResponse",
|
||||||
"UpdateImageResponse",
|
"UpdateImageResponse",
|
||||||
"RecipeToolCreate",
|
|
||||||
"RecipeToolOut",
|
|
||||||
"RecipeToolResponse",
|
|
||||||
"RecipeToolSave",
|
|
||||||
"CategoryBase",
|
|
||||||
"CategoryIn",
|
|
||||||
"CategoryOut",
|
|
||||||
"CategorySave",
|
|
||||||
"RecipeCategoryResponse",
|
|
||||||
"RecipeTagResponse",
|
|
||||||
"TagBase",
|
|
||||||
"TagIn",
|
|
||||||
"TagOut",
|
|
||||||
"TagSave",
|
|
||||||
"ScrapeRecipe",
|
|
||||||
"ScrapeRecipeBase",
|
|
||||||
"ScrapeRecipeData",
|
|
||||||
"ScrapeRecipeTest",
|
|
||||||
"RecipeImageTypes",
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -28,14 +28,14 @@ __all__ = [
|
||||||
"QueryFilterJSONPart",
|
"QueryFilterJSONPart",
|
||||||
"RelationalKeyword",
|
"RelationalKeyword",
|
||||||
"RelationalOperator",
|
"RelationalOperator",
|
||||||
"SearchFilter",
|
"ValidationResponse",
|
||||||
"OrderByNullPosition",
|
"OrderByNullPosition",
|
||||||
"OrderDirection",
|
"OrderDirection",
|
||||||
"PaginationBase",
|
"PaginationBase",
|
||||||
"PaginationQuery",
|
"PaginationQuery",
|
||||||
"RecipeSearchQuery",
|
"RecipeSearchQuery",
|
||||||
"RequestQuery",
|
"RequestQuery",
|
||||||
"ValidationResponse",
|
"SearchFilter",
|
||||||
"ErrorResponse",
|
"ErrorResponse",
|
||||||
"FileTokenResponse",
|
"FileTokenResponse",
|
||||||
"SuccessResponse",
|
"SuccessResponse",
|
||||||
|
|
|
@ -38,6 +38,12 @@ from .user_passwords import (
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
"ForgotPassword",
|
||||||
|
"PasswordResetToken",
|
||||||
|
"PrivatePasswordResetToken",
|
||||||
|
"ResetPassword",
|
||||||
|
"SavePasswordResetToken",
|
||||||
|
"ValidateResetToken",
|
||||||
"CredentialsRequest",
|
"CredentialsRequest",
|
||||||
"CredentialsRequestForm",
|
"CredentialsRequestForm",
|
||||||
"Token",
|
"Token",
|
||||||
|
@ -69,10 +75,4 @@ __all__ = [
|
||||||
"UserRatings",
|
"UserRatings",
|
||||||
"UserSummary",
|
"UserSummary",
|
||||||
"UserSummaryPagination",
|
"UserSummaryPagination",
|
||||||
"ForgotPassword",
|
|
||||||
"PasswordResetToken",
|
|
||||||
"PrivatePasswordResetToken",
|
|
||||||
"ResetPassword",
|
|
||||||
"SavePasswordResetToken",
|
|
||||||
"ValidateResetToken",
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -217,13 +217,14 @@ def test_get_cookbooks_with_recipes(api_client: TestClient, unique_user: TestUse
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get the cookbook and make sure we only get the public recipes from each household
|
# Get the cookbook recipes and make sure we only get the public recipes from each household
|
||||||
response = api_client.get(api_routes.explore_groups_group_slug_cookbooks_item_id(unique_user.group_id, cookbook.id))
|
response = api_client.get(
|
||||||
|
api_routes.explore_groups_group_slug_recipes(unique_user.group_id), params={"cookbook": cookbook.slug}
|
||||||
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
cookbook_data = response.json()
|
recipe_data = response.json()
|
||||||
assert cookbook_data["id"] == str(cookbook.id)
|
|
||||||
|
|
||||||
cookbook_recipe_ids: set[str] = {recipe["id"] for recipe in cookbook_data["recipes"]}
|
cookbook_recipe_ids: set[str] = {recipe["id"] for recipe in recipe_data["items"]}
|
||||||
assert len(cookbook_recipe_ids) == 2
|
assert len(cookbook_recipe_ids) == 2
|
||||||
assert str(public_recipe.id) in cookbook_recipe_ids
|
assert str(public_recipe.id) in cookbook_recipe_ids
|
||||||
assert str(private_recipe.id) not in cookbook_recipe_ids
|
assert str(private_recipe.id) not in cookbook_recipe_ids
|
||||||
|
@ -297,13 +298,14 @@ def test_get_cookbooks_private_household(api_client: TestClient, unique_user: Te
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get the cookbook and make sure we only get the public recipes from each household
|
# Get the cookbook recipes and make sure we only get the public recipes from each household
|
||||||
response = api_client.get(api_routes.explore_groups_group_slug_cookbooks_item_id(unique_user.group_id, cookbook.id))
|
response = api_client.get(
|
||||||
|
api_routes.explore_groups_group_slug_recipes(unique_user.group_id), params={"cookbook": cookbook.slug}
|
||||||
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
cookbook_data = response.json()
|
recipe_data = response.json()
|
||||||
assert cookbook_data["id"] == str(cookbook.id)
|
|
||||||
|
|
||||||
cookbook_recipe_ids: set[str] = {recipe["id"] for recipe in cookbook_data["recipes"]}
|
cookbook_recipe_ids: set[str] = {recipe["id"] for recipe in recipe_data["items"]}
|
||||||
assert len(cookbook_recipe_ids) == 1
|
assert len(cookbook_recipe_ids) == 1
|
||||||
assert str(public_recipe.id) in cookbook_recipe_ids
|
assert str(public_recipe.id) in cookbook_recipe_ids
|
||||||
assert str(other_household_private_recipe.id) not in cookbook_recipe_ids
|
assert str(other_household_private_recipe.id) not in cookbook_recipe_ids
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue