From 18b2c92a762afb91507a3e9ba89dc6b742c4a4a8 Mon Sep 17 00:00:00 2001 From: Hayden <64056131+hay-kot@users.noreply.github.com> Date: Sun, 28 Aug 2022 20:08:33 -0800 Subject: [PATCH] feat: public recipe access (#1610) * initial public explorer API endpoint * public API endpoint * cleanup recipe page * wip: init explorer page * use public URLs for shared recipes * refactor private share tokens to use shared page --- .../api/class-interfaces/recipes/recipe.ts | 16 +- frontend/api/public-api.ts | 6 + frontend/api/public/explore.ts | 14 + frontend/api/public/shared.ts | 14 + .../Domain/Recipe/RecipeActionMenu.vue | 53 +-- .../components/Domain/Recipe/RecipeCard.vue | 1 + .../Domain/Recipe/RecipeCardMobile.vue | 1 + .../Domain/Recipe/RecipeContextMenu.vue | 44 +- .../Domain/Recipe/RecipeDialogShare.vue | 3 +- .../Domain/Recipe/RecipePage/RecipePage.vue | 7 +- .../RecipePageParts/RecipePageHeader.vue | 20 +- .../RecipePageIngredientToolsView.vue | 15 +- .../composables/recipes/use-recipe-meta.ts | 10 +- frontend/composables/use-copy.ts | 16 +- frontend/lang/messages/en-US.json | 3 +- .../pages/explore/recipes/_groupId/_slug.vue | 50 +++ frontend/pages/group/mealplan/planner.vue | 1 + frontend/pages/recipe/_slug/index.vue | 8 +- frontend/pages/shared/recipes/_id.vue | 400 ++---------------- mealie/routes/__init__.py | 17 +- mealie/routes/explore/__init__.py | 7 + .../explore/controller_public_recipes.py | 25 ++ mealie/routes/recipe/shared_routes.py | 5 +- .../public_recipe_tests.py | 62 +++ 24 files changed, 361 insertions(+), 437 deletions(-) create mode 100644 frontend/api/public/explore.ts create mode 100644 frontend/api/public/shared.ts create mode 100644 frontend/pages/explore/recipes/_groupId/_slug.vue create mode 100644 mealie/routes/explore/__init__.py create mode 100644 mealie/routes/explore/controller_public_recipes.py create mode 100644 tests/integration_tests/public_explorer_tests/public_recipe_tests.py diff --git a/frontend/api/class-interfaces/recipes/recipe.ts b/frontend/api/class-interfaces/recipes/recipe.ts index 957f37675983..2f305b7ff6c7 100644 --- a/frontend/api/class-interfaces/recipes/recipe.ts +++ b/frontend/api/class-interfaces/recipes/recipe.ts @@ -2,7 +2,15 @@ import { CommentsApi } from "./recipe-comments"; import { RecipeShareApi } from "./recipe-share"; import { BaseCRUDAPI } from "~/api/_base"; -import { Recipe, CreateRecipe, RecipeAsset, CreateRecipeByUrlBulk, ParsedIngredient, UpdateImageResponse, RecipeZipTokenResponse } from "~/types/api-types/recipe"; +import { + Recipe, + CreateRecipe, + RecipeAsset, + CreateRecipeByUrlBulk, + ParsedIngredient, + UpdateImageResponse, + RecipeZipTokenResponse, +} from "~/types/api-types/recipe"; import { ApiRequestInstance } from "~/types/api"; export type Parser = "nlp" | "brute"; @@ -35,8 +43,6 @@ const routes = { recipesSlugComments: (slug: string) => `${prefix}/recipes/${slug}/comments`, recipesSlugCommentsId: (slug: string, id: number) => `${prefix}/recipes/${slug}/comments/${id}`, - - recipeShareToken: (token: string) => `${prefix}/recipes/shared/${token}`, }; export class RecipeAPI extends BaseCRUDAPI { @@ -110,8 +116,4 @@ export class RecipeAPI extends BaseCRUDAPI { getZipRedirectUrl(recipeSlug: string, token: string) { return `${routes.recipesRecipeSlugExportZip(recipeSlug)}?token=${token}`; } - - async getShared(item_id: string) { - return await this.requests.get(routes.recipeShareToken(item_id)); - } } diff --git a/frontend/api/public-api.ts b/frontend/api/public-api.ts index d6f691db91f2..584c966f15e8 100644 --- a/frontend/api/public-api.ts +++ b/frontend/api/public-api.ts @@ -1,11 +1,17 @@ import { ValidatorsApi } from "./public/validators"; +import { ExploreApi } from "./public/explore"; +import { SharedApi } from "./public/shared"; import { ApiRequestInstance } from "~/types/api"; export class PublicApi { public validators: ValidatorsApi; + public explore: ExploreApi; + public shared: SharedApi; constructor(requests: ApiRequestInstance) { this.validators = new ValidatorsApi(requests); + this.explore = new ExploreApi(requests); + this.shared = new SharedApi(requests); Object.freeze(this); } diff --git a/frontend/api/public/explore.ts b/frontend/api/public/explore.ts new file mode 100644 index 000000000000..2ef463e5acaf --- /dev/null +++ b/frontend/api/public/explore.ts @@ -0,0 +1,14 @@ +import { BaseAPI } from "../_base"; +import { Recipe } from "~/types/api-types/recipe"; + +const prefix = "/api"; + +const routes = { + recipe: (groupId: string, recipeSlug: string) => `${prefix}/explore/recipes/${groupId}/${recipeSlug}`, +}; + +export class ExploreApi extends BaseAPI { + async recipe(groupId: string, recipeSlug: string) { + return await this.requests.get(routes.recipe(groupId, recipeSlug)); + } +} diff --git a/frontend/api/public/shared.ts b/frontend/api/public/shared.ts new file mode 100644 index 000000000000..dc0b19c430e3 --- /dev/null +++ b/frontend/api/public/shared.ts @@ -0,0 +1,14 @@ +import { BaseAPI } from "../_base"; +import { Recipe } from "~/types/api-types/recipe"; + +const prefix = "/api"; + +const routes = { + recipeShareToken: (token: string) => `${prefix}/recipes/shared/${token}`, +}; + +export class SharedApi extends BaseAPI { + async getShared(item_id: string) { + return await this.requests.get(routes.recipeShareToken(item_id)); + } +} diff --git a/frontend/components/Domain/Recipe/RecipeActionMenu.vue b/frontend/components/Domain/Recipe/RecipeActionMenu.vue index 6781ec08213e..3679832f9187 100644 --- a/frontend/components/Domain/Recipe/RecipeActionMenu.vue +++ b/frontend/components/Domain/Recipe/RecipeActionMenu.vue @@ -21,7 +21,7 @@
- +