meal migration

This commit is contained in:
Hayden 2021-01-11 13:23:39 -09:00
commit 74ff14ae73
7 changed files with 141 additions and 119 deletions

View file

@ -51,8 +51,9 @@ export default {
async update(data) {
const recipeSlug = data.slug;
apiReq.post(recipeURLs.update(recipeSlug), data);
let response = await apiReq.post(recipeURLs.update(recipeSlug), data);
store.dispatch("requestRecentRecipes");
return response.data;
},
async delete(recipeSlug) {

View file

@ -130,7 +130,7 @@ export default {
api.recipes.delete(this.recipeDetails.slug);
},
async saveRecipe() {
await api.recipes.update(this.recipeDetails);
let slug = await api.recipes.update(this.recipeDetails);
if (this.fileObject) {
await api.recipes.updateImage(this.recipeDetails.slug, this.fileObject);
@ -138,6 +138,7 @@ export default {
this.form = false;
this.imageKey += 1;
this.$router.push(`/recipe/${slug}`);
},
showForm() {
this.form = true;

View file

@ -1,30 +1,33 @@
{
"@context": "http://schema.org",
"@type": "Recipe",
"articleBody": "In this brothy beans recipe, caramelizing fennel, shallots, and lemon builds a base layer that is sweet, tangy, and bright. Tinned sardines add briney flavor (and protein!)\u2014leave them whole or break them up and fold them into the soup. \u00a0And chopped celery or mushrooms work just as well as fennel if you want to swap. This recipe is part of the 2021\u00a0Feel Good Food Plan, our eight-day dinner plan for starting the year off right.",
"alternativeHeadline": "Tinned sardines add briney flavor (and protein!)\u2014leave them whole or break them up and fold them into the soup.",
"dateModified": "2021-01-10 13:22:02.933000",
"articleBody": "With plenty of protein, a double punch of acid from citrus and vinegar, and a garlicky chili oil, this salad is made for dinner. While your chicken is getting toasty in the oven, make your chile crisp-inspired dressing with garlic, paprika, cracked coriander, and red pepper flakes. If you have leftovers (or want to make extra for a bit of meal prep), keep all of your ingredients separate in the fridge so that they stay fresher for longer. \u00a0This recipe is part of the 2021\u00a0Feel Good Food Plan, our eight-day dinner plan for starting the year off right.",
"alternativeHeadline": "With plenty of protein, a double punch of acid from citrus and vinegar, and a garlicky chili oil, this salad is made for dinner.",
"dateModified": "2021-01-11 11:51:19.699000",
"datePublished": "2021-01-01 06:00:00",
"keywords": [
"recipes",
"healthyish",
"fennel",
"lemon",
"olive oil",
"shallot",
"garlic",
"herb",
"white wine",
"chicken broth",
"cannellini beans",
"sardine",
"parsley",
"salad",
"chicken recipes",
"kosher salt",
"pepper",
"olive oil",
"garlic",
"paprika",
"coriander",
"endive",
"radicchio",
"blood orange",
"orange",
"vinegar",
"red wine vinegar",
"sesame seed",
"feel good food plan",
"feel good food plan 2021",
"web"
],
"thumbnailUrl": "https://assets.bonappetit.com/photos/5fdbe3ac045c6b67ead1938c/1:1/w_2880,h_2880,c_limit/BA0221feelgood06_web.jpg",
"thumbnailUrl": "https://assets.bonappetit.com/photos/5fdbe110607088d75a57bc54/1:1/w_3142,h_3142,c_limit/BA0221coverfinal01_rev.jpg",
"publisher": {
"@context": "https://schema.org",
"@type": "Organization",
@ -54,52 +57,51 @@
],
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": 4.1,
"ratingValue": 4.89,
"ratingCount": 12
},
"description": "Tinned sardines add briney flavor (and protein!)\u2014leave them whole or break them up and fold them into the soup.",
"image": "braised-beans-and-sardines-with-fennel.jpg",
"headline": "Braised Beans and Sardines With Fennel",
"name": "Braised Beans and Sardines With Fennel",
"description": "With plenty of protein, a double punch of acid from citrus and vinegar, and a garlicky chili oil, this salad is made for dinner.",
"image": "chicken-salad-with-citrus-and-chile-oil.jpg",
"headline": "Chicken Salad With Citrus and Chile Oil",
"name": "Chicken Salad With Citrus and Chile Oil",
"recipeIngredient": [
"1 fennel bulb with fronds, stalks and fronds removed",
"1 lemon, halved",
"\u00bc cup extra-virgin olive oil",
"2 medium shallots, thinly sliced",
"6 garlic cloves, thinly sliced",
"Small handful of mixed hardy herb sprigs (such as bay leaves, thyme, and/or rosemary)",
"3 skin-on, bone-in chicken breasts\u00a0 (about 1\u00bd lb. total)",
"Kosher salt, freshly ground pepper",
"2 Tbsp. plus \u2153 cup extra-virgin olive oil",
"3 garlic cloves, thinly sliced",
"2 tsp. paprika",
"1 tsp. coriander seeds, coarsely\u00a0crushed",
"\u00bd tsp. crushed red pepper flakes",
"\u00bc cup dry white wine",
"6 cups low-sodium chicken broth",
"2 15-oz. cans cannellini (white kidney) or cranberry beans, rinsed1 4.4-oz. tin oil-packed sardines, drained",
"1 (loosely packed) cup very coarsely chopped parsley",
"Kosher salt",
"Toasted seeded bread (for serving)"
"2 medium endive, leaves separated",
"1 large head of radicchio, leaves\u00a0 separated, torn if large",
"4 satsumas or blood oranges or 3 medium oranges, peeled, sliced into rounds, seeds removed",
"2 Tbsp. white wine vinegar or red wine vinegar",
"2 tsp. toasted sesame seeds, lightly crushed"
],
"recipeInstructions": [
{
"text": "Slice fennel bulb in half lengthwise and cut each half lengthwise into 3 wedges. Thinly slice 1 lemon half into rounds and wriggle out and discard any seeds; leave remaining half intact and set aside."
"text": "Preheat oven to 450\u00b0. Pat chicken breasts dry with paper towels; season on all sides with salt and pepper, then rub with 2 Tbsp. oil."
},
{
"text": "Heat oil in a medium pot over medium-high. Add fennel, shallots, garlic, hardy herbs, lemon rounds, and red pepper flakes and cook, stirring occasionally, until fennel and lemon are softened slightly and golden brown in spots, 5\u20137 minutes."
"text": "Heat a large ovenproof skillet over medium-high. Arrange chicken, skin side down, in pan and cook, undisturbed, until skin is deep golden brown, about 3 minutes. Turn chicken over with tongs and transfer skillet to oven. Roast chicken until cooked all the way through, 15\u201317 minutes. Transfer to a cutting board and let cool 10 minutes."
},
{
"text": "Using tongs, transfer lemon rounds to a small bowl; set aside. Add wine to pot and cook until reduced by half, about\u00a0 2 minutes. Pour in broth and bring to a boil. Reduce heat to medium-low and simmer, stirring occasionally, until fennel is tender, about 5 minutes. Add beans and simmer until beans soak up some of the broth and are warmed through, 8\u201310 minutes."
"text": "Meanwhile, cook garlic and remaining \u2153 cup oil in a small skillet over medium heat, stirring occasionally, until garlic is fragrant and pale golden, about 4 minutes. Immediately pour garlic oil into a small bowl and stir in paprika, coriander seeds, and red pepper flakes; season with salt."
},
{
"text": "Meanwhile, working one at a time, slice open each sardine with the tip of a paring knife and remove any visible bones; discard. Separate fillets from one another and place in a small bowl. Squeeze juice from remaining reserved lemon half over fillets."
"text": "Cut chicken off the bone, then slice\u00a0 \u00bd\" thick; discard bones."
},
{
"text": "Fish out and discard any hardy herbs and stems you can from braise. Stir in parsley; taste and season broth with more salt if needed."
"text": "Toss endive, radicchio, and satsumas with vinegar and half of spiced garlic oil in a large bowl to combine; season salad with salt and pepper."
},
{
"text": "Divide braise among bowls; top with reserved lemon slices and sardines. Serve with bread alongside."
"text": "Divide salad among plates or shallow bowls; top with chicken and drizzle with more spiced garlic oil. Sprinkle sesame seeds over."
}
],
"recipeYield": "4 servings",
"url": "https://www.bonappetit.com/recipe/braised-beans-and-sardines-with-fennel",
"slug": "braised-beans-and-sardines-with-fennel",
"orgURL": "https://www.bonappetit.com/recipe/braised-beans-and-sardines-with-fennel",
"url": "https://www.bonappetit.com/recipe/chicken-salad-with-citrus-and-chile-oil",
"slug": "chicken-salad-with-citrus-and-chile-oil",
"orgURL": "https://www.bonappetit.com/recipe/chicken-salad-with-citrus-and-chile-oil",
"categories": [],
"tags": [],
"dateAdded": null,

View file

@ -1,9 +1,10 @@
import json
from typing import List
import mongoengine
from settings import USE_MONGO, USE_TINYDB
from db.mongo.meal_models import MealPlanDocument
from db.mongo.meal_models import MealDocument, MealPlanDocument
from db.mongo.recipe_models import RecipeDocument
from db.mongo.settings_models import SiteSettingsDocument, SiteThemeDocument
from db.tinydb.baseclass import StoreBase
@ -44,25 +45,48 @@ class BaseDocument:
def __init__(self) -> None:
self.primary_key: str
self.store: StoreBase
self._document: mongoengine.Document
self.document: mongoengine.Document
@staticmethod
def _unpack_mongo(document) -> dict:
document = json.loads(document.to_json())
del document["_id"]
# Recipe Cleanup
try:
document["dateAdded"] = document["dateAdded"]["$date"]
except:
pass
try:
document["uid"] = document["uid"]["$uuid"]
except:
pass
# Meal Plan
try:
document["startDate"] = document["startDate"]["$date"]
document["endDate"] = document["endDate"]["$date"]
meals = []
for meal in document["meals"]:
meal["date"] = meal["date"]["$date"]
meals.append(meal)
document["meals"] = meals
except:
pass
return document
def get_all(self, limit: int = None, order_by: str = "dateAdded") -> list[dict]:
if USE_MONGO:
documents = self._document.objects.order_by(str(order_by)).limit(limit)
documents = self.document.objects.order_by(str(order_by)).limit(limit)
docs = []
for item in documents:
doc = BaseDocument._unpack_mongo(item)
docs.append(doc)
if limit == 1:
return docs[0]
return docs
elif USE_TINYDB:
@ -70,7 +94,7 @@ class BaseDocument:
def get(self, match_value: str, match_key: str = None, limit=1) -> dict:
if USE_MONGO:
document = self._document.objects.get(**{str(match_key): match_value})
document = self.document.objects.get(**{str(match_key): match_value})
return BaseDocument._unpack_mongo(document)
elif USE_TINYDB:
@ -78,17 +102,15 @@ class BaseDocument:
def save_new(self, document: dict) -> str:
if USE_MONGO:
new_document = self._document(**document)
new_document = self.document(**document)
new_document.save()
return new_document.slug
return new_document
elif USE_TINYDB:
return self.store.save(document)
def delete(self, primary_key) -> dict:
if USE_MONGO:
document = self._document.objects.get(
**{str(self.primary_key): primary_key}
)
document = self.document.objects.get(**{str(self.primary_key): primary_key})
if document:
document.delete()
@ -109,11 +131,11 @@ class Database:
self.primary_key = "slug"
if USE_TINYDB:
self.store = tiny_db.recipes
self._document = RecipeDocument
self.document = RecipeDocument
def update(self, slug: str, new_data: dict) -> None:
if USE_MONGO:
document = self._document.objects.get(slug=slug)
document = self.document.objects.get(slug=slug)
if document:
document.update(set__name=new_data.get("name"))
@ -128,6 +150,7 @@ class Database:
)
document.update(set__totalTime=new_data.get("totalTime"))
document.update(set__slug=new_data.get("slug"))
document.update(set__categories=new_data.get("categories"))
document.update(set__tags=new_data.get("tags"))
document.update(set__notes=new_data.get("notes"))
@ -135,12 +158,15 @@ class Database:
document.update(set__rating=new_data.get("rating"))
document.update(set__extras=new_data.get("extras"))
document.save()
return new_data.get("slug")
elif USE_TINYDB:
self.store.update_doc(slug, new_data)
return new_data.get("slug")
def update_image(self, slug: str, extension: str) -> None:
if USE_MONGO:
document = self._document.objects.get(slug=slug)
document = self.document.objects.get(slug=slug)
if document:
document.update(set__image=f"{slug}.{extension}")
@ -154,19 +180,35 @@ class Database:
self.store = tiny_db.meals
self.document = MealPlanDocument
def update(self, key: str, new_data: dict) -> dict:
def update(self, uid: str, new_meals: List[MealDocument]) -> dict:
if USE_MONGO:
pass
document = self.document.objects.get(uid=uid)
if document:
document.update(set__meals=new_meals)
document.save()
elif USE_TINYDB:
pass
class _Settings(BaseDocument):
def __init__(self) -> None:
self.primary_key = "name"
if USE_TINYDB:
self.store = tiny_db.settings
self.document = SiteSettingsDocument
def save_new(self, main: dict, webhooks: dict) -> str:
if USE_MONGO:
new_doc = self.document(**main)
return new_doc.save()
elif USE_TINYDB:
main["webhooks"] = webhooks
return self.store.save(main)
def update(self, key: str, new_data: dict) -> dict:
if USE_MONGO:
pass

View file

@ -98,11 +98,11 @@ def update_recipe_image(
@router.post("/api/recipe/{recipe_slug}/update/", tags=["Recipes"])
async def update_recipe(recipe_slug: str, data: Recipe):
""" Updates a recipe by existing slug and data. Data should containt """
""" Updates a recipe by existing slug and data. """
data.update(recipe_slug)
new_slug = data.update(recipe_slug)
return {"message": "PLACEHOLDER"}
return new_slug
@router.delete("/api/recipe/{recipe_slug}/delete/", tags=["Recipes"])

View file

@ -3,7 +3,8 @@ from datetime import date, timedelta
from pathlib import Path
from typing import List, Optional
from db.mongo.meal_models import MealDocument, MealPlanDocument
from db.db_setup import db
from db.mongo.meal_models import MealDocument
from pydantic import BaseModel
from services.recipe_services import Recipe
@ -80,6 +81,7 @@ class MealPlan(BaseModel):
self.meals = meals
def save_to_db(self):
meal_docs = []
for meal in self.meals:
meal = meal.dict()
@ -87,22 +89,16 @@ class MealPlan(BaseModel):
meal_docs.append(meal_doc)
self.meals = meal_docs
meal_plan = MealPlanDocument(**self.dict())
meal_plan.save()
db.meals.save_new(self.dict())
@staticmethod
def get_all() -> List:
all_meals = []
for plan in MealPlanDocument.objects.order_by("startDate"):
all_meals.append(MealPlan._unpack_doc(plan))
print(all_meals)
all_meals = [MealPlan(**x) for x in db.meals.get_all(order_by="startDate")]
return all_meals
def update(self, uid):
document = MealPlanDocument.objects.get(uid=uid)
meal_docs = []
for meal in self.meals:
@ -110,43 +106,24 @@ class MealPlan(BaseModel):
meal_doc = MealDocument(**meal)
meal_docs.append(meal_doc)
self.meals = meal_docs
if document:
document.update(set__meals=self.meals)
document.save()
db.meals.update(uid, meal_docs)
@staticmethod
def delete(uid):
document = MealPlanDocument.objects.get(uid=uid)
if document:
document.delete()
@staticmethod
def _unpack_doc(document: MealPlanDocument):
meal_plan = json.loads(document.to_json())
del meal_plan["_id"]["$oid"]
print(meal_plan)
meal_plan["uid"] = meal_plan["uid"]["$uuid"]
meal_plan["startDate"] = meal_plan["startDate"]["$date"]
meal_plan["endDate"] = meal_plan["endDate"]["$date"]
meals = []
for meal in meal_plan["meals"]:
meal["date"] = meal["date"]["$date"]
meals.append(Meal(**meal))
meal_plan["meals"] = meals
return MealPlan(**meal_plan)
db.meals.delete(uid)
@staticmethod
def today() -> str:
""" Returns the meal slug for Today """
meal_plan = MealPlanDocument.objects.order_by("startDate").limit(1)
meal_plan = MealPlan._unpack_doc(meal_plan[0])
meal_plan = db.meals.get_all(limit=1, order_by="startDate")
for meal in meal_plan.meals:
meal_docs = []
for meal in meal_plan["meals"]:
print(meal)
meal_doc = Meal(**meal)
meal_docs.append(meal_doc)
for meal in meal_docs:
if meal.date == date.today():
return meal.slug
@ -154,7 +131,6 @@ class MealPlan(BaseModel):
@staticmethod
def this_week():
meal_plan = MealPlanDocument.objects.order_by("startDate").limit(1)
meal_plan = MealPlan._unpack_doc(meal_plan[0])
meal_plan = db.meals.get_all(limit=1, order_by="startDate")
return meal_plan

View file

@ -4,7 +4,6 @@ from pathlib import Path
from typing import Any, List, Optional
from db.db_setup import db
from db.mongo.recipe_models import RecipeDocument
from pydantic import BaseModel, validator
from slugify import slugify
@ -93,12 +92,12 @@ class Recipe(BaseModel):
return cls(**document)
@classmethod
def get_by_slug(_cls, slug: str):
""" Returns a recipe dictionary from the slug """
def get_by_slug(cls, slug: str):
""" Returns a Recipe Object by Slug """
document = db.recipes.get(slug, "slug")
return document
return cls(**document)
def save_to_db(self) -> str:
recipe_dict = self.dict()
@ -115,9 +114,9 @@ class Recipe(BaseModel):
except:
pass
recipe_slug = db.recipes.save_new(recipe_dict)
recipe_doc = db.recipes.save_new(recipe_dict)
return recipe_slug
return recipe_doc.slug
@staticmethod
def delete(recipe_slug: str) -> str:
@ -128,7 +127,8 @@ class Recipe(BaseModel):
def update(self, recipe_slug: str):
""" Updates the recipe from the database by slug"""
db.recipes.update(recipe_slug, self.dict())
updated_slug = db.recipes.update(recipe_slug, self.dict())
return updated_slug
@staticmethod
def update_image(slug: str, extension: str):