feat: add user recipe export functionality (#845)

* feat(frontend):  add user recipe export functionality

* remove depreciated folders

* change/remove depreciated folders

* add testing variable in config

* add GUID support for group_id

* improve testing feedback on 422 errors

* remove/cleanup files/folders

* initial user export support

* delete unused css

* update backup page UI

* remove depreciated settings

* feat:  export download links

* fix #813

* remove top level statements

* show footer

* add export purger to scheduler

* update purge glob

* fix meal-planner lockout

* feat:  add bulk delete/purge exports

* style(frontend): 💄 update UI for site settings

* feat:  add version checker

* update documentation

Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
Hayden
2021-12-04 14:18:46 -09:00
committed by GitHub
parent 2ce195a0d4
commit c32d7d7486
84 changed files with 1329 additions and 667 deletions

View File

@@ -3,10 +3,12 @@ from __future__ import annotations
from pathlib import Path
from mealie.core.root_logger import get_logger
from mealie.schema.group.group_exports import GroupDataExport
from mealie.schema.recipe import CategoryBase, Recipe
from mealie.schema.recipe.recipe_category import TagBase
from mealie.services._base_http_service.http_services import UserHttpService
from mealie.services.events import create_recipe_event
from mealie.services.exporter import Exporter, RecipeExporter
logger = get_logger(__name__)
@@ -18,8 +20,36 @@ class RecipeBulkActions(UserHttpService[int, Recipe]):
def populate_item(self, _: int) -> Recipe:
return
def export_recipes(self, temp_path: Path, recipes: list[str]) -> None:
return
def export_recipes(self, temp_path: Path, slugs: list[str]) -> None:
recipe_exporter = RecipeExporter(self.db, self.group_id, slugs)
exporter = Exporter(self.group_id, temp_path, [recipe_exporter])
exporter.run(self.db)
def get_exports(self) -> list[GroupDataExport]:
return self.db.group_exports.multi_query({"group_id": self.group_id})
def purge_exports(self) -> int:
all_exports = self.get_exports()
exports_deleted = 0
for export in all_exports:
try:
Path(export.path).unlink(missing_ok=True)
self.db.group_exports.delete(export.id)
exports_deleted += 1
except Exception as e:
logger.error(f"Failed to delete export {export.id}")
logger.error(e)
group = self.db.groups.get_one(self.group_id)
for match in group.directory.glob("**/export/*zip"):
if match.is_file():
match.unlink()
exports_deleted += 1
return exports_deleted
def assign_tags(self, recipes: list[str], tags: list[TagBase]) -> None:
for slug in recipes:

View File

@@ -59,14 +59,18 @@ class RecipeService(CrudHttpMixins[CreateRecipe, Recipe, Recipe], UserHttpServic
if not self.item.settings.public and not self.user:
raise HTTPException(status.HTTP_403_FORBIDDEN)
def get_all(self, start=0, limit=None):
items = self.db.recipes.summary(self.user.group_id, start=start, limit=limit)
def get_all(self, start=0, limit=None, load_foods=False) -> list[RecipeSummary]:
items = self.db.recipes.summary(self.user.group_id, start=start, limit=limit, load_foods=load_foods)
new_items = []
for item in items:
# Pydantic/FastAPI can't seem to serialize the ingredient field on thier own.
new_item = item.__dict__
new_item["recipe_ingredient"] = [x.__dict__ for x in item.recipe_ingredient]
if load_foods:
new_item["recipe_ingredient"] = [x.__dict__ for x in item.recipe_ingredient]
new_items.append(new_item)
return [RecipeSummary.construct(**x) for x in new_items]