Coverage for opt/mealie/lib/python3.12/site-packages/mealie/repos/repository_cookbooks.py: 71%
49 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 03:04 +0000
1import re
2from collections.abc import Iterable
4from fastapi import HTTPException, status
5from pydantic import UUID4
6from slugify import slugify
7from sqlalchemy.exc import IntegrityError
9from mealie.db.models.household.cookbook import CookBook
10from mealie.repos.repository_generic import HouseholdRepositoryGeneric
11from mealie.schema.cookbook.cookbook import ReadCookBook, SaveCookBook
12from mealie.schema.response.responses import ErrorResponse
15class RepositoryCookbooks(HouseholdRepositoryGeneric[ReadCookBook, CookBook]):
16 def create(self, data: SaveCookBook | dict) -> ReadCookBook:
17 if isinstance(data, dict): 17 ↛ 18line 17 didn't jump to line 18 because the condition on line 17 was never true
18 data = SaveCookBook(**data)
19 data.slug = slugify(data.name)
21 max_retries = 10
22 for i in range(max_retries):
23 try:
24 return super().create(data)
25 except IntegrityError:
26 self.session.rollback()
27 data.slug = slugify(f"{data.name} ({i + 1})")
29 raise # raise the last IntegrityError
31 def create_many(self, data: Iterable[ReadCookBook | dict]) -> list[ReadCookBook]:
32 return [self.create(entry) for entry in data]
34 def update(self, match_value: str | int | UUID4, data: SaveCookBook | dict) -> ReadCookBook:
35 if isinstance(data, dict): 35 ↛ 36line 35 didn't jump to line 36 because the condition on line 35 was never true
36 data = SaveCookBook(**data)
38 new_slug = slugify(data.name)
39 if not (data.slug and re.match(rf"^({new_slug})(-\d+)?$", data.slug)): 39 ↛ 42line 39 didn't jump to line 42 because the condition on line 39 was always true
40 data.slug = new_slug
42 max_retries = 10
43 for i in range(max_retries):
44 try:
45 return super().update(match_value, data)
46 except IntegrityError:
47 self.session.rollback()
48 data.slug = slugify(f"{data.name} ({i + 1})")
50 raise # raise the last IntegrityError
52 def update_many(self, data: Iterable[ReadCookBook | dict]) -> list[ReadCookBook]:
53 return [self.update(entry.id if isinstance(entry, ReadCookBook) else entry["id"], entry) for entry in data]
55 def patch(self, match_value: str | int | UUID4, data: SaveCookBook | dict) -> ReadCookBook:
56 cookbook = self.get_one(match_value)
57 if not cookbook:
58 raise HTTPException(
59 status.HTTP_404_NOT_FOUND,
60 detail=ErrorResponse.respond(message="Not found."),
61 )
62 cookbook_data = cookbook.model_dump()
64 if not isinstance(data, dict):
65 data = data.model_dump()
66 return self.update(match_value, cookbook_data | data)