mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-24 02:39:20 -05:00
Merge branch 'TandoorRecipes:develop' into develop
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -74,6 +74,7 @@ mediafiles/
|
||||
\.env
|
||||
staticfiles/
|
||||
postgresql/
|
||||
data/
|
||||
|
||||
|
||||
/docker-compose.override.yml
|
||||
|
||||
2
boot.sh
2
boot.sh
@@ -35,7 +35,7 @@ echo "Waiting for database to be ready..."
|
||||
attempt=0
|
||||
max_attempts=20
|
||||
|
||||
if [ "${DB_ENGINE}" != 'django.db.backends.sqlite3' ]; then
|
||||
if [ "${DB_ENGINE}" == 'django.db.backends.postgresql' ] || [ "${DATABASE_URL}" == 'postgres'* ]; then
|
||||
|
||||
# POSTGRES_PASSWORD (or a valid file at POSTGRES_PASSWORD_FILE) must be set in .env file
|
||||
|
||||
|
||||
@@ -192,7 +192,7 @@ class RecipeAdmin(admin.ModelAdmin):
|
||||
def created_by(obj):
|
||||
return obj.created_by.get_user_display_name()
|
||||
|
||||
if settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
|
||||
if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':
|
||||
actions = [rebuild_index]
|
||||
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ from django_scopes import scopes_disabled
|
||||
from django_scopes.forms import SafeModelChoiceField, SafeModelMultipleChoiceField
|
||||
from hcaptcha.fields import hCaptchaField
|
||||
|
||||
from .models import (Comment, Food, InviteLink, Keyword, MealPlan, MealType, Recipe, RecipeBook,
|
||||
RecipeBookEntry, SearchPreference, Space, Storage, Sync, User, UserPreference)
|
||||
from .models import (Comment, Food, InviteLink, Keyword, Recipe, RecipeBook, RecipeBookEntry,
|
||||
SearchPreference, Space, Storage, Sync, User, UserPreference)
|
||||
|
||||
|
||||
class SelectWidget(widgets.Select):
|
||||
|
||||
@@ -16,7 +16,7 @@ from recipes import settings
|
||||
|
||||
# TODO consider creating a simpleListRecipe API that only includes minimum of recipe info and minimal filtering
|
||||
class RecipeSearch():
|
||||
_postgres = settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']
|
||||
_postgres = settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql'
|
||||
|
||||
def __init__(self, request, **params):
|
||||
self._request = request
|
||||
|
||||
2529
cookbook/locale/he/LC_MESSAGES/django.po
Normal file
2529
cookbook/locale/he/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
from django.conf import settings
|
||||
from django.contrib.postgres.search import SearchVector
|
||||
from django.core.management.base import BaseCommand
|
||||
from django_scopes import scopes_disabled
|
||||
from django.utils import translation
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
from cookbook.managers import DICTIONARY
|
||||
from cookbook.models import Recipe, Step
|
||||
@@ -14,7 +14,7 @@ class Command(BaseCommand):
|
||||
help = _('Rebuilds full text search index on Recipe')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if settings.DATABASES['default']['ENGINE'] not in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
|
||||
if settings.DATABASES['default']['ENGINE'] != 'django.db.backends.postgresql':
|
||||
self.stdout.write(self.style.WARNING(_('Only Postgresql databases use full text search, no index to rebuild')))
|
||||
|
||||
try:
|
||||
|
||||
@@ -9,7 +9,7 @@ from django.utils import translation
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
from cookbook.managers import DICTIONARY
|
||||
from cookbook.models import (Index, PermissionModelMixin, Recipe, Step, SearchFields)
|
||||
from cookbook.models import Index, PermissionModelMixin, Recipe, SearchFields, Step
|
||||
|
||||
|
||||
def allSearchFields():
|
||||
@@ -21,7 +21,7 @@ def nameSearchField():
|
||||
|
||||
|
||||
def set_default_search_vector(apps, schema_editor):
|
||||
if settings.DATABASES['default']['ENGINE'] not in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
|
||||
if settings.DATABASES['default']['ENGINE'] != 'django.db.backends.postgresql':
|
||||
return
|
||||
language = DICTIONARY.get(translation.get_language(), 'simple')
|
||||
with scopes_disabled():
|
||||
|
||||
@@ -16,8 +16,7 @@ from cookbook.models import (Food, MealPlan, PropertyType, Recipe, SearchFields,
|
||||
Step, Unit, UserPreference)
|
||||
|
||||
SQLITE = True
|
||||
if settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',
|
||||
'django.db.backends.postgresql']:
|
||||
if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':
|
||||
SQLITE = False
|
||||
|
||||
|
||||
|
||||
@@ -4,17 +4,14 @@
|
||||
{% load i18n %}
|
||||
{% load l10n %}
|
||||
|
||||
|
||||
{% block title %}{% trans 'Export Recipes' %}{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
<div id="app">
|
||||
<export-view></export-view>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block script %}
|
||||
{% if debug %}
|
||||
<script src="{% url 'js_reverse' %}"></script>
|
||||
@@ -23,11 +20,13 @@
|
||||
{% endif %}
|
||||
|
||||
<script type="application/javascript">
|
||||
window.EXPORT_ID = {{pk}};
|
||||
{% if pk %}
|
||||
window.EXPORT_ID = {{ pk }}
|
||||
{% else %}
|
||||
window.EXPORT_ID = null
|
||||
{% endif %}
|
||||
window.CUSTOM_LOCALE = '{{ request.LANGUAGE_CODE }}';
|
||||
</script>
|
||||
|
||||
{% render_bundle 'export_view' %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
@@ -7,15 +7,12 @@
|
||||
{% block title %}{% trans 'Export' %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div id="app">
|
||||
<export-response-view></export-response-view>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block script %}
|
||||
{% if debug %}
|
||||
<script src="{% url 'js_reverse' %}"></script>
|
||||
@@ -24,7 +21,11 @@
|
||||
{% endif %}
|
||||
|
||||
<script type="application/javascript">
|
||||
window.EXPORT_ID = {{pk}};
|
||||
{% if pk %}
|
||||
window.EXPORT_ID = {{ pk }}
|
||||
{% else %}
|
||||
window.EXPORT_ID = null
|
||||
{% endif %}
|
||||
window.CUSTOM_LOCALE = '{{ request.LANGUAGE_CODE }}'
|
||||
</script>
|
||||
|
||||
|
||||
@@ -10,8 +10,7 @@ from django_scopes import scopes_disabled
|
||||
from cookbook.models import Food, Ingredient
|
||||
from cookbook.tests.factories import MealPlanFactory, RecipeFactory, StepFactory, UserFactory
|
||||
|
||||
if settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',
|
||||
'django.db.backends.postgresql']:
|
||||
if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':
|
||||
from django.db.backends.postgresql.features import DatabaseFeatures
|
||||
DatabaseFeatures.can_defer_constraint_checks = False
|
||||
|
||||
|
||||
@@ -23,8 +23,7 @@ from cookbook.tests.factories import (CookLogFactory, FoodFactory, IngredientFac
|
||||
# TODO makenow with above filters
|
||||
# TODO test search food/keywords including/excluding children
|
||||
LIST_URL = 'api:recipe-list'
|
||||
sqlite = settings.DATABASES['default']['ENGINE'] not in [
|
||||
'django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']
|
||||
sqlite = settings.DATABASES['default']['ENGINE'] != 'django.db.backends.postgresql'
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -186,8 +186,7 @@ class FuzzyFilterMixin(ViewSetMixin, ExtendedRecipeMixin):
|
||||
fuzzy = True
|
||||
|
||||
if query is not None and query not in ["''", '']:
|
||||
if fuzzy and (settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',
|
||||
'django.db.backends.postgresql']):
|
||||
if fuzzy and (settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql'):
|
||||
if self.request.user.is_authenticated and any(
|
||||
[self.model.__name__.lower() in x for x in self.request.user.searchpreference.unaccent.values_list('field', flat=True)]):
|
||||
self.queryset = self.queryset.annotate(trigram=TrigramSimilarity('name__unaccent', query))
|
||||
|
||||
@@ -16,12 +16,13 @@ from django.utils import timezone
|
||||
from django.utils.translation import gettext as _
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
from cookbook.forms import (CommentForm, Recipe, SearchPreferenceForm, SpaceCreateForm, SpaceJoinForm, User,
|
||||
UserCreateForm, UserPreference)
|
||||
from cookbook.helper.permission_helper import group_required, has_group_permission, share_link_valid, switch_user_active_space
|
||||
from cookbook.models import (Comment, CookLog, InviteLink, SearchFields, SearchPreference, ShareLink,
|
||||
Space, ViewLog, UserSpace)
|
||||
from cookbook.tables import (CookLogTable, ViewLogTable)
|
||||
from cookbook.forms import (CommentForm, Recipe, SearchPreferenceForm, SpaceCreateForm,
|
||||
SpaceJoinForm, User, UserCreateForm, UserPreference)
|
||||
from cookbook.helper.permission_helper import (group_required, has_group_permission,
|
||||
share_link_valid, switch_user_active_space)
|
||||
from cookbook.models import (Comment, CookLog, InviteLink, SearchFields, SearchPreference,
|
||||
ShareLink, Space, UserSpace, ViewLog)
|
||||
from cookbook.tables import CookLogTable, ViewLogTable
|
||||
from cookbook.version_info import VERSION_INFO
|
||||
from recipes.settings import PLUGINS
|
||||
|
||||
@@ -219,10 +220,10 @@ def shopping_settings(request):
|
||||
if not sp:
|
||||
sp = SearchPreferenceForm(user=request.user)
|
||||
fields_searched = (
|
||||
len(search_form.cleaned_data['icontains'])
|
||||
+ len(search_form.cleaned_data['istartswith'])
|
||||
+ len(search_form.cleaned_data['trigram'])
|
||||
+ len(search_form.cleaned_data['fulltext'])
|
||||
len(search_form.cleaned_data['icontains'])
|
||||
+ len(search_form.cleaned_data['istartswith'])
|
||||
+ len(search_form.cleaned_data['trigram'])
|
||||
+ len(search_form.cleaned_data['fulltext'])
|
||||
)
|
||||
if search_form.cleaned_data['preset'] == 'fuzzy':
|
||||
sp.search = SearchPreference.SIMPLE
|
||||
@@ -278,8 +279,7 @@ def shopping_settings(request):
|
||||
search_form = SearchPreferenceForm()
|
||||
|
||||
# these fields require postgresql - just disable them if postgresql isn't available
|
||||
if not settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2',
|
||||
'django.db.backends.postgresql']:
|
||||
if not settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':
|
||||
sp.search = SearchPreference.SIMPLE
|
||||
sp.trigram.clear()
|
||||
sp.fulltext.clear()
|
||||
@@ -309,10 +309,7 @@ def system(request):
|
||||
if not request.user.is_superuser:
|
||||
return HttpResponseRedirect(reverse('index'))
|
||||
|
||||
postgres = False if (
|
||||
settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2' # noqa: E501
|
||||
or settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql' # noqa: E501
|
||||
) else True
|
||||
postgres = settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql'
|
||||
|
||||
secret_key = False if os.getenv('SECRET_KEY') else True
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
backup.velero.io/backup-volumes: media,static
|
||||
backup.velero.io/backup-volumes: media,static
|
||||
labels:
|
||||
app: recipes
|
||||
tier: frontend
|
||||
@@ -35,7 +35,7 @@ spec:
|
||||
name: recipes
|
||||
key: secret-key
|
||||
- name: DB_ENGINE
|
||||
value: django.db.backends.postgresql_psycopg2
|
||||
value: django.db.backends.postgresql
|
||||
- name: POSTGRES_HOST
|
||||
value: recipes-postgresql
|
||||
- name: POSTGRES_PORT
|
||||
@@ -162,7 +162,7 @@ spec:
|
||||
- name: GUNICORN_MEDIA
|
||||
value: "0"
|
||||
- name: DB_ENGINE
|
||||
value: django.db.backends.postgresql_psycopg2
|
||||
value: django.db.backends.postgresql
|
||||
- name: POSTGRES_HOST
|
||||
value: recipes-postgresql
|
||||
- name: POSTGRES_PORT
|
||||
|
||||
@@ -350,7 +350,7 @@ WSGI_APPLICATION = 'recipes.wsgi.application'
|
||||
# Load settings from env files
|
||||
if os.getenv('DATABASE_URL'):
|
||||
match = re.match(
|
||||
r'(?P<schema>\w+):\/\/(?P<user>[\w\d_-]+)(:(?P<password>[^@]+))?@(?P<host>[^:/]+)(:(?P<port>\d+))?(\/(?P<database>[\w\d\/\._-]+))?',
|
||||
r'(?P<schema>\w+):\/\/(?:(?P<user>[\w\d_-]+)(?::(?P<password>[^@]+))?@)?(?P<host>[^:/]+)(?:(?P<port>\d+))?(?:/(?P<database>[\w\d/._-]+))?',
|
||||
os.getenv('DATABASE_URL')
|
||||
)
|
||||
settings = match.groupdict()
|
||||
@@ -358,6 +358,8 @@ if os.getenv('DATABASE_URL'):
|
||||
if schema.startswith('postgres'):
|
||||
engine = 'django.db.backends.postgresql'
|
||||
elif schema == 'sqlite':
|
||||
if not os.path.exists(db_path := os.path.dirname(settings['database'])):
|
||||
os.makedirs(db_path)
|
||||
engine = 'django.db.backends.sqlite3'
|
||||
else:
|
||||
raise Exception("Unsupported database schema: '%s'" % schema)
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
|
||||
{{ $t("If download did not start automatically: ") }}
|
||||
|
||||
<template v-if="export_info.expired">
|
||||
<a disabled
|
||||
><del>{{ $t("Download") }}</del></a
|
||||
>
|
||||
<template v-if="false">
|
||||
<!--template v-if="export_info.expired" temporary disabling this to get around immediate expiration-->
|
||||
<a disabled ref="downloadAnchor">
|
||||
<del>{{ $t("Download") }}</del>
|
||||
</a>
|
||||
({{ $t("Expired") }})
|
||||
</template>
|
||||
<a v-else :href="`${resolveDjangoUrl('view_export_file', export_id)}`" ref="downloadAnchor">{{ $t("Download") }}</a>
|
||||
@@ -53,20 +54,20 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue"
|
||||
import { BootstrapVue } from "bootstrap-vue"
|
||||
import Vue from "vue"
|
||||
|
||||
import "bootstrap-vue/dist/bootstrap-vue.css"
|
||||
|
||||
import { ResolveUrlMixin, makeToast, ToastMixin } from "@/utils/utils"
|
||||
import { ResolveUrlMixin, ToastMixin, makeToast } from "@/utils/utils"
|
||||
|
||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||
|
||||
import { ApiApiFactory } from "@/utils/openapi/api.ts"
|
||||
import VueSanitize from "vue-sanitize"
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
import VueSanitize from "vue-sanitize";
|
||||
Vue.use(VueSanitize);
|
||||
Vue.use(VueSanitize)
|
||||
export default {
|
||||
name: "ExportResponseView",
|
||||
mixins: [ResolveUrlMixin, ToastMixin],
|
||||
|
||||
@@ -45,14 +45,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue"
|
||||
import { BootstrapVue } from "bootstrap-vue"
|
||||
import Vue from "vue"
|
||||
|
||||
import "bootstrap-vue/dist/bootstrap-vue.css"
|
||||
|
||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||
|
||||
import { StandardToasts, makeToast, resolveDjangoUrl, ApiMixin } from "@/utils/utils"
|
||||
import { ApiMixin, StandardToasts, makeToast, resolveDjangoUrl } from "@/utils/utils"
|
||||
// import Multiselect from "vue-multiselect"
|
||||
import GenericMultiselect from "@/components/GenericMultiselect"
|
||||
import { ApiApiFactory } from "@/utils/openapi/api.ts"
|
||||
@@ -108,7 +106,7 @@ export default {
|
||||
let formData = new FormData()
|
||||
formData.append("type", this.recipe_app)
|
||||
formData.append("all", this.export_all)
|
||||
formData.append("custom_filter", this.filter?.id ?? null)
|
||||
formData.append("custom_filter", this.filter?.id ?? "")
|
||||
|
||||
for (var i = 0; i < this.recipe_list.length; i++) {
|
||||
formData.append("recipes", this.recipe_list[i].id)
|
||||
|
||||
@@ -246,32 +246,32 @@
|
||||
"New_Meal_Type": "סוג אוכל חדש",
|
||||
"Use_Fractions": "השתמש בשברים",
|
||||
"Use_Fractions_Help": "המר אוטומטית מדצמילי לשברים כאשר צופים במתכון.",
|
||||
"AddFoodToShopping": "",
|
||||
"RemoveFoodFromShopping": "",
|
||||
"DeleteShoppingConfirm": "",
|
||||
"IgnoredFood": "",
|
||||
"Add_Servings_to_Shopping": "",
|
||||
"Week_Numbers": "",
|
||||
"Show_Week_Numbers": "",
|
||||
"Export_As_ICal": "",
|
||||
"Export_To_ICal": "",
|
||||
"Cannot_Add_Notes_To_Shopping": "",
|
||||
"Added_To_Shopping_List": "",
|
||||
"Shopping_List_Empty": "",
|
||||
"Next_Period": "",
|
||||
"Previous_Period": "",
|
||||
"Current_Period": "",
|
||||
"Next_Day": "",
|
||||
"Previous_Day": "",
|
||||
"AddFoodToShopping": "הוסף {מזון} לרשימת הקניות",
|
||||
"RemoveFoodFromShopping": "הסר {מזון} מרשימת הקניות",
|
||||
"DeleteShoppingConfirm": "האם אתה בטוח שברצונך להסיר את כל ה{מזון} מרשימת הקניות ?",
|
||||
"IgnoredFood": "{מזון} להתעלם בקנייה.",
|
||||
"Add_Servings_to_Shopping": "הוסף{מנה}מנות לקנייה",
|
||||
"Week_Numbers": "מספר השבוע",
|
||||
"Show_Week_Numbers": "להציג מספר שבועות?",
|
||||
"Export_As_ICal": "ייצוא תקופה נוכחית בפורמט iCal",
|
||||
"Export_To_ICal": "ייצא .ics",
|
||||
"Cannot_Add_Notes_To_Shopping": "לא ניתן להוסיף הערות לרשימת הקניות",
|
||||
"Added_To_Shopping_List": "נוסף לרשימת הקניות",
|
||||
"Shopping_List_Empty": "רשימת הקניות שלך ריקה כרגע. ניתן להוסיף פריטים דרך תפריט תוכנית אוכל (מקש ימני על הכרטיס או מקש שמאלי על האייקון בתפריט)",
|
||||
"Next_Period": "התקופה הבאה",
|
||||
"Previous_Period": "תקופה קודמת",
|
||||
"Current_Period": "תקופה נוכחית",
|
||||
"Next_Day": "היום הבא",
|
||||
"Previous_Day": "יום קודם",
|
||||
"Inherit": "",
|
||||
"InheritFields": "",
|
||||
"FoodInherit": "",
|
||||
"ShowUncategorizedFood": "",
|
||||
"GroupBy": "",
|
||||
"Language": "",
|
||||
"Theme": "",
|
||||
"SupermarketCategoriesOnly": "",
|
||||
"MoveCategory": "",
|
||||
"ShowUncategorizedFood": "הצג לא מוגדר",
|
||||
"GroupBy": "אסוף לפי",
|
||||
"Language": "שפה",
|
||||
"Theme": "נושא",
|
||||
"SupermarketCategoriesOnly": "קטגוריות סופרמרקט בלבד",
|
||||
"MoveCategory": "העבר אל: ",
|
||||
"CountMore": "...+{count} עוד",
|
||||
"IgnoreThis": "לעולם אל תוסיף {food} לרשימת הקניות",
|
||||
"DelayFor": "השהה ל {hours} שעות",
|
||||
@@ -316,7 +316,7 @@
|
||||
"filter_to_supermarket_desc": "בברירת המחדל, רשימת קניות כוללה רק את הקטגוריות לסופרמקט הנבחר.",
|
||||
"CategoryName": "שם קטגוריה",
|
||||
"SupermarketName": "שם סופרמרקט",
|
||||
"CategoryInstruction": "",
|
||||
"CategoryInstruction": "גרור קטגוריות לשינוי הסדר שבו הן מופיעות ברשימת הקניות.",
|
||||
"shopping_recent_days_desc": "",
|
||||
"shopping_recent_days": "",
|
||||
"download_pdf": "",
|
||||
@@ -517,5 +517,9 @@
|
||||
"Use_Plural_Food_Simple": "השתמש בצורת רבים למאכלים בצורה דינאמית",
|
||||
"plural_usage_info": "תמיד השתמש בצורת רבים למאכלים במרחב זה.",
|
||||
"Create Recipe": "צור מתכון",
|
||||
"Import Recipe": "ייבא מתכון"
|
||||
"Import Recipe": "ייבא מתכון",
|
||||
"Alignment": "יישור",
|
||||
"StartDate": "תאריך התחלה",
|
||||
"EndDate": "תאריך סיום",
|
||||
"OrderInformation": "המוצרים מוצגים מהמספר הקטן לגדול."
|
||||
}
|
||||
|
||||
@@ -24,53 +24,53 @@
|
||||
"convert_internal": "Konvertuoti į vidinį receptą",
|
||||
"show_only_internal": "Rodyti tik vidinius receptus",
|
||||
"show_split_screen": "Padalintas vaizdas",
|
||||
"Log_Recipe_Cooking": "",
|
||||
"External_Recipe_Image": "",
|
||||
"Add_to_Shopping": "",
|
||||
"Add_to_Plan": "",
|
||||
"Step_start_time": "",
|
||||
"Sort_by_new": "",
|
||||
"Table_of_Contents": "",
|
||||
"Recipes_per_page": "",
|
||||
"Show_as_header": "",
|
||||
"Hide_as_header": "",
|
||||
"Add_nutrition_recipe": "",
|
||||
"Remove_nutrition_recipe": "",
|
||||
"Copy_template_reference": "",
|
||||
"per_serving": "",
|
||||
"Save_and_View": "",
|
||||
"Manage_Books": "",
|
||||
"Meal_Plan": "",
|
||||
"Select_Book": "",
|
||||
"Select_File": "",
|
||||
"Recipe_Image": "",
|
||||
"Import_finished": "",
|
||||
"View_Recipes": "",
|
||||
"Log_Cooking": "",
|
||||
"New_Recipe": "",
|
||||
"Url_Import": "",
|
||||
"Reset_Search": "",
|
||||
"Recently_Viewed": "",
|
||||
"Load_More": "",
|
||||
"New_Keyword": "",
|
||||
"Delete_Keyword": "",
|
||||
"Edit_Keyword": "",
|
||||
"Edit_Recipe": "",
|
||||
"Move_Keyword": "",
|
||||
"Merge_Keyword": "",
|
||||
"Hide_Keywords": "",
|
||||
"Hide_Recipes": "",
|
||||
"Move_Up": "",
|
||||
"Move_Down": "",
|
||||
"Step_Name": "",
|
||||
"Step_Type": "",
|
||||
"Make_Header": "",
|
||||
"Make_Ingredient": "",
|
||||
"Amount": "",
|
||||
"Enable_Amount": "",
|
||||
"Disable_Amount": "",
|
||||
"Ingredient Editor": "",
|
||||
"Description_Replace": "",
|
||||
"Log_Recipe_Cooking": "Užregistruoti recepto pagaminimą",
|
||||
"External_Recipe_Image": "Išorinis recepto vaizdas",
|
||||
"Add_to_Shopping": "Pridėti į apsipirkimo sąrašą",
|
||||
"Add_to_Plan": "Pridėti į planą",
|
||||
"Step_start_time": "Žingsnio pradžios laikas",
|
||||
"Sort_by_new": "Rūšiuoti pagal naujumą",
|
||||
"Table_of_Contents": "Turinys",
|
||||
"Recipes_per_page": "Receptų skaičius per puslapį",
|
||||
"Show_as_header": "Rodyti kaip antraštę",
|
||||
"Hide_as_header": "Slėpti kaip antraštę",
|
||||
"Add_nutrition_recipe": "Įtraukti mitybos informaciją į receptą",
|
||||
"Remove_nutrition_recipe": "Ištrinti mitybos informaciją iš recepto",
|
||||
"Copy_template_reference": "Nukopijuoti šablono nuorodą",
|
||||
"per_serving": "per porciją",
|
||||
"Save_and_View": "Išsaugoti ir peržiūrėti",
|
||||
"Manage_Books": "Tvarkyti knygas",
|
||||
"Meal_Plan": "Maisto planas",
|
||||
"Select_Book": "Pasirinkti Knygą",
|
||||
"Select_File": "Pasirinkti Failą",
|
||||
"Recipe_Image": "Recepto nuotrauka",
|
||||
"Import_finished": "Importavimas baigtas",
|
||||
"View_Recipes": "Žiūrėti receptus",
|
||||
"Log_Cooking": "Užregistruoti patiekalo gaminimą",
|
||||
"New_Recipe": "Naujas Receptas",
|
||||
"Url_Import": "URL importavimas",
|
||||
"Reset_Search": "Iš naujo nustatyti paiešką",
|
||||
"Recently_Viewed": "Neseniai Žiūrėta",
|
||||
"Load_More": "Įkelti daugiau",
|
||||
"New_Keyword": "Naujas Raktažodis",
|
||||
"Delete_Keyword": "Ištrinti raktažodį",
|
||||
"Edit_Keyword": "Redaguoti raktažodį",
|
||||
"Edit_Recipe": "Redaguoti receptą",
|
||||
"Move_Keyword": "Perkelti Raktažodį",
|
||||
"Merge_Keyword": "Sujungti raktažodį",
|
||||
"Hide_Keywords": "Paslėpti raktažodį",
|
||||
"Hide_Recipes": "Paslėpti receptus",
|
||||
"Move_Up": "Pakelti aukštyn",
|
||||
"Move_Down": "Nuleisti žemyn",
|
||||
"Step_Name": "Žingsnio pavadinimas",
|
||||
"Step_Type": "Žingsnio tipas",
|
||||
"Make_Header": "Padaryti antraštę",
|
||||
"Make_Ingredient": "Padaryti ingredientą",
|
||||
"Amount": "Suma",
|
||||
"Enable_Amount": "Įjungti sumą",
|
||||
"Disable_Amount": "Išjungti sumą",
|
||||
"Ingredient Editor": "Ingredientų redaktorius",
|
||||
"Description_Replace": "Pakeisti aprašymą",
|
||||
"Instruction_Replace": "",
|
||||
"Auto_Sort": "",
|
||||
"Auto_Sort_Help": "",
|
||||
|
||||
Reference in New Issue
Block a user