Compare commits

...

129 Commits

Author SHA1 Message Date
Hayden
6bd5a82b92 rewrite logger to support custom config files (#3104) 2024-04-16 15:52:49 +00:00
renovate[bot]
cba076b6a4 chore(deps): update dependency ruff to v0.3.7 (#3458)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 10:41:00 -05:00
Michael Genson
2ff1135b00 fix: duplicate ld+json data (#3444)
Co-authored-by: boc-the-git <3479092+boc-the-git@users.noreply.github.com>
2024-04-16 10:54:14 +00:00
renovate[bot]
467b9c6d65 fix(deps): update dependency apprise to v1.7.6 (#3464)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: boc-the-git <3479092+boc-the-git@users.noreply.github.com>
2024-04-16 10:46:17 +00:00
renovate[bot]
176e471276 fix(deps): update dependency orjson to v3.10.1 (#3467)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 20:35:27 +10:00
renovate[bot]
193888fb30 chore(deps): update dependency mkdocs-material to v9.5.18 (#3468)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-16 00:13:49 -05:00
Hayden
13edefbf41 New Crowdin updates (#3465) 2024-04-14 19:21:05 +02:00
Hayden
fd33468fda New Crowdin updates (#3462) 2024-04-13 17:24:37 +02:00
Michael Genson
2a541f081a feat: User-specific Recipe Ratings (#3345) 2024-04-11 21:28:43 -05:00
renovate[bot]
8ab09cf03b fix(deps): update dependency tzdata to v2024 (#3456)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-12 01:49:18 +00:00
Hayden
9e6ae2e514 chore: remove black (#3437) 2024-04-11 20:36:55 -05:00
renovate[bot]
94678fe6e0 chore(deps): update dependency ruff to v0.3.6 (#3451)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 15:39:17 -05:00
renovate[bot]
ed533c8fad fix(deps): update dependency pydantic to v2.7.0 (#3452)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-11 15:24:24 -05:00
Hayden
93f7d15917 New Crowdin updates (#3447) 2024-04-10 14:39:49 +02:00
Hayden
53aa4dab51 New Crowdin updates (#3443) 2024-04-09 15:07:18 +02:00
tba-code
92659c64eb fix: properly escape postgres password (#3424)
Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
2024-04-08 14:47:57 +00:00
Hayden
6f871c6bdb New Crowdin updates (#3441) 2024-04-08 10:57:49 +00:00
renovate[bot]
f4f511aad6 Update dependency rapidfuzz to v3.8.1 (#3439)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-08 20:08:52 +10:00
Hayden
03d384f3a5 New Crowdin updates (#3435) 2024-04-07 09:45:46 -08:00
renovate[bot]
0c2917a112 Update dependency rapidfuzz to v3.8.0 (#3431)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-06 12:02:11 -05:00
boc-the-git
606a8f03a3 Merge pull request #3429 from mealie-recipes/l10n_mealie-next
New Crowdin updates
2024-04-06 21:40:31 +11:00
Hayden
2d31c0abf2 New translations en-us.json (French, Canada) 2024-04-06 05:29:58 -05:00
Hayden
15c752d428 New translations en-us.json (Latvian) 2024-04-06 05:29:58 -05:00
Hayden
b254cf3833 New translations en-us.json (Croatian) 2024-04-06 05:29:57 -05:00
Hayden
0bd023d8a8 New translations en-us.json (Portuguese, Brazilian) 2024-04-06 05:29:56 -05:00
Hayden
aad50f2267 New translations en-us.json (Icelandic) 2024-04-06 05:29:55 -05:00
Hayden
fcbc57b392 New translations en-us.json (Galician) 2024-04-06 05:29:54 -05:00
Hayden
a62299e6ef New translations en-us.json (Vietnamese) 2024-04-06 05:29:53 -05:00
Hayden
82563fa948 New translations en-us.json (Chinese Traditional) 2024-04-06 05:29:52 -05:00
Hayden
7583c56b35 New translations en-us.json (Chinese Simplified) 2024-04-06 05:29:51 -05:00
Hayden
b9cc2dc257 New translations en-us.json (Ukrainian) 2024-04-06 05:29:50 -05:00
Hayden
0dcf81e764 New translations en-us.json (Turkish) 2024-04-06 05:29:49 -05:00
Hayden
3d3763d4b9 New translations en-us.json (Serbian (Cyrillic)) 2024-04-06 05:29:49 -05:00
Hayden
517727a4b6 New translations en-us.json (Slovenian) 2024-04-06 05:29:48 -05:00
Hayden
1c26dff1e9 New translations en-us.json (Slovak) 2024-04-06 05:29:47 -05:00
Hayden
ed1834d945 New translations en-us.json (Russian) 2024-04-06 05:29:46 -05:00
Hayden
bf8bc88ffb New translations en-us.json (Portuguese) 2024-04-06 05:29:45 -05:00
Hayden
6c48eba5f7 New translations en-us.json (Norwegian) 2024-04-06 05:29:44 -05:00
Hayden
dc7df0d4aa New translations en-us.json (Dutch) 2024-04-06 05:29:43 -05:00
Hayden
45d5194f19 New translations en-us.json (Lithuanian) 2024-04-06 05:29:42 -05:00
Hayden
8ad1a15bf1 New translations en-us.json (Korean) 2024-04-06 05:29:41 -05:00
Hayden
57aeb401b8 New translations en-us.json (Japanese) 2024-04-06 05:29:41 -05:00
Hayden
e15a2f35e2 New translations en-us.json (Italian) 2024-04-06 05:29:40 -05:00
Hayden
b28e135ceb New translations en-us.json (Hungarian) 2024-04-06 05:29:39 -05:00
Hayden
148aca5e85 New translations en-us.json (Hebrew) 2024-04-06 05:29:38 -05:00
Hayden
1ac7f90c28 New translations en-us.json (Finnish) 2024-04-06 05:29:37 -05:00
Hayden
413a8a82fc New translations en-us.json (Greek) 2024-04-06 05:29:36 -05:00
Hayden
72c414bf94 New translations en-us.json (German) 2024-04-06 05:29:35 -05:00
Hayden
b67263e63f New translations en-us.json (Danish) 2024-04-06 05:29:34 -05:00
Hayden
1673eedff7 New translations en-us.json (Czech) 2024-04-06 05:29:33 -05:00
Hayden
d3ee5f34f8 New translations en-us.json (Catalan) 2024-04-06 05:29:32 -05:00
Hayden
683f1ac69e New translations en-us.json (Bulgarian) 2024-04-06 05:29:31 -05:00
Hayden
d6d0f7de71 New translations en-us.json (Arabic) 2024-04-06 05:29:30 -05:00
Hayden
dd0eaac45f New translations en-us.json (Afrikaans) 2024-04-06 05:29:29 -05:00
Hayden
f8e672c7ac New translations en-us.json (French) 2024-04-06 05:29:28 -05:00
Hayden
2aa9d84d6c New translations en-us.json (Romanian) 2024-04-06 05:29:27 -05:00
Hayden
2c13c4760e New translations en-us.json (Polish) 2024-04-06 05:29:26 -05:00
Hayden
62bf733548 New translations en-us.json (English, United Kingdom) 2024-04-06 05:29:25 -05:00
Hayden
2c72ea17a2 New translations en-us.json (Swedish) 2024-04-06 05:29:24 -05:00
Hayden
06406c86f5 New translations en-us.json (Spanish) 2024-04-06 05:29:23 -05:00
boc-the-git
b7f7712011 fix: Update description for manage data page (#3427)
* Update description for manage data page

* Add some punctuation consistency.

* Capitalise item types

Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>

---------

Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
2024-04-05 22:04:32 +02:00
Hayden
4b13686261 New Crowdin updates (#3425)
* New translations en-us.json (Hungarian)

* New translations en-us.json (Portuguese)

* New translations en-us.json (Slovenian)

* New translations en-us.json (Turkish)

* New translations en-us.json (Ukrainian)
2024-04-05 10:05:13 +00:00
tba-code
9fade36014 feat: Support HEIF, HEIC and AVIF recipe image uploads (#3409)
* feat: Support HEIF, HEIC and AVIF recipe image uploads

* fix: lint import block

* fix: avif now included

* fix: lint import block
2024-04-04 18:31:10 -05:00
Carter
eb1d569e95 Infinite redirect fix again (#3419)
* override the check method to not care about the id token if we have a valid mealie token

* prevent auto log in with auth check is already good

* fix check

* simplify check logic
2024-04-04 21:23:33 +00:00
tba-code
1099e30a1d feat: Add OIDC_USER_CLAIM (#3422)
* feat: Add OIDC_USER_CLAIM

* fix: add validation
2024-04-04 21:16:54 +00:00
tba-code
fa9a2d64f7 fix: unstyled docs 404 page (#3421) 2024-04-04 18:56:27 +02:00
boc-the-git
de142c47df Merge pull request #3420 from mealie-recipes/l10n_mealie-next
New Crowdin updates
2024-04-04 22:00:23 +11:00
Hayden
c990420a87 New translations en-us.json (Slovenian) 2024-04-04 04:58:11 -05:00
Hayden
d772e3bb4f New translations en-us.json (French, Canada) 2024-04-04 04:58:10 -05:00
Hayden
bb8080475c New translations en-us.json (Latvian) 2024-04-04 04:58:09 -05:00
Hayden
c1e05f57db New translations en-us.json (Croatian) 2024-04-04 04:58:08 -05:00
Hayden
9ad68542e0 New translations en-us.json (Portuguese, Brazilian) 2024-04-04 04:58:07 -05:00
Hayden
83997dbb47 New translations en-us.json (Icelandic) 2024-04-04 04:58:06 -05:00
Hayden
b5f3c5bef7 New translations en-us.json (Galician) 2024-04-04 04:58:04 -05:00
Hayden
ddd97cce10 New translations en-us.json (Vietnamese) 2024-04-04 04:58:03 -05:00
Hayden
0ecd57a50b New translations en-us.json (Chinese Traditional) 2024-04-04 04:58:02 -05:00
Hayden
e4efcee0df New translations en-us.json (Chinese Simplified) 2024-04-04 04:58:00 -05:00
Hayden
a6920f057e New translations en-us.json (Ukrainian) 2024-04-04 04:58:00 -05:00
Hayden
dbb212ceda New translations en-us.json (Turkish) 2024-04-04 04:57:59 -05:00
Hayden
5d5805459a New translations en-us.json (Serbian (Cyrillic)) 2024-04-04 04:57:58 -05:00
Hayden
3e68920e69 New translations en-us.json (Slovenian) 2024-04-04 04:57:57 -05:00
Hayden
91c978a309 New translations en-us.json (Slovak) 2024-04-04 04:57:56 -05:00
Hayden
e7c101c96b New translations en-us.json (Russian) 2024-04-04 04:57:55 -05:00
Hayden
004f3552c0 New translations en-us.json (Portuguese) 2024-04-04 04:57:54 -05:00
Hayden
cd56149371 New translations en-us.json (Norwegian) 2024-04-04 04:57:53 -05:00
Hayden
8edea0a7e0 New translations en-us.json (Dutch) 2024-04-04 04:57:52 -05:00
Hayden
df15e97026 New translations en-us.json (Lithuanian) 2024-04-04 04:57:51 -05:00
Hayden
760462e12f New translations en-us.json (Korean) 2024-04-04 04:57:50 -05:00
Hayden
60793bb560 New translations en-us.json (Japanese) 2024-04-04 04:57:49 -05:00
Hayden
7c84d3dea5 New translations en-us.json (Italian) 2024-04-04 04:57:47 -05:00
Hayden
eee1c5733d New translations en-us.json (Hungarian) 2024-04-04 04:57:46 -05:00
Hayden
cf0a7ae9c9 New translations en-us.json (Hebrew) 2024-04-04 04:57:45 -05:00
Hayden
be80d3e74c New translations en-us.json (Finnish) 2024-04-04 04:57:44 -05:00
Hayden
db1fabf5c8 New translations en-us.json (Greek) 2024-04-04 04:57:43 -05:00
Hayden
e7e73772e0 New translations en-us.json (German) 2024-04-04 04:57:42 -05:00
Hayden
e5cab0e4d0 New translations en-us.json (Danish) 2024-04-04 04:57:41 -05:00
Hayden
6a14d5b7db New translations en-us.json (Czech) 2024-04-04 04:57:40 -05:00
Hayden
57106c4cce New translations en-us.json (Catalan) 2024-04-04 04:57:38 -05:00
Hayden
61c6a991f3 New translations en-us.json (Bulgarian) 2024-04-04 04:57:37 -05:00
Hayden
6824b3c269 New translations en-us.json (Arabic) 2024-04-04 04:57:36 -05:00
Hayden
6b13166880 New translations en-us.json (Afrikaans) 2024-04-04 04:57:35 -05:00
Hayden
b2747d77e1 New translations en-us.json (French) 2024-04-04 04:57:34 -05:00
Hayden
fc4d1b88d0 New translations en-us.json (Romanian) 2024-04-04 04:57:32 -05:00
Hayden
8798bd6e55 New translations en-us.json (Polish) 2024-04-04 04:57:31 -05:00
Hayden
cef61ae29f New translations en-us.json (English, United Kingdom) 2024-04-04 04:57:30 -05:00
Hayden
e304d48e84 New translations en-us.json (Swedish) 2024-04-04 04:57:29 -05:00
Hayden
4f1a7c55b9 New translations en-us.json (Spanish) 2024-04-04 04:57:28 -05:00
boc-the-git
bae7acbc3b Merge pull request #3395 from tba-code/postgres-url-feature
feat: PostgresProvider - Add POSTGRES_URL_OVERRIDE
2024-04-04 13:18:45 +11:00
boc-the-git
c0cf6a9aca Merge branch 'mealie-next' into postgres-url-feature 2024-04-04 13:12:39 +11:00
Kuchenpirat
f4570faf1a cleanup: Add Organizers translation (#3415)
* Add Organizers translation

* 🧹
2024-04-03 15:07:20 -05:00
Tarek Al-Qarqaz
9548a7eb70 fix: removed period in POSTGRES_URL_OVERRIDE for consistency 2024-04-03 14:01:30 +00:00
Tarek Al-Qarqaz
d5e3a1dacb change: updated POSTGRES_URL_OVERRIDE description 2024-04-03 14:00:25 +00:00
tba-code
1ce760ec7e Merge branch 'mealie-recipes:mealie-next' into postgres-url-feature 2024-04-03 08:57:19 -05:00
github-actions[bot]
9e23ed1a07 docs(auto): Update image tag, for release v1.4.0 (#3411)
* Update image tag, for release v1.4.0

* Commit without changing anything.. to trigger workflows on PR 3411

---------

Co-authored-by: boc-the-git <3479092+boc-the-git@users.noreply.github.com>
2024-04-03 06:02:19 -05:00
Tarek Al-Qarqaz
b3885cc3f8 change: docs now use TZ variable over read only bind mount /etc/timezone 2024-04-02 16:38:19 +00:00
tba-code
5da990abd4 Merge branch 'mealie-recipes:mealie-next' into postgres-url-feature 2024-04-02 10:18:48 -05:00
Tarek Al-Qarqaz
cb7302d2d9 fix: added validation to POSTGRES_URL_OVERRIDE 2024-04-02 12:24:51 +00:00
Tarek Al-Qarqaz
a30084a199 change: POSTGRES_URL_OVERRIDE note wording in docs 2024-04-02 11:23:06 +00:00
tba-code
c0654a5d95 Merge branch 'mealie-recipes:mealie-next' into postgres-url-feature 2024-04-02 06:21:35 -05:00
tba-code
945810c47a Merge branch 'mealie-recipes:mealie-next' into postgres-url-feature 2024-04-01 06:32:17 -05:00
Tarek Al-Qarqaz
35f6b0e80e fix: POSTGRES_URL is now POSTGRES_URL_OVERRIDE 2024-03-31 04:49:41 +00:00
Tarek Al-Qarqaz
ab37c2e8c0 change: reverted BASE_URL value, removed notes, removed mention of POSTGRES_URL_OVERRIDE 2024-03-31 04:48:21 +00:00
Tarek Al-Qarqaz
d1f82df936 change: reverted BASE_URL value, removed note, removed incorrect lines 2024-03-31 04:47:15 +00:00
Tarek Al-Qarqaz
6c7cb7e795 change: rename POSTGRES_URL to POSTGRES_URL_OVERRIDE / no longer changes value 2024-03-31 04:42:38 +00:00
tba-code
ecf80b8e9c Merge branch 'mealie-recipes:mealie-next' into postgres-url-feature 2024-03-30 18:50:20 -05:00
Tarek Al-Qarqaz
24d8854723 fix: typo in db_providers.py 2024-03-30 20:55:00 +00:00
Tarek Al-Qarqaz
2f9b711973 revert: revert typo in docker tag. 2024-03-30 20:18:13 +00:00
Tarek Al-Qarqaz
2b09495e87 fix: update sqlite doc for consistency 2024-03-30 19:39:15 +00:00
Tarek Al-Qarqaz
ae5a1a9af2 feat: PostgresProvider - Add POSTGRES_URL override. 2024-03-30 19:38:23 +00:00
139 changed files with 3359 additions and 2036 deletions

View File

@@ -30,7 +30,6 @@
"dbaeumer.vscode-eslint",
"matangover.mypy",
"ms-python.black-formatter",
"ms-python.isort",
"ms-python.pylint",
"ms-python.python",
"ms-python.vscode-pylance",
@@ -42,6 +41,7 @@
"forwardPorts": [
3000,
9000,
9091, // used by docker production
24678 // used by nuxt when hot-reloading using polling
],
// Use 'onCreateCommand' to run commands at the end of container creation.

View File

@@ -66,7 +66,7 @@ jobs:
id: cache-validate
if: steps.cached-poetry-dependencies.outputs.cache-hit == 'true'
run: |
echo "import black;print('venv good?')" > test.py && poetry run python test.py && echo "cache-hit-success=true" >> $GITHUB_OUTPUT
echo "import fastapi;print('venv good?')" > test.py && poetry run python test.py && echo "cache-hit-success=true" >> $GITHUB_OUTPUT
rm test.py
continue-on-error: true
@@ -78,9 +78,9 @@ jobs:
poetry add "psycopg2-binary==2.9.9"
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' || steps.cache-validate.outputs.cache-hit-success != 'true'
- name: Formatting (Black)
- name: Formatting (Ruff)
run: |
poetry run black . --check
poetry run ruff format . --check
- name: Lint (Ruff)
run: |

View File

@@ -10,7 +10,8 @@ repos:
- id: end-of-file-fixer
- id: trailing-whitespace
exclude: ^tests/data/
- repo: https://github.com/psf/black
rev: 24.1.0
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.3.5
hooks:
- id: black
- id: ruff-format

View File

@@ -60,8 +60,5 @@
},
"[vue]": {
"editor.formatOnSave": false
},
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
},
}
}

View File

@@ -74,6 +74,7 @@ tasks:
desc: run code generators
cmds:
- poetry run python dev/code-generation/main.py
- task: py:format
dev:services:
desc: starts postgres and mailpit containers
@@ -105,7 +106,7 @@ tasks:
py:format:
desc: runs python code formatter
cmds:
- poetry run black mealie
- poetry run ruff format .
py:lint:
desc: runs python linter
@@ -146,6 +147,12 @@ tasks:
cmds:
- poetry run python mealie/app.py
py:migrate:
desc: generates a new migration file e.g. task py:migrate:generate "add new column"
cmds:
- poetry run alembic revision --autogenerate -m "{{ .CLI_ARGS }}"
- task: py:format
ui:build:
desc: builds the frontend in frontend/dist
dir: frontend

View File

@@ -58,15 +58,3 @@ sqlalchemy.url =
# post_write_hooks defines scripts or Python functions that are run
# on newly generated revision scripts. See the documentation for further
# detail and examples
hooks = isort, black
# format using "isort" - use the console_scripts runner, against the "isort" entrypoint
isort.type = console_scripts
isort.entrypoint = isort
isort.options = REVISION_SCRIPT_FILENAME
# format using "black" - use the console_scripts runner, against the "black" entrypoint
black.type = console_scripts
black.entrypoint = black
black.options = REVISION_SCRIPT_FILENAME

View File

@@ -22,7 +22,11 @@ target_metadata = SqlAlchemyBase.metadata
# Set DB url from config
settings = get_app_settings()
config.set_main_option("sqlalchemy.url", settings.DB_URL)
if not settings.DB_URL:
raise Exception("DB URL not set in config")
config.set_main_option("sqlalchemy.url", settings.DB_URL.replace("%", "%%"))
def run_migrations_offline():

View File

@@ -0,0 +1,229 @@
"""migrate favorites and ratings to user_ratings
Revision ID: d7c6efd2de42
Revises: 09aba125b57a
Create Date: 2024-03-18 02:28:15.896959
"""
from datetime import datetime
from textwrap import dedent
from typing import Any
from uuid import uuid4
import sqlalchemy as sa
from sqlalchemy import orm
import mealie.db.migration_types
from alembic import op
# revision identifiers, used by Alembic.
revision = "d7c6efd2de42"
down_revision = "09aba125b57a"
branch_labels = None
depends_on = None
def is_postgres():
return op.get_context().dialect.name == "postgresql"
def new_user_rating(user_id: Any, recipe_id: Any, rating: float | None = None, is_favorite: bool = False):
if is_postgres():
id = str(uuid4())
else:
id = "%.32x" % uuid4().int
now = datetime.now().isoformat()
return {
"id": id,
"user_id": user_id,
"recipe_id": recipe_id,
"rating": rating,
"is_favorite": is_favorite,
"created_at": now,
"update_at": now,
}
def migrate_user_favorites_to_user_ratings():
bind = op.get_bind()
session = orm.Session(bind=bind)
with session:
user_ids_and_recipe_ids = session.execute(sa.text("SELECT user_id, recipe_id FROM users_to_favorites")).all()
rows = [
new_user_rating(user_id, recipe_id, is_favorite=True)
for user_id, recipe_id in user_ids_and_recipe_ids
if user_id and recipe_id
]
if is_postgres():
query = dedent(
"""
INSERT INTO users_to_recipes (id, user_id, recipe_id, rating, is_favorite, created_at, update_at)
VALUES (:id, :user_id, :recipe_id, :rating, :is_favorite, :created_at, :update_at)
ON CONFLICT DO NOTHING
"""
)
else:
query = dedent(
"""
INSERT OR IGNORE INTO users_to_recipes
(id, user_id, recipe_id, rating, is_favorite, created_at, update_at)
VALUES (:id, :user_id, :recipe_id, :rating, :is_favorite, :created_at, :update_at)
"""
)
for row in rows:
session.execute(sa.text(query), row)
def migrate_group_to_user_ratings(group_id: Any):
bind = op.get_bind()
session = orm.Session(bind=bind)
with session:
user_ids = (
session.execute(sa.text("SELECT id FROM users WHERE group_id=:group_id").bindparams(group_id=group_id))
.scalars()
.all()
)
recipe_ids_ratings = session.execute(
sa.text(
"SELECT id, rating FROM recipes WHERE group_id=:group_id AND rating > 0 AND rating IS NOT NULL"
).bindparams(group_id=group_id)
).all()
# Convert recipe ratings to user ratings. Since we don't know who
# rated the recipe initially, we copy the rating to all users.
rows: list[dict] = []
for recipe_id, rating in recipe_ids_ratings:
for user_id in user_ids:
rows.append(new_user_rating(user_id, recipe_id, rating, is_favorite=False))
if is_postgres():
insert_query = dedent(
"""
INSERT INTO users_to_recipes (id, user_id, recipe_id, rating, is_favorite, created_at, update_at)
VALUES (:id, :user_id, :recipe_id, :rating, :is_favorite, :created_at, :update_at)
ON CONFLICT (user_id, recipe_id) DO NOTHING;
"""
)
else:
insert_query = dedent(
"""
INSERT OR IGNORE INTO users_to_recipes
(id, user_id, recipe_id, rating, is_favorite, created_at, update_at)
VALUES (:id, :user_id, :recipe_id, :rating, :is_favorite, :created_at, :update_at);
"""
)
update_query = dedent(
"""
UPDATE users_to_recipes
SET rating = :rating, update_at = :update_at
WHERE user_id = :user_id AND recipe_id = :recipe_id;
"""
)
# Create new user ratings with is_favorite set to False
for row in rows:
session.execute(sa.text(insert_query), row)
# Update existing user ratings with the correct rating
for row in rows:
session.execute(sa.text(update_query), row)
def migrate_to_user_ratings():
migrate_user_favorites_to_user_ratings()
bind = op.get_bind()
session = orm.Session(bind=bind)
with session:
group_ids = session.execute(sa.text("SELECT id FROM groups")).scalars().all()
for group_id in group_ids:
migrate_group_to_user_ratings(group_id)
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"users_to_recipes",
sa.Column("user_id", mealie.db.migration_types.GUID(), nullable=False),
sa.Column("recipe_id", mealie.db.migration_types.GUID(), nullable=False),
sa.Column("rating", sa.Float(), nullable=True),
sa.Column("is_favorite", sa.Boolean(), nullable=False),
sa.Column("id", mealie.db.migration_types.GUID(), nullable=False),
sa.Column("created_at", sa.DateTime(), nullable=True),
sa.Column("update_at", sa.DateTime(), nullable=True),
sa.ForeignKeyConstraint(
["recipe_id"],
["recipes.id"],
),
sa.ForeignKeyConstraint(
["user_id"],
["users.id"],
),
sa.PrimaryKeyConstraint("user_id", "recipe_id", "id"),
sa.UniqueConstraint("user_id", "recipe_id", name="user_id_recipe_id_rating_key"),
)
op.create_index(op.f("ix_users_to_recipes_created_at"), "users_to_recipes", ["created_at"], unique=False)
op.create_index(op.f("ix_users_to_recipes_is_favorite"), "users_to_recipes", ["is_favorite"], unique=False)
op.create_index(op.f("ix_users_to_recipes_rating"), "users_to_recipes", ["rating"], unique=False)
op.create_index(op.f("ix_users_to_recipes_recipe_id"), "users_to_recipes", ["recipe_id"], unique=False)
op.create_index(op.f("ix_users_to_recipes_user_id"), "users_to_recipes", ["user_id"], unique=False)
migrate_to_user_ratings()
if is_postgres():
op.drop_index("ix_users_to_favorites_recipe_id", table_name="users_to_favorites")
op.drop_index("ix_users_to_favorites_user_id", table_name="users_to_favorites")
op.alter_column("recipes", "rating", existing_type=sa.INTEGER(), type_=sa.Float(), existing_nullable=True)
else:
op.execute("DROP INDEX IF EXISTS ix_users_to_favorites_recipe_id")
op.execute("DROP INDEX IF EXISTS ix_users_to_favorites_user_id")
with op.batch_alter_table("recipes") as batch_op:
batch_op.alter_column("rating", existing_type=sa.INTEGER(), type_=sa.Float(), existing_nullable=True)
op.drop_table("users_to_favorites")
op.create_index(op.f("ix_recipes_rating"), "recipes", ["rating"], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column(
"recipes_ingredients", "quantity", existing_type=sa.Float(), type_=sa.INTEGER(), existing_nullable=True
)
op.drop_index(op.f("ix_recipes_rating"), table_name="recipes")
op.alter_column("recipes", "rating", existing_type=sa.Float(), type_=sa.INTEGER(), existing_nullable=True)
op.create_unique_constraint("ingredient_units_name_group_id_key", "ingredient_units", ["name", "group_id"])
op.create_unique_constraint("ingredient_foods_name_group_id_key", "ingredient_foods", ["name", "group_id"])
op.create_table(
"users_to_favorites",
sa.Column("user_id", sa.CHAR(length=32), nullable=True),
sa.Column("recipe_id", sa.CHAR(length=32), nullable=True),
sa.ForeignKeyConstraint(
["recipe_id"],
["recipes.id"],
),
sa.ForeignKeyConstraint(
["user_id"],
["users.id"],
),
sa.UniqueConstraint("user_id", "recipe_id", name="user_id_recipe_id_key"),
)
op.create_index("ix_users_to_favorites_user_id", "users_to_favorites", ["user_id"], unique=False)
op.create_index("ix_users_to_favorites_recipe_id", "users_to_favorites", ["recipe_id"], unique=False)
op.drop_index(op.f("ix_users_to_recipes_user_id"), table_name="users_to_recipes")
op.drop_index(op.f("ix_users_to_recipes_recipe_id"), table_name="users_to_recipes")
op.drop_index(op.f("ix_users_to_recipes_rating"), table_name="users_to_recipes")
op.drop_index(op.f("ix_users_to_recipes_is_favorite"), table_name="users_to_recipes")
op.drop_index(op.f("ix_users_to_recipes_created_at"), table_name="users_to_recipes")
op.drop_table("users_to_recipes")
# ### end Alembic commands ###

View File

@@ -3,8 +3,6 @@ import re
from dataclasses import dataclass
from pathlib import Path
import black
import isort
from jinja2 import Template
from rich.logging import RichHandler
@@ -23,10 +21,7 @@ def render_python_template(template_file: Path | str, dest: Path, data: dict):
text = tplt.render(data=data)
text = black.format_str(text, mode=black.FileMode())
dest.write_text(text)
isort.file(dest)
@dataclass

View File

@@ -14,6 +14,7 @@ services:
- 9091:9000
environment:
ALLOW_SIGNUP: "false"
LOG_LEVEL: "DEBUG"
DB_ENGINE: sqlite # Optional: 'sqlite', 'postgres'
# =====================================

View File

@@ -40,10 +40,11 @@ init
GUNICORN_PORT=${API_PORT:-9000}
# Start API
hostip=`/sbin/ip route|awk '/default/ { print $3 }'`
HOST_IP=`/sbin/ip route|awk '/default/ { print $3 }'`
if [ "$WEB_GUNICORN" = 'true' ]; then
echo "Starting Gunicorn"
exec gunicorn mealie.app:app -b 0.0.0.0:$GUNICORN_PORT --forwarded-allow-ips=$hostip -k uvicorn.workers.UvicornWorker -c /app/gunicorn_conf.py --preload
exec gunicorn mealie.app:app -b 0.0.0.0:$GUNICORN_PORT --forwarded-allow-ips=$HOST_IP -k uvicorn.workers.UvicornWorker -c /app/gunicorn_conf.py --preload
else
exec uvicorn mealie.app:app --host 0.0.0.0 --forwarded-allow-ips=$hostip --port $GUNICORN_PORT
exec python /app/mealie/main.py
fi

View File

@@ -15,6 +15,8 @@
| API_DOCS | True | Turns on/off access to the API documentation locally. |
| TZ | UTC | Must be set to get correct date/time on the server |
| ALLOW_SIGNUP<super>\*</super> | false | Allow user sign-up without token |
| LOG_CONFIG_OVERRIDE | | Override the config for logging with a custom path |
| LOG_LEVEL | info | logging level configured |
<super>\*</super> Starting in v1.4.0 this was changed to default to `false` as apart of a security review of the application.
@@ -27,14 +29,15 @@
### Database
| Variables | Default | Description |
| ----------------- | :------: | -------------------------------- |
| DB_ENGINE | sqlite | Optional: 'sqlite', 'postgres' |
| POSTGRES_USER | mealie | Postgres database user |
| POSTGRES_PASSWORD | mealie | Postgres database password |
| POSTGRES_SERVER | postgres | Postgres database server address |
| POSTGRES_PORT | 5432 | Postgres database port |
| POSTGRES_DB | mealie | Postgres database name |
| Variables | Default | Description |
| --------------------- | :------: | ----------------------------------------------------------------------- |
| DB_ENGINE | sqlite | Optional: 'sqlite', 'postgres' |
| POSTGRES_USER | mealie | Postgres database user |
| POSTGRES_PASSWORD | mealie | Postgres database password |
| POSTGRES_SERVER | postgres | Postgres database server address |
| POSTGRES_PORT | 5432 | Postgres database port |
| POSTGRES_DB | mealie | Postgres database name |
| POSTGRES_URL_OVERRIDE | None | Optional Postgres URL override to use instead of POSTGRES\_\* variables |
### Email
@@ -95,6 +98,7 @@ For usage, see [Usage - OpenID Connect](../authentication/oidc.md)
| OIDC_PROVIDER_NAME | OAuth | The provider name is shown in SSO login button. "Login with <OIDC_PROVIDER_NAME\>" |
| OIDC_REMEMBER_ME | False | Because redirects bypass the login screen, you cant extend your session by clicking the "Remember Me" checkbox. By setting this value to true, a session will be extended as if "Remember Me" was checked |
| OIDC_SIGNING_ALGORITHM | RS256 | The algorithm used to sign the id token (examples: RS256, HS256) |
| OIDC_USER_CLAIM | email | Optional: 'email', 'preferred_username' |
### Themeing

View File

@@ -0,0 +1,16 @@
# Logs
:octicons-tag-24: v1.5.0
## Highlighs
- Logs are written to `/app/data/mealie.log` by default in the container.
- Logs are also written to stdout and stderr.
- You can adjust the log level using the `LOG_LEVEL` environment variable.
## Configuration
Starting in v1.5.0 logging is now highly configurable. Using the `LOG_CONFIG_OVERRIDE` you can provide the application with a custom configuration to log however you'd like. This configuration file is based off the [Python Logging Config](https://docs.python.org/3/library/logging.config.html#logging.config.fileConfig). It can be difficult to understand the configuration at first, so here are some resources to help get started.
- This [YouTube Video](https://www.youtube.com/watch?v=9L77QExPmI0) for a great walkthrough on the logging file format.
- Our [Logging Config](https://github.com/mealie-recipes/mealie/blob/mealie-next/mealie/core/logger/logconf.prod.json)

View File

@@ -5,40 +5,39 @@ PostgreSQL might be considered if you need to support many concurrent users. In
**For Environment Variable Configuration, see** [Backend Configuration](./backend-config.md)
```yaml
---
version: "3.7"
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v1.3.2 # (3)
image: ghcr.io/mealie-recipes/mealie:v1.4.0 # (3)
container_name: mealie
restart: always
ports:
- "9925:9000" # (1)
deploy:
resources:
limits:
memory: 1000M # (2)
depends_on:
- postgres
volumes:
- mealie-data:/app/data/
environment:
# Set Backend ENV Variables Here
- ALLOW_SIGNUP=true
- PUID=1000
- PGID=1000
- TZ=America/Anchorage
- MAX_WORKERS=1
- WEB_CONCURRENCY=1
- BASE_URL=https://mealie.yourdomain.com
# Set Backend ENV Variables Here
ALLOW_SIGNUP: true
PUID: 1000
PGID: 1000
TZ: America/Anchorage
MAX_WORKERS: 1
WEB_CONCURRENCY: 1
BASE_URL: https://mealie.yourdomain.com
# Database Settings
DB_ENGINE: postgres
POSTGRES_USER: mealie
POSTGRES_PASSWORD: mealie
POSTGRES_SERVER: postgres
POSTGRES_PORT: 5432
POSTGRES_DB: mealie
depends_on:
postgres:
condition: service_healthy
# Database Settings
- DB_ENGINE=postgres
- POSTGRES_USER=mealie
- POSTGRES_PASSWORD=mealie
- POSTGRES_SERVER=postgres
- POSTGRES_PORT=5432
- POSTGRES_DB=mealie
restart: always
postgres:
container_name: postgres
image: postgres:15
@@ -48,12 +47,15 @@ services:
environment:
POSTGRES_PASSWORD: mealie
POSTGRES_USER: mealie
healthcheck:
test: ["CMD", "pg_isready"]
interval: 30s
timeout: 20s
retries: 3
volumes:
mealie-data:
driver: local
mealie-pgdata:
driver: local
```
<!-- Updating This? Be Sure to also update the SQLite Annotations -->

View File

@@ -9,12 +9,11 @@ SQLite is a popular, open source, self-contained, zero-configuration database th
**For Environment Variable Configuration, see** [Backend Configuration](./backend-config.md)
```yaml
---
version: "3.7"
services:
mealie:
image: ghcr.io/mealie-recipes/mealie:v1.3.2 # (3)
image: ghcr.io/mealie-recipes/mealie:v1.4.0 # (3)
container_name: mealie
restart: always
ports:
- "9925:9000" # (1)
deploy:
@@ -24,19 +23,17 @@ services:
volumes:
- mealie-data:/app/data/
environment:
# Set Backend ENV Variables Here
- ALLOW_SIGNUP=true
- PUID=1000
- PGID=1000
- TZ=America/Anchorage
- MAX_WORKERS=1
- WEB_CONCURRENCY=1
- BASE_URL=https://mealie.yourdomain.com
restart: always
# Set Backend ENV Variables Here
ALLOW_SIGNUP: true
PUID: 1000
PGID: 1000
TZ: America/Anchorage
MAX_WORKERS: 1
WEB_CONCURRENCY: 1
BASE_URL: https://mealie.yourdomain.com
volumes:
mealie-data:
driver: local
```
<!-- Updating This? Be Sure to also update the Postgres Annotations -->

View File

@@ -73,6 +73,7 @@ nav:
- PostgreSQL: "documentation/getting-started/installation/postgres.md"
- Backend Configuration: "documentation/getting-started/installation/backend-config.md"
- Security: "documentation/getting-started/installation/security.md"
- Logs: "documentation/getting-started/installation/logs.md"
- Usage:
- Backup and Restoring: "documentation/getting-started/usage/backups-and-restoring.md"
- Permissions and Public Access: "documentation/getting-started/usage/permissions-and-public-access.md"

View File

@@ -19,7 +19,7 @@
<script lang="ts">
import { defineComponent, computed, useContext } from "@nuxtjs/composition-api";
import RecipeOrganizerSelector from "~/components/Domain/Recipe/RecipeOrganizerSelector.vue";
import { RecipeTag, RecipeCategory } from "~/lib/api/types/group";
import { RecipeTag, RecipeCategory } from "~/lib/api/types/recipe";
export default defineComponent({
components: {

View File

@@ -21,7 +21,7 @@
<v-spacer></v-spacer>
<div v-if="!open" class="custom-btn-group ma-1">
<RecipeFavoriteBadge v-if="loggedIn" class="mx-1" color="info" button-style :slug="recipe.slug" show-always />
<RecipeFavoriteBadge v-if="loggedIn" class="mx-1" color="info" button-style :recipe-id="recipe.id" show-always />
<RecipeTimelineBadge v-if="loggedIn" button-style :slug="recipe.slug" :recipe-name="recipe.name" />
<div v-if="loggedIn">
<v-tooltip v-if="!locked" bottom color="info">

View File

@@ -35,9 +35,9 @@
<slot name="actions">
<v-card-actions v-if="showRecipeContent" class="px-1">
<RecipeFavoriteBadge v-if="isOwnGroup" class="absolute" :slug="slug" show-always />
<RecipeFavoriteBadge v-if="isOwnGroup" class="absolute" :recipe-id="recipeId" show-always />
<RecipeRating class="pb-1" :value="rating" :name="name" :slug="slug" :small="true" />
<RecipeRating class="pb-1" :value="rating" :recipe-id="recipeId" :slug="slug" :small="true" />
<v-spacer></v-spacer>
<RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" url-prefix="tags" />
@@ -97,6 +97,10 @@ export default defineComponent({
required: false,
default: 0,
},
ratingColor: {
type: String,
default: "secondary",
},
image: {
type: String,
required: false,

View File

@@ -38,17 +38,14 @@
</v-list-item-subtitle>
<div class="d-flex flex-wrap justify-end align-center">
<slot name="actions">
<RecipeFavoriteBadge v-if="isOwnGroup && showRecipeContent" :slug="slug" show-always />
<v-rating
v-if="showRecipeContent"
color="secondary"
<RecipeFavoriteBadge v-if="isOwnGroup && showRecipeContent" :recipe-id="recipeId" show-always />
<RecipeRating
:class="isOwnGroup ? 'ml-auto' : 'ml-auto pb-2'"
background-color="secondary lighten-3"
dense
length="5"
size="15"
:value="rating"
></v-rating>
:recipe-id="recipeId"
:slug="slug"
:small="true"
/>
<v-spacer></v-spacer>
<!-- If we're not logged-in, no items display, so we hide this menu -->
@@ -85,12 +82,14 @@ import { computed, defineComponent, useContext, useRoute } from "@nuxtjs/composi
import RecipeFavoriteBadge from "./RecipeFavoriteBadge.vue";
import RecipeContextMenu from "./RecipeContextMenu.vue";
import RecipeCardImage from "./RecipeCardImage.vue";
import RecipeRating from "./RecipeRating.vue";
import { useLoggedInState } from "~/composables/use-logged-in-state";
export default defineComponent({
components: {
RecipeFavoriteBadge,
RecipeContextMenu,
RecipeRating,
RecipeCardImage,
},
props: {

View File

@@ -18,7 +18,7 @@
<script lang="ts">
import { computed, defineComponent, useContext, useRoute } from "@nuxtjs/composition-api";
import { RecipeCategory, RecipeTag, RecipeTool } from "~/lib/api/types/user";
import { RecipeCategory, RecipeTag, RecipeTool } from "~/lib/api/types/recipe";
export type UrlPrefixParam = "tags" | "categories" | "tools";

View File

@@ -22,11 +22,12 @@
<script lang="ts">
import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";
import { useUserSelfRatings } from "~/composables/use-users";
import { useUserApi } from "~/composables/api";
import { UserOut } from "~/lib/api/types/user";
export default defineComponent({
props: {
slug: {
recipeId: {
type: String,
default: "",
},
@@ -42,19 +43,23 @@ export default defineComponent({
setup(props) {
const api = useUserApi();
const { $auth } = useContext();
const { userRatings, refreshUserRatings } = useUserSelfRatings();
// TODO Setup the correct type for $auth.user
// See https://github.com/nuxt-community/auth-module/issues/1097
const user = computed(() => $auth.user as unknown as UserOut);
const isFavorite = computed(() => user.value?.favoriteRecipes?.includes(props.slug));
const isFavorite = computed(() => {
const rating = userRatings.value.find((r) => r.recipeId === props.recipeId);
return rating?.isFavorite || false;
});
async function toggleFavorite() {
if (!isFavorite.value) {
await api.users.addFavorite(user.value?.id, props.slug);
await api.users.addFavorite(user.value?.id, props.recipeId);
} else {
await api.users.removeFavorite(user.value?.id, props.slug);
await api.users.removeFavorite(user.value?.id, props.recipeId);
}
$auth.fetchUser();
await refreshUserRatings();
}
return { isFavorite, toggleFavorite };

View File

@@ -46,7 +46,7 @@
<script lang="ts">
import { defineComponent, ref, useContext, computed, onMounted } from "@nuxtjs/composition-api";
import RecipeOrganizerDialog from "./RecipeOrganizerDialog.vue";
import { RecipeCategory, RecipeTag } from "~/lib/api/types/user";
import { RecipeCategory, RecipeTag } from "~/lib/api/types/recipe";
import { RecipeTool } from "~/lib/api/types/admin";
import { useTagStore } from "~/composables/store/use-tag-store";
import { useCategoryStore, useToolStore } from "~/composables/store";

View File

@@ -5,7 +5,7 @@
<v-card-text>
<v-card-title class="headline pa-0 flex-column align-center">
{{ recipe.name }}
<RecipeRating :key="recipe.slug" v-model="recipe.rating" :name="recipe.name" :slug="recipe.slug" />
<RecipeRating :key="recipe.slug" :value="recipe.rating" :recipe-id="recipe.id" :slug="recipe.slug" />
</v-card-title>
<v-divider class="my-2"></v-divider>
<SafeMarkdown :source="recipe.description" />

View File

@@ -20,7 +20,7 @@
v-if="landscape && $vuetify.breakpoint.smAndUp"
:key="recipe.slug"
v-model="recipe.rating"
:name="recipe.name"
:recipe-id="recipe.id"
:slug="recipe.slug"
/>
</div>

View File

@@ -24,7 +24,7 @@
v-if="$vuetify.breakpoint.smAndDown"
:key="recipe.slug"
v-model="recipe.rating"
:name="recipe.name"
:recipe-id="recipe.id"
:slug="recipe.slug"
/>
</div>

View File

@@ -1,34 +1,35 @@
<template>
<div @click.prevent>
<v-rating
v-model="rating"
:readonly="!isOwnGroup"
color="secondary"
background-color="secondary lighten-3"
length="5"
:dense="small ? true : undefined"
:size="small ? 15 : undefined"
hover
:value="value"
clearable
@input="updateRating"
@click="updateRating"
></v-rating>
<v-hover v-slot="{ hover }">
<v-rating
:value="rating.ratingValue"
:half-increments="(!hover) || (!isOwnGroup)"
:readonly="!isOwnGroup"
:color="hover ? attrs.hoverColor : attrs.color"
:background-color="attrs.backgroundColor"
length="5"
:dense="small ? true : undefined"
:size="small ? 15 : undefined"
hover
clearable
@input="updateRating"
@click="updateRating"
/>
</v-hover>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from "@nuxtjs/composition-api";
import { computed, defineComponent, ref, useContext, watch } from "@nuxtjs/composition-api";
import { useLoggedInState } from "~/composables/use-logged-in-state";
import { useUserApi } from "~/composables/api";
import { useUserSelfRatings } from "~/composables/use-users";
export default defineComponent({
props: {
emitOnly: {
type: Boolean,
default: false,
},
// TODO Remove name prop?
name: {
recipeId: {
type: String,
default: "",
},
@@ -44,26 +45,79 @@ export default defineComponent({
type: Boolean,
default: false,
},
preferGroupRating: {
type: Boolean,
default: false,
},
},
setup(props, context) {
const { $auth } = useContext();
const { isOwnGroup } = useLoggedInState();
const { userRatings, setRating, ready: ratingsLoaded } = useUserSelfRatings();
const hideGroupRating = ref(false);
const rating = ref(props.value);
type Rating = {
ratingValue: number | undefined;
hasUserRating: boolean | undefined
};
const api = useUserApi();
function updateRating(val: number | null) {
if (val === 0) {
val = null;
// prefer user rating over group rating
const rating = computed<Rating>(() => {
if (!ratingsLoaded.value) {
return { ratingValue: undefined, hasUserRating: undefined };
}
if (!($auth.user?.id) || props.preferGroupRating) {
return { ratingValue: props.value, hasUserRating: false };
}
const userRating = userRatings.value.find((r) => r.recipeId === props.recipeId);
return {
ratingValue: userRating?.rating || (hideGroupRating.value ? 0 : props.value),
hasUserRating: !!userRating?.rating
};
});
// if a user unsets their rating, we don't want to fall back to the group rating since it's out of sync
watch(
() => rating.value.hasUserRating,
() => {
if (rating.value.hasUserRating && !props.preferGroupRating) {
hideGroupRating.value = true;
}
},
)
const attrs = computed(() => {
return isOwnGroup.value ? {
// Logged-in user
color: rating.value.hasUserRating ? "secondary" : "grey darken-1",
hoverColor: "secondary",
backgroundColor: "secondary lighten-3",
} : {
// Anonymous user
color: "secondary",
hoverColor: "secondary",
backgroundColor: "secondary lighten-3",
};
})
function updateRating(val: number | null) {
if (!isOwnGroup.value) {
return;
}
if (!props.emitOnly) {
api.recipes.patchOne(props.slug, {
rating: val,
});
setRating(props.slug, val || 0, null);
}
context.emit("input", val);
}
return { isOwnGroup, rating, updateRating };
return {
attrs,
isOwnGroup,
rating,
updateRating,
};
},
});
</script>

View File

@@ -188,7 +188,7 @@
},
{
icon: $globals.icons.organizers,
title: "Organizers",
title: i18n.tc("general.organizers"),
restricted: true,
children: [
{

View File

@@ -2,7 +2,7 @@ import { reactive, ref, useAsync } from "@nuxtjs/composition-api";
import { useAsyncKey } from "../use-utils";
import { useUserApi } from "~/composables/api";
import { VForm } from "~/types/vuetify";
import { RecipeTool } from "~/lib/api/types/user";
import { RecipeTool } from "~/lib/api/types/recipe";
export const useTools = function (eager = true) {
const workingToolData = reactive<RecipeTool>({

View File

@@ -2,7 +2,7 @@ import { reactive, ref, Ref } from "@nuxtjs/composition-api";
import { usePublicStoreActions, useStoreActions } from "../partials/use-actions-factory";
import { usePublicExploreApi } from "../api/api-client";
import { useUserApi } from "~/composables/api";
import { RecipeCategory } from "~/lib/api/types/admin";
import { RecipeCategory } from "~/lib/api/types/recipe";
const categoryStore: Ref<RecipeCategory[]> = ref([]);
const publicStoreLoading = ref(false);

View File

@@ -1,2 +1,3 @@
export { useUserForm } from "./user-form";
export { useUserRegistrationForm } from "./user-registration-form";
export { useUserSelfRatings } from "./user-ratings";

View File

@@ -0,0 +1,40 @@
import { ref, useContext } from "@nuxtjs/composition-api";
import { useUserApi } from "~/composables/api";
import { UserRatingSummary } from "~/lib/api/types/user";
const userRatings = ref<UserRatingSummary[]>([]);
const loading = ref(false);
const ready = ref(false);
export const useUserSelfRatings = function () {
const { $auth } = useContext();
const api = useUserApi();
async function refreshUserRatings() {
if (loading.value) {
return;
}
loading.value = true;
const { data } = await api.users.getSelfRatings();
userRatings.value = data?.ratings || [];
loading.value = false;
ready.value = true;
}
async function setRating(slug: string, rating: number | null, isFavorite: boolean | null) {
loading.value = true;
const userId = $auth.user?.id || "";
await api.users.setRating(userId, slug, rating, isFavorite);
loading.value = false;
await refreshUserRatings();
}
refreshUserRatings();
return {
userRatings,
refreshUserRatings,
setRating,
ready,
}
}

View File

@@ -207,7 +207,8 @@
"created-on-date": "Geskep op: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Is jy seker jy wil <b>{groupName}<b/> uitvee?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "Welkom, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Bestuur jou profiel, resepte en groepverstellings.",
"get-invite-link": "Kry uitnodigingskakel",
"get-public-link": "Kry openbare skakel",
"account-summary": "Rekeningopsomming",
"account-summary-description": "Hier is 'n opsomming van jou groep se inligting",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Groepstatistieke",
"group-statistics-description": "Jou groepstatistieke gee 'n bietjie insig hoe jy Mealie gebruik.",
"storage-capacity": "Stoorkapasiteit",
"storage-capacity-description": "Jou stoorkapasiteit is 'n berekening van die prente en dokumente wat jy opgelaai het.",
"personal": "Persoonlik",
"personal-description": "Dit is jou persoonlike verstellings. Veranderinge hier sal nie ander gebruikers beïnvloed nie",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Gebruikers verstellings",
"user-settings-description": "Bestuur jou voorkeure, verander jou wagwoord en werk jou e-posadres op",
"api-tokens-description": "Bestuur jou API-tokens vir toegang vanaf eksterne toepassings",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Hierdie items word binne jou groep gedeel. Deur een van hulle te wysig, sal dit vir die hele groep verander!",
"group-settings": "Groep verstellings",
"group-settings-description": "Bestuur jou algemene groep verstellings soos eetplan en privaatheidinstellings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Kennisgewers",
"notifiers-description": "Stel e-pos- en stootkennisgewings op wat deur spesifieke gebeurtenisse geaktiveer word.",
"manage-data": "Databestuur",
"manage-data-description": "Bestuur jou kos en eenhede (meer opsies kom binnekort)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data-migrasies",
"data-migrations-description": "Migreer jou bestaande data vanaf ander toepassings, soos Nextcloud-resepte en Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-pos gestuur",
"error-sending-email": "Kon nie die e-pos stuur nie",
"personal-information": "Persoonlike inligting",

View File

@@ -207,7 +207,8 @@
"created-on-date": "تم الإنشاء في {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "هل انت متأكد من رغبتك في حذف <b>{groupName}<b/>؟",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Създадено на {0}",
"unsaved-changes": "Имате незапазени промени. Желаете ли да ги запазите преди да излезете? Натиснете Ок за запазване и Отказ за отхвърляне на промените.",
"clipboard-copy-failure": "Линкът към рецептата е копиран в клипборда.",
"confirm-delete-generic-items": "Сигурни ли сте, че желаете да изтриете следните елементи?"
"confirm-delete-generic-items": "Сигурни ли сте, че желаете да изтриете следните елементи?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Сигурни ли сте, че искате да изтриете <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Добре дошъл(а), {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Настройки на профил, рецепти и настройки на групата.",
"get-invite-link": "Вземи линк за покана",
"get-public-link": "Вземи публичен линк",
"account-summary": "Обобщение на акаунта",
"account-summary-description": "Обобщение на информацията за Вашата група",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Статистики на групата",
"group-statistics-description": "Вашата статистика на групата дава известна представа как използвате Mealie.",
"storage-capacity": "Капацитет за съхранение",
"storage-capacity-description": "Вашият капацитет за съхранение е изчисление на изображенията и активите, които сте качили.",
"personal": "Лични",
"personal-description": "Това са настройки, които са лични за Вас. Промените тук няма да засегнат други потребители",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Потребителски настройки",
"user-settings-description": "Нстройки на предпочитанията, смяна на парола и актуализация на имей адрес",
"api-tokens-description": "Управление на API токени за достъп от външни приложения",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Тези елементи се споделят във вашата група. Редактирането на един от тях ще го промени за цялата група!",
"group-settings": "Настройки на групата",
"group-settings-description": "Общи групови настройки като седмично меню и настройки за поверителност.",
@@ -1192,9 +1193,9 @@
"notifiers": "Уведомители",
"notifiers-description": "Настройте имейл и push известия, които се задействат при конкретни събития.",
"manage-data": "Управление на данни",
"manage-data-description": "Настройки на продукти и мерни единици (очаквайте добавяне на още възможности)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Миграция на данни",
"data-migrations-description": "Мигрирайте вашите съществуващи данни от други приложения като Nextcloud Recipes и Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Имейлът е изпратен",
"error-sending-email": "Грешка при изпращане на имейл",
"personal-information": "Лична информация",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Creat el: {0}",
"unsaved-changes": "Tens canvis que no estan guardats. Vols guardar-los abans de sortir? Clica d'acord per guardar-los o cancel·lar per descartar els canvis.",
"clipboard-copy-failure": "No s'ha pogut copiar al porta-retalls.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Esteu segur de voler suprimir el grup <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Benvingut, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Enllaç públic",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Vytvořeno dne: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Jste si jisti, že chcete smazat <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Vítejte, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Přehled účtu",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Statistiky skupiny",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Kapacita úložiště",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Osobní",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Uživatelské nastavení",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Nastavení skupiny",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Oznámení",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Spravovat data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migrace dat",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-mail odeslán",
"error-sending-email": "Nastala chyba při odesílání e-mailu",
"personal-information": "Osobní údaje",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Oprettet den: {0}",
"unsaved-changes": "Du har ændringer som ikke er gemt. Vil du gemme før du forlader? Vælg \"Okay\" for at gemme, eller \"Annullér\" for at kassere ændringer.",
"clipboard-copy-failure": "Kopiering til udklipsholderen mislykkedes.",
"confirm-delete-generic-items": "Er du sikker på at du ønsker at slette de valgte emner?"
"confirm-delete-generic-items": "Er du sikker på at du ønsker at slette de valgte emner?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Er du sikker på, du vil slette <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Velkommen, {0}",
"welcome-user": "👋 Velkommen, {0}!",
"description": "Administrer din profil, opskrifter og gruppeindstillinger.",
"get-invite-link": "Få Invitationslink",
"get-public-link": "Offentligt link",
"account-summary": "Konto oversigt",
"account-summary-description": "Her er en oversigt over din gruppes oplysninger",
"account-summary-description": "Her er en oversigt over din gruppes oplysninger.",
"group-statistics": "Gruppestatistik",
"group-statistics-description": "Din gruppestatistik giver indsigt i, hvordan du bruger Mealie.",
"storage-capacity": "Lagerkapacitet",
"storage-capacity-description": "Din lagerkapacitet er en beregning af de billeder og elementer, du har uploadet.",
"personal": "Personlig",
"personal-description": "Disse indstillinger er personlige for dig. Ændringer her vil ikke påvirke andre brugere",
"personal-description": "Disse indstillinger er personlige for dig. Ændringer vil ikke påvirke andre brugere.",
"user-settings": "Brugerindstillinger",
"user-settings-description": "Administrer dine indstillinger, din adgangskode eller din e-mail",
"api-tokens-description": "Administrer dine API Tokens, der giver adgang til eksterne applikationer",
"user-settings-description": "Administrer dine indstillinger, din adgangskode eller din e-mail.",
"api-tokens-description": "Administrer dine API Tokens for adgang fra eksterne applikationer.",
"group-description": "Disse elementer deles i din gruppe. Redigering af et af dem vil ændre det for hele gruppen!",
"group-settings": "Gruppeindstillinger",
"group-settings-description": "Administrer dine fælles gruppeindstillinger såsom madplaner og privatlivsindstillinger.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifikationer",
"notifiers-description": "Opsæt e-mail og push-notifikationer, der udløser på specifikke begivenheder.",
"manage-data": "Administrer data",
"manage-data-description": "Administrer dine fødevarer og enheder (flere muligheder kommer snart)",
"manage-data-description": "Administrer dine Mealie data; Mad, Enheder, Kategorier, Tags og meget mere.",
"data-migrations": "Migrering af data",
"data-migrations-description": "Migrer dine eksisterende data fra andre programmer som Nextcloud Recipes og Chowdown",
"data-migrations-description": "Migrér dine eksisterende data fra andre programmer som Nextcloud Opskrifter og Chowdown.",
"email-sent": "E-mail sendt",
"error-sending-email": "Fejl ved afsendelse af email",
"personal-information": "Personlige oplysninger",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Erstellt am: {0}",
"unsaved-changes": "Du hast ungespeicherte Änderungen. Möchtest du vor dem Verlassen speichern? OK um zu speichern, Cancel um Änderungen zu verwerfen.",
"clipboard-copy-failure": "Fehler beim Kopieren in die Zwischenablage.",
"confirm-delete-generic-items": "Bist du dir sicher, dass du die folgenden Einträge löschen möchtest?"
"confirm-delete-generic-items": "Bist du dir sicher, dass du die folgenden Einträge löschen möchtest?",
"organizers": "Organisieren"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Bist du dir sicher, dass du die Gruppe <b>{groupName}<b/> löschen möchtest?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Willkommen, {0}",
"welcome-user": "👋 Willkommen, {0}!",
"description": "Verwalte dein Profil, Rezepte und Gruppeneinstellungen.",
"get-invite-link": "Einladungslink erzeugen",
"get-public-link": "Öffentlichen Link abrufen",
"account-summary": "Kontoübersicht",
"account-summary-description": "Hier ist eine Übersicht der Informationen deiner Gruppe",
"account-summary-description": "Hier ist eine Zusammenfassung der Details deiner Gruppe.",
"group-statistics": "Gruppenstatistik",
"group-statistics-description": "Deine Gruppenstatistik gibt dir einen Einblick, wie du Mealie verwendest.",
"storage-capacity": "Speicherplatz",
"storage-capacity-description": "Dein Speicherplatz wird anhand der Bilder und Anhänge berechnet, die du hochgeladen hast.",
"personal": "Persönlich",
"personal-description": "Das sind deine persönlichen Einstellungen. Änderungen hier wirken sich nicht auf andere Benutzer aus",
"personal-description": "Das sind deine persönlichen Einstellungen. Änderungen hier wirken sich nicht auf andere Benutzer aus.",
"user-settings": "Benutzereinstellungen",
"user-settings-description": "Verwalte deine Einstellungen, ändere dein Passwort und aktualisiere deine E-Mail-Adresse",
"api-tokens-description": "Verwalte deine API Token für den Zugriff von externen Anwendungen",
"user-settings-description": "Verwalte deine Einstellungen, ändere dein Passwort und aktualisiere deine E-Mail-Adresse.",
"api-tokens-description": "Verwalte deine API Token für den Zugriff von externen Anwendungen.",
"group-description": "Diese Elemente werden innerhalb deiner Gruppe geteilt. Änderungen wirken sich auf die gesamte Gruppe aus!",
"group-settings": "Gruppen-Einstellungen",
"group-settings-description": "Verwalte deine allgemeinen Gruppeneinstellungen wie Essenspläne und Privatsphäre.",
@@ -1192,9 +1193,9 @@
"notifiers": "Benachrichtigungen",
"notifiers-description": "Richte E-Mail und Push-Benachrichtigungen ein, die bei bestimmten Ereignissen ausgelöst werden.",
"manage-data": "Daten verwalten",
"manage-data-description": "Verwalte deine Rezepte, Lebensmittel, Einheiten und Etiketten (weitere Optionen kommen bald)",
"manage-data-description": "Verwalte deine Mealie-Daten: Lebensmittel, Einheiten, Kategorien, Schlagworte und mehr.",
"data-migrations": "Datenmigration",
"data-migrations-description": "Migriere deine vorhandenen Daten aus anderen Anwendungen wie Nextcloud-Rezepte und Chowdown",
"data-migrations-description": "Migriere deine vorhandenen Daten aus anderen Anwendungen wie Nextcloud-Rezepte und Chowdown.",
"email-sent": "E-Mail gesendet",
"error-sending-email": "Fehler beim Senden der E-Mail",
"personal-information": "Persönliche Daten",

View File

@@ -174,7 +174,7 @@
"units": "Μονάδες",
"back": "Πίσω",
"next": "Επόμενο",
"start": "Start",
"start": "Εναρξη",
"toggle-view": "Εναλλαγή προβολής",
"date": "Ημερομηνία",
"id": "Αναγνωριστικό",
@@ -207,7 +207,8 @@
"created-on-date": "Δημιουργήθηκε στις: {0}",
"unsaved-changes": "Εχετε μη αποθηκευμένες αλλαγές. Θέλετε να κάνετε αποθήκευση πριν από την αποχώρηση; Εντάξει για αποθήκευση, Ακυρο για απόρριψη των αλλαγών.",
"clipboard-copy-failure": "Η αντιγραφή στο πρόχειρο απέτυχε.",
"confirm-delete-generic-items": "Θέλετε σίγουρα να διαγράψετε τα ακόλουθα αντικείμενα;"
"confirm-delete-generic-items": "Θέλετε σίγουρα να διαγράψετε τα ακόλουθα αντικείμενα;",
"organizers": "Οργανωτές"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Θέλετε σίγουρα να διαγράψετε αυτό τον ασφαλή σύνδεσμο <b>{groupName}<b/>;",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Καλώς ορίσατε, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Ακολουθεί μια περίληψη των πληροφοριών της ομάδας σας.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "Αυτές είναι προσωπικές ρυθμίσεις σας. Οι αλλαγές εδώ δεν θα επηρεάσουν άλλους χρήστες.",
"user-settings": "User Settings",
"user-settings-description": "Διαχειριστείτε τις προτιμήσεις σας, αλλάξτε τον κωδικό πρόσβασής σας και ενημερώστε το email σας",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Διαχειριστείτε τις προτιμήσεις σας, αλλάξτε τον κωδικό πρόσβασής σας και ενημερώστε το email σας.",
"api-tokens-description": "Διαχειριστείτε τα API Tokens σας για πρόσβαση από εξωτερικές εφαρμογές.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Διαχειριστείτε τα δεδομένα σας στο Mealie. Τρόφιμα, Μονάδες, Κατηγορίες, Ετικέτες και πολλά άλλα.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organisers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
@@ -371,7 +372,7 @@
"title": "Plan to Eat",
"description-long": "Mealie can import recipies from Plan to Eat."
},
"myrecipebox" : {
"myrecipebox": {
"title": "My Recipe Box",
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
}
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Set up email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Creado el {0}",
"unsaved-changes": "Tienes cambios sin guardar. ¿Quieres guardar antes de salir? Aceptar para guardar, Cancelar para descartar cambios.",
"clipboard-copy-failure": "No se pudo copiar al portapapeles.",
"confirm-delete-generic-items": "¿Estás seguro que quieres eliminar los siguientes elementos?"
"confirm-delete-generic-items": "¿Estás seguro que quieres eliminar los siguientes elementos?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Por favor, confirma que deseas eliminar <b>{groupName}<b/>",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Hola, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Administra tu perfil, recetas y ajustes de grupo.",
"get-invite-link": "Obtener enlace de invitación",
"get-public-link": "Obtener enlace público",
"account-summary": "Información de la cuenta",
"account-summary-description": "Este es un resumen de la información de tu grupo",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Estadísticas del grupo",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Capacidad de almacenamiento",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Ajustes de usuario",
"user-settings-description": "Administrar preferencias, cambiar contraseña y actualizar correo electrónico",
"api-tokens-description": "Administra tus API Tokens para acceder desde aplicaciones externas",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Ajustes de grupo",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notificaciones",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Administrar datos",
"manage-data-description": "Administra tu Comida y Unidades (próximamente más opciones)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migración de datos",
"data-migrations-description": "Migrar tus datos existentes de otras aplicaciones como Nextcloud Recipes y Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email enviado",
"error-sending-email": "Error enviando email",
"personal-information": "Datos Personales",

View File

@@ -80,12 +80,12 @@
"recipe-events": "Recipe Events"
},
"general": {
"add": "Add",
"add": "Lisää",
"cancel": "Peruuta",
"clear": "Tyhjennä",
"close": "Sulje",
"confirm": "Vahvista",
"confirm-how-does-everything-look": "How does everything look?",
"confirm-how-does-everything-look": "Miltä näyttää?",
"confirm-delete-generic": "Haluatko varmasti poistaa tämän?",
"copied_message": "Kopioitu!",
"create": "Luo",
@@ -116,10 +116,10 @@
"json": "JSON",
"keyword": "Hakusana",
"link-copied": "Linkki kopioitu",
"loading": "Loading",
"loading": "Ladataan",
"loading-events": "Ladataan tapahtumia",
"loading-recipe": "Loading recipe...",
"loading-ocr-data": "Loading OCR data...",
"loading-recipe": "Ladataan reseptiä...",
"loading-ocr-data": "Ladataan tekstintunnistustietoja...",
"loading-recipes": "Ladataan reseptejä",
"message": "Viesti",
"monday": "Maanantai",
@@ -130,7 +130,7 @@
"no-recipe-found": "Reseptiä ei löytynyt",
"ok": "OK",
"options": "Valinnat:",
"plural-name": "Plural Name",
"plural-name": "Monikollinen nimi",
"print": "Tulosta",
"print-preferences": "Tulosta asetukset",
"random": "Satunnainen",
@@ -144,18 +144,18 @@
"save": "Tallenna",
"settings": "Asetukset",
"share": "Jaa",
"show-all": "Show All",
"show-all": "Näytä kaikki",
"shuffle": "Sekoita",
"sort": "Järjestä",
"sort-ascending": "Sort Ascending",
"sort-descending": "Sort Descending",
"sort-ascending": "Järjestä nousevasti",
"sort-descending": "Järjestä laskevasti",
"sort-alphabetically": "Aakkosjärjestyksessä",
"status": "Tila",
"subject": "Aihe",
"submit": "Lähetä",
"success-count": "Onnistui: {count}",
"sunday": "Sunnuntai",
"system": "System",
"system": "Järjestelmä",
"templates": "Mallipohjat:",
"test": "Testi",
"themes": "Teemat",
@@ -174,7 +174,7 @@
"units": "Yksiköt",
"back": "Takaisin",
"next": "Seuraava",
"start": "Start",
"start": "Aloita",
"toggle-view": "Vaihda näkymää",
"date": "Päivämäärä",
"id": "Id",
@@ -205,9 +205,10 @@
"refresh": "Päivitä",
"upload-file": "Tuo tiedosto",
"created-on-date": "Luotu {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"unsaved-changes": "Et ole tallentanut tekemiäsi muutoksia. Tallennetaanko ne? Paina \"ok\" tallentaaksesi ja \"peruuta\", jos et halua tallentaa.",
"clipboard-copy-failure": "Kopioiminen leikepöydälle epäonnistui.",
"confirm-delete-generic-items": "Haluatko varmasti poistaa seuraavat kohteet?",
"organizers": "Järjestäjät"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Haluatko varmasti poistaa ryhmän <b>{groupName}<b/>?",
@@ -222,7 +223,7 @@
"group-id-with-value": "Ryhmän ID: {groupID}",
"group-name": "Ryhmän nimi",
"group-not-found": "Ryhmää ei löytynyt",
"group-token": "Group Token",
"group-token": "Ryhmän tunnus",
"group-with-value": "Ryhmä: {groupID}",
"groups": "Ryhmät",
"manage-groups": "Hallitse ryhmiä",
@@ -243,8 +244,8 @@
"group-preferences": "Ryhmän oletusasetukset",
"private-group": "Yksityinen ryhmä",
"private-group-description": "Jos asetat ryhmäsi yksityiseksi, kaikki julkisen näkymän asetukset ovat oletusarvoisia. Tämä ohittaa yksittäisten reseptien julkisen näkymän asetukset.",
"enable-public-access": "Enable Public Access",
"enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in",
"enable-public-access": "Salli julkinen käyttö",
"enable-public-access-description": "Julkista ryhmän reseptit automaattisesti ja anna vierailijoiden nähdä reseptit kirjautumatta sisään",
"allow-users-outside-of-your-group-to-see-your-recipes": "Anna muiden kuin ryhmäsi jäsenten nähdä reseptisi",
"allow-users-outside-of-your-group-to-see-your-recipes-description": "Kun tämä on käytössä, voit käyttää julkista jakolinkkiä tiettyjen reseptien jakamiseen ilman käyttäjän valtuutusta. Kun se on poistettu käytöstä, voit jakaa reseptejä vain käyttäjien kanssa, jotka ovat ryhmässäsi tai joilla on ennalta luotu yksityinen linkki",
"show-nutrition-information": "Näytä ravintotiedot",
@@ -260,7 +261,7 @@
"general-preferences": "Yleiset Asetukset",
"group-recipe-preferences": "Ryhmän reseptiasetukset",
"report": "Raportti",
"report-with-id": "Report ID: {id}",
"report-with-id": "Ilmoituksen tunnus: {id}",
"group-management": "Ryhmien hallinta",
"admin-group-management": "Ylläpitoryhmien hallinta",
"admin-group-management-text": "Muutokset tähän ryhmään tulevat näkymään välittömästi.",
@@ -358,11 +359,11 @@
},
"recipe-data-migrations": "Reseptien tietojen migraatiot",
"recipe-data-migrations-explanation": "Reseptit voidaan siirtää toisesta tuetusta sovelluksesta Mealie -sovellukseen. Tämä on hyvä tapa päästä alkuun Mealiella.",
"coming-from-another-application-or-an-even-older-version-of-mealie": "Coming from another application or an even older version of Mealie? Check out migrations and see if your data can be imported.",
"coming-from-another-application-or-an-even-older-version-of-mealie": "Olitko toisessa sovelluksessa tai Mealien aiemmassa versiossa? Tarkista, voidaanko tietosi siirtää.",
"choose-migration-type": "Valitse migraatiotyyppi",
"tag-all-recipes": "Merkitse kaikki reseptit tunnisteella {tag-name}",
"nextcloud-text": "Nextcloud reseptejä voidaan tuoda zip-tiedostosta, joka sisältää Nextcloudiin tallennetut tiedot. Katso esimerkkikansiorakenne alla varmistaaksesi, että reseptisi voidaan tuoda.",
"chowdown-text": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below.",
"chowdown-text": "Mealie tukee Chowdown-säilömistä. Lataa koodin arkisto zip-tiedostona alempaa.",
"recipe-1": "Resepti 1",
"recipe-2": "Resepti 2",
"paprika-text": "Mealie voi tuoda reseptejä Paprika-sovelluksesta. Vie reseptisi ohjelmasta ulos, nimeä tiedoston pääte uudelleen .zip ja lataa se alla.",
@@ -372,8 +373,8 @@
"description-long": "Mealieen voi tuoda reseptejä Plan to Eat -sovelluksesta."
},
"myrecipebox": {
"title": "My Recipe Box",
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
"title": "Reseptilaatikkoni",
"description-long": "Voit tuoda Mealieen reseptejä reseptilaatikosta. Tuo reseptisi csv-muodossa ja lataa sitten csv-tiedosto alempaa."
}
},
"new-recipe": {
@@ -487,12 +488,12 @@
"add-to-plan": "Lisää suunnitelmaan",
"add-to-timeline": "Lisää aikajanalle",
"recipe-added-to-list": "Resepti lisätty listalle",
"recipes-added-to-list": "Recipes added to list",
"successfully-added-to-list": "Successfully added to list",
"recipes-added-to-list": "Reseptit lisätty luetteloon",
"successfully-added-to-list": "Luetteloon lisääminen onnistui",
"recipe-added-to-mealplan": "Resepti lisätty ateriasuunnitelmaan",
"failed-to-add-recipes-to-list": "Failed to add recipe to list",
"failed-to-add-recipes-to-list": "Luetteloon lisääminen epäonnistui",
"failed-to-add-recipe-to-mealplan": "Reseptiä ei voitu lisätä ateriasuunnitelmaan",
"failed-to-add-to-list": "Failed to add to list",
"failed-to-add-to-list": "Luetteloon lisääminen epäonnistui",
"yield": "Sato",
"quantity": "Määrä",
"choose-unit": "Valitse Yksikkö",
@@ -508,8 +509,8 @@
"cook-mode": "Kokkitila",
"link-ingredients": "Linkitä Ainesosat",
"merge-above": "Yhdistä Yläpuolelle",
"move-to-bottom": "Move To Bottom",
"move-to-top": "Move To Top",
"move-to-bottom": "Siirrä alas",
"move-to-top": "Siirrä ylös",
"reset-scale": "Palauta skaala",
"decrease-scale-label": "Vähennä mittakaavaa yhdellä",
"increase-scale-label": "Suurenna mittakaavaa yhdellä",
@@ -525,18 +526,18 @@
"edit-timeline-event": "Muokkaa Aikajanan Tapahtumaa",
"timeline": "Aikajana",
"timeline-is-empty": "Aikajana on tyhjä. Tee resepti.",
"timeline-no-events-found-try-adjusting-filters": "No events found. Try adjusting your search filters.",
"timeline-no-events-found-try-adjusting-filters": "Tapahtumia ei löytynyt. Voit yrittää muuttaa hakusuodattimia.",
"group-global-timeline": "{groupName} Yleinen Aikajana",
"open-timeline": "Avaa aikajana",
"made-this": "Tein tämän",
"how-did-it-turn-out": "Miten se onnistui?",
"user-made-this": "{user} teki tämän",
"last-made-date": "Viimeksi valmistettu {date}",
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
"api-extras-description": "Reseptiekstrat ovat Mealien API:n tärkeä ominaisuus. Niiden avulla voidaan luoda mukautettuja JSON-avain/arvo-pareja reseptin sisällä viitaten kolmannen osapuolen sovelluksiin. Näitä avaimia voi käyttää tiedon antamiseksi, esimerkiksi automaattisen toiminnon tai mukautetun viestin käynnistämiseksi haluamaasi laitteeseen.",
"message-key": "Viestiavain",
"parse": "Jäsennä",
"attach-images-hint": "Liitä kuvia vetämällä ja pudottamalla ne editoriin",
"drop-image": "Drop image",
"drop-image": "Tuo kuva",
"enable-ingredient-amounts-to-use-this-feature": "Käytä ainesosan määriä käyttääksesi tätä ominaisuutta",
"recipes-with-units-or-foods-defined-cannot-be-parsed": "Reseptejä, joissa on yksiköitä tai elintarvikkeita, ei voida jäsentää.",
"parse-ingredients": "Jäsennä ainekset",
@@ -546,8 +547,8 @@
"looking-for-migrations": "Etsitkö Migraatioita?",
"import-with-url": "Tuo URL-osoitteesta",
"create-recipe": "Luo Resepti",
"create-recipe-description": "Create a new recipe from scratch.",
"create-recipes": "Create Recipes",
"create-recipe-description": "Luo resepti alusta.",
"create-recipes": "Luo reseptejä",
"import-with-zip": "Tuo .zip:llä",
"create-recipe-from-an-image": "Luo resepti kuvasta",
"bulk-url-import": "Massa tuonti URL-osoitteesta",
@@ -581,7 +582,7 @@
"upload-image": "Lataa kuva",
"screen-awake": "Pidä näyttö aina päällä",
"remove-image": "Poista kuva",
"nextStep": "Next step"
"nextStep": "Seuraava askel"
},
"search": {
"advanced-search": "Tarkennettu haku",
@@ -600,16 +601,16 @@
"search-hint": "Paina '/'",
"advanced": "Lisäasetukset",
"auto-search": "Automaattinen Haku",
"no-results": "No results found"
"no-results": "Ei tuloksia"
},
"settings": {
"add-a-new-theme": "Lisää uusi teema",
"admin-settings": "Ylläpitäjän asetukset",
"backup": {
"backup-created": "Backup created successfully",
"backup-created": "Varmuuskopio luotu",
"backup-created-at-response-export_path": "Varmuuskopio luotu sijaintiin {path}",
"backup-deleted": "Varmuuskopio poistettu",
"restore-success": "Restore successful",
"restore-success": "Palautus onnistui",
"backup-tag": "Varmuuskopion tunniste",
"create-heading": "Create a Backup",
"delete-backup": "Poista varmuuskopio",
@@ -618,7 +619,7 @@
"import-summary": "Tuo yhteenveto",
"partial-backup": "Osittainen varmuuskopiointi",
"unable-to-delete-backup": "Varmuuskopiota ei voi poistaa.",
"experimental-description": "Backups are total snapshots of the database and data directory of the site. This includes all data and cannot be set to exclude subsets of data. You can think of this as a snapshot of Mealie at a specific time. These serve as a database agnostic way to export and import data, or back up the site to an external location.",
"experimental-description": "Varmuuskopiot ovat sivuston tietokannan ja -hakemiston tilannekuvia. Siihen sisältyy kaikki tieto, eikä siitä voi poistaa tietojen osajoukkoja. Tämä on verrattavissa tilannekuvaan Mealiesta tiettynä ajankohtana. Nämä toimivat tietokantojen tapana tuoda ja viedä tietoja sekä sivuston varmuuskopioina ulkoisessa sijainnissa.",
"backup-restore": "Varmuuskopion palautus",
"back-restore-description": "Tämän varmuuskopion palauttaminen korvaa kaikki tietokannassasi ja tietokannassasi olevat tiedot ja korvaa ne tämän varmuuskopion sisällöllä. {cannot-be-undone} Jos palautus onnistuu, sinut kirjataan ulos.",
"cannot-be-undone": "Tätä toimintoa ei voi kumota - käytä varoen.",
@@ -710,7 +711,7 @@
"webhooks-caps": "WEBHOOKIT",
"webhooks": "Webhookit",
"webhook-name": "Webhookin nimi",
"description": "The webhooks defined below will be executed when a meal is defined for the day. At the scheduled time the webhooks will be sent with the data from the recipe that is scheduled for the day. Note that webhook execution is not exact. The webhooks are executed on a 5 minutes interval so the webhooks will be executed within 5 +/- minutes of the scheduled."
"description": "Alla olevat nettikoukut suoritetaan, kun päivälle on määritelty ateria. Tiettynä ajankohtana koukut lähetetään päivän mukaisen reseptin tietojen mukana. Koukkujen suoritusaika ei ole tarkka, vaan niitä suoritetaan viiden minuutin välein."
},
"bug-report": "Virheraportti",
"bug-report-information": "Käytä näitä tietoja raportoidaksesi viasta. Kehittäjille annettavien tietojen antaminen on paras tapa saada ongelmasi ratkaistua nopeasti.",
@@ -718,13 +719,13 @@
"configuration": "Konfigurointi",
"docker-volume": "Docker-kontin tiedostojärjestelmä",
"docker-volume-help": "Mealie vaatii, että frontend-kontti ja backend jakaa saman dockerin tiedostojärjestelmän tai varaston. Näin varmistetaan, että frontend-kontti pääsee kunnolla käsiksi levylle tallennettuihin kuviin ja resursseihin.",
"volumes-are-misconfigured": "Volumes are misconfigured.",
"volumes-are-misconfigured": "Äänenvoimakkuudet ovat virheellisiä.",
"volumes-are-configured-correctly": "Tiedostojärjestelmät ovat oikein konfiguroitu.",
"status-unknown-try-running-a-validation": "Tila tuntematon. Yritä suorittaa validointi.",
"validate": "Vahvista",
"email-configuration-status": "Sähköpostin varmistuksen tila",
"email-configured": "Email Configured",
"email-test-results": "Email Test Results",
"email-configured": "Sähköposti on määritelty",
"email-test-results": "Sähköpostin testin tulokset",
"ready": "Valmis",
"not-ready": "Ei Valmis - Tarkista Ympäristömuuttujat",
"succeeded": "Onnistui",
@@ -736,15 +737,15 @@
"secure-site": "Turvallinen Sivusto",
"secure-site-error-text": "Palvele paikallisen tai suojatun palvelimen kautta https-sovelluksella. Leikepöytä ja muut selaimen API-sovellukset eivät välttämättä toimi.",
"secure-site-success-text": "Sivustolle pääsee localhost tai https",
"server-side-base-url": "Server Side Base URL",
"server-side-base-url": "Palvelimen pohja-URL",
"server-side-base-url-error-text": "`BASE_URL` on API-palvelimen oletusarvo. Tämä aiheuttaa ongelmia ilmoitusten linkkien kanssa, jotka on luotu palvelimella sähköposteja varten jne.",
"server-side-base-url-success-text": "Server Side URL does not match the default",
"server-side-base-url-success-text": "Palvelimen nettiosoite ei vastaa oletusta",
"ldap-ready": "LDAP Valmis",
"ldap-ready-error-text": "Kaikkia LDAP-arvoja ei ole määritetty. Tämä voidaan ohittaa, jos et käytä LDAP-todennusta.",
"ldap-ready-success-text": "Kaikki vaaditut LDAP-muuttujat on asetettu.",
"build": "Koonti",
"recipe-scraper-version": "Reseptikaappaimen versio",
"oidc-ready": "OIDC Ready",
"oidc-ready": "OIDC valmis",
"oidc-ready-error-text": "Not all OIDC Values are configured. This can be ignored if you are not using OIDC Authentication.",
"oidc-ready-success-text": "Required OIDC variables are all set."
},
@@ -1161,27 +1162,27 @@
"already-set-up-bring-to-homepage": "I'm already set up, just bring me to the homepage",
"common-settings-for-new-sites": "Here are some common settings for new sites",
"setup-complete": "Setup Complete!",
"here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie",
"restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.",
"manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others."
"here-are-a-few-things-to-help-you-get-started": "Näillä muutamilla asioilla pääset alkuun",
"restore-from-v1-backup": "Onko sinulla varmuuskopio aiemmasta Mealie v1 -instanssista? Palauta se tästä.",
"manage-profile-or-get-invite-link": "Hallitse profiiliasi tai hanki kutsulinkki muille."
}
},
"profile": {
"welcome-user": "👋 Tervetuloa, {0}",
"welcome-user": "👋 Tervetuloa, {0}!",
"description": "Hallitse profiiliasi, reseptejäsi ja ryhmäasetuksiasi.",
"get-invite-link": "Hanki Kutsulinkki",
"get-public-link": "Julkinen linkki",
"account-summary": "Tilin Yhteenveto",
"account-summary-description": "Tässä on yhteenveto ryhmäsi tiedoista",
"account-summary-description": "Tässä on yhteenveto ryhmäsi tiedoista.",
"group-statistics": "Ryhmätilastot",
"group-statistics-description": "Ryhmätilaston avulla saat tietoa siitä, miten käytät Mealietä.",
"storage-capacity": "Tallennustila",
"storage-capacity-description": "Tallennuskapasiteetti on laskettu niistä kuvista ja resursseista, jotka olet ladannut.",
"personal": "Henkilökohtainen",
"personal-description": "Nämä ovat henkilökohtaisia asetuksia, jotka eivät vaikuta muihin käyttäjiin",
"personal-description": "Nämä asetukset ovat henkilökohtaisia, eivätkä ne vaikuta muihin käyttäjiin.",
"user-settings": "Käyttäjäasetukset",
"user-settings-description": "Hallitse asetuksiasi, vaihda salasanasi ja päivitä sähköpostiosoitteesi",
"api-tokens-description": "Hallinnoi API-tunnisteitasi päästäksesi käsiksi ulkoisista sovelluksista",
"user-settings-description": "Hallitse asetuksiasi, muuta salasanaasi ja päivitä sähköpostiosoitteesi.",
"api-tokens-description": "Hallitse ulkoisten sovellusten API-tunnisteitasi.",
"group-description": "Nämä kohteet on jaettu ryhmässäsi. Yhden muokkaaminen muuttaa sitä koko ryhmälle!",
"group-settings": "Ryhmäasetukset",
"group-settings-description": "Hallinnoi ryhmäsi asetuksia kuten ateriasuunnitelmaa ja yksityisyysasetuksia.",
@@ -1192,9 +1193,9 @@
"notifiers": "Ilmoitukset",
"notifiers-description": "Määritä sähköposti- ja push-ilmoitukset, jotka käynnistävät tiettyjä tapahtumia.",
"manage-data": "Hallinnoi tietoja",
"manage-data-description": "Hallinnoi elintarvikkeita ja yksiköitä (lisää vaihtoehtoja tulossa pian)",
"manage-data-description": "Hallitse Mealie-tietojasi: elintarvikkeita, yksiköitä, luokkia, tunnisteita ja muita.",
"data-migrations": "Tietojen migraatiot",
"data-migrations-description": "Siirrä olemassa olevat tiedot muista sovelluksista, kuten Nextcloud Recipes ja Chowdown",
"data-migrations-description": "Siirrä tietosi muista sovelluksista, kuten Nextcloudista ja Chowdownista.",
"email-sent": "Sähköposti lähetetty",
"error-sending-email": "Virhe sähköpostin lähetyksessä",
"personal-information": "Henkilötiedot",
@@ -1222,7 +1223,7 @@
"require-all-tools": "Vaadi Kaikki Työkalut",
"cookbook-name": "Keittokirjan Nimi",
"cookbook-with-name": "Keittokirja {0}",
"create-a-cookbook": "Create a Cookbook",
"cookbook": "Cookbook"
"create-a-cookbook": "Luo keittokirja",
"cookbook": "Keittokirja"
}
}

View File

@@ -207,7 +207,8 @@
"created-on-date": "Créé le {0}",
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous les enregistrer? Ok pour enregistrer, annuler pour ignorer les modifications.",
"clipboard-copy-failure": "Échec de la copie vers le presse-papiers.",
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?"
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Êtes-vous certain de vouloir supprimer <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Bienvenue, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Gérez votre profil, les recettes et les paramètres de groupe.",
"get-invite-link": "Obtenir un lien d'invitation",
"get-public-link": "Voir le lien public",
"account-summary": "Aperçu du compte",
"account-summary-description": "Voici un résumé des informations de votre groupe",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Statistiques du groupe",
"group-statistics-description": "Les statistiques de votre groupe vous donnent un aperçu de la façon dont vous utilisez Mealie.",
"storage-capacity": "Capacité de stockage",
"storage-capacity-description": "Votre capacité de stockage est un calcul des images et des ressources que vous avez téléchargées.",
"personal": "Personnel",
"personal-description": "Ici se trouvent des paramètres qui vous sont propres personnellement. Toute modification n'affectera pas les autres utilisateurs.",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Paramètres utilisateur",
"user-settings-description": "Gérez vos préférences, changez votre mot de passe et mettez à jour votre adresse e-mail",
"api-tokens-description": "Gérez vos jetons API pour un accès à partir d'applications externes",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Ces éléments sont partagés au sein de votre groupe. Un changement impactera l'ensemble du groupe !",
"group-settings": "Paramètres de groupe",
"group-settings-description": "Gérez vos paramètres de groupe habituels tels que le menu de la semaine et les paramètres de confidentialité.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifications",
"notifiers-description": "Configurer les e-mails et les notifications push qui se déclenchent sur des événements spécifiques.",
"manage-data": "Gérer les données",
"manage-data-description": "Gérer vos Aliments et Unités (plus d'options seront bientôt disponibles)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migration des données",
"data-migrations-description": "Migrez vos données existantes à partir d'autres applications comme Nextcloud Cookbook et Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-mail envoyé",
"error-sending-email": "Erreur lors de l'envoi de l'email",
"personal-information": "Informations personnelles",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Créé le {0}",
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous enregistrer avant de partir? OK pour enregistrer, Annuler pour ignorer les modifications.",
"clipboard-copy-failure": "Échec de la copie dans le presse-papiers.",
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?"
"confirm-delete-generic-items": "Êtes-vous sûr de vouloir supprimer les éléments suivants ?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Voulez-vous vraiment supprimer <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Bienvenue, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Gérez votre profil, les recettes et les paramètres de groupe.",
"get-invite-link": "Obtenir un lien d'invitation",
"get-public-link": "Voir le lien public",
"account-summary": "Aperçu du compte",
"account-summary-description": "Voici un résumé des informations de votre groupe",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Statistiques du groupe",
"group-statistics-description": "Les statistiques de votre groupe vous donnent un aperçu de la façon dont vous utilisez Mealie.",
"storage-capacity": "Capacité de stockage",
"storage-capacity-description": "Votre capacité de stockage est un calcul des images et des ressources que vous avez téléchargées.",
"personal": "Personnel",
"personal-description": "Ici se trouvent des paramètres qui vous sont propres personnellement. Toute modification n'affectera pas les autres utilisateurs.",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Paramètres utilisateur",
"user-settings-description": "Gérez vos préférences, changez votre mot de passe et mettez à jour votre adresse e-mail",
"api-tokens-description": "Gérez vos jetons API pour un accès à partir d'applications externes",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Ces éléments sont partagés au sein de votre groupe. Un changement impactera l'ensemble du groupe !",
"group-settings": "Paramètres de groupe",
"group-settings-description": "Gérez vos paramètres de groupe habituels tels que le menu de la semaine et les paramètres de confidentialité.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifications",
"notifiers-description": "Configurer les e-mails et les notifications push qui se déclenchent sur des événements spécifiques.",
"manage-data": "Gérer les données",
"manage-data-description": "Gérer vos Aliments et Unités (plus d'options seront bientôt disponibles)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migration des données",
"data-migrations-description": "Migrez vos données existantes à partir d'autres applications comme Nextcloud Cookbook et Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-mail envoyé",
"error-sending-email": "Erreur lors de l'envoi de l'email",
"personal-information": "Informations personnelles",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "נוצר ב-{0}",
"unsaved-changes": "יש שינויים שלא נשמרו. לצאת לפני שמירה? אשר לשמירה, בטל למחיקת שינויים.",
"clipboard-copy-failure": "כשלון בהעתקה ללוח ההדבקה.",
"confirm-delete-generic-items": "האם אתה בטוח שברצונך למחוק את הפריטים הנבחרים?"
"confirm-delete-generic-items": "האם אתה בטוח שברצונך למחוק את הפריטים הנבחרים?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "האם את/ה בטוח/ה שברצונך למחוק את <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 שלום, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "ניהול פרופיל, מתכונים והגדרות קבוצה.",
"get-invite-link": "קבלת קישור להזמנה",
"get-public-link": "כתובת פומבית",
"account-summary": "פירוט משתמש",
"account-summary-description": "סיכום המידע של הקבוצות שלך",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "נתונים סטטיסטיים של קבוצה",
"group-statistics-description": "סטטיסטיקות על הקבוצה שלך.",
"storage-capacity": "מקום אחסון",
"storage-capacity-description": "מקום האחסון מחושב ע\"י סיכום התמונות והקבצים שהעלת.",
"personal": "אישי",
"personal-description": "הגדרות אישיות",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "הגדרות משתמש",
"user-settings-description": "העדפות, שינוי סיסמא, שינוי email",
"api-tokens-description": "נהל את ה API tokens עבור תכונות חיצוניות",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "פריטים אלו שותפו עם קבוצתך. עריכתם תבצע שינוי עבור כל הקבוצה!",
"group-settings": "הגדרות קבוצה",
"group-settings-description": "נהל את הגדרות הקבוצה כמו תוכנית ארוחות והגדרות פרטיות.",
@@ -1192,9 +1193,9 @@
"notifiers": "מתריעים",
"notifiers-description": "הגדרת הודעות דואל והודעות בדחיפה אשר יופעלו עם אירועים ספציפיים.",
"manage-data": "נהל נתונים",
"manage-data-description": "נהל את המאכלים ויחידות המדידה (אפשרויות נוספות יגיעו בקרוב)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "ניוד נתונים",
"data-migrations-description": "העבר לתוך מילי מידע קיים מאפליקציות אחרות כמו Nextcloud Recipes ו- Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "דוא\"ל נשלח",
"error-sending-email": "שגיאה בשליחת דוא\"ל",
"personal-information": "פרטים אישיים",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Kreirano dana: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Jeste li sigurni da želite izbrisati <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Dobrodošli, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Upravljajte svojim profilom, receptima i postavkama grupa.",
"get-invite-link": "Zatražite Poveznicu Pozivnice",
"get-public-link": "Get Public Link",
"account-summary": "Zbirni Prikaz Računa",
"account-summary-description": "Evo sažetka informacija o vašoj grupi",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Statistika Grupe",
"group-statistics-description": "Statistika vaše grupe pruža uvid u to kako koristite Mealie.",
"storage-capacity": "Prostor za Pohranu",
"storage-capacity-description": "Vaša kapacitet za pohranu je izračun temeljen na slikama i resursima koje ste prenijeli.",
"personal": "Osobno",
"personal-description": "Ovo su postavke koje su osobne samo za vas. Promjene ovdje neće utjecati na druge korisnike",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Korisničke Postavke",
"user-settings-description": "Upravljajte svojim postavkama, promijenite lozinku i ažurirajte svoju e-poštu",
"api-tokens-description": "Upravljajte svojim API tokenima za pristup izvanjskim aplikacijama",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Ovi predmeti su zajednički unutar vaše grupe. Uređivanje jednog od njih promijenit će ga za cijelu grupu!",
"group-settings": "Postavke grupe",
"group-settings-description": "Upravljajte zajedničkim postavkama grupe kao što su postavke plana obroka i privatnosti.",
@@ -1192,9 +1193,9 @@
"notifiers": "Obavještavači (Notifiers)",
"notifiers-description": "Postavi obavijesti putem e-pošte i push obavijesti koje se aktiviraju na određene događaje.",
"manage-data": "Upravljaj podacima",
"manage-data-description": "Upravljajte hranom i jedinicama mjere (uskoro će biti dostupno više opcija)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migracija podataka",
"data-migrations-description": "Migrirajte postojeće podatke iz drugih aplikacija poput Nextcloud Recipes i Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-pošta poslana",
"error-sending-email": "Pogreška pri slanju e-maila",
"personal-information": "Osobne informacije",

View File

@@ -155,7 +155,7 @@
"submit": "Küldés",
"success-count": "Sikeres: {count}",
"sunday": "Vasárnap",
"system": "System",
"system": "Rendszer",
"templates": "Sablonok:",
"test": "Teszt",
"themes": "Témák",
@@ -207,7 +207,8 @@
"created-on-date": "Létrehozva: {0}",
"unsaved-changes": "El nem mentett módosításai vannak. Szeretné elmenteni, mielőtt kilép? A mentéshez kattintson az Ok, a módosítások elvetéséhez a Mégsem gombra.",
"clipboard-copy-failure": "Nem sikerült a vágólapra másolás.",
"confirm-delete-generic-items": "Biztos benne, hogy törölni szeretné az alábbi tételeket?"
"confirm-delete-generic-items": "Biztos benne, hogy törölni szeretné az alábbi tételeket?",
"organizers": "Rendszerezők"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Biztosan törölni szeretnéd ezt: <b>{groupName}<b/>?",
@@ -243,7 +244,7 @@
"group-preferences": "Csoport beállítások",
"private-group": "Privát csoport",
"private-group-description": "Ha a csoportot privátra állítja, az összes nyilvános nézeti beállítás alapértelmezettre lesz állítva. Ez felülírja az egyes receptek nyilvános nézet beállításait.",
"enable-public-access": "Enable Public Access",
"enable-public-access": "Nyilvános hozzáférés engedélyezése",
"enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in",
"allow-users-outside-of-your-group-to-see-your-recipes": "Engedélyezze a csoporton kívüli felhasználók számára a receptek megtekintését",
"allow-users-outside-of-your-group-to-see-your-recipes-description": "Ha engedélyezve van, nyilvános megosztási hivatkozással megoszthat adott recepteket a felhasználó felhatalmazása nélkül. Ha le van tiltva, csak olyan felhasználókkal oszthat meg recepteket, akik a csoportjába tartoznak, vagy egy előre generált privát linkkel",
@@ -547,7 +548,7 @@
"import-with-url": "Importálás URL-címről",
"create-recipe": "Recept létrehozása",
"create-recipe-description": "Create a new recipe from scratch.",
"create-recipes": "Create Recipes",
"create-recipes": "Receptek létrehozása",
"import-with-zip": "Importálás .zip formátummal",
"create-recipe-from-an-image": "Recept létrehozása fotóról",
"bulk-url-import": "Tömeges URL importálás",
@@ -1157,31 +1158,31 @@
"tasks": "Feladatok",
"setup": {
"first-time-setup": "Első beállítás",
"welcome-to-mealie-get-started": "Welcome to Mealie! Let's get started",
"welcome-to-mealie-get-started": "Üdvözöl a Mealie! Vágjunk bele",
"already-set-up-bring-to-homepage": "I'm already set up, just bring me to the homepage",
"common-settings-for-new-sites": "Here are some common settings for new sites",
"setup-complete": "Beállítás kész!",
"here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie",
"restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.",
"restore-from-v1-backup": "Van egy korábbi Mealie v1 biztonsági másolatod? Itt visszaállíthatod.",
"manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others."
}
},
"profile": {
"welcome-user": "👋 Üdvözöljük, {0}",
"welcome-user": "👋 Üdvözöljük, {0}!",
"description": "Profiljának, receptjeinek és csoportbeállításainak kezelése.",
"get-invite-link": "Meghívó link beszerzése",
"get-public-link": "Nyilvánon link beszerzése",
"account-summary": "Fiók áttekintése",
"account-summary-description": "Itt egy áttekintés a csoportja információiról",
"account-summary-description": "Itt egy áttekintés a csoportja információiról.",
"group-statistics": "Csoportstatisztikák",
"group-statistics-description": "Az Ön csoportstatisztikái betekintést nyújtanak abba, hogyan használja a Mealie-t.",
"storage-capacity": "Tárhely mérete",
"storage-capacity-description": "A tárhely kapacitása az Ön által feltöltött képek és eszközök számításából adódik.",
"personal": "Személyes",
"personal-description": "Ezek a beállítások az Ön személyes beállításai. Az itt végzett változtatások nincsenek hatással más felhasználókra",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Felhasználói beállítások",
"user-settings-description": "Beállításainak kezelése, jelszavának módosítása és e-mail címének frissítése",
"api-tokens-description": "API tokenek kezelése külső alkalmazásokon keresztül történő hozzáféréshez",
"user-settings-description": "Itt kezelheti beállításait, módosíthatja jelszavát és frissítheti e-mail címét.",
"api-tokens-description": "API kulcsok kezelése külső alkalmazásokból.",
"group-description": "Ezek az elemek a csoporton belül megosztottak. Az egyik szerkesztése az egész csoport számára megváltoztatja azt!",
"group-settings": "Csoport beállításai",
"group-settings-description": "Közös csoportbeállítások, például menüterv és adatvédelmi beállítások kezelése.",
@@ -1192,9 +1193,9 @@
"notifiers": "Értesítések",
"notifiers-description": "Állítson be olyan e-mail és push-értesítéseket, amelyek meghatározott események esetén lépnek működésbe.",
"manage-data": "Adatok kezelése",
"manage-data-description": "Alapanyagainak és mennyiségi egységeinek kezelése (további opciók hamarosan)",
"manage-data-description": "Az Ön Mealie adatainak kezelése: alapanyagok, mértékegységek, kategóriák, címkék, stb.",
"data-migrations": "Adat migráció",
"data-migrations-description": "Migrálja meglévő adatait más alkalmazásokból, például a Nextcloud Recipes és a Chowdown",
"data-migrations-description": "Migrálja meglévő adatait más alkalmazásokból, például Nextcloud Recipes vagy Chowdown.",
"email-sent": "E-mail elküldve",
"error-sending-email": "Hiba történt az e-Mail küldésénél",
"personal-information": "Személyes adatok",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Set up email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Creato il: {0}",
"unsaved-changes": "Sono state apportate modifiche non salvate. Salvare prima di uscire? Premi Ok per salvare, Annulla per scartare le modifiche.",
"clipboard-copy-failure": "Impossibile copiare negli appunti.",
"confirm-delete-generic-items": "Sei sicuro di voler eliminare i seguenti elementi?"
"confirm-delete-generic-items": "Sei sicuro di voler eliminare i seguenti elementi?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Sei sicuro di volerlo eliminare <b>{groupName}<b/>'?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Benvenuto, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Gestisci il tuo profilo, le ricette e le impostazioni di gruppo.",
"get-invite-link": "Ottieni Link Di Invito",
"get-public-link": "Ottieni link pubblico",
"account-summary": "Riepilogo Account",
"account-summary-description": "Ecco un riepilogo delle informazioni del tuo gruppo",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Statistiche Gruppo",
"group-statistics-description": "Le statistiche di gruppo forniscono alcune informazioni su come stai usando Mealie.",
"storage-capacity": "Capacità di Archiviazione",
"storage-capacity-description": "La capacità di archiviazione è data dall'insieme delle immagini e delle risorse caricate.",
"personal": "Personale",
"personal-description": "Queste sono le tue impostazioni personali. Le modifiche non influenzeranno gli altri utenti",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Impostazioni Utente",
"user-settings-description": "Gestisci le tue preferenze, modifica la tua password e aggiorna la tua email",
"api-tokens-description": "Gestisci i tuoi Token API per l'accesso da applicazioni esterne",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Questi elementi sono condivisi all'interno del tuo gruppo. Modificando uno di essi cambierà per l'intero gruppo!",
"group-settings": "Impostazioni Gruppo",
"group-settings-description": "Gestisci le impostazioni comuni del gruppo, come il piano alimentare e impostazioni di privacy.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiche",
"notifiers-description": "Imposta email e notifiche push che si attivano per eventi specifici.",
"manage-data": "Gestisci Dati",
"manage-data-description": "Gestisci il tuoi Alimenti e le tue Unità (più opzioni in arrivo a breve)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migrazioni Dati",
"data-migrations-description": "Migra i dati esistenti da altre applicazioni come Nextcloud Recipes e Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Inviata",
"error-sending-email": "Errore Nell'Invio Email",
"personal-information": "Informazioni Personali",

View File

@@ -207,7 +207,8 @@
"created-on-date": "作成日: {0}",
"unsaved-changes": "保存されていない変更があります。移動する前に保存しますか?保存するには はい を、変更を破棄するにはキャンセルしてください。",
"clipboard-copy-failure": "クリップボードにコピーできませんでした",
"confirm-delete-generic-items": "次のアイテムを本当に削除しますか?"
"confirm-delete-generic-items": "次のアイテムを本当に削除しますか?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "<b>{groupName}<b/> を削除しますか?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 ようこそ, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "プロフィール、レシピ、グループ設定を管理します。",
"get-invite-link": "招待リンクを取得",
"get-public-link": "公開リンクを取得",
"account-summary": "アカウントの概要",
"account-summary-description": "グループ情報の概要は次のとおりです",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "グループ統計",
"group-statistics-description": "グループ統計によりMealieの使用状況がわかります。",
"storage-capacity": "ストレージ容量",
"storage-capacity-description": "ストレージ容量は、アップロードした画像とアセットの合計です。",
"personal": "個人",
"personal-description": "これらは個人的な設定です。ここでの変更は他のユーザーには影響しません",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "ユーザー設定",
"user-settings-description": "設定の管理、パスワードの変更、メールアドレスの更新",
"api-tokens-description": "外部アプリケーションからアクセスするためのAPIトークンを管理します",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "これらのアイテムはグループ内で共有されます。そのうちの 1 つを編集すると、グループ全体の内容が変更されます。",
"group-settings": "グループ設定",
"group-settings-description": "食事プランやプライバシー設定などの共通のグループ設定を管理します。",
@@ -1192,9 +1193,9 @@
"notifiers": "通知",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "データ管理",
"manage-data-description": "食品と単位の管理(近日公開予定)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "データ移行",
"data-migrations-description": "NextcloudレシピやChowdownなどの他のアプリケーションから既存のデータを移行します",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "メールが送信されました",
"error-sending-email": "メール送信エラー",
"personal-information": "個人情報",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "저장 공간",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "사용자 설정",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "그룹 설정",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "데이터 관리하기",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Sukurta: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Ar tikrai norite ištrinti <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Sveiki atvykę, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Valdykite savo profilį, receptus ir grupių nustatymus.",
"get-invite-link": "Gauti pakvietimo nuorodą",
"get-public-link": "Get Public Link",
"account-summary": "Paskyros apžvalga",
"account-summary-description": "Čia pateikiama jūsų grupės informacijos santrauka",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Grupės statistika",
"group-statistics-description": "Jūsų grupės statistika pateikia įžvalgų apie jūsų Mealie naudojimą.",
"storage-capacity": "Atminties talpa",
"storage-capacity-description": "Duomenų užimama talpa yra dydis, apskaičiuojamas pagal jkeltų nuotraukų ir duomenų dydį.",
"personal": "Asmeniniai",
"personal-description": "Šie nustatymai yra jūsų asmeniniai. Čia atlikti pakeitimai nepaveiks kitų naudotojų",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Vartotojo nustatymai",
"user-settings-description": "Valdykite savo nustatymus, pasikeiskite slaptažodį ar atnaujinkite el. pašto adresą",
"api-tokens-description": "Valdykite savo API Tokens prieigai iš išorinių sistemų",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Šie nustatymai yra bendri jūsų grupei. Čia atlikti pakeitimai paveiks visus grupės naudotojus.",
"group-settings": "Gupės nustatymai",
"group-settings-description": "Valdykite bendrus grupės nustatymus, tokius kaip valgių plano ar privatumo nustatymai.",
@@ -1192,9 +1193,9 @@
"notifiers": "Pranešikliai",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Duomenų valdymas",
"manage-data-description": "Tvarkykite produktus ir vienetus (daugiau pasirinkimų jau greitai)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Duomenų migracijos",
"data-migrations-description": "Perkelkite esamus duomenis iš kitų sistemų, pvz. \"Nextcloud Recipes\" ar \"Chowdown\"",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "El. laiškas išsiųstas",
"error-sending-email": "Klaida siunčiant el. laišką",
"personal-information": "Asmeninė informacija",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Gemaakt op {0}",
"unsaved-changes": "Er zijn niet-opgeslagen wijzigingen. Wil je eerst opslaan voordat je vertrekt? Okay om op te slaan, Annuleren om wijzigingen ongedaan te maken.",
"clipboard-copy-failure": "Kopiëren naar klembord mislukt.",
"confirm-delete-generic-items": "Weet u zeker dat u de volgende items wilt verwijderen?"
"confirm-delete-generic-items": "Weet u zeker dat u de volgende items wilt verwijderen?",
"organizers": "Organisatoren"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Weet je zeker dat je <b>{groupName}<b/> wil verwijderen?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welkom, {0}",
"welcome-user": "👋 Welkom, {0}!",
"description": "Beheer je profiel, recepten en groepsinstellingen.",
"get-invite-link": "Krijg uitnodigingslink",
"get-public-link": "Openbare link krijgen",
"account-summary": "Accountoverzicht",
"account-summary-description": "Hier is een samenvatting van de informatie van jouw groep",
"account-summary-description": "Hier is een samenvatting van jouw groep.",
"group-statistics": "Groepsstatistieken",
"group-statistics-description": "Jouw groepsstatistieken bieden inzicht in hoe je Mealie gebruikt.",
"storage-capacity": "Opslagcapaciteit",
"storage-capacity-description": "Jouw opslagcapaciteit is een berekening van de afbeeldingen en bijlagen die je hebt geüpload.",
"personal": "Persoonlijk",
"personal-description": "Dit zijn je persoonlijke instellingen. Veranderingen hier hebben geen invloed op andere gebruikers",
"personal-description": "Dit zijn jouw persoonlijke instellingen. Aanpassingen hier hebben geen invloed op andere gebruikers.",
"user-settings": "Gebruikersinstellingen",
"user-settings-description": "Beheer jouw voorkeuren, verander jouw wachtwoord en werk jouw e-mailadres bij",
"api-tokens-description": "Beheer jouw API-tokens voor toegang vanuit externe applicaties",
"user-settings-description": "Beheer jouw voorkeuren, verander jouw wachtwoord en werk jouw e-mailadres bij.",
"api-tokens-description": "Beheer jouw API-tokens voor toegang vanuit externe applicaties.",
"group-description": "Deze items worden gedeeld binnen je groep. Het bewerken van een van deze items zal het voor de hele groep veranderen!",
"group-settings": "Groepsinstellingen",
"group-settings-description": "Beheer je groepsinstellingen zoals maaltijdplan en privacyinstellingen.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notificeerders",
"notifiers-description": "Stel e-mail en push-meldingen in die worden getriggerd bij specifieke gebeurtenissen.",
"manage-data": "Gegevensbeheer",
"manage-data-description": "Beheer Voedsel en Eenheden (er komen binnenkort meer opties)",
"manage-data-description": "Beheer je Mealie-gegevens: Levensmiddelen, Eenheden, Categorieën, Tags en meer.",
"data-migrations": "Datamigratie",
"data-migrations-description": "Migreer je bestaande gegevens van andere applicaties, zoals Nextcloud recepten en Chowdown",
"data-migrations-description": "Importeer jouw bestaande gegevens van andere applicaties, zoals Nextcloud recepten en Chowdown.",
"email-sent": "E-mail verzonden",
"error-sending-email": "Fout tijdens het verzenden van de e-mail",
"personal-information": "Persoonlijke gegevens",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Opprettet: {0}",
"unsaved-changes": "Du har ulagrede endringer. Ønsker du å lagre før du forlater? Trykk 'OK' for å lagre, 'Avbryt' for å forkaste endringene.",
"clipboard-copy-failure": "Kunne ikke kopiere til utklippstavlen.",
"confirm-delete-generic-items": "Er du sikker på at du vil følgende elementer?"
"confirm-delete-generic-items": "Er du sikker på at du vil følgende elementer?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Er du sikker på at du vil slette <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Velkommen, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Administrer din profil, oppskrifter og gruppeinnstillinger.",
"get-invite-link": "Få invitasjonslenke",
"get-public-link": "Få offentlig lenke",
"account-summary": "Kontosammendrag",
"account-summary-description": "Her er en oppsummering av informasjonen til gruppen din",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Gruppestatistikk",
"group-statistics-description": "Gruppestatistikken din gir deg et innblikk i hvordan du bruker Mealie.",
"storage-capacity": "Lagringskapasitet",
"storage-capacity-description": "Lagringskapasiteten er en beregning av bildene og ressursene du har lastet opp.",
"personal": "Personlig",
"personal-description": "Dette er innstillingene som er personlige for deg. Endringer gjort her påvirker ikke andre brukere",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Brukerinnstillinger",
"user-settings-description": "Administrer innstillingene, endre passordet og oppdater e-postadressen din",
"api-tokens-description": "Administrer dine API-tokens for tilgang fra eksterne programmer",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Disse elementene deles innad i gruppen din. Redigering av elementenee vil føre til endringer for hele gruppen!",
"group-settings": "Gruppeinnstillinger",
"group-settings-description": "Administrer felles gruppeinnstillinger som innstillinger for måltidsplaner og personvern.",
@@ -1192,9 +1193,9 @@
"notifiers": "Varslingsagenter",
"notifiers-description": "Sett opp e-post- og pushvarsler som utløses av spesifikke hendelser.",
"manage-data": "Administrer data",
"manage-data-description": "Administrer dine matvarer og enheter (flere alternativer kommer snart)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Dataoverføringer",
"data-migrations-description": "Overfør eksisterende data fra andre programmer som Nextcloud Recipes og Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-post sendt",
"error-sending-email": "Feil ved sending av e-post",
"personal-information": "Personlig informasjon",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Utworzono dnia: {0}",
"unsaved-changes": "Masz niezapisane zmiany. Czy chcesz zapisać przed wyjściem? Ok, aby zapisać, Anuluj, żeby odrzucić zmiany.",
"clipboard-copy-failure": "Nie udało się skopiować do schowka.",
"confirm-delete-generic-items": "Czy na pewno chcesz usunąć następujące elementy?"
"confirm-delete-generic-items": "Czy na pewno chcesz usunąć następujące elementy?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Czy na pewno chcesz usunąć <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Witaj, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Zarządzaj swoim profilem, przepisami i ustawieniami grupy.",
"get-invite-link": "Uzyskaj link z zaproszeniem",
"get-public-link": "Uzyskaj link publiczny",
"account-summary": "Podsumowanie konta",
"account-summary-description": "Oto podsumowanie informacji o Twojej grupie",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Statystyki Grupy",
"group-statistics-description": "Twoje statystyki grupy dostarczają informacji o tym, jak używasz Mealie.",
"storage-capacity": "Pojemność Magazynowa",
"storage-capacity-description": "Twoja pojemność magazynowa jest wyliczeniem zdjęć i zasobów, które przesłałeś.",
"personal": "Osobiste",
"personal-description": "To są ustawienia, które są dla Ciebie osobiste. Zmiany tutaj nie będą miały wpływu na innych użytkowników",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Ustawienia użytkownika",
"user-settings-description": "Zarządzaj swoimi preferencjami, zmień hasło i zaktualizuj swój e-mail",
"api-tokens-description": "Zarządzaj tokenami API, aby uzyskać dostęp z zewnętrznych aplikacji",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Te elementy są współdzielone w Twojej grupie. Edycja jednego z nich zmieni je dla całej grupy!",
"group-settings": "Ustawienia Grupy",
"group-settings-description": "Zarządzaj swoimi wspólnymi ustawieniami grupy, takimi jak plan posiłkowy i ustawienia prywatności.",
@@ -1192,9 +1193,9 @@
"notifiers": "Powiadomienia",
"notifiers-description": "Skonfiguruj e-mail i powiadomienia, które uruchamiają określone zdarzenia.",
"manage-data": "Zarządzanie Danymi",
"manage-data-description": "Zarządzaj Żywnością i Jednostkami (wkrótce więcej opcji)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migracje Danych",
"data-migrations-description": "Migruj swoje istniejące dane z innych aplikacji, takich jak przepisy Nextcloud i Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-mail wysłany",
"error-sending-email": "Błąd podczas wysyłania e-mail",
"personal-information": "Informacje osobiste",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Criado em {0}",
"unsaved-changes": "Você possui alterações não salvas. Deseja salvar antes de sair? Ok para salvar, Cancelar para descartar alterações.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Tem certeza que deseja excluir o grupo <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Bem-vindo, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Gerencie seu perfil, receitas e configurações de grupo.",
"get-invite-link": "Obter link de convite",
"get-public-link": "Obter link público",
"account-summary": "Resumo da conta",
"account-summary-description": "Aqui está um resumo das informações do seu grupo",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Estatísticas do Grupo",
"group-statistics-description": "Suas Estatísticas em Grupo fornecem algumas informações sobre como você está usando o Mealie.",
"storage-capacity": "Capacidade de armazenamento",
"storage-capacity-description": "Sua capacidade de armazenamento é um cálculo das imagens e arquivos que você carregou.",
"personal": "Pessoal",
"personal-description": "Estas são as configurações que são pessoais para você. As alterações aqui não afetarão outros usuários",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Configurações de Usuário",
"user-settings-description": "Gerencie suas preferências, altere sua senha e atualize seu e-mail",
"api-tokens-description": "Gerencie seus Tokens de API para acesso de aplicativos externos",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Esses itens são compartilhados dentro do seu grupo. Ao editar um deles vai mudá-lo para todo o grupo!",
"group-settings": "Configurações do Grupo",
"group-settings-description": "Gerencie suas configurações comuns de grupo como a refeição e as configurações de privacidade.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notificadores",
"notifiers-description": "Configure e-mails e notificações push que desencadeiam eventos específicos.",
"manage-data": "Gerenciar dados",
"manage-data-description": "Gerencie suas Comidas e Unidades (mais opções em breve)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migrações de dados",
"data-migrations-description": "Migre os dados existentes de outras aplicações, como Nextcloud Recipes e Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-mail enviado",
"error-sending-email": "Erro enviando email",
"personal-information": "Informações pessoais",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Criado em: {0}",
"unsaved-changes": "Tem alterações por gravar. Quer gravar antes de sair? OK para gravar, Cancelar para descartar alterações.",
"clipboard-copy-failure": "Erro ao copiar para a área de transferência.",
"confirm-delete-generic-items": "Tem a certeza de que deseja eliminar os seguintes itens?"
"confirm-delete-generic-items": "Tem a certeza de que deseja eliminar os seguintes itens?",
"organizers": "Organizadores"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Tem a certeza que quer eliminar <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Bem-vindo, {0}",
"welcome-user": "👋 Bem-vindo, {0}!",
"description": "Gira o seu perfil, receitas e definições de grupo.",
"get-invite-link": "Obter ligação de convite",
"get-public-link": "Obter ligação pública",
"account-summary": "Resumo da conta",
"account-summary-description": "Aqui está um resumo das informações do seu grupo",
"account-summary-description": "Aqui está um resumo das informações do seu grupo.",
"group-statistics": "Estatísticas do Grupo",
"group-statistics-description": "A suas Estatísticas de Grupo fornecem algumas informações sobre como usa o Mealie.",
"storage-capacity": "Capacidade de armazenamento",
"storage-capacity-description": "A sua capacidade de armazenamento é um cálculo das imagens e itens que carregou.",
"personal": "Pessoal",
"personal-description": "Estas são definições que só se aplicam a si. Alterações aqui não afetam os outros utilizadores",
"personal-description": "Estas são definições que só se aplicam a si. Alterações aqui não afetam os outros utilizadores.",
"user-settings": "Definições do utilizador",
"user-settings-description": "Gira as suas preferências, altera a sua senha e atualize o seu email",
"api-tokens-description": "Gira os seus Tokens da API para acesso de aplicações externas",
"user-settings-description": "Gira as suas preferências, altere a sua senha e atualize o seu email.",
"api-tokens-description": "Gira os seus Tokens da API para acesso a partir de aplicações externas.",
"group-description": "Estes itens são partilhados no seu grupo. As alterações aqui afetam todos os elementos do grupo!",
"group-settings": "Definições do grupo",
"group-settings-description": "Gira as definições comuns do grupo, tais como o plano de refeições e as definições de privacidade.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notificadores",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Gerir Dados",
"manage-data-description": "Gira os seus Alimentos e Unidades (mais opções em breve)",
"manage-data-description": "Gira os seus dados no Mealie; Ingredientes, Unidades, Categorias, Etiquetas, etc.",
"data-migrations": "Migrações de dados",
"data-migrations-description": "Migre os seus dados existentes noutras aplicações, como Receitas Nextcloud e Chowdown",
"data-migrations-description": "Migre os seus dados existentes noutras aplicações, tais como o Nextcloud Recipes e Chowdown.",
"email-sent": "Email Enviado",
"error-sending-email": "Erro ao enviar Email",
"personal-information": "Informação pessoal",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Creat pe {0}",
"unsaved-changes": "Aveți modificări nesalvate. Doriți să salvați înainte de a închide aplicația? Apăsați \"OK\" pentru a salva sau \"Anulare\" pentru a renunța la modificări.",
"clipboard-copy-failure": "Copierea în clipboard a eșuat.",
"confirm-delete-generic-items": "Sunteți sigur că doriți să ștergeți următoarele?"
"confirm-delete-generic-items": "Sunteți sigur că doriți să ștergeți următoarele?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Sunteți sigur că doriți să ștergeți <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Создано: {0}",
"unsaved-changes": "У вас есть несохраненные изменения. Вы хотите сохранить их перед выходом?",
"clipboard-copy-failure": "Не удалось скопировать текст.",
"confirm-delete-generic-items": "Вы уверены, что хотите удалить следующие элементы?"
"confirm-delete-generic-items": "Вы уверены, что хотите удалить следующие элементы?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Вы действительно хотите удалить <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Добро пожаловать, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Управление настройками профиля, рецептов и группы.",
"get-invite-link": "Получить ссылку для приглашения",
"get-public-link": "Получить публичную ссылку",
"account-summary": "Cведения об учетной записи",
"account-summary-description": "Сводка информации о вашей группе",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Статистика группы",
"group-statistics-description": "Статистика вашей группы дает некоторую информацию о том, как вы используете Mealie.",
"storage-capacity": "Емкость хранилища",
"storage-capacity-description": "Указанный размер хранилища - это подсчёт размера изображений и приложений рецептов загруженных вами.",
"personal": "Личное",
"personal-description": "Это персональные настройки. Изменения здесь не повлияют на других пользователей",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Настройки пользователя",
"user-settings-description": "Управляйте своими предпочтениями, меняйте свой пароль и обновите ваш адрес электронной почты",
"api-tokens-description": "Управление API токенами для доступа из внешних приложений",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Эти элементы доступны внутри вашей группы. Редактирование одного из них изменит их для всей группы!",
"group-settings": "Настройки группы",
"group-settings-description": "Управляйте общими настройками группы, такими как настройки плана питания и конфиденциальности.",
@@ -1192,9 +1193,9 @@
"notifiers": "Уведомления",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Настройки хранилища данных",
"manage-data-description": "Управление продуктами и единицами измерений (скоро появятся дополнительные опции)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Перенос данных",
"data-migrations-description": "Переносите ваши существующие данные из других приложений, таких как Nextcloud Recipes и Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Отправленные письма",
"error-sending-email": "Ошибка при отправке письма",
"personal-information": "Личные данные",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Vytvorené: {0}",
"unsaved-changes": "Posledne vykonané zmeny nie sú uložené. Želáte si ich uložiť alebo zrušiť?",
"clipboard-copy-failure": "Skopírovanie do schránky zlyhalo.",
"confirm-delete-generic-items": "Ste si istý, že chcete odstrániť nasledujúce položky?"
"confirm-delete-generic-items": "Ste si istý, že chcete odstrániť nasledujúce položky?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Naozaj chcete odstrániť <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Vitajte, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Spravujte svoj profil, recepty a nastavenia skupín.",
"get-invite-link": "Odkaz s pozvánkou",
"get-public-link": "Vytvoriť verejný odkaz",
"account-summary": "Zhrnutie účtu",
"account-summary-description": "Tu je zhrnutie informácií o vašej skupine",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Štatistiky skupiny",
"group-statistics-description": "Štatistiky vašej skupiny poskytujú ďalší pohľad na to, ako využívate Mealie.",
"storage-capacity": "Kapacita úložiska",
"storage-capacity-description": "Kapacita vášho úložiska sa počíta ako celkový objem obrázkov a príloh, ktoré máte nahraté.",
"personal": "Osobné",
"personal-description": "Tieto nastavenia sa týkajú výlučne vás. Ich zmena neovplyvní iných užívateľov",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Užívateľské nastavenia",
"user-settings-description": "Spravujte vaše nastavenia, zmeňte svoje heslo alebo aktualizujte váš e-mail",
"api-tokens-description": "Spravujte vaše API tokeny pre prístupy z externých aplikácií",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Tieto položky sú zdieľané v rámci vašej skupiny. Zmena ktorejkoľvek z nich sa prejaví v celej skupine!",
"group-settings": "Nastavenia skupiny",
"group-settings-description": "Spravujte bežné nastavenia vašej skupiny ako napr. jedálniček, či nastavenia súkromia.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifikátory",
"notifiers-description": "Nastaviť e-mail a push notifikácie, ktoré sa spúšťajú pri špecifických udalostiach.",
"manage-data": "Spravovať dáta",
"manage-data-description": "Spravovať vaše jedlo a jednotky (viac možností čoskoro)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Migrácie dát",
"data-migrations-description": "Preneste si vaše existujúce dáta z iných aplikácií ako napr. Nextcloud Recipes a Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-mail Odoslaný",
"error-sending-email": "Chyba pri odosielaní e-mailu",
"personal-information": "Osobné údaje",

File diff suppressed because it is too large Load Diff

View File

@@ -207,7 +207,8 @@
"created-on-date": "Крерирано: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Да ли сте сигурни да желите да обришете <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Управљајте општим подешавањима групе као што су подешавања јеловника и приватности.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -80,7 +80,7 @@
"recipe-events": "Recepthändelser"
},
"general": {
"add": "Add",
"add": "Lägg till",
"cancel": "Avbryt",
"clear": "Rensa",
"close": "Stäng",
@@ -207,7 +207,8 @@
"created-on-date": "Skapad {0}",
"unsaved-changes": "Du har osparade ändringar. Vill du spara innan du lämnar? Tryck Okej att spara, Avbryt för att ignorera ändringar.",
"clipboard-copy-failure": "Det gick inte att kopiera till urklipp.",
"confirm-delete-generic-items": "Är du säker på att du vill radera följande objekt?"
"confirm-delete-generic-items": "Är du säker på att du vill radera följande objekt?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Är du säker på att du vill radera <b>{groupName}<b/>?",
@@ -547,7 +548,7 @@
"import-with-url": "Importera från URL",
"create-recipe": "Skapa recept",
"create-recipe-description": "Create a new recipe from scratch.",
"create-recipes": "Create Recipes",
"create-recipes": "Skapa recept",
"import-with-zip": "Importera från .zip",
"create-recipe-from-an-image": "Skapa recept från en bild",
"bulk-url-import": "Massimport från URL",
@@ -854,8 +855,8 @@
"link-id": "Länk ID",
"link-name": "Länk namn",
"login": "Logga in",
"login-oidc": "Login with",
"or": "or",
"login-oidc": "Logga in med",
"or": "eller",
"logout": "Logga ut",
"manage-users": "Hantera användare",
"manage-users-description": "Create and manage users.",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Välkommen, {0}",
"welcome-user": "👋 Välkommen, {0}!",
"description": "Hantera dina profil, recept och gruppinställningar.",
"get-invite-link": "Få inbjudningslänk",
"get-public-link": "Få offentlig länk",
"account-summary": "Kontosammanfattning",
"account-summary-description": "Här är en sammanfattning av din grupps information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Gruppstatistik",
"group-statistics-description": "Din gruppstatistik ger dig en inblick i hur du använder Mealie.",
"storage-capacity": "Lagringskapacitet",
"storage-capacity-description": "Din lagringskapacitet är en beräkning av de bilder och tillgångar du har laddat upp.",
"personal": "Personligt",
"personal-description": "Detta är inställningar som är personliga för dig. Ändringar här påverkar inte andra användare",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Användarinställningar",
"user-settings-description": "Hantera dina inställningar, ändra ditt lösenord och uppdatera din e-post",
"api-tokens-description": "Hantera dina API-Tokens för åtkomst från externa applikationer",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Dessa objekt delas inom din grupp. Att redigera en av dem kommer att ändra den för hela gruppen!",
"group-settings": "Gruppinställningar",
"group-settings-description": "Hantera dina gemensamma gruppinställningar som måltidsplan och sekretessinställningar.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifierare",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Hantera data",
"manage-data-description": "Hantera Mat och Enheter (fler alternativ kommer snart)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data migreringar",
"data-migrations-description": "Migrera befintliga data från andra program som Nextcloud Recipes och Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "E-post skickades",
"error-sending-email": "Fel vid sändning av e-post",
"personal-information": "Personlig information",

View File

@@ -207,7 +207,8 @@
"created-on-date": "{0} tarihinde oluşturuldu",
"unsaved-changes": "Kaydedilmemiş değişiklikleriniz mevcut. Ayrılmadan önce kaydetmek ister misiniz? Kaydetmek için Tamam'ı, değişiklikleri iptal etmek için İptal'i seçin.",
"clipboard-copy-failure": "Panoya kopyalanamadı.",
"confirm-delete-generic-items": "Aşağıdaki öğeleri silmek istediğinizden emin misiniz?"
"confirm-delete-generic-items": "Aşağıdaki öğeleri silmek istediğinizden emin misiniz?",
"organizers": "Organizatörler"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "<b>{groupName}<b/>'i silmek istediğine emin misin?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Hoşgeldiniz, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Herkese açık bağlantıyı al",
"account-summary": "Hesap Özeti",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Grup İstatistikleri",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Depolama kapasiten yüklediğin resim ve diğer bileşenlerin toplamıdır.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Belirli etkinliklerde tetiklenen e-posta ve anlık bildirimleri ayarlayın.",
"manage-data": "Verileri Yönet",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -147,15 +147,15 @@
"show-all": "Показати все",
"shuffle": "Перемішати",
"sort": "Сортувати",
"sort-ascending": "Sort Ascending",
"sort-descending": "Sort Descending",
"sort-ascending": "Сортувати за зростанням",
"sort-descending": "Сортувати за спаданням",
"sort-alphabetically": "За алфавітом",
"status": "Статус",
"subject": "Тема",
"submit": "Надіслати",
"success-count": "Успіх: {count}",
"sunday": "Неділя",
"system": "System",
"system": "Система",
"templates": "Шаблони:",
"test": "Тест",
"themes": "Теми",
@@ -207,7 +207,8 @@
"created-on-date": "Створено: {0}",
"unsaved-changes": "У вас є незбережені зміни. Ви хочете зберегти їх перед виходом? Гаразд, щоб зберегти, Скасувати, щоб скасувати.",
"clipboard-copy-failure": "Не вдалося скопіювати до буфера обміну.",
"confirm-delete-generic-items": "Ви впевнені, що хочете видалити вибрані елементи?"
"confirm-delete-generic-items": "Ви впевнені, що хочете видалити вибрані елементи?",
"organizers": "Організатори"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Ви дійсно бажаєте видалити <b>{groupName}<b/>?",
@@ -362,7 +363,7 @@
"choose-migration-type": "Оберіть тип міграції",
"tag-all-recipes": "Позначити усі рецепти тегом {tag-name}",
"nextcloud-text": "Рецепти Nextcloud можна імпортувати з zip-архіву, який містить дані, що зберігаються в Nextcloud. Перегляньте приклади структури тек нижче, щоб пересвідчитися що ваші рецепти можна імпортувати.",
"chowdown-text": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below.",
"chowdown-text": "Mealie підтримує формат chowdown репозиторію. Завантажте репозиторій коду як файл .zip і відвантажте його нижче.",
"recipe-1": "Рецепт 1",
"recipe-2": "Рецепт 2",
"paprika-text": "Mealie може імпортувати рецепти з додатку Paprika. Експортуйте ваші рецепти з Paprika, перейменуйте розширення експорту в .zip та відвантажте його нижче.",
@@ -373,7 +374,7 @@
},
"myrecipebox": {
"title": "My Recipe Box",
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
"description-long": "Mealie може імпортувати рецепти з My Recipe Box. Експортуйте ваші рецепти в форматі CSV, а потім відвантажте .csv файл нижче."
}
},
"new-recipe": {
@@ -525,7 +526,7 @@
"edit-timeline-event": "Редагувати подію хронології",
"timeline": "Хронологія",
"timeline-is-empty": "Хронологія порожня. Спробуйте зробити цей рецепт!",
"timeline-no-events-found-try-adjusting-filters": "No events found. Try adjusting your search filters.",
"timeline-no-events-found-try-adjusting-filters": "Не знайдено жодних подій. Спробуйте змінити фільтри пошуку.",
"group-global-timeline": "Глобальна хроніка {groupName}",
"open-timeline": "Відкрити хронологію",
"made-this": "Я це зробив",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Ласкаво просимо, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Керування вашим профілем, рецептами та налаштуваннями групи.",
"get-invite-link": "Отримати посилання-запрошення",
"get-public-link": "Отримати публічне посилання",
"account-summary": "Аккаунт",
"account-summary-description": "Ось підсумок інформації про вашу групу",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Статистика групи",
"group-statistics-description": "Статистика вашої групи дає можливість зрозуміти, як ви користуєтеся Mealie.",
"storage-capacity": "Обсяг сховища",
"storage-capacity-description": "Об'єм сховища це сума зображені та відвантажених медіаресурсів.",
"personal": "Особисте",
"personal-description": "Це особисті налаштування. Зміни тут не впливають на інших користувачів",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "Налаштування користувача",
"user-settings-description": "Керуйте вашими налаштуваннями, змінюйте пароль і оновлюйте адресу електронної пошти",
"api-tokens-description": "Керуйте своїми ключами API для доступу із зовнішніх програм",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "Ці елементи є спільними для вашої групи. Редагування одного з них змінить його для всієї групи!",
"group-settings": "Налаштування групи",
"group-settings-description": "Керуйте спільними налаштуванням груп, такими як плани харчування і налаштування конфіденційності.",
@@ -1192,9 +1193,9 @@
"notifiers": "Сповіщувачі",
"notifiers-description": "Налаштуйте email та push сповіщення, що спрацьовують для певних подій.",
"manage-data": "Керування даними",
"manage-data-description": "Керуйте своїми продуктами та одиницями (більше варіантів найближчим часом)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Міграції даних",
"data-migrations-description": "Перенести наявні дані з таких програм, як Nextcloud Recipes і Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Лист надіслано",
"error-sending-email": "Помилка надсилання листа",
"personal-information": "Персональні данні",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Are you sure you want to delete <b>{groupName}<b/>?",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -85,7 +85,7 @@
"clear": "清空",
"close": "关闭",
"confirm": "确定",
"confirm-how-does-everything-look": "How does everything look?",
"confirm-how-does-everything-look": "看起来如何?",
"confirm-delete-generic": "你确定要删除这个?",
"copied_message": "已复制!",
"create": "创建",
@@ -147,15 +147,15 @@
"show-all": "全部显示",
"shuffle": "随机",
"sort": "排序",
"sort-ascending": "Sort Ascending",
"sort-descending": "Sort Descending",
"sort-ascending": "升序",
"sort-descending": "降序",
"sort-alphabetically": "按字母顺序排序",
"status": "状态",
"subject": "标题",
"submit": "提交",
"success-count": "成功: {count}",
"sunday": "周日",
"system": "System",
"system": "系统",
"templates": "模板:",
"test": "测试",
"themes": "布景主题",
@@ -174,7 +174,7 @@
"units": "单位",
"back": "返回",
"next": "下一步",
"start": "Start",
"start": "开始",
"toggle-view": "切换视图",
"date": "日期",
"id": "Id",
@@ -207,7 +207,8 @@
"created-on-date": "创建于: {0}",
"unsaved-changes": "你有未保存的更改。你希望现在离开前保存吗?保存选择“是”,不保存选择“取消”。",
"clipboard-copy-failure": "未能复制到剪切板。",
"confirm-delete-generic-items": "你确定删除以下条目吗?"
"confirm-delete-generic-items": "你确定删除以下条目吗?",
"organizers": "组织者"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "您确定要删除<b>{groupName}<b/>吗?",
@@ -243,8 +244,8 @@
"group-preferences": "群组偏好设置",
"private-group": "私人群组",
"private-group-description": "将群组设置为私有后,群组内每个食谱单独配置的可见性选项都将被覆盖,所有食谱都无法被公开访问。",
"enable-public-access": "Enable Public Access",
"enable-public-access-description": "Make group recipes public by default, and allow visitors to view recipes without logging-in",
"enable-public-access": "启用公开访问",
"enable-public-access-description": "默认公开群组食谱,即访客用户无需登录便可查看食谱",
"allow-users-outside-of-your-group-to-see-your-recipes": "允许组外用户查看你的食谱",
"allow-users-outside-of-your-group-to-see-your-recipes-description": "若启用,你能通过公开链接将指定食谱分享给无需登陆验证的用户;若禁用,你仅能将食谱分享给同组用户,或是通过预生成的私有链接分享。",
"show-nutrition-information": "显示营养信息",
@@ -358,11 +359,11 @@
},
"recipe-data-migrations": "食谱数据迁移",
"recipe-data-migrations-explanation": "你可以从受支持的应用中将食谱迁移至Mealie这是上手Mealie的好方法。",
"coming-from-another-application-or-an-even-older-version-of-mealie": "Coming from another application or an even older version of Mealie? Check out migrations and see if your data can be imported.",
"coming-from-another-application-or-an-even-older-version-of-mealie": "之前使用其他食谱应用或是旧版本Mealie吗检查迁移设置来确认你的原有数据是否可以导入。",
"choose-migration-type": "选择迁移类型",
"tag-all-recipes": "用{tag-name} 标签标记所有食谱",
"nextcloud-text": "Mealie支持从Nextcloud中导入食谱。为了确保能被导入应按照下方示例整理文件夹结构并将其压缩成zip文件然后在下方上传。",
"chowdown-text": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below.",
"chowdown-text": "Mealie原生支持chowdown格式只需将代码仓库打包成zip文件并在下方上传。",
"recipe-1": "食谱 1",
"recipe-2": "食谱 2",
"paprika-text": "Mealie 可以从 Paprika 导入食谱。请从paprika 导出食谱,重命名导出文件并压缩成.zip格式后在下方上传",
@@ -373,7 +374,7 @@
},
"myrecipebox": {
"title": "My Recipe Box",
"description-long": "Mealie can import recipes from My Recipe Box. Export your recipes in CSV format, then upload the .csv file below."
"description-long": "Mealie可以从“My Recipe Box\"导入食谱。把你的食谱导出为CSV模式然后在下面上传.csv文件。"
}
},
"new-recipe": {
@@ -525,7 +526,7 @@
"edit-timeline-event": "编辑时间轴事件",
"timeline": "时间轴",
"timeline-is-empty": "时间轴还空空如也,试着先去制作一个食谱吧!",
"timeline-no-events-found-try-adjusting-filters": "No events found. Try adjusting your search filters.",
"timeline-no-events-found-try-adjusting-filters": "没有找到事件。请尝试调整你的搜索过滤器。",
"group-global-timeline": "{groupName}的全局时间轴",
"open-timeline": "查看时间轴",
"made-this": "我做了这道菜",
@@ -546,8 +547,8 @@
"looking-for-migrations": "在找迁移设置?",
"import-with-url": "通过URL导入",
"create-recipe": "创建食谱",
"create-recipe-description": "Create a new recipe from scratch.",
"create-recipes": "Create Recipes",
"create-recipe-description": "从头创建一个新食谱。",
"create-recipes": "创建食谱",
"import-with-zip": "使用 .zip 导入",
"create-recipe-from-an-image": "用图片创建食谱",
"bulk-url-import": "批量URL导入",
@@ -744,9 +745,9 @@
"ldap-ready-success-text": "LDAP所需的环境变量均已配置。",
"build": "生成",
"recipe-scraper-version": "食谱刮削器版本",
"oidc-ready": "OIDC Ready",
"oidc-ready-error-text": "Not all OIDC Values are configured. This can be ignored if you are not using OIDC Authentication.",
"oidc-ready-success-text": "Required OIDC variables are all set."
"oidc-ready": "OIDC 已就绪",
"oidc-ready-error-text": "某些OIDC环境变量尚未配置。如果你不使用OIDC验证可以忽略该报错",
"oidc-ready-success-text": "OIDC所需的环境变量均已配置。"
},
"shopping-list": {
"all-lists": "所有购物清单",
@@ -854,8 +855,8 @@
"link-id": "链接ID",
"link-name": "链接名",
"login": "登录",
"login-oidc": "Login with",
"or": "or",
"login-oidc": "登录方式",
"or": "",
"logout": "登出",
"manage-users": "管理用户",
"manage-users-description": "Create and manage users.",
@@ -1156,32 +1157,32 @@
"no-logs-found": "未找到日志",
"tasks": "任务",
"setup": {
"first-time-setup": "First Time Setup",
"welcome-to-mealie-get-started": "Welcome to Mealie! Let's get started",
"already-set-up-bring-to-homepage": "I'm already set up, just bring me to the homepage",
"common-settings-for-new-sites": "Here are some common settings for new sites",
"setup-complete": "Setup Complete!",
"first-time-setup": "初始配置",
"welcome-to-mealie-get-started": "欢迎来到Mealie让我们开始吧",
"already-set-up-bring-to-homepage": "我已经配置好了,直接跳转到主页",
"common-settings-for-new-sites": "这有一些新站点的常见设置",
"setup-complete": "配置完成!",
"here-are-a-few-things-to-help-you-get-started": "Here are a few things to help you get started with Mealie",
"restore-from-v1-backup": "Have a backup from a previous instance of Mealie v1? You can restore it here.",
"manage-profile-or-get-invite-link": "Manage your own profile, or grab an invite link to share with others."
}
},
"profile": {
"welcome-user": "👋 欢迎,{0}",
"welcome-user": "👋 欢迎,{0}",
"description": "管理您的个人资料、食谱谱和群组设置。",
"get-invite-link": "生成邀请链接",
"get-public-link": "生成公开链接",
"account-summary": "账户概况",
"account-summary-description": "以下是你的群组概况",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "群组统计",
"group-statistics-description": "群组统计为你如何使用Mealie提供一些深入信息。",
"storage-capacity": "总储存容量",
"storage-capacity-description": "你的存储容量基于你上传的图片和资源计算得出。",
"personal": "个人设置",
"personal-description": "这些是你的个人设置。此处的更改不影响同组其他用户。",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "个人资料",
"user-settings-description": "修改密码,更换邮箱,管理偏好设置",
"api-tokens-description": "管理您的 API 令牌以从外部应用程序访问",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "这些项目已在你的群组中共享,一旦被编辑,更改之处会对所有群组成员生效!",
"group-settings": "基础选项",
"group-settings-description": "管理常见的群组设置,如饮食计划和隐私设置。",
@@ -1192,9 +1193,9 @@
"notifiers": "通知方案",
"notifiers-description": "设置基于特定事件触发的邮件提醒和通知推送。",
"manage-data": "数据库",
"manage-data-description": "管理食品和单位(将会提供更多选项)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "数据迁移",
"data-migrations-description": "将现有数据从其他应用如Nextcloud食谱、Chowdown迁移至Mealie",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "邮件已发送",
"error-sending-email": "发送邮件出错",
"personal-information": "个人信息",

View File

@@ -207,7 +207,8 @@
"created-on-date": "Created on: {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard.",
"confirm-delete-generic-items": "Are you sure you want to delete the following items?"
"confirm-delete-generic-items": "Are you sure you want to delete the following items?",
"organizers": "Organizers"
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "確定要刪除<b>{groupName}<b/>",
@@ -1167,21 +1168,21 @@
}
},
"profile": {
"welcome-user": "👋 Welcome, {0}",
"welcome-user": "👋 Welcome, {0}!",
"description": "Manage your profile, recipes, and group settings.",
"get-invite-link": "Get Invite Link",
"get-public-link": "Get Public Link",
"account-summary": "Account Summary",
"account-summary-description": "Here's a summary of your group's information",
"account-summary-description": "Here's a summary of your group's information.",
"group-statistics": "Group Statistics",
"group-statistics-description": "Your Group Statistics provide some insight how you're using Mealie.",
"storage-capacity": "Storage Capacity",
"storage-capacity-description": "Your storage capacity is a calculation of the images and assets you have uploaded.",
"personal": "Personal",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users",
"personal-description": "These are settings that are personal to you. Changes here won't affect other users.",
"user-settings": "User Settings",
"user-settings-description": "Manage your preferences, change your password, and update your email",
"api-tokens-description": "Manage your API Tokens for access from external applications",
"user-settings-description": "Manage your preferences, change your password, and update your email.",
"api-tokens-description": "Manage your API Tokens for access from external applications.",
"group-description": "These items are shared within your group. Editing one of them will change it for the whole group!",
"group-settings": "Group Settings",
"group-settings-description": "Manage your common group settings like mealplan and privacy settings.",
@@ -1192,9 +1193,9 @@
"notifiers": "Notifiers",
"notifiers-description": "Setup email and push notifications that trigger on specific events.",
"manage-data": "Manage Data",
"manage-data-description": "Manage your Food and Units (more options coming soon)",
"manage-data-description": "Manage your Mealie data; Foods, Units, Categories, Tags and more.",
"data-migrations": "Data Migrations",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown",
"data-migrations-description": "Migrate your existing data from other applications like Nextcloud Recipes and Chowdown.",
"email-sent": "Email Sent",
"error-sending-email": "Error Sending Email",
"personal-information": "Personal Information",

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="ready">
<v-app dark>
<v-card-title>
<slot>
<h1 class="mx-auto">{{ $t("page.404-page-not-found") }}</h1>
@@ -24,7 +24,7 @@
</slot>
<v-spacer></v-spacer>
</v-card-actions>
</div>
</v-app>
</template>
<script lang="ts">

View File

@@ -203,7 +203,6 @@ export interface MaintenanceStorageDetails {
}
export interface MaintenanceSummary {
dataDirSize: string;
logFileSize: string;
cleanableImages: number;
cleanableDirs: number;
}

View File

@@ -5,10 +5,11 @@
/* Do not modify it by hand - just update the pydantic models and then re-run the script
*/
export type WebhookType = "mealplan";
export type AuthMethod = "Mealie" | "LDAP" | "OIDC";
export interface ChangePassword {
currentPassword: string;
currentPassword?: string;
newPassword: string;
}
export interface CreateToken {
@@ -30,6 +31,11 @@ export interface CreateUserRegistration {
seedData?: boolean;
locale?: string;
}
export interface CredentialsRequest {
username: string;
password: string;
remember_me?: boolean;
}
export interface DeleteTokenResponse {
tokenDelete: string;
}
@@ -44,7 +50,7 @@ export interface GroupInDB {
id: string;
slug: string;
categories?: CategoryBase[];
webhooks?: unknown[];
webhooks?: ReadWebhook[];
users?: UserOut[];
preferences?: ReadGroupPreferences;
}
@@ -60,7 +66,17 @@ export interface CategoryBase {
id: string;
slug: string;
}
export interface ReadWebhook {
enabled?: boolean;
name?: string;
url?: string;
webhookType?: WebhookType & string;
scheduledTime: string;
groupId: string;
id: string;
}
export interface UserOut {
id: string;
username?: string;
fullName?: string;
email: string;
@@ -68,11 +84,9 @@ export interface UserOut {
admin?: boolean;
group: string;
advanced?: boolean;
favoriteRecipes?: string[];
canInvite?: boolean;
canManage?: boolean;
canOrganize?: boolean;
id: string;
groupId: string;
groupSlug: string;
tokens?: LongLiveTokenOut[];
@@ -109,6 +123,7 @@ export interface LongLiveTokenInDB {
user: PrivateUser;
}
export interface PrivateUser {
id: string;
username?: string;
fullName?: string;
email: string;
@@ -116,11 +131,9 @@ export interface PrivateUser {
admin?: boolean;
group: string;
advanced?: boolean;
favoriteRecipes?: string[];
canInvite?: boolean;
canManage?: boolean;
canOrganize?: boolean;
id: string;
groupId: string;
groupSlug: string;
tokens?: LongLiveTokenOut[];
@@ -129,6 +142,9 @@ export interface PrivateUser {
loginAttemps?: number;
lockedAt?: string;
}
export interface OIDCRequest {
id_token: string;
}
export interface PasswordResetToken {
token: string;
}
@@ -163,9 +179,17 @@ export interface UpdateGroup {
id: string;
slug: string;
categories?: CategoryBase[];
webhooks?: unknown[];
webhooks?: CreateWebhook[];
}
export interface CreateWebhook {
enabled?: boolean;
name?: string;
url?: string;
webhookType?: WebhookType & string;
scheduledTime: string;
}
export interface UserBase {
id?: string;
username?: string;
fullName?: string;
email: string;
@@ -173,65 +197,12 @@ export interface UserBase {
admin?: boolean;
group?: string;
advanced?: boolean;
favoriteRecipes?: string[];
canInvite?: boolean;
canManage?: boolean;
canOrganize?: boolean;
}
export interface UserFavorites {
username?: string;
fullName?: string;
email: string;
authMethod?: AuthMethod & string;
admin?: boolean;
group?: string;
advanced?: boolean;
favoriteRecipes?: RecipeSummary[];
canInvite?: boolean;
canManage?: boolean;
canOrganize?: boolean;
}
export interface RecipeSummary {
id?: string;
userId?: string;
groupId?: string;
name?: string;
slug?: string;
image?: unknown;
recipeYield?: string;
totalTime?: string;
prepTime?: string;
cookTime?: string;
performTime?: string;
description?: string;
recipeCategory?: RecipeCategory[];
tags?: RecipeTag[];
tools?: RecipeTool[];
rating?: number;
orgURL?: string;
dateAdded?: string;
dateUpdated?: string;
createdAt?: string;
updateAt?: string;
lastMade?: string;
}
export interface RecipeCategory {
id?: string;
name: string;
slug: string;
}
export interface RecipeTag {
id?: string;
name: string;
slug: string;
}
export interface RecipeTool {
id: string;
name: string;
slug: string;
onHand?: boolean;
}
export interface UserIn {
id?: string;
username?: string;
fullName?: string;
email: string;
@@ -239,15 +210,32 @@ export interface UserIn {
admin?: boolean;
group?: string;
advanced?: boolean;
favoriteRecipes?: string[];
canInvite?: boolean;
canManage?: boolean;
canOrganize?: boolean;
password: string;
}
export interface UserRatingCreate {
recipeId: string;
rating?: number;
isFavorite?: boolean;
userId: string;
}
export interface UserRatingOut {
recipeId: string;
rating?: number;
isFavorite?: boolean;
userId: string;
id: string;
}
export interface UserRatingSummary {
recipeId: string;
rating?: number;
isFavorite?: boolean;
}
export interface UserSummary {
id: string;
fullName?: string;
fullName: string;
}
export interface ValidateResetToken {
token: string;

View File

@@ -9,17 +9,27 @@ import {
LongLiveTokenOut,
ResetPassword,
UserBase,
UserFavorites,
UserIn,
UserOut,
UserRatingOut,
UserRatingSummary,
UserSummary,
} from "~/lib/api/types/user";
export interface UserRatingsSummaries {
ratings: UserRatingSummary[];
}
export interface UserRatingsOut {
ratings: UserRatingOut[];
}
const prefix = "/api";
const routes = {
groupUsers: `${prefix}/users/group-users`,
usersSelf: `${prefix}/users/self`,
ratingsSelf: `${prefix}/users/self/ratings`,
groupsSelf: `${prefix}/users/self/group`,
passwordReset: `${prefix}/users/reset-password`,
passwordChange: `${prefix}/users/password`,
@@ -30,6 +40,10 @@ const routes = {
usersId: (id: string) => `${prefix}/users/${id}`,
usersIdFavorites: (id: string) => `${prefix}/users/${id}/favorites`,
usersIdFavoritesSlug: (id: string, slug: string) => `${prefix}/users/${id}/favorites/${slug}`,
usersIdRatings: (id: string) => `${prefix}/users/${id}/ratings`,
usersIdRatingsSlug: (id: string, slug: string) => `${prefix}/users/${id}/ratings/${slug}`,
usersSelfFavoritesId: (id: string) => `${prefix}/users/self/favorites/${id}`,
usersSelfRatingsId: (id: string) => `${prefix}/users/self/ratings/${id}`,
usersApiTokens: `${prefix}/users/api-tokens`,
usersApiTokensTokenId: (token_id: string | number) => `${prefix}/users/api-tokens/${token_id}`,
@@ -56,7 +70,23 @@ export class UserApi extends BaseCRUDAPI<UserIn, UserOut, UserBase> {
}
async getFavorites(id: string) {
return await this.requests.get<UserFavorites>(routes.usersIdFavorites(id));
return await this.requests.get<UserRatingsOut>(routes.usersIdFavorites(id));
}
async getSelfFavorites() {
return await this.requests.get<UserRatingsSummaries>(routes.ratingsSelf);
}
async getRatings(id: string) {
return await this.requests.get<UserRatingsOut>(routes.usersIdRatings(id));
}
async setRating(id: string, slug: string, rating: number | null, isFavorite: boolean | null) {
return await this.requests.post(routes.usersIdRatingsSlug(id, slug), { rating, isFavorite });
}
async getSelfRatings() {
return await this.requests.get<UserRatingsSummaries>(routes.ratingsSelf);
}
async changePassword(changePassword: ChangePassword) {

View File

@@ -22,10 +22,6 @@
<template #title> {{ $t("admin.maintenance.page-title") }} </template>
</BasePageTitle>
<div class="d-flex justify-end">
<ButtonLink to="/admin/maintenance/logs" text="Logs" :icon="$globals.icons.file" />
</div>
<section>
<BaseCardSectionTitle class="pb-0" :icon="$globals.icons.wrench" :title="$tc('admin.maintenance.summary-title')">
</BaseCardSectionTitle>
@@ -110,7 +106,6 @@ export default defineComponent({
const infoResults = ref<MaintenanceSummary>({
dataDirSize: i18n.tc("about.unknown-version"),
logFileSize: i18n.tc("about.unknown-version"),
cleanableDirs: 0,
cleanableImages: 0,
});
@@ -121,7 +116,6 @@ export default defineComponent({
infoResults.value = data ?? {
dataDirSize: i18n.tc("about.unknown-version"),
logFileSize: i18n.tc("about.unknown-version"),
cleanableDirs: 0,
cleanableImages: 0,
};
@@ -129,17 +123,12 @@ export default defineComponent({
state.fetchingInfo = false;
}
const info = computed(() => {
return [
{
name: i18n.t("admin.maintenance.info-description-data-dir-size"),
value: infoResults.value.dataDirSize,
},
{
name: i18n.t("admin.maintenance.info-description-log-file-size"),
value: infoResults.value.logFileSize,
},
{
name: i18n.t("admin.maintenance.info-description-cleanable-directories"),
value: infoResults.value.cleanableDirs,
@@ -184,12 +173,6 @@ export default defineComponent({
// ==========================================================================
// Actions
async function handleDeleteLogFile() {
state.actionLoading = true;
await adminApi.maintenance.cleanLogFile();
state.actionLoading = false;
}
async function handleCleanDirectories() {
state.actionLoading = true;
await adminApi.maintenance.cleanRecipeFolders();
@@ -209,11 +192,6 @@ export default defineComponent({
}
const actions = [
{
name: i18n.t("admin.maintenance.action-delete-log-files-name"),
handler: handleDeleteLogFile,
subtitle: i18n.t("admin.maintenance.action-delete-log-files-description"),
},
{
name: i18n.t("admin.maintenance.action-clean-directories-name"),
handler: handleCleanDirectories,

View File

@@ -1,109 +0,0 @@
<template>
<v-container fluid>
<BaseCardSectionTitle class="pb-0" :icon="$globals.icons.cog" :title="$t('admin.maintenance.summary-title')">
</BaseCardSectionTitle>
<div class="mb-6 ml-2 d-flex" style="gap: 0.8rem">
<BaseButton color="info" :loading="state.loading" @click="refreshLogs">
<template #icon> {{ $globals.icons.refreshCircle }} </template>
{{ $t("admin.maintenance.logs-action-refresh") }}
</BaseButton>
<AppButtonCopy :copy-text="copyText" />
<div class="ml-auto" style="max-width: 150px">
<v-text-field
v-model="state.lines"
type="number"
:label="$t('admin.maintenance.logs-tail-lines-label')"
hide-details
dense
outlined
>
</v-text-field>
</div>
</div>
<v-card outlined>
<v-virtual-scroll
v-scroll="scrollOptions"
:bench="20"
:items="logs.logs"
height="800"
item-height="20"
class="keep-whitespace log-container"
>
<template #default="{ item }">
<p class="log-text">
{{ item }}
</p>
</template>
</v-virtual-scroll>
</v-card>
</v-container>
</template>
<script lang="ts">
import { defineComponent, ref, computed, onMounted, reactive } from "@nuxtjs/composition-api";
import { useAdminApi } from "~/composables/api";
export default defineComponent({
layout: "admin",
setup() {
const adminApi = useAdminApi();
const state = reactive({
loading: false,
lines: 500,
autoRefresh: true,
});
const scrollOptions = reactive({
enable: true,
always: false,
smooth: false,
notSmoothOnInit: true,
});
const logs = ref({
logs: [] as string[],
});
async function refreshLogs() {
state.loading = true;
const { data } = await adminApi.maintenance.logs(state.lines);
if (data) {
logs.value = data;
}
state.loading = false;
}
onMounted(() => {
refreshLogs();
});
const copyText = computed(() => {
return logs.value.logs.join("") || "";
});
return {
copyText,
scrollOptions,
state,
refreshLogs,
logs,
};
},
head() {
return {
title: this.$t("admin.maintenance.logs-page-title") as string,
};
},
});
</script>
<style>
.log-text {
font: 0.8rem Inconsolata, monospace;
}
.log-container {
background-color: var(--v-background-base) !important;
}
.keep-whitespace {
white-space: pre;
}
</style>

View File

@@ -96,7 +96,7 @@
import { defineComponent, reactive, ref, useContext } from "@nuxtjs/composition-api";
import { validators } from "~/composables/use-validators";
import { useCategoryStore, useCategoryData } from "~/composables/store";
import { RecipeCategory } from "~/lib/api/types/admin";
import { RecipeCategory } from "~/lib/api/types/recipe";
export default defineComponent({
setup() {

View File

@@ -191,7 +191,7 @@ export default defineComponent({
const oidcProviderName = computed(() => appInfo.value?.oidcProviderName || "OAuth")
whenever(
() => allowOidc.value && oidcRedirect.value && !isCallback() && !isDirectLogin(),
() => allowOidc.value && oidcRedirect.value && !isCallback() && !isDirectLogin() && !$auth.check().valid,
() => oidcAuthenticate(),
{immediate: true}
)

View File

@@ -1,7 +1,11 @@
<template>
<v-container>
<RecipeCardSection v-if="user && isOwnGroup" :icon="$globals.icons.heart" :title="$tc('user.user-favorites')" :recipes="user.favoriteRecipes">
</RecipeCardSection>
<RecipeCardSection
v-if="recipes && isOwnGroup"
:icon="$globals.icons.heart"
:title="$tc('user.user-favorites')"
:recipes="recipes"
/>
</v-container>
</template>
@@ -21,14 +25,13 @@ export default defineComponent({
const { isOwnGroup } = useLoggedInState();
const userId = route.value.params.id;
const user = useAsync(async () => {
const { data } = await api.users.getFavorites(userId);
return data;
const recipes = useAsync(async () => {
const { data } = await api.recipes.getAll(1, -1, { queryFilter: `favoritedBy.id = "${userId}"` });
return data?.items || null;
}, useAsyncKey());
return {
user,
recipes,
isOwnGroup,
};
},

View File

@@ -21,6 +21,22 @@ export default class DynamicOpenIDConnectScheme extends OpenIDConnectScheme {
return await super.mounted()
}
// Overrides the check method in the OpenIDConnectScheme
// We don't care if the id token is expired as long as we have a valid Mealie token.
// We only use the id token to verify identity on the initial login, then issue a Mealie token
check(checkStatus = false) {
const response = super.check(checkStatus)
// we can do this because id token is the last thing to be checked so if the id token is expired then it was
// the only thing making the request not valid
if (response.idTokenExpired && !response.valid) {
response.valid = true;
response.idTokenExpired = false;
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return response;
}
async fetchUser() {
if (!this.check().valid) {
return
@@ -36,7 +52,7 @@ export default class DynamicOpenIDConnectScheme extends OpenIDConnectScheme {
async _handleCallback() {
// sometimes the mealie token is being sent in the request to the IdP on callback which
// causes an error, so we clear it if we have one
if (this.token.get()) {
if (!this.token.status().valid()) {
this.token.reset();
}
const redirect = await super._handleCallback()
@@ -47,10 +63,11 @@ export default class DynamicOpenIDConnectScheme extends OpenIDConnectScheme {
}
async updateAccessToken() {
if (!this.idToken.sync()) {
if (this.isValidMealieToken()) {
return
}
if (this.isValidMealieToken()) {
if (!this.idToken.status().valid()) {
this.idToken.reset();
return
}

View File

@@ -0,0 +1,67 @@
import json
import logging
import pathlib
import typing
from logging import config as logging_config
__dir = pathlib.Path(__file__).parent
__conf: dict[str, str] | None = None
def _load_config(path: pathlib.Path, substitutions: dict[str, str] | None = None) -> dict[str, typing.Any]:
with open(path) as file:
if substitutions:
contents = file.read()
for key, value in substitutions.items():
# Replaces the key matches
#
# Example:
# {"key": "value"}
# "/path/to/${key}/file" -> "/path/to/value/file"
contents = contents.replace(f"${{{key}}}", value)
json_data = json.loads(contents)
else:
json_data = json.load(file)
return json_data
def log_config() -> dict[str, str]:
if __conf is None:
raise ValueError("logger not configured, must call configured_logger first")
return __conf
def configured_logger(
*,
mode: str,
config_override: pathlib.Path | None = None,
substitutions: dict[str, str] | None = None,
) -> logging.Logger:
"""
Configure the logger based on the mode and return the root logger
Args:
mode (str): The mode to configure the logger for (production, development, testing)
config_override (pathlib.Path, optional): A path to a custom logging config. Defaults to None.
substitutions (dict[str, str], optional): A dictionary of substitutions to apply to the logging config.
"""
global __conf
if config_override:
__conf = _load_config(config_override, substitutions)
else:
if mode == "production":
__conf = _load_config(__dir / "logconf.prod.json", substitutions)
elif mode == "development":
__conf = _load_config(__dir / "logconf.dev.json", substitutions)
elif mode == "testing":
__conf = _load_config(__dir / "logconf.test.json", substitutions)
else:
raise ValueError(f"Invalid mode: {mode}")
logging_config.dictConfig(config=__conf)
return logging.getLogger()

View File

@@ -0,0 +1,17 @@
{
"version": 1,
"disable_existing_loggers": false,
"handlers": {
"rich": {
"class": "rich.logging.RichHandler"
}
},
"loggers": {
"root": {
"level": "DEBUG",
"handlers": [
"rich"
]
}
}
}

View File

@@ -0,0 +1,74 @@
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"simple": {
"format": "%(levelname)-8s %(asctime)s - %(message)s",
"datefmt": "%Y-%m-%dT%H:%M:%S"
},
"detailed": {
"format": "[%(levelname)s|%(module)s|L%(lineno)d] %(asctime)s: %(message)s",
"datefmt": "%Y-%m-%dT%H:%M:%S"
},
"access": {
"()": "uvicorn.logging.AccessFormatter",
"fmt": "%(levelname)-8s %(asctime)s - [%(client_addr)s] %(status_code)s \"%(request_line)s\"",
"datefmt": "%Y-%m-%dT%H:%M:%S"
}
},
"handlers": {
"stderr": {
"class": "logging.StreamHandler",
"level": "WARNING",
"formatter": "simple",
"stream": "ext://sys.stderr"
},
"stdout": {
"class": "logging.StreamHandler",
"level": "${LOG_LEVEL}",
"formatter": "simple",
"stream": "ext://sys.stdout"
},
"access": {
"class": "logging.StreamHandler",
"level": "${LOG_LEVEL}",
"formatter": "access",
"stream": "ext://sys.stdout"
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"level": "DEBUG",
"formatter": "detailed",
"filename": "${DATA_DIR}/mealie.log",
"maxBytes": 10000,
"backupCount": 3
}
},
"loggers": {
"root": {
"level": "${LOG_LEVEL}",
"handlers": [
"stderr",
"file",
"stdout"
]
},
"uvicorn.error": {
"handlers": [
"stderr",
"file",
"stdout"
],
"level": "${LOG_LEVEL}",
"propagate": false
},
"uvicorn.access": {
"handlers": [
"access",
"file"
],
"level": "${LOG_LEVEL}",
"propagate": false
}
}
}

View File

@@ -0,0 +1,26 @@
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"detailed": {
"format": "[%(levelname)s|%(module)s|L%(lineno)d] %(asctime)s: %(message)s",
"datefmt": "%Y-%m-%dT%H:%M:%S"
}
},
"handlers": {
"stdout": {
"class": "logging.StreamHandler",
"level": "DEBUG",
"formatter": "detailed",
"stream": "ext://sys.stdout"
}
},
"loggers": {
"root": {
"level": "${LOG_LEVEL}",
"handlers": [
"stdout"
]
}
}
}

View File

@@ -1,85 +1,46 @@
import logging
import sys
from dataclasses import dataclass
from functools import lru_cache
from mealie.core.config import determine_data_dir
from .config import get_app_dirs, get_app_settings
from .logger.config import configured_logger
DATA_DIR = determine_data_dir()
from .config import get_app_settings # noqa E402
LOGGER_FILE = DATA_DIR.joinpath("mealie.log")
DATE_FORMAT = "%d-%b-%y %H:%M:%S"
LOGGER_FORMAT = "%(levelname)s: %(asctime)s \t%(message)s"
@dataclass
class LoggerConfig:
handlers: list
format: str
date_format: str
logger_file: str
level: int = logging.INFO
@lru_cache
def get_logger_config():
settings = get_app_settings()
log_level = logging._nameToLevel[settings.LOG_LEVEL]
if not settings.PRODUCTION:
from rich.logging import RichHandler
return LoggerConfig(
handlers=[RichHandler(rich_tracebacks=True, tracebacks_show_locals=True)],
format=None,
date_format=None,
logger_file=None,
level=log_level,
)
output_file_handler = logging.FileHandler(LOGGER_FILE)
handler_format = logging.Formatter(LOGGER_FORMAT, datefmt=DATE_FORMAT)
output_file_handler.setFormatter(handler_format)
# Stdout
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(handler_format)
return LoggerConfig(
handlers=[output_file_handler, stdout_handler],
format="%(levelname)s: %(asctime)s \t%(message)s",
date_format="%d-%b-%y %H:%M:%S",
logger_file=LOGGER_FILE,
level=log_level,
)
logger_config = get_logger_config()
logging.basicConfig(
level=logger_config.level,
format=logger_config.format,
datefmt=logger_config.date_format,
handlers=logger_config.handlers,
)
def logger_init() -> logging.Logger:
"""Returns the Root Logging Object for Mealie"""
return logging.getLogger("mealie")
root_logger = logger_init()
__root_logger: None | logging.Logger = None
def get_logger(module=None) -> logging.Logger:
"""Returns a child logger for mealie"""
global root_logger
"""
Get a logger instance for a module, in most cases module should not be
provided. Simply using the root logger is sufficient.
Cases where you would want to use a module specific logger might be a background
task or a long running process where you want to easily identify the source of
those messages
"""
global __root_logger
if __root_logger is None:
app_settings = get_app_settings()
mode = "development"
if app_settings.TESTING:
mode = "testing"
elif app_settings.PRODUCTION:
mode = "production"
dirs = get_app_dirs()
substitutions = {
"DATA_DIR": dirs.DATA_DIR.as_posix(),
"LOG_LEVEL": app_settings.LOG_LEVEL.upper(),
}
__root_logger = configured_logger(
mode=mode,
config_override=app_settings.LOG_CONFIG_OVERRIDE,
substitutions=substitutions,
)
if module is None:
return root_logger
return __root_logger
return root_logger.getChild(module)
return __root_logger.getChild(module)

View File

@@ -34,7 +34,7 @@ class OpenIDProvider(AuthProvider[OIDCRequest]):
repos = get_repositories(self.session)
user = self.try_get_user(claims.get("email"))
user = self.try_get_user(claims.get(settings.OIDC_USER_CLAIM))
group_claim = claims.get("groups", [])
is_admin = settings.OIDC_ADMIN_GROUP in group_claim if settings.OIDC_ADMIN_GROUP else False
is_valid_user = settings.OIDC_USER_GROUP in group_claim if settings.OIDC_USER_GROUP else True

View File

@@ -39,18 +39,33 @@ class PostgresProvider(AbstractDBProvider, BaseSettings):
POSTGRES_SERVER: str = "postgres"
POSTGRES_PORT: str = "5432"
POSTGRES_DB: str = "mealie"
POSTGRES_URL_OVERRIDE: str | None = None
model_config = SettingsConfigDict(arbitrary_types_allowed=True, extra="allow")
@property
def db_url(self) -> str:
host = f"{self.POSTGRES_SERVER}:{self.POSTGRES_PORT}"
if self.POSTGRES_URL_OVERRIDE:
url = self.POSTGRES_URL_OVERRIDE
scheme, remainder = url.split("://", 1)
if scheme != "postgresql":
raise ValueError("POSTGRES_URL_OVERRIDE scheme must be postgresql")
remainder = remainder.split(":", 1)[1]
password = remainder[: remainder.rfind("@")]
quoted_password = urlparse.quote(password)
safe_url = url.replace(password, quoted_password)
return safe_url
return str(
PostgresDsn.build(
scheme="postgresql",
username=self.POSTGRES_USER,
password=urlparse.quote_plus(self.POSTGRES_PASSWORD),
host=host,
password=urlparse.quote(self.POSTGRES_PASSWORD),
host=f"{self.POSTGRES_SERVER}:{self.POSTGRES_PORT}",
path=f"{self.POSTGRES_DB or ''}",
)
)

View File

@@ -36,13 +36,21 @@ class AppSettings(BaseSettings):
"""path to static files directory (ex. `mealie/dist`)"""
IS_DEMO: bool = False
HOST_IP: str = "*"
API_HOST: str = "0.0.0.0"
API_PORT: int = 9000
API_DOCS: bool = True
TOKEN_TIME: int = 48
"""time in hours"""
SECRET: str
LOG_LEVEL: str = "INFO"
LOG_CONFIG_OVERRIDE: Path | None = None
"""path to custom logging configuration file"""
LOG_LEVEL: str = "info"
"""corresponds to standard Python log levels"""
GIT_COMMIT_HASH: str = "unknown"
@@ -183,6 +191,7 @@ class AppSettings(BaseSettings):
OIDC_PROVIDER_NAME: str = "OAuth"
OIDC_REMEMBER_ME: bool = False
OIDC_SIGNING_ALGORITHM: str = "RS256"
OIDC_USER_CLAIM: str = "email"
@property
def OIDC_READY(self) -> bool:
@@ -190,7 +199,9 @@ class AppSettings(BaseSettings):
required = {self.OIDC_CLIENT_ID, self.OIDC_CONFIGURATION_URL}
not_none = None not in required
return self.OIDC_AUTH_ENABLED and not_none
valid_user_claim = self.OIDC_USER_CLAIM in ["email", "preferred_username"]
return self.OIDC_AUTH_ENABLED and not_none and valid_user_claim
# ===============================================
# Testing Config

View File

@@ -7,12 +7,14 @@ from pydantic import ConfigDict
from sqlalchemy import event
from sqlalchemy.ext.orderinglist import ordering_list
from sqlalchemy.orm import Mapped, mapped_column, validates
from sqlalchemy.orm.attributes import get_history
from sqlalchemy.orm.session import object_session
from mealie.db.models._model_utils.guid import GUID
from .._model_base import BaseMixins, SqlAlchemyBase
from .._model_utils import auto_init
from ..users.user_to_favorite import users_to_favorites
from ..users.user_to_recipe import UserToRecipe
from .api_extras import ApiExtras, api_extras
from .assets import RecipeAsset
from .category import recipes_to_categories
@@ -49,12 +51,20 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
user_id: Mapped[GUID | None] = mapped_column(GUID, sa.ForeignKey("users.id", use_alter=True), index=True)
user: Mapped["User"] = orm.relationship("User", uselist=False, foreign_keys=[user_id])
meal_entries: Mapped[list["GroupMealPlan"]] = orm.relationship(
"GroupMealPlan", back_populates="recipe", cascade="all, delete-orphan"
rating: Mapped[float | None] = mapped_column(sa.Float, index=True, nullable=True)
rated_by: Mapped[list["User"]] = orm.relationship(
"User", secondary=UserToRecipe.__tablename__, back_populates="rated_recipes"
)
favorited_by: Mapped[list["User"]] = orm.relationship(
"User",
secondary=UserToRecipe.__tablename__,
primaryjoin="and_(RecipeModel.id==UserToRecipe.recipe_id, UserToRecipe.is_favorite==True)",
back_populates="favorite_recipes",
viewonly=True,
)
favorited_by: Mapped[list["User"]] = orm.relationship(
"User", secondary=users_to_favorites, back_populates="favorite_recipes"
meal_entries: Mapped[list["GroupMealPlan"]] = orm.relationship(
"GroupMealPlan", back_populates="recipe", cascade="all, delete-orphan"
)
# General Recipe Properties
@@ -110,7 +120,6 @@ class RecipeModel(SqlAlchemyBase, BaseMixins):
)
tags: Mapped[list["Tag"]] = orm.relationship("Tag", secondary=recipes_to_tags, back_populates="recipes")
notes: Mapped[list[Note]] = orm.relationship("Note", cascade="all, delete-orphan")
rating: Mapped[int | None] = mapped_column(sa.Integer)
org_url: Mapped[str | None] = mapped_column(sa.String)
extras: Mapped[list[ApiExtras]] = orm.relationship("ApiExtras", cascade="all, delete-orphan")
is_ocr_recipe: Mapped[bool | None] = mapped_column(sa.Boolean, default=False)
@@ -246,3 +255,23 @@ def receive_description(target: RecipeModel, value: str, oldvalue, initiator):
target.description_normalized = RecipeModel.normalize(value)
else:
target.description_normalized = None
@event.listens_for(RecipeModel, "before_update")
def calculate_rating(mapper, connection, target: RecipeModel):
session = object_session(target)
if not session:
return
if session.is_modified(target, "rating"):
history = get_history(target, "rating")
old_value = history.deleted[0] if history.deleted else None
new_value = history.added[0] if history.added else None
if old_value == new_value:
return
target.rating = (
session.query(sa.func.avg(UserToRecipe.rating))
.filter(UserToRecipe.recipe_id == target.id, UserToRecipe.rating is not None, UserToRecipe.rating > 0)
.scalar()
)

View File

@@ -1,3 +1,3 @@
from .password_reset import *
from .user_to_favorite import *
from .user_to_recipe import *
from .users import *

View File

@@ -1,12 +0,0 @@
from sqlalchemy import Column, ForeignKey, Table, UniqueConstraint
from .._model_base import SqlAlchemyBase
from .._model_utils import GUID
users_to_favorites = Table(
"users_to_favorites",
SqlAlchemyBase.metadata,
Column("user_id", GUID, ForeignKey("users.id"), index=True),
Column("recipe_id", GUID, ForeignKey("recipes.id"), index=True),
UniqueConstraint("user_id", "recipe_id", name="user_id_recipe_id_key"),
)

View File

@@ -0,0 +1,42 @@
from sqlalchemy import Boolean, Column, Float, ForeignKey, UniqueConstraint, event
from sqlalchemy.engine.base import Connection
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.orm.session import Session
from .._model_base import BaseMixins, SqlAlchemyBase
from .._model_utils import GUID, auto_init
class UserToRecipe(SqlAlchemyBase, BaseMixins):
__tablename__ = "users_to_recipes"
__table_args__ = (UniqueConstraint("user_id", "recipe_id", name="user_id_recipe_id_rating_key"),)
id: Mapped[GUID] = mapped_column(GUID, primary_key=True, default=GUID.generate)
user_id = Column(GUID, ForeignKey("users.id"), index=True, primary_key=True)
recipe_id = Column(GUID, ForeignKey("recipes.id"), index=True, primary_key=True)
rating = Column(Float, index=True, nullable=True)
is_favorite = Column(Boolean, index=True, nullable=False)
@auto_init()
def __init__(self, **_) -> None:
pass
def update_recipe_rating(session: Session, target: UserToRecipe):
from mealie.db.models.recipe.recipe import RecipeModel
recipe = session.query(RecipeModel).filter(RecipeModel.id == target.recipe_id).first()
if not recipe:
return
recipe.rating = -1 # this will trigger the recipe to re-calculate the rating
@event.listens_for(UserToRecipe, "after_insert")
@event.listens_for(UserToRecipe, "after_update")
@event.listens_for(UserToRecipe, "after_delete")
def update_recipe_rating_on_insert_or_delete(_, connection: Connection, target: UserToRecipe):
session = Session(bind=connection)
update_recipe_rating(session, target)
session.commit()

View File

@@ -12,7 +12,7 @@ from mealie.db.models._model_utils.guid import GUID
from .._model_base import BaseMixins, SqlAlchemyBase
from .._model_utils import auto_init
from .user_to_favorite import users_to_favorites
from .user_to_recipe import UserToRecipe
if TYPE_CHECKING:
from ..group import Group
@@ -49,7 +49,7 @@ class User(SqlAlchemyBase, BaseMixins):
username: Mapped[str | None] = mapped_column(String, index=True, unique=True)
email: Mapped[str | None] = mapped_column(String, unique=True, index=True)
password: Mapped[str | None] = mapped_column(String)
auth_method: Mapped[Enum(AuthMethod)] = mapped_column(Enum(AuthMethod), default=AuthMethod.MEALIE)
auth_method: Mapped[Enum[AuthMethod]] = mapped_column(Enum(AuthMethod), default=AuthMethod.MEALIE)
admin: Mapped[bool | None] = mapped_column(Boolean, default=False)
advanced: Mapped[bool | None] = mapped_column(Boolean, default=False)
@@ -84,8 +84,15 @@ class User(SqlAlchemyBase, BaseMixins):
"GroupMealPlan", order_by="GroupMealPlan.date", **sp_args
)
shopping_lists: Mapped[Optional["ShoppingList"]] = orm.relationship("ShoppingList", **sp_args)
rated_recipes: Mapped[list["RecipeModel"]] = orm.relationship(
"RecipeModel", secondary=UserToRecipe.__tablename__, back_populates="rated_by"
)
favorite_recipes: Mapped[list["RecipeModel"]] = orm.relationship(
"RecipeModel", secondary=users_to_favorites, back_populates="favorited_by"
"RecipeModel",
secondary=UserToRecipe.__tablename__,
primaryjoin="and_(User.id==UserToRecipe.user_id, UserToRecipe.is_favorite==True)",
back_populates="favorited_by",
viewonly=True,
)
model_config = ConfigDict(
exclude={
@@ -112,7 +119,7 @@ class User(SqlAlchemyBase, BaseMixins):
self.group = Group.get_by_name(session, group)
self.favorite_recipes = []
self.rated_recipes = []
self.password = password

View File

@@ -33,12 +33,12 @@
"generic-deleted": "{name} wurde gelöscht"
},
"datetime": {
"year": "jahr|jahre",
"day": "tag|tage",
"hour": "stunde|stunden",
"minute": "minute|minuten",
"year": "Jahr|Jahre",
"day": "Tag|Tage",
"hour": "Stunde|Stunden",
"minute": "Minute|Minuten",
"second": "sekunde|sekunden",
"millisecond": "millisekunde|millisekunden",
"microsecond": "mikrosekunde|mikrosekunden"
"millisecond": "Millisekunde|Millisekunden",
"microsecond": "Mikrosekunde|Mikrosekunden"
}
}

View File

@@ -33,12 +33,12 @@
"generic-deleted": "{name} on poistettu"
},
"datetime": {
"year": "year|years",
"day": "day|days",
"hour": "hour|hours",
"minute": "minute|minutes",
"second": "second|seconds",
"millisecond": "millisecond|milliseconds",
"microsecond": "microsecond|microseconds"
"year": "vuosi|vuotta",
"day": "päivä|päivää",
"hour": "tunti|tuntia",
"minute": "minuutti|minuuttia",
"second": "sekunti|sekuntia",
"millisecond": "millisekunti|millisekuntia",
"microsecond": "mikrosekunti|mikrosekuntia"
}
}

View File

@@ -33,12 +33,12 @@
"generic-deleted": "{name} je bil izbrisan"
},
"datetime": {
"year": "year|years",
"day": "day|days",
"hour": "hour|hours",
"minute": "minute|minutes",
"second": "second|seconds",
"millisecond": "millisecond|milliseconds",
"microsecond": "microsecond|microseconds"
"year": "leto|let",
"day": "dan|dnevi",
"hour": "ura|ure",
"minute": "minuta|minute",
"second": "sekunda|sekunde",
"millisecond": "milisekunda|milisekunde",
"microsecond": "mikrosekunda|mikrosekunde"
}
}

View File

@@ -33,12 +33,12 @@
"generic-deleted": "{name} 已删除"
},
"datetime": {
"year": "year|years",
"day": "day|days",
"hour": "hour|hours",
"minute": "minute|minutes",
"second": "second|seconds",
"millisecond": "millisecond|milliseconds",
"microsecond": "microsecond|microseconds"
"year": "年|年",
"day": "天|天",
"hour": "小时|小时",
"minute": "分钟|分钟",
"second": "秒|秒",
"millisecond": "毫秒|毫秒",
"microsecond": "微秒|微秒"
}
}

20
mealie/main.py Normal file
View File

@@ -0,0 +1,20 @@
import uvicorn
from mealie.app import settings
from mealie.core.logger.config import log_config
def main():
uvicorn.run(
"app:app",
host=settings.API_HOST,
port=settings.API_PORT,
log_level=settings.LOG_LEVEL.lower(),
log_config=log_config(),
workers=1,
forwarded_allow_ips=settings.HOST_IP,
)
if __name__ == "__main__":
main()

Some files were not shown because too many files have changed in this diff Show More