Git Product home page Git Product logo

kptncook's Introduction

KptnCook

A small command line client for downloading KptnCook recipes. Atm it's only possible to download the three recipes for today. If you know how to get the data for other days/oids of recipes, please let me know :).

Thanks to this blogpost for the url to get the json for today's recipes.

It's in pre alpha status.

Dependencies

  • Python >=3.10
  • Mealie >=v1.0

Installation

$ pipx install kptncook

Usage

help

Usage: kptncook [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion [bash|zsh|fish|powershell|pwsh]
                                  Install completion for the specified
                                  shell.
  --show-completion [bash|zsh|fish|powershell|pwsh]
                                  Show completion for the specified shell,
                                  to copy it or customize the installation.
  --help                          Show this message and exit.

Commands:
  backup-favorites          Store kptncook favorites in local repository.
  kptncook-access-token     Get access token for kptncook.
  kptncook-today            List all recipes for today from the kptncook...
  list-recipes              List all locally saved recipes.
  save-todays-recipes       Save recipes for today from kptncook site.
  search-by-id              Search for a recipe by id in kptncook api, id...
  sync                      Fetch recipes for today from api, save them to...
  sync-with-mealie          Sync locally saced recipes with mealie.
  export-recipes-to-paprika  Export a recipe by id or all recipes to Paprika app

Environment

Set environment variables via ~/.kptncook/.env dotenv file or directly in your shell. You'll need to set at least the KPTNCOOK_API_KEY variable. If you want to sync the recipes with mealie, you also have to set some additional variables.

If you want to back up your favorite receipts from KptnCook, you have to set the KPTNCOOK_ACCESS_TOKEN variable as well. You can obtain the access token by running the kptncook kptncook-access_token command. But you need a kptncook account to do that. Beware: If you don't have a kptncook account, you'll lose all your favorites by creating a new one.

Here's an example:

KPTNCOOK_API_KEY=6q7QNKy-oIgk-IMuWisJ-jfN7s6
KPTNCOOK_ACCESS_TOKEN=9353xxxx-xxxx-4fe1-xxxx-xxx4a173805  # replace with correct token
MEALIE_URL=https://mealie.staging.django-cast.com/api
MEALIE_USERNAME=jochen
MEALIE_PASSWORD=password  # replace with correct password

Contribute

Install Development Version

  • Checkout source repository
  • Create a virtualenv

Inside the virtualenv install flit (not via pipx!):

$ python -m pip install flit

Install a symlinked development version of the package:

$ flit install -s

Install the git pre-commit hooks:

$ pre-commit install

Run Tests

Flit should have already installed pytest:

$ pytest

Publish a Release

After running the tests, run flit publish to publish the package to PyPI.

$ flit publish

kptncook's People

Contributors

alexdetsch avatar ephes avatar luebbert42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

kptncook's Issues

handling non-parsable recipes

Hi Jochen,

I came across the recipe with the id 63f48c995000009a054010c4

Adding it to the local repo works fine, but get_kptncook_recipes_from_repository cannot handle it, so the local repo and the functionality which needs the local repo won't work any longer.

I was wondering how to fix that - trying to parse it before adding it to the local repo, skip the recipe with a try/except in the get_kptncook_recipes_from_repository function or trying to fix the json (probably mission impossible, as we never know what might be wrong in the future).

Any thoughts on this?

P.S. error message for the recipe mentioned above is:

CRITICAL:root:1 validation error for Recipe
ingredients -> 1 -> ingredient -> uncountableTitle
field required (type=value_error.missing)

but I think of it more as a general problem.

Mealie Read Timeout

Often I see:

$ kptncook sync
Could not login to mealie: The read operation timed out

After login to the mealie site manually it works again.

sync-with-mealie: no Step-Images since Mealie V1.0.0-RC2

Hello everyone,

there is a problem in the current build which causes the images of the individual steps to no longer be displayed correctly in Mealie V1.0.0-RC2 (and also not in the nightly-build from 22.12.2023) when using sync-with-mealie.

There is no problem visible in the log of mealie (the Recipe-Images are working properly in both Versions):

INFO: 10-Dec-23 23:19:15 	Recipe Directory Removed: rote-thai-curry-suppe-mit-reisnudeln-rauchertofu-pak-choi
INFO: 10-Dec-23 23:19:22 	Image URL: https://kptncookmobile2.herokuapp.com/image/656863685b0000497be72e5c?kptnkey=6q7QNKy-oIgk-IMuWisJ-jfN7s6
INFO: 10-Dec-23 23:19:23 	HTTP Request: GET https://kptncookmobile2.herokuapp.com/image/656863685b0000497be72e5c?kptnkey=6q7QNKy-oIgk-IMuWisJ-jfN7s6 "HTTP/1.1 200 OK"
INFO: 10-Dec-23 23:19:24 	original.jpg minified
INFO: 10-Dec-23 23:19:24 	Tiny image saved
INFO: 10-Dec-23 23:19:35 	Image URL: https://d2am1qai33sroc.cloudfront.net/image/63cfb34d520000fc04ff7f95?kptnkey=6q7QNKy-oIgk-IMuWisJ-jfN7s6
INFO: 10-Dec-23 23:19:36 	HTTP Request: GET https://d2am1qai33sroc.cloudfront.net/image/63cfb34d520000fc04ff7f95?kptnkey=6q7QNKy-oIgk-IMuWisJ-jfN7s6 "HTTP/1.1 200 OK"
INFO: 10-Dec-23 23:19:36 	original.jpg minified
INFO: 10-Dec-23 23:19:36 	Tiny image saved

Here we see V1.0.0-RC1.2 on the left and V1.0.0.-RC1.1 on the right: the step-images still appear correctly in V1.0.0-RC1.1:
Bildschirm­foto 2023-12-11 um 09 14 56

Both Mealie versions are running seperately in Docker:

Here is the log from my mealie-nightly container:

 2023-12-11 09:17:35 INFO:     Started server process [15]
 2023-12-11 09:17:35 INFO:     Waiting for application startup.
 2023-12-11 09:17:35 INFO:     Application startup complete.
 2023-12-11 09:17:35 INFO:     Uvicorn running on http://0.0.0.0:9000 (Press CTRL+C to quit)
 2023-12-11 09:18:02 INFO:     127.0.0.1:51216 - "GET /api/app/about HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37977 - "GET /api/users/self HTTP/1.1" 401 Unauthorized
 2023-12-11 09:18:15 INFO:     192.168.65.1:37978 - "GET /api/explore/organizers/home/categories?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37980 - "GET /api/explore/organizers/home/tags?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37982 - "GET /api/explore/organizers/home/tools?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37977 - "GET /api/explore/cookbooks/home?page=1&perPage=-1&orderBy=position&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37981 - "GET /api/explore/recipes/home?page=1&perPage=64&orderBy=created_at&orderDirection=desc&paginationSeed=1702282695409&searchSeed=1702282695409&search=&requireAllCategories=false&requireAllTags=false&requireAllTools=false&requireAllFoods=false HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37979 - "GET /api/explore/foods/home?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37977 - "GET /api/media/recipes/c57ee990-353b-4b97-97af-842f3717db99/images/min-original.webp?rnd=1&version= HTTP/1.1" 200 OK
 2023-12-11 09:18:15 INFO:     192.168.65.1:37978 - "GET /api/media/recipes/eed4fe1e-2623-4f3d-8d3b-1976211676d1/images/min-original.webp?rnd=1&version= HTTP/1.1" 200 OK
 2023-12-11 09:18:20 INFO:     192.168.65.1:37984 - "GET /api/app/about HTTP/1.1" 200 OK
 2023-12-11 09:18:20 INFO:     192.168.65.1:37983 - "GET /api/app/about/startup-info HTTP/1.1" 200 OK
 2023-12-11 09:18:24 INFO:     192.168.65.1:37984 - "POST /api/auth/token HTTP/1.1" 200 OK
 2023-12-11 09:18:24 INFO:     192.168.65.1:37984 - "GET /api/users/self HTTP/1.1" 200 OK
 2023-12-11 09:18:25 INFO:     192.168.65.1:37983 - "GET /api/organizers/tools?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:25 INFO:     192.168.65.1:37986 - "GET /api/media/users/b3e273c2-7083-4d4e-8294-cd6a2a62ac7f/profile.webp?cacheKey=1234 HTTP/1.1" 200 OK
 2023-12-11 09:18:25 INFO:     192.168.65.1:37985 - "GET /api/recipes?page=1&perPage=64&orderBy=created_at&orderDirection=desc&paginationSeed=1702282705187&searchSeed=1702282705187&search=&requireAllCategories=false&requireAllTags=false&requireAllTools=false&requireAllFoods=false HTTP/1.1" 200 OK
 2023-12-11 09:18:25 INFO:     192.168.65.1:37984 - "GET /api/organizers/categories?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:26 INFO:     192.168.65.1:37983 - "GET /api/admin/about/check HTTP/1.1" 200 OK
 2023-12-11 09:18:27 INFO:     192.168.65.1:37984 - "GET /api/admin/about HTTP/1.1" 200 OK
 2023-12-11 09:18:33 INFO:     127.0.0.1:52272 - "GET /api/app/about HTTP/1.1" 200 OK
 2023-12-11 09:18:51 INFO:     192.168.65.1:37987 - "GET /api/admin/maintenance/logs?lines=500 HTTP/1.1" 200 OK
 2023-12-11 09:18:59 INFO:     192.168.65.1:37988 - "GET /api/organizers/tools?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:59 INFO:     192.168.65.1:37990 - "GET /api/organizers/categories?page=1&perPage=-1&orderBy=name&orderDirection=asc HTTP/1.1" 200 OK
 2023-12-11 09:18:59 INFO:     192.168.65.1:37989 - "GET /api/recipes?page=1&perPage=64&orderBy=created_at&orderDirection=desc&paginationSeed=1702282739701&searchSeed=1702282739701&search=&requireAllCategories=false&requireAllTags=false&requireAllTools=false&requireAllFoods=false HTTP/1.1" 200 OK
 2023-12-11 09:19:03 INFO:     127.0.0.1:37442 - "GET /api/app/about HTTP/1.1" 200 OK
 2023-12-11 09:19:03 INFO:     192.168.65.1:37990 - "GET /api/recipes/grunkohl-salat-mit-knusprigem-halloumi HTTP/1.1" 200 OK
 2023-12-11 09:19:03 INFO:     192.168.65.1:37990 - "GET /api/media/recipes/eed4fe1e-2623-4f3d-8d3b-1976211676d1/assets/rez-3502-01.jpg HTTP/1.1" 500 Internal Server Error
 2023-12-11 09:19:03 ERROR:    Exception in ASGI application
 2023-12-11 09:19:03 Traceback (most recent call last):
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/responses.py", line 335, in __call__
 2023-12-11 09:19:03     stat_result = await anyio.to_thread.run_sync(os.stat, self.path)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/anyio/to_thread.py", line 33, in run_sync
 2023-12-11 09:19:03     return await get_asynclib().run_sync_in_worker_thread(
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 877, in run_sync_in_worker_thread
 2023-12-11 09:19:03     return await future
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/anyio/_backends/_asyncio.py", line 807, in run
 2023-12-11 09:19:03     result = context.run(func, *args)
 2023-12-11 09:19:03 FileNotFoundError: [Errno 2] No such file or directory: '/app/data/recipes/eed4fe1e-2623-4f3d-8d3b-1976211676d1/assets/rez-3502-01.jpg'
 2023-12-11 09:19:03 
 2023-12-11 09:19:03 During handling of the above exception, another exception occurred:
 2023-12-11 09:19:03 
 2023-12-11 09:19:03 Traceback (most recent call last):
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 436, in run_asgi
 2023-12-11 09:19:03     result = await app(  # type: ignore[func-returns-value]
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
 2023-12-11 09:19:03     return await self.app(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/fastapi/applications.py", line 1106, in __call__
 2023-12-11 09:19:03     await super().__call__(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/applications.py", line 122, in __call__
 2023-12-11 09:19:03     await self.middleware_stack(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
 2023-12-11 09:19:03     raise exc
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
 2023-12-11 09:19:03     await self.app(scope, receive, _send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/middleware/gzip.py", line 24, in __call__
 2023-12-11 09:19:03     await responder(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/middleware/gzip.py", line 44, in __call__
 2023-12-11 09:19:03     await self.app(scope, receive, self.send_with_gzip)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
 2023-12-11 09:19:03     raise exc
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
 2023-12-11 09:19:03     await self.app(scope, receive, sender)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__
 2023-12-11 09:19:03     raise e
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__
 2023-12-11 09:19:03     await self.app(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/routing.py", line 718, in __call__
 2023-12-11 09:19:03     await route.handle(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
 2023-12-11 09:19:03     await self.app(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/routing.py", line 69, in app
 2023-12-11 09:19:03     await response(scope, receive, send)
 2023-12-11 09:19:03   File "/opt/pysetup/.venv/lib/python3.10/site-packages/starlette/responses.py", line 338, in __call__
 2023-12-11 09:19:03     raise RuntimeError(f"File at path {self.path} does not exist.")
 2023-12-11 09:19:03 RuntimeError: File at path /app/data/recipes/eed4fe1e-2623-4f3d-8d3b-1976211676d1/assets/rez-3502-01.jpg does not exist.
 2023-12-11 09:19:03 ERROR:    Exception in ASGI application

Is there any fix to make the Step-Images working in Mealie V1.0.0-RC2?

Best Regards
Felix

Cli command raises exception :(

Probably a compatibility issue between click and typer.

╰─>$ kptncook --help                                   Mi 30 Mär 18:14:20 2022
Traceback (most recent call last):
  File "/Users/jochen/.local/bin/kptncook", line 5, in <module>
    from kptncook import cli
  File "/Users/jochen/.local/pipx/venvs/kptncook/lib/python3.10/site-packages/kptncook/__init__.py", line 8, in <module>
    import typer
  File "/Users/jochen/.local/pipx/venvs/kptncook/lib/python3.10/site-packages/typer/__init__.py", line 12, in <module>
    from click.termui import get_terminal_size as get_terminal_size
ImportError: cannot import name 'get_terminal_size' from 'click.termui' (/Users/jochen/.local/pipx/venvs/kptncook/lib/python3.10/site-packages/click/termui.py)

Error retrieving kptncook access token

Hi,

first, great work :)

But I'm not able to get the access token. "404 not found" :(

Using Win 11 with Windows Terminal, Python 3.12.

Any idea, what I'm doing wrong?

Many thanks & Regards,
Matthias

Traceback (most recent call last)
│ xxx\kptncook\Lib\site-packages\kptncook_init_.py:179 in │
│ get_kptncook_access_token │
│ │
│ 176 │ username = Prompt.ask("Enter your kptncook email address") │
│ 177 │ password = Prompt.ask("Enter your kptncook password", password=True) │
│ 178 │ client = KptnCookClient() │
│ ❱ 179 │ access_token = client.get_access_token(username, password) │
│ 180 │ rprint("your access token: ", access_token) │
│ 181 │
│ 182 │
│ │
│ ╭─────────────────────────────── locals ────────────────────────────────╮ │
│ │ client = <kptncook.api.KptnCookClient object at 0x000001C1D640DDC0> │ │
│ │ password = 'xxx' │ │
│ │ username = '[email protected]' │ │
│ ╰───────────────────────────────────────────────────────────────────────╯ │
│ │
│ xxx\kptncook\Lib\site-packages\kptncook\api.py:87 in │
│ get_access_token │
│ │
│ 84 │ │ │ "/login/userpass", │
│ 85 │ │ │ json={"email": username, "password": password}, │
│ 86 │ │ ) │
│ ❱ 87 │ │ response.raise_for_status() │
│ 88 │ │ token_data = response.json() │
│ 89 │ │ return token_data["accessToken"] │
│ 90 │
│ │
│ ╭─────────────────────────────── locals ────────────────────────────────╮ │
│ │ password = 'xxx' │ │
│ │ response = <Response [404 Not Found]> │ │
│ │ self = <kptncook.api.KptnCookClient object at 0x000001C1D640DDC0> │ │
│ │ username = '[email protected]' │ │
│ ╰───────────────────────────────────────────────────────────────────────╯ │
│ │
│ xxx\kptncook\Lib\site-packages\httpx_models.py:749 in │
│ raise_for_status │
│ │
│ 746 │ │ } │
│ 747 │ │ error_type = error_types.get(status_class, "Invalid status code") │
│ 748 │ │ message = message.format(self, error_type=error_type) │
│ ❱ 749 │ │ raise HTTPStatusError(message, request=request, response=self) │
│ 750 │ │
│ 751 │ def json(self, **kwargs: typing.Any) -> typing.Any: │
│ 752 │ │ if self.charset_encoding is None and self.content and len(self.content) > 3: │
│ │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ error_type = 'Client error' │ │
│ │ error_types = { │ │
│ │ │ 1: 'Informational response', │ │
│ │ │ 3: 'Redirect response', │ │
│ │ │ 4: 'Client error', │ │
│ │ │ 5: 'Server error' │ │
│ │ } │ │
│ │ message = "Client error '404 Not Found' for url │ │
│ │ 'https://mobile.kptncook.com//login/userpas"+91 │ │
│ │ request = <Request('POST', 'https://mobile.kptncook.com//login/userpass')> │ │
│ │ self = <Response [404 Not Found]> │ │
│ │ status_class = 4 │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
HTTPStatusError: Client error '404 Not Found' for url 'https://mobile.kptncook.com//login/userpass'

Cannot sync with mealie when having recipes from other source

The script doesnt seem to like it when having recipies in mealie that are not from kptncook.
We have a lot of recipies that we added manually or imported from url in our mealie.
Is there a way to exclude them form the sync? Because the pydantic validator throws an exeption when theres missing variables like cookingTime or lastMade when syncing. Maybe we could give synced kptncook recepies a orgURL that we can parse in the script so it knows if its a syncable script or not

TypeError on every CLI call

Regardless of which CLI-command is called, everytime, this exact error is raised:

Traceback (most recent call last):
  File "/root/.local/bin/kptncook", line 5, in <module>
    from kptncook import cli
  File "/root/.local/pipx/venvs/kptncook/lib/python3.9/site-packages/kptncook/__init__.py", line 15, in <module>
    from .api import KptnCookClient, parse_id
  File "/root/.local/pipx/venvs/kptncook/lib/python3.9/site-packages/kptncook/api.py", line 120, in <module>
    def parse_id(text: str) -> tuple[Literal["oid", "uid"], str] | None:
TypeError: unsupported operand type(s) for |: 'types.GenericAlias' and 'NoneType'

I use Python 3.9.2

several errors

Hello,

I'm trying to use your scripts to fetch kpntcook recipes and export them to mealie. But it does not work :(

kptncook kptncook-today --> is working fine, it lists all recipes
kptncook backup-favorites --> read timeout
kptncook save-todays-recipes --> unicode decode error

What I'm doing wrong here? Can you help me (again) please? (I'm running the script using powershell in Win 11)

Many thanks & Regards,
Matthias

TemplateNotFound: paprika.jinja2.json

Hi,

trying to export to paprika I'm getting a TemplateNotFound error.
I am using kptncook version 0.0.14 and got the same error on windows and linux (the log if from windows).
Is this a bug or am I doing something wrong?
Thank you.

Console Output:

> kptncook export-recipes-to-paprika
...
│ │                 │   │   │   │   │   de='Salz',                                               │ │
│ │                 │   │   │   │   │   es='sal',                                                │ │
│ │                 │   │   │   │   │   fr='sel',                                                │ │
│ │                 │   │   │   │   │   pt='sal'                                                 │ │
│ │                 │   │   │   │   ),                                                           │ │
│ │                 │   │   │   │   category='SpicesSeasoning'                                   │ │
│ │                 │   │   │   )                                                                │ │
│ │                 │   │   ),                                                                   │ │
│ │                 │   │   ... +2                                                               │ │
│ │                 │   ]                                                                        │ │
│ │                 )                                                                            │ │
│ │          self = <kptncook.paprika.ExportRenderer object at 0x000001708A22C470>               │ │
│ │ template_name = 'paprika.jinja2.json'                                                        │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ C:\Users\patry\.local\pipx\venvs\kptncook\Lib\site-packages\jinja2\environment.py:1010 in        │
│ get_template                                                                                     │
│                                                                                                  │
│   1007 │   │   if parent is not None:                                                            │
│   1008 │   │   │   name = self.join_path(name, parent)                                           │
│   1009 │   │                                                                                     │
│ ❱ 1010 │   │   return self._load_template(name, globals)                                         │
│   1011 │                                                                                         │
│   1012 │   @internalcode                                                                         │
│   1013 │   def select_template(                                                                  │
│                                                                                                  │
│ ╭──────────────────────────────── locals ─────────────────────────────────╮                      │
│ │ globals = None                                                          │                      │
│ │    name = 'paprika.jinja2.json'                                         │                      │
│ │  parent = None                                                          │                      │
│ │    self = <jinja2.environment.Environment object at 0x000001708A0660F0> │                      │
│ ╰─────────────────────────────────────────────────────────────────────────╯                      │
│                                                                                                  │
│ C:\Users\patry\.local\pipx\venvs\kptncook\Lib\site-packages\jinja2\environment.py:969 in         │
│ _load_template                                                                                   │
│                                                                                                  │
│    966 │   │   │   │                                                                             │
│    967 │   │   │   │   return template                                                           │
│    968 │   │                                                                                     │
│ ❱  969 │   │   template = self.loader.load(self, name, self.make_globals(globals))               │
│    970 │   │                                                                                     │
│    971 │   │   if self.cache is not None:                                                        │
│    972 │   │   │   self.cache[cache_key] = template                                              │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ cache_key = (                                                                                │ │
│ │             │   <weakref at 0x000001708A233560; to 'FileSystemLoader' at                     │ │
│ │             0x0000017087ACE4E0>,                                                             │ │
│ │             │   'paprika.jinja2.json'                                                        │ │
│ │             )                                                                                │ │
│ │   globals = None                                                                             │ │
│ │      name = 'paprika.jinja2.json'                                                            │ │
│ │      self = <jinja2.environment.Environment object at 0x000001708A0660F0>                    │ │
│ │  template = None                                                                             │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ C:\Users\patry\.local\pipx\venvs\kptncook\Lib\site-packages\jinja2\loaders.py:126 in load        │
│                                                                                                  │
│   123 │   │                                                                                      │
│   124 │   │   # first we try to get the source for this template together                        │
│   125 │   │   # with the filename and the uptodate function.                                     │
│ ❱ 126 │   │   source, filename, uptodate = self.get_source(environment, name)                    │
│   127 │   │                                                                                      │
│   128 │   │   # try to load the code from the bytecode cache if there is a                       │
│   129 │   │   # bytecode cache configured.                                                       │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │        code = None                                                                           │ │
│ │ environment = <jinja2.environment.Environment object at 0x000001708A0660F0>                  │ │
│ │     globals = ChainMap({}, {'range': <class 'range'>, 'dict': <class 'dict'>, 'lipsum':      │ │
│ │               <function generate_lorem_ipsum at 0x000001708A01A0C0>, 'cycler': <class        │ │
│ │               'jinja2.utils.Cycler'>, 'joiner': <class 'jinja2.utils.Joiner'>, 'namespace':  │ │
│ │               <class 'jinja2.utils.Namespace'>})                                             │ │
│ │        name = 'paprika.jinja2.json'                                                          │ │
│ │        self = <jinja2.loaders.FileSystemLoader object at 0x0000017087ACE4E0>                 │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                  │
│ C:\Users\patry\.local\pipx\venvs\kptncook\Lib\site-packages\jinja2\loaders.py:218 in get_source  │
│                                                                                                  │
│   215 │   │   │                                                                                  │
│   216 │   │   │   # Use normpath to convert Windows altsep to sep.                               │
│   217 │   │   │   return contents, os.path.normpath(filename), uptodate                          │
│ ❱ 218 │   │   raise TemplateNotFound(template)                                                   │
│   219 │                                                                                          │
│   220 │   def list_templates(self) -> t.List[str]:                                               │
│   221 │   │   found = set()                                                                      │
│                                                                                                  │
│ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │
│ │ environment = <jinja2.environment.Environment object at 0x000001708A0660F0>                  │ │
│ │           f = None                                                                           │ │
│ │    filename = 'C:\\Users\\patry\\.local\\pipx\\venvs\\kptncook\\Lib\\site-packages\\templat… │ │
│ │      pieces = ['paprika.jinja2.json']                                                        │ │
│ │  searchpath = 'C:\\Users\\patry\\.local\\pipx\\venvs\\kptncook\\Lib\\site-packages\\templat… │ │
│ │        self = <jinja2.loaders.FileSystemLoader object at 0x0000017087ACE4E0>                 │ │
│ │    template = 'paprika.jinja2.json'                                                          │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
TemplateNotFound: paprika.jinja2.json

Mealie API version not clear

I have the strong feeling, that this needs the 1.0 version tree of mealie? The current release version of mealie v0.5.6 seems to have major differences in API routes to the code in this repo. I first thought, that maybe the routes in this repo are overcome, but the API routes in mealie v1.0-beta seems to match much better. So am I right, that this package depend on mealie 1.0?

PydanticImportError

Hi Jochen,

whilst trying to run your awesome package I came across a breaking error, probably because of a new dependency version of pydantic.
I found this happening in a clean anaconda environment for both python 3.10 and 3.11 when running any command.

This is the error I get:

Traceback (most recent call last): File "/Users/max/.local/bin/kptncook", line 5, in <module> from kptncook import cli File "/Users/max/.local/pipx/venvs/kptncook/lib/python3.11/site-packages/kptncook/__init__.py", line 16, in <module> from .api import KptnCookClient, parse_id File "/Users/max/.local/pipx/venvs/kptncook/lib/python3.11/site-packages/kptncook/api.py", line 8, in <module> from .config import settings File "/Users/max/.local/pipx/venvs/kptncook/lib/python3.11/site-packages/kptncook/config.py", line 7, in <module> from pydantic import ( File "/Users/max/.local/pipx/venvs/kptncook/lib/python3.11/site-packages/pydantic/__init__.py", line 218, in __getattr__ return _getattr_migration(attr_name) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/max/.local/pipx/venvs/kptncook/lib/python3.11/site-packages/pydantic/_migration.py", line 294, in wrapper raise PydanticImportError( pydantic.errors.PydanticImportError: BaseSettings has been moved to the pydantic-settings package. See https://docs.pydantic.dev/2.4/migration/#basesettings-has-moved-to-pydantic-settings for more details. For further information visit https://errors.pydantic.dev/2.4/u/import-error

I would really appreciate you looking into this.

Thanks in advance! :)

Fetch recipes based on different api endpoints

Here are some api endpoints, maybe it would be nice to have some cli commands to fetch recipes from those endpoints?

https://mobile.kptncook.com/discovery/list/curated/6512a9475100004c009f516a?favorites=5b99084f2700007d089e190c&lang=de&store=de&preferences=rt%3Adiet_vegetarian%2C

alternative list ids:
	6512a9475100004c009f516a
	6511394a4f0000a5050f686e
	64edb8195000001309c52a4c
	651673793c00001a073cc9c2
	6511394a4f0000a5050f686e


https://mobile.kptncook.com/discovery/list/automated/63778ff050000058041dd3a0?favorites=5eff3489690000937e9c421e%2C58da4cfc3900005f111778d4%2C53d043d770a559461ebed47f%2C5b99084f2700007d089e190c&lang=de&store=de&preferences=rt%3Adiet_vegetarian%2C

alternative list ids:
	63778ff050000058041dd3a0
	637790744c00002b04705c1a
	637e34864e00000801c96e72
	63779112480000e604488f09
	637f46234f00003600c27cf0
	637f46774400003800bf95e9
	637f489e4f00006e00ad3a91

https://mobile.kptncook.com/discovery/list/latest?lang=de&store=de&preferences=rt%3Adiet_vegetarian%2C

https://mobile.kptncook.com/discovery/list/recommended?lang=de&store=de&preferences=rt%3Adiet_vegetarian%2C

https://mobile.kptncook.com/discovery/screen?v=2&favorites=5b99084f2700007d089e190c&lang=de&store=de&preferences=rt%3Adiet_vegetarian%2C

https://mobile.kptncook.com/dailies?recipeFilter=veggie&store=de&zone=%2B02:00&isSubscribed=false&lang=de

POST https://mobile.kptncook.com/recipes/onboarding
	?lang=de&store=de
data:
	{"tags":["rt:diet_vegetarian"]}

POST https://mobile.kptncook.com/recipes/search?lang=de&store=de

https://mobile.kptncook.com/ingredients/popular?lang=de&store=de

POST https://mobile.kptncook.com/recipes/withIngredients?lang=de&store=de
data:
	{"ingredientIds":["52bc0f4f91217a1c01a8ad4e"]}

Additional information on kptncook API

Nice project :)
I was also inspired by the blog post by fhantke and did some reversing of the app myself.
I posted the findings here: https://github.com/gloriousDan/kptncook-api-reverse-engineering

You may find it interesting since a couple more endpoints are included in my writedown :)

There's also https://github.com/hhursev/recipe-scrapers which supports scraping kptncook recipes from their share link since version v13.19.0.

Feel free to close this issue :)

Validation error for recipes

Hi everyone,

after installing version 0.0.17 (according to pipx), I am able to get the required token and could also pull my favorites.
But it will instantly throw the following error for one recipe. I tried to pick specific recipes via oid, but they all return the same thing. The download into the json file did work regardless of the error.

ValidationError: 1 validation error for Recipe
steps.1.image
Field required [type=missing, input_value={'title': {'en': 'Quarter...ari',
'pt': 'melão'}}]}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.5/v/missing

Whenever I try to list the local recipes or run the Paprika export I get the same error.
Is there any way to fix this?

Python 3.10.13 macOS

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.