add search debug
This commit is contained in:
parent
3fe5340592
commit
55a0304700
1
.gitignore
vendored
1
.gitignore
vendored
@ -84,3 +84,4 @@ vetur.config.js
|
|||||||
cookbook/static/vue
|
cookbook/static/vue
|
||||||
vue/webpack-stats.json
|
vue/webpack-stats.json
|
||||||
cookbook/templates/sw.js
|
cookbook/templates/sw.js
|
||||||
|
.prettierignore
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
from collections import Counter
|
from collections import Counter
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from recipes import settings
|
from django.contrib.postgres.search import SearchQuery, SearchRank, TrigramSimilarity
|
||||||
from django.contrib.postgres.search import (
|
|
||||||
SearchQuery, SearchRank, TrigramSimilarity
|
|
||||||
)
|
|
||||||
from django.core.cache import caches
|
from django.core.cache import caches
|
||||||
from django.db.models import Avg, Case, Count, Func, Max, Q, Subquery, Value, When
|
from django.db.models import Avg, Case, Count, Func, Max, Q, Subquery, Value, When
|
||||||
from django.db.models.functions import Coalesce
|
from django.db.models.functions import Coalesce
|
||||||
from django.utils import timezone, translation
|
from django.utils import timezone, translation
|
||||||
|
|
||||||
|
from cookbook.filters import RecipeFilter
|
||||||
|
from cookbook.helper.permission_helper import has_group_permission
|
||||||
from cookbook.managers import DICTIONARY
|
from cookbook.managers import DICTIONARY
|
||||||
from cookbook.models import Food, Keyword, ViewLog, SearchPreference
|
from cookbook.models import Food, Keyword, Recipe, SearchPreference, ViewLog
|
||||||
|
from recipes import settings
|
||||||
|
|
||||||
|
|
||||||
class Round(Func):
|
class Round(Func):
|
||||||
@ -143,9 +143,9 @@ def search_recipes(request, queryset, params):
|
|||||||
|
|
||||||
# TODO add order by user settings - only do search rank and annotation if rank order is configured
|
# TODO add order by user settings - only do search rank and annotation if rank order is configured
|
||||||
search_rank = (
|
search_rank = (
|
||||||
SearchRank('name_search_vector', search_query, cover_density=True)
|
SearchRank('name_search_vector', search_query, cover_density=True)
|
||||||
+ SearchRank('desc_search_vector', search_query, cover_density=True)
|
+ SearchRank('desc_search_vector', search_query, cover_density=True)
|
||||||
+ SearchRank('steps__search_vector', search_query, cover_density=True)
|
+ SearchRank('steps__search_vector', search_query, cover_density=True)
|
||||||
)
|
)
|
||||||
queryset = queryset.filter(query_filter).annotate(rank=search_rank)
|
queryset = queryset.filter(query_filter).annotate(rank=search_rank)
|
||||||
orderby += ['-rank']
|
orderby += ['-rank']
|
||||||
@ -400,3 +400,13 @@ def annotated_qs(qs, root=False, fill=False):
|
|||||||
if start_depth and start_depth > 0:
|
if start_depth and start_depth > 0:
|
||||||
info['close'] = list(range(0, prev_depth - start_depth + 1))
|
info['close'] = list(range(0, prev_depth - start_depth + 1))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def old_search(request):
|
||||||
|
if has_group_permission(request.user, ('guest',)):
|
||||||
|
params = dict(request.GET)
|
||||||
|
params['internal'] = None
|
||||||
|
f = RecipeFilter(params,
|
||||||
|
queryset=Recipe.objects.filter(space=request.user.userpreference.space).all().order_by('name'),
|
||||||
|
space=request.space)
|
||||||
|
return f.qs
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
localStorage.setItem('SCRIPT_NAME', "{% base_path request 'script' %}")
|
localStorage.setItem('SCRIPT_NAME', "{% base_path request 'script' %}")
|
||||||
localStorage.setItem('BASE_PATH', "{% base_path request 'base' %}")
|
localStorage.setItem('BASE_PATH', "{% base_path request 'base' %}")
|
||||||
localStorage.setItem('STATIC_URL', "{% base_path request 'static_base' %}")
|
localStorage.setItem('STATIC_URL', "{% base_path request 'static_base' %}")
|
||||||
|
localStorage.setItem('DEBUG', "{% is_debug %}")
|
||||||
window.addEventListener("load", () => {
|
window.addEventListener("load", () => {
|
||||||
if ("serviceWorker" in navigator) {
|
if ("serviceWorker" in navigator) {
|
||||||
navigator.serviceWorker.register("{% url 'service_worker' %}", {scope: "{% base_path request 'base' %}" + '/'}).then(function (reg) {
|
navigator.serviceWorker.register("{% url 'service_worker' %}", {scope: "{% base_path request 'base' %}" + '/'}).then(function (reg) {
|
||||||
|
@ -2,17 +2,17 @@ from pydoc import locate
|
|||||||
|
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
from recipes.version import VERSION_NUMBER
|
from rest_framework import permissions, routers
|
||||||
from rest_framework import routers, permissions
|
|
||||||
from rest_framework.schemas import get_schema_view
|
from rest_framework.schemas import get_schema_view
|
||||||
|
|
||||||
from cookbook.helper import dal
|
from cookbook.helper import dal
|
||||||
|
from recipes.settings import DEBUG
|
||||||
|
from recipes.version import VERSION_NUMBER
|
||||||
|
|
||||||
from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe,
|
from .models import (Automation, Comment, Food, InviteLink, Keyword, MealPlan, Recipe, RecipeBook,
|
||||||
RecipeBook, RecipeBookEntry, RecipeImport, ShoppingList,
|
RecipeBookEntry, RecipeImport, ShoppingList, Step, Storage, Supermarket,
|
||||||
Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, get_model_name, Automation,
|
SupermarketCategory, Sync, SyncLog, Unit, UserFile, get_model_name)
|
||||||
UserFile, Step)
|
from .views import api, data, delete, edit, import_export, lists, new, telegram, views
|
||||||
from .views import api, data, delete, edit, import_export, lists, new, views, telegram
|
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = routers.DefaultRouter()
|
||||||
router.register(r'user-name', api.UserNameViewSet, basename='username')
|
router.register(r'user-name', api.UserNameViewSet, basename='username')
|
||||||
@ -68,8 +68,6 @@ urlpatterns = [
|
|||||||
path('history/', views.history, name='view_history'),
|
path('history/', views.history, name='view_history'),
|
||||||
path('supermarket/', views.supermarket, name='view_supermarket'),
|
path('supermarket/', views.supermarket, name='view_supermarket'),
|
||||||
path('abuse/<slug:token>', views.report_share_abuse, name='view_report_share_abuse'),
|
path('abuse/<slug:token>', views.report_share_abuse, name='view_report_share_abuse'),
|
||||||
path('test/', views.test, name='view_test'),
|
|
||||||
path('test2/', views.test2, name='view_test2'),
|
|
||||||
|
|
||||||
path('import/', import_export.import_recipe, name='view_import'),
|
path('import/', import_export.import_recipe, name='view_import'),
|
||||||
path('import-response/<int:pk>/', import_export.import_response, name='view_import_response'),
|
path('import-response/<int:pk>/', import_export.import_response, name='view_import_response'),
|
||||||
@ -189,3 +187,7 @@ for m in vue_models:
|
|||||||
f'list/{url_name}/', c, name=f'list_{py_name}'
|
f'list/{url_name}/', c, name=f'list_{py_name}'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
urlpatterns.append(path('test/', views.test, name='view_test'))
|
||||||
|
urlpatterns.append(path('test2/', views.test2, name='view_test2'))
|
||||||
|
@ -2,11 +2,11 @@ import io
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from annoying.decorators import ajax_request
|
from annoying.decorators import ajax_request
|
||||||
from annoying.functions import get_object_or_None
|
from annoying.functions import get_object_or_None
|
||||||
from collections import OrderedDict
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.postgres.search import TrigramSimilarity
|
from django.contrib.postgres.search import TrigramSimilarity
|
||||||
@ -15,12 +15,12 @@ from django.core.files import File
|
|||||||
from django.db.models import Case, ProtectedError, Q, Value, When
|
from django.db.models import Case, ProtectedError, Q, Value, When
|
||||||
from django.db.models.fields.related import ForeignObjectRel
|
from django.db.models.fields.related import ForeignObjectRel
|
||||||
from django.http import FileResponse, HttpResponse, JsonResponse
|
from django.http import FileResponse, HttpResponse, JsonResponse
|
||||||
from django_scopes import scopes_disabled
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
from django.shortcuts import redirect, get_object_or_404
|
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
from django_scopes import scopes_disabled
|
||||||
from icalendar import Calendar, Event
|
from icalendar import Calendar, Event
|
||||||
from recipe_scrapers import scrape_me, WebsiteNotImplementedError, NoSchemaFoundInWildMode
|
from recipe_scrapers import NoSchemaFoundInWildMode, WebsiteNotImplementedError, scrape_me
|
||||||
from rest_framework import decorators, status, viewsets
|
from rest_framework import decorators, status, viewsets
|
||||||
from rest_framework.exceptions import APIException, PermissionDenied
|
from rest_framework.exceptions import APIException, PermissionDenied
|
||||||
from rest_framework.pagination import PageNumberPagination
|
from rest_framework.pagination import PageNumberPagination
|
||||||
@ -28,41 +28,39 @@ from rest_framework.parsers import MultiPartParser
|
|||||||
from rest_framework.renderers import JSONRenderer, TemplateHTMLRenderer
|
from rest_framework.renderers import JSONRenderer, TemplateHTMLRenderer
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.viewsets import ViewSetMixin
|
from rest_framework.viewsets import ViewSetMixin
|
||||||
from treebeard.exceptions import PathOverflow, InvalidMoveToDescendant, InvalidPosition
|
from treebeard.exceptions import InvalidMoveToDescendant, InvalidPosition, PathOverflow
|
||||||
|
|
||||||
from cookbook.helper.image_processing import handle_image
|
from cookbook.helper.image_processing import handle_image
|
||||||
from cookbook.helper.ingredient_parser import IngredientParser
|
from cookbook.helper.ingredient_parser import IngredientParser
|
||||||
from cookbook.helper.permission_helper import (CustomIsAdmin, CustomIsGuest,
|
from cookbook.helper.permission_helper import (CustomIsAdmin, CustomIsGuest, CustomIsOwner,
|
||||||
CustomIsOwner, CustomIsShare,
|
CustomIsShare, CustomIsShared, CustomIsUser,
|
||||||
CustomIsShared, CustomIsUser,
|
|
||||||
group_required)
|
group_required)
|
||||||
from cookbook.helper.recipe_html_import import get_recipe_from_source
|
from cookbook.helper.recipe_html_import import get_recipe_from_source
|
||||||
|
from cookbook.helper.recipe_search import get_facet, old_search, search_recipes
|
||||||
from cookbook.helper.recipe_search import search_recipes, get_facet
|
|
||||||
from cookbook.helper.recipe_url_import import get_from_scraper
|
from cookbook.helper.recipe_url_import import get_from_scraper
|
||||||
from cookbook.models import (CookLog, Food, Ingredient, Keyword, MealPlan,
|
from cookbook.models import (Automation, BookmarkletImport, CookLog, Food, ImportLog, Ingredient,
|
||||||
MealType, Recipe, RecipeBook, ShoppingList,
|
Keyword, MealPlan, MealType, Recipe, RecipeBook, RecipeBookEntry,
|
||||||
ShoppingListEntry, ShoppingListRecipe, Step,
|
ShareLink, ShoppingList, ShoppingListEntry, ShoppingListRecipe, Step,
|
||||||
Storage, Sync, SyncLog, Unit, UserPreference,
|
Storage, Supermarket, SupermarketCategory, SupermarketCategoryRelation,
|
||||||
ViewLog, RecipeBookEntry, Supermarket, ImportLog, BookmarkletImport, SupermarketCategory, UserFile, ShareLink, SupermarketCategoryRelation, Automation)
|
Sync, SyncLog, Unit, UserFile, UserPreference, ViewLog)
|
||||||
from cookbook.provider.dropbox import Dropbox
|
from cookbook.provider.dropbox import Dropbox
|
||||||
from cookbook.provider.local import Local
|
from cookbook.provider.local import Local
|
||||||
from cookbook.provider.nextcloud import Nextcloud
|
from cookbook.provider.nextcloud import Nextcloud
|
||||||
from cookbook.schemas import FilterSchema, RecipeSchema, TreeSchema, QueryOnlySchema
|
from cookbook.schemas import FilterSchema, QueryOnlySchema, RecipeSchema, TreeSchema
|
||||||
from cookbook.serializer import (FoodSerializer, IngredientSerializer,
|
from cookbook.serializer import (AutomationSerializer, BookmarkletImportSerializer,
|
||||||
KeywordSerializer, MealPlanSerializer,
|
CookLogSerializer, FoodSerializer, ImportLogSerializer,
|
||||||
MealTypeSerializer, RecipeBookSerializer,
|
IngredientSerializer, KeywordSerializer, MealPlanSerializer,
|
||||||
RecipeImageSerializer, RecipeSerializer,
|
MealTypeSerializer, RecipeBookEntrySerializer,
|
||||||
ShoppingListAutoSyncSerializer,
|
RecipeBookSerializer, RecipeImageSerializer,
|
||||||
ShoppingListEntrySerializer,
|
RecipeOverviewSerializer, RecipeSerializer,
|
||||||
ShoppingListRecipeSerializer,
|
ShoppingListAutoSyncSerializer, ShoppingListEntrySerializer,
|
||||||
ShoppingListSerializer, StepSerializer,
|
ShoppingListRecipeSerializer, ShoppingListSerializer,
|
||||||
StorageSerializer, SyncLogSerializer,
|
StepSerializer, StorageSerializer,
|
||||||
SyncSerializer, UnitSerializer,
|
SupermarketCategoryRelationSerializer,
|
||||||
UserNameSerializer, UserPreferenceSerializer,
|
SupermarketCategorySerializer, SupermarketSerializer,
|
||||||
ViewLogSerializer, CookLogSerializer, RecipeBookEntrySerializer,
|
SyncLogSerializer, SyncSerializer, UnitSerializer,
|
||||||
RecipeOverviewSerializer, SupermarketSerializer, ImportLogSerializer,
|
UserFileSerializer, UserNameSerializer, UserPreferenceSerializer,
|
||||||
BookmarkletImportSerializer, SupermarketCategorySerializer, UserFileSerializer, SupermarketCategoryRelationSerializer, AutomationSerializer)
|
ViewLogSerializer)
|
||||||
from recipes import settings
|
from recipes import settings
|
||||||
|
|
||||||
|
|
||||||
@ -547,7 +545,16 @@ class RecipeViewSet(viewsets.ModelViewSet):
|
|||||||
|
|
||||||
return super().get_queryset()
|
return super().get_queryset()
|
||||||
|
|
||||||
|
def list(self, request, *args, **kwargs):
|
||||||
|
if self.request.GET.get('debug', False):
|
||||||
|
return JsonResponse({
|
||||||
|
'new': str(self.get_queryset().query),
|
||||||
|
'old': str(old_search(request).query)
|
||||||
|
})
|
||||||
|
return super().list(request, *args, **kwargs)
|
||||||
|
|
||||||
# TODO write extensive tests for permissions
|
# TODO write extensive tests for permissions
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
return RecipeOverviewSerializer
|
return RecipeOverviewSerializer
|
||||||
|
@ -13,7 +13,7 @@ from django.contrib.auth.password_validation import validate_password
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db.models import Avg, Q, Sum
|
from django.db.models import Avg, Q, Sum
|
||||||
from django.http import HttpResponseRedirect, JsonResponse
|
from django.http import HttpResponseRedirect, JsonResponse
|
||||||
from django.shortcuts import get_object_or_404, render, redirect
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
@ -22,16 +22,15 @@ from django_tables2 import RequestConfig
|
|||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
|
|
||||||
from cookbook.filters import RecipeFilter
|
from cookbook.filters import RecipeFilter
|
||||||
from cookbook.forms import (CommentForm, Recipe, User,
|
from cookbook.forms import (CommentForm, Recipe, SearchPreferenceForm, SpaceCreateForm,
|
||||||
UserCreateForm, UserNameForm, UserPreference,
|
SpaceJoinForm, User, UserCreateForm, UserNameForm, UserPreference,
|
||||||
UserPreferenceForm, SpaceJoinForm, SpaceCreateForm,
|
UserPreferenceForm)
|
||||||
SearchPreferenceForm)
|
from cookbook.helper.permission_helper import group_required, has_group_permission, share_link_valid
|
||||||
from cookbook.helper.permission_helper import group_required, share_link_valid, has_group_permission
|
from cookbook.models import (Comment, CookLog, Food, InviteLink, Keyword, MealPlan, RecipeImport,
|
||||||
from cookbook.models import (Comment, CookLog, InviteLink, MealPlan,
|
SearchFields, SearchPreference, ShareLink, ShoppingList, Space, Unit,
|
||||||
ViewLog, ShoppingList, Space, Keyword, RecipeImport, Unit,
|
UserFile, ViewLog)
|
||||||
Food, UserFile, ShareLink, SearchPreference, SearchFields)
|
from cookbook.tables import (CookLogTable, InviteLinkTable, RecipeTable, RecipeTableSmall,
|
||||||
from cookbook.tables import (CookLogTable, RecipeTable, RecipeTableSmall,
|
ViewLogTable)
|
||||||
ViewLogTable, InviteLinkTable)
|
|
||||||
from cookbook.views.data import Object
|
from cookbook.views.data import Object
|
||||||
from recipes.version import BUILD_REF, VERSION_NUMBER
|
from recipes.version import BUILD_REF, VERSION_NUMBER
|
||||||
|
|
||||||
@ -331,10 +330,10 @@ def user_settings(request):
|
|||||||
if not sp:
|
if not sp:
|
||||||
sp = SearchPreferenceForm(user=request.user)
|
sp = SearchPreferenceForm(user=request.user)
|
||||||
fields_searched = (
|
fields_searched = (
|
||||||
len(search_form.cleaned_data['icontains'])
|
len(search_form.cleaned_data['icontains'])
|
||||||
+ len(search_form.cleaned_data['istartswith'])
|
+ len(search_form.cleaned_data['istartswith'])
|
||||||
+ len(search_form.cleaned_data['trigram'])
|
+ len(search_form.cleaned_data['trigram'])
|
||||||
+ len(search_form.cleaned_data['fulltext'])
|
+ len(search_form.cleaned_data['fulltext'])
|
||||||
)
|
)
|
||||||
if fields_searched == 0:
|
if fields_searched == 0:
|
||||||
search_form.add_error(None, _('You must select at least one field to search!'))
|
search_form.add_error(None, _('You must select at least one field to search!'))
|
||||||
@ -382,7 +381,7 @@ def user_settings(request):
|
|||||||
if up:
|
if up:
|
||||||
preference_form = UserPreferenceForm(instance=up, space=request.space)
|
preference_form = UserPreferenceForm(instance=up, space=request.space)
|
||||||
else:
|
else:
|
||||||
preference_form = UserPreferenceForm( space=request.space)
|
preference_form = UserPreferenceForm(space=request.space)
|
||||||
|
|
||||||
fields_searched = len(sp.icontains.all()) + len(sp.istartswith.all()) + len(sp.trigram.all()) + len(
|
fields_searched = len(sp.icontains.all()) + len(sp.istartswith.all()) + len(sp.trigram.all()) + len(
|
||||||
sp.fulltext.all())
|
sp.fulltext.all())
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,210 +1,211 @@
|
|||||||
{
|
{
|
||||||
"warning_feature_beta": "This feature is currently in a BETA (testing) state. Please expect bugs and possibly breaking changes in the future (possibly loosing feature related data) when using this feature.",
|
"warning_feature_beta": "This feature is currently in a BETA (testing) state. Please expect bugs and possibly breaking changes in the future (possibly loosing feature related data) when using this feature.",
|
||||||
"err_fetching_resource": "There was an error fetching a resource!",
|
"err_fetching_resource": "There was an error fetching a resource!",
|
||||||
"err_creating_resource": "There was an error creating a resource!",
|
"err_creating_resource": "There was an error creating a resource!",
|
||||||
"err_updating_resource": "There was an error updating a resource!",
|
"err_updating_resource": "There was an error updating a resource!",
|
||||||
"err_deleting_resource": "There was an error deleting a resource!",
|
"err_deleting_resource": "There was an error deleting a resource!",
|
||||||
"success_fetching_resource": "Successfully fetched a resource!",
|
"success_fetching_resource": "Successfully fetched a resource!",
|
||||||
"success_creating_resource": "Successfully created a resource!",
|
"success_creating_resource": "Successfully created a resource!",
|
||||||
"success_updating_resource": "Successfully updated a resource!",
|
"success_updating_resource": "Successfully updated a resource!",
|
||||||
"success_deleting_resource": "Successfully deleted a resource!",
|
"success_deleting_resource": "Successfully deleted a resource!",
|
||||||
"file_upload_disabled": "File upload is not enabled for your space.",
|
"file_upload_disabled": "File upload is not enabled for your space.",
|
||||||
"step_time_minutes": "Step time in minutes",
|
"step_time_minutes": "Step time in minutes",
|
||||||
"confirm_delete": "Are you sure you want to delete this {object}?",
|
"confirm_delete": "Are you sure you want to delete this {object}?",
|
||||||
"import_running": "Import running, please wait!",
|
"import_running": "Import running, please wait!",
|
||||||
"all_fields_optional": "All fields are optional and can be left empty.",
|
"all_fields_optional": "All fields are optional and can be left empty.",
|
||||||
"convert_internal": "Convert to internal recipe",
|
"convert_internal": "Convert to internal recipe",
|
||||||
"show_only_internal": "Show only internal recipes",
|
"show_only_internal": "Show only internal recipes",
|
||||||
"show_split_screen": "Split View",
|
"show_split_screen": "Split View",
|
||||||
"Log_Recipe_Cooking": "Log Recipe Cooking",
|
"Log_Recipe_Cooking": "Log Recipe Cooking",
|
||||||
"External_Recipe_Image": "External Recipe Image",
|
"External_Recipe_Image": "External Recipe Image",
|
||||||
"Add_to_Shopping": "Add to Shopping",
|
"Add_to_Shopping": "Add to Shopping",
|
||||||
"Add_to_Plan": "Add to Plan",
|
"Add_to_Plan": "Add to Plan",
|
||||||
"Step_start_time": "Step start time",
|
"Step_start_time": "Step start time",
|
||||||
"Sort_by_new": "Sort by new",
|
"Sort_by_new": "Sort by new",
|
||||||
"Table_of_Contents": "Table of Contents",
|
"Table_of_Contents": "Table of Contents",
|
||||||
"Recipes_per_page": "Recipes per Page",
|
"Recipes_per_page": "Recipes per Page",
|
||||||
"Show_as_header": "Show as header",
|
"Show_as_header": "Show as header",
|
||||||
"Hide_as_header": "Hide as header",
|
"Hide_as_header": "Hide as header",
|
||||||
"Add_nutrition_recipe": "Add nutrition to recipe",
|
"Add_nutrition_recipe": "Add nutrition to recipe",
|
||||||
"Remove_nutrition_recipe": "Delete nutrition from recipe",
|
"Remove_nutrition_recipe": "Delete nutrition from recipe",
|
||||||
"Copy_template_reference": "Copy template reference",
|
"Copy_template_reference": "Copy template reference",
|
||||||
"Save_and_View": "Save & View",
|
"Save_and_View": "Save & View",
|
||||||
"Manage_Books": "Manage Books",
|
"Manage_Books": "Manage Books",
|
||||||
"Meal_Plan": "Meal Plan",
|
"Meal_Plan": "Meal Plan",
|
||||||
"Select_Book": "Select Book",
|
"Select_Book": "Select Book",
|
||||||
"Select_File": "Select File",
|
"Select_File": "Select File",
|
||||||
"Recipe_Image": "Recipe Image",
|
"Recipe_Image": "Recipe Image",
|
||||||
"Import_finished": "Import finished",
|
"Import_finished": "Import finished",
|
||||||
"View_Recipes": "View Recipes",
|
"View_Recipes": "View Recipes",
|
||||||
"Log_Cooking": "Log Cooking",
|
"Log_Cooking": "Log Cooking",
|
||||||
"New_Recipe": "New Recipe",
|
"New_Recipe": "New Recipe",
|
||||||
"Url_Import": "Url Import",
|
"Url_Import": "Url Import",
|
||||||
"Reset_Search": "Reset Search",
|
"Reset_Search": "Reset Search",
|
||||||
"Recently_Viewed": "Recently Viewed",
|
"Recently_Viewed": "Recently Viewed",
|
||||||
"Load_More": "Load More",
|
"Load_More": "Load More",
|
||||||
"New_Keyword": "New Keyword",
|
"New_Keyword": "New Keyword",
|
||||||
"Delete_Keyword": "Delete Keyword",
|
"Delete_Keyword": "Delete Keyword",
|
||||||
"Edit_Keyword": "Edit Keyword",
|
"Edit_Keyword": "Edit Keyword",
|
||||||
"Edit_Recipe": "Edit Recipe",
|
"Edit_Recipe": "Edit Recipe",
|
||||||
"Move_Keyword": "Move Keyword",
|
"Move_Keyword": "Move Keyword",
|
||||||
"Merge_Keyword": "Merge Keyword",
|
"Merge_Keyword": "Merge Keyword",
|
||||||
"Hide_Keywords": "Hide Keyword",
|
"Hide_Keywords": "Hide Keyword",
|
||||||
"Hide_Recipes": "Hide Recipes",
|
"Hide_Recipes": "Hide Recipes",
|
||||||
"Move_Up": "Move up",
|
"Move_Up": "Move up",
|
||||||
"Move_Down": "Move down",
|
"Move_Down": "Move down",
|
||||||
"Step_Name": "Step Name",
|
"Step_Name": "Step Name",
|
||||||
"Step_Type": "Step Type",
|
"Step_Type": "Step Type",
|
||||||
"Make_header": "Make_Header",
|
"Make_header": "Make_Header",
|
||||||
"Make_Ingredient": "Make_Ingredient",
|
"Make_Ingredient": "Make_Ingredient",
|
||||||
"Enable_Amount": "Enable Amount",
|
"Enable_Amount": "Enable Amount",
|
||||||
"Disable_Amount": "Disable Amount",
|
"Disable_Amount": "Disable Amount",
|
||||||
"Add_Step": "Add Step",
|
"Add_Step": "Add Step",
|
||||||
"Keywords": "Keywords",
|
"Keywords": "Keywords",
|
||||||
"Books": "Books",
|
"Books": "Books",
|
||||||
"Proteins": "Proteins",
|
"Proteins": "Proteins",
|
||||||
"Fats": "Fats",
|
"Fats": "Fats",
|
||||||
"Carbohydrates": "Carbohydrates",
|
"Carbohydrates": "Carbohydrates",
|
||||||
"Calories": "Calories",
|
"Calories": "Calories",
|
||||||
"Energy": "Energy",
|
"Energy": "Energy",
|
||||||
"Nutrition": "Nutrition",
|
"Nutrition": "Nutrition",
|
||||||
"Date": "Date",
|
"Date": "Date",
|
||||||
"Share": "Share",
|
"Share": "Share",
|
||||||
"Automation": "Automation",
|
"Automation": "Automation",
|
||||||
"Parameter": "Parameter",
|
"Parameter": "Parameter",
|
||||||
"Export": "Export",
|
"Export": "Export",
|
||||||
"Copy": "Copy",
|
"Copy": "Copy",
|
||||||
"Rating": "Rating",
|
"Rating": "Rating",
|
||||||
"Close": "Close",
|
"Close": "Close",
|
||||||
"Cancel": "Cancel",
|
"Cancel": "Cancel",
|
||||||
"Link": "Link",
|
"Link": "Link",
|
||||||
"Add": "Add",
|
"Add": "Add",
|
||||||
"New": "New",
|
"New": "New",
|
||||||
"Note": "Note",
|
"Note": "Note",
|
||||||
"Success": "Success",
|
"Success": "Success",
|
||||||
"Failure": "Failure",
|
"Failure": "Failure",
|
||||||
"Ingredients": "Ingredients",
|
"Ingredients": "Ingredients",
|
||||||
"Supermarket": "Supermarket",
|
"Supermarket": "Supermarket",
|
||||||
"Categories": "Categories",
|
"Categories": "Categories",
|
||||||
"Category": "Category",
|
"Category": "Category",
|
||||||
"Selected": "Selected",
|
"Selected": "Selected",
|
||||||
"min": "min",
|
"min": "min",
|
||||||
"Servings": "Servings",
|
"Servings": "Servings",
|
||||||
"Waiting": "Waiting",
|
"Waiting": "Waiting",
|
||||||
"Preparation": "Preparation",
|
"Preparation": "Preparation",
|
||||||
"External": "External",
|
"External": "External",
|
||||||
"Size": "Size",
|
"Size": "Size",
|
||||||
"Files": "Files",
|
"Files": "Files",
|
||||||
"File": "File",
|
"File": "File",
|
||||||
"Edit": "Edit",
|
"Edit": "Edit",
|
||||||
"Image": "Image",
|
"Image": "Image",
|
||||||
"Delete": "Delete",
|
"Delete": "Delete",
|
||||||
"Open": "Open",
|
"Open": "Open",
|
||||||
"Ok": "Open",
|
"Ok": "Open",
|
||||||
"Save": "Save",
|
"Save": "Save",
|
||||||
"Step": "Step",
|
"Step": "Step",
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
"Import": "Import",
|
"Import": "Import",
|
||||||
"Print": "Print",
|
"Print": "Print",
|
||||||
"Settings": "Settings",
|
"Settings": "Settings",
|
||||||
"or": "or",
|
"or": "or",
|
||||||
"and": "and",
|
"and": "and",
|
||||||
"Information": "Information",
|
"Information": "Information",
|
||||||
"Download": "Download",
|
"Download": "Download",
|
||||||
"Create": "Create",
|
"Create": "Create",
|
||||||
"Advanced Search Settings": "Advanced Search Settings",
|
"Advanced Search Settings": "Advanced Search Settings",
|
||||||
"View": "View",
|
"View": "View",
|
||||||
"Recipes": "Recipes",
|
"Recipes": "Recipes",
|
||||||
"Move": "Move",
|
"Move": "Move",
|
||||||
"Merge": "Merge",
|
"Merge": "Merge",
|
||||||
"Parent": "Parent",
|
"Parent": "Parent",
|
||||||
"delete_confirmation": "Are you sure that you want to delete {source}?",
|
"delete_confirmation": "Are you sure that you want to delete {source}?",
|
||||||
"move_confirmation": "Move <i>{child}</i> to parent <i>{parent}</i>",
|
"move_confirmation": "Move <i>{child}</i> to parent <i>{parent}</i>",
|
||||||
"merge_confirmation": "Replace <i>{source}</i> with <i>{target}</i>",
|
"merge_confirmation": "Replace <i>{source}</i> with <i>{target}</i>",
|
||||||
"create_rule": "and create automation",
|
"create_rule": "and create automation",
|
||||||
"move_selection": "Select a parent {type} to move {source} to.",
|
"move_selection": "Select a parent {type} to move {source} to.",
|
||||||
"merge_selection": "Replace all occurrences of {source} with the selected {type}.",
|
"merge_selection": "Replace all occurrences of {source} with the selected {type}.",
|
||||||
"Root": "Root",
|
"Root": "Root",
|
||||||
"Ignore_Shopping": "Ignore Shopping",
|
"Ignore_Shopping": "Ignore Shopping",
|
||||||
"Shopping_Category": "Shopping Category",
|
"Shopping_Category": "Shopping Category",
|
||||||
"Edit_Food": "Edit Food",
|
"Edit_Food": "Edit Food",
|
||||||
"Move_Food": "Move Food",
|
"Move_Food": "Move Food",
|
||||||
"New_Food": "New Food",
|
"New_Food": "New Food",
|
||||||
"Hide_Food": "Hide Food",
|
"Hide_Food": "Hide Food",
|
||||||
"Food_Alias": "Food Alias",
|
"Food_Alias": "Food Alias",
|
||||||
"Unit_Alias": "Unit Alias",
|
"Unit_Alias": "Unit Alias",
|
||||||
"Keyword_Alias": "Keyword Alias",
|
"Keyword_Alias": "Keyword Alias",
|
||||||
"Delete_Food": "Delete Food",
|
"Delete_Food": "Delete Food",
|
||||||
"No_ID": "ID not found, cannot delete.",
|
"No_ID": "ID not found, cannot delete.",
|
||||||
"Meal_Plan_Days": "Future meal plans",
|
"Meal_Plan_Days": "Future meal plans",
|
||||||
"merge_title": "Merge {type}",
|
"merge_title": "Merge {type}",
|
||||||
"move_title": "Move {type}",
|
"move_title": "Move {type}",
|
||||||
"Food": "Food",
|
"Food": "Food",
|
||||||
"Recipe_Book": "Recipe Book",
|
"Recipe_Book": "Recipe Book",
|
||||||
"del_confirmation_tree": "Are you sure that you want to delete {source} and all of it's children?",
|
"del_confirmation_tree": "Are you sure that you want to delete {source} and all of it's children?",
|
||||||
"delete_title": "Delete {type}",
|
"delete_title": "Delete {type}",
|
||||||
"create_title": "New {type}",
|
"create_title": "New {type}",
|
||||||
"edit_title": "Edit {type}",
|
"edit_title": "Edit {type}",
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
"Type": "Type",
|
"Type": "Type",
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Recipe": "Recipe",
|
"Recipe": "Recipe",
|
||||||
"tree_root": "Root of Tree",
|
"tree_root": "Root of Tree",
|
||||||
"Icon": "Icon",
|
"Icon": "Icon",
|
||||||
"Unit": "Unit",
|
"Unit": "Unit",
|
||||||
"No_Results": "No Results",
|
"No_Results": "No Results",
|
||||||
"New_Unit": "New Unit",
|
"New_Unit": "New Unit",
|
||||||
"Create_New_Shopping Category": "Create New Shopping Category",
|
"Create_New_Shopping Category": "Create New Shopping Category",
|
||||||
"Create_New_Food": "Add New Food",
|
"Create_New_Food": "Add New Food",
|
||||||
"Create_New_Keyword": "Add New Keyword",
|
"Create_New_Keyword": "Add New Keyword",
|
||||||
"Create_New_Unit": "Add New Unit",
|
"Create_New_Unit": "Add New Unit",
|
||||||
"Create_New_Meal_Type": "Add New Meal Type",
|
"Create_New_Meal_Type": "Add New Meal Type",
|
||||||
"and_up": "& Up",
|
"and_up": "& Up",
|
||||||
"Instructions": "Instructions",
|
"Instructions": "Instructions",
|
||||||
"Unrated": "Unrated",
|
"Unrated": "Unrated",
|
||||||
"Automate": "Automate",
|
"Automate": "Automate",
|
||||||
"Empty": "Empty",
|
"Empty": "Empty",
|
||||||
"Key_Ctrl": "Ctrl",
|
"Key_Ctrl": "Ctrl",
|
||||||
"Key_Shift": "Shift",
|
"Key_Shift": "Shift",
|
||||||
"Time": "Time",
|
"Time": "Time",
|
||||||
"Text": "Text",
|
"Text": "Text",
|
||||||
"Shopping_list": "Shopping List",
|
"Shopping_list": "Shopping List",
|
||||||
"Create_Meal_Plan_Entry": "Create meal plan entry",
|
"Create_Meal_Plan_Entry": "Create meal plan entry",
|
||||||
"Edit_Meal_Plan_Entry": "Edit meal plan entry",
|
"Edit_Meal_Plan_Entry": "Edit meal plan entry",
|
||||||
"Title": "Title",
|
"Title": "Title",
|
||||||
"Week": "Week",
|
"Week": "Week",
|
||||||
"Month": "Month",
|
"Month": "Month",
|
||||||
"Year": "Year",
|
"Year": "Year",
|
||||||
"Planner": "Planner",
|
"Planner": "Planner",
|
||||||
"Planner_Settings": "Planner settings",
|
"Planner_Settings": "Planner settings",
|
||||||
"Period": "Period",
|
"Period": "Period",
|
||||||
"Plan_Period_To_Show": "Show weeks, months or years",
|
"Plan_Period_To_Show": "Show weeks, months or years",
|
||||||
"Periods": "Periods",
|
"Periods": "Periods",
|
||||||
"Plan_Show_How_Many_Periods": "How many periods to show",
|
"Plan_Show_How_Many_Periods": "How many periods to show",
|
||||||
"Starting_Day": "Starting day of the week",
|
"Starting_Day": "Starting day of the week",
|
||||||
"Meal_Types": "Meal types",
|
"Meal_Types": "Meal types",
|
||||||
"Meal_Type": "Meal type",
|
"Meal_Type": "Meal type",
|
||||||
"Clone": "Clone",
|
"Clone": "Clone",
|
||||||
"Drag_Here_To_Delete": "Drag here to delete",
|
"Drag_Here_To_Delete": "Drag here to delete",
|
||||||
"Meal_Type_Required": "Meal type is required",
|
"Meal_Type_Required": "Meal type is required",
|
||||||
"Title_or_Recipe_Required": "Title or recipe selection required",
|
"Title_or_Recipe_Required": "Title or recipe selection required",
|
||||||
"Color": "Color",
|
"Color": "Color",
|
||||||
"New_Meal_Type": "New Meal type",
|
"New_Meal_Type": "New Meal type",
|
||||||
"Week_Numbers": "Week numbers",
|
"Week_Numbers": "Week numbers",
|
||||||
"Show_Week_Numbers": "Show week numbers ?",
|
"Show_Week_Numbers": "Show week numbers ?",
|
||||||
"Export_As_ICal": "Export current period to iCal format",
|
"Export_As_ICal": "Export current period to iCal format",
|
||||||
"Export_To_ICal": "Export .ics",
|
"Export_To_ICal": "Export .ics",
|
||||||
"Cannot_Add_Notes_To_Shopping": "Notes cannot be added to the shopping list",
|
"Cannot_Add_Notes_To_Shopping": "Notes cannot be added to the shopping list",
|
||||||
"Added_To_Shopping_List": "Added to shopping list",
|
"Added_To_Shopping_List": "Added to shopping list",
|
||||||
"Shopping_List_Empty": "Your shopping list is currently empty, you can add items via the context menu of a meal plan entry (right click on the card or left click the menu icon)",
|
"Shopping_List_Empty": "Your shopping list is currently empty, you can add items via the context menu of a meal plan entry (right click on the card or left click the menu icon)",
|
||||||
"Next_Period": "Next Period",
|
"Next_Period": "Next Period",
|
||||||
"Previous_Period": "Previous Period",
|
"Previous_Period": "Previous Period",
|
||||||
"Current_Period": "Current Period",
|
"Current_Period": "Current Period",
|
||||||
"Next_Day": "Next Day",
|
"Next_Day": "Next Day",
|
||||||
"Previous_Day": "Previous Day",
|
"Previous_Day": "Previous Day",
|
||||||
"Coming_Soon": "Coming-Soon",
|
"Coming_Soon": "Coming-Soon",
|
||||||
"Auto_Planner": "Auto-Planner",
|
"Auto_Planner": "Auto-Planner",
|
||||||
"New_Cookbook": "New cookbook",
|
"New_Cookbook": "New cookbook",
|
||||||
"Hide_Keyword": "Hide keywords",
|
"Hide_Keyword": "Hide keywords",
|
||||||
"Clear": "Clear"
|
"Clear": "Clear",
|
||||||
|
"show_sql": "Show SQL"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user