mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-07 23:28:16 -05:00
merge
This commit is contained in:
@@ -10,8 +10,7 @@ from django.views.generic import UpdateView
|
||||
from django.views.generic.edit import FormMixin
|
||||
|
||||
from cookbook.forms import CommentForm, ExternalRecipeForm, StorageForm, SyncForm, ConnectorConfigForm
|
||||
from cookbook.helper.permission_helper import (GroupRequiredMixin, OwnerRequiredMixin,
|
||||
above_space_limit, group_required)
|
||||
from cookbook.helper.permission_helper import GroupRequiredMixin, OwnerRequiredMixin, above_space_limit, group_required
|
||||
from cookbook.models import Comment, Recipe, RecipeImport, Storage, Sync, ConnectorConfig
|
||||
from cookbook.provider.dropbox import Dropbox
|
||||
from cookbook.provider.local import Local
|
||||
@@ -106,26 +105,16 @@ def edit_storage(request, pk):
|
||||
|
||||
instance.save()
|
||||
|
||||
messages.add_message(
|
||||
request, messages.SUCCESS, _('Storage saved!')
|
||||
)
|
||||
messages.add_message(request, messages.SUCCESS, _('Storage saved!'))
|
||||
else:
|
||||
messages.add_message(
|
||||
request,
|
||||
messages.ERROR,
|
||||
_('There was an error updating this storage backend!')
|
||||
)
|
||||
messages.add_message(request, messages.ERROR, _('There was an error updating this storage backend!'))
|
||||
else:
|
||||
pseudo_instance = instance
|
||||
pseudo_instance.password = VALUE_NOT_CHANGED
|
||||
pseudo_instance.token = VALUE_NOT_CHANGED
|
||||
form = StorageForm(instance=pseudo_instance)
|
||||
|
||||
return render(
|
||||
request,
|
||||
'generic/edit_template.html',
|
||||
{'form': form, 'title': _('Storage')}
|
||||
)
|
||||
return render(request, 'generic/edit_template.html', {'form': form, 'title': _('Storage')})
|
||||
|
||||
|
||||
class ConnectorConfigUpdate(GroupRequiredMixin, UpdateView):
|
||||
@@ -165,9 +154,7 @@ class CommentUpdate(OwnerRequiredMixin, UpdateView):
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(CommentUpdate, self).get_context_data(**kwargs)
|
||||
context['title'] = _("Comment")
|
||||
context['view_url'] = reverse(
|
||||
'view_recipe', args=[self.object.recipe.pk]
|
||||
)
|
||||
context['view_url'] = reverse('view_recipe', args=[self.object.recipe.pk])
|
||||
return context
|
||||
|
||||
|
||||
@@ -206,11 +193,7 @@ class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
|
||||
if self.object.storage.method == Storage.LOCAL:
|
||||
Local.rename_file(old_recipe, self.object.name)
|
||||
|
||||
self.object.file_path = "%s/%s%s" % (
|
||||
os.path.dirname(self.object.file_path),
|
||||
self.object.name,
|
||||
os.path.splitext(self.object.file_path)[1]
|
||||
)
|
||||
self.object.file_path = "%s/%s%s" % (os.path.dirname(self.object.file_path), self.object.name, os.path.splitext(self.object.file_path)[1])
|
||||
|
||||
messages.add_message(self.request, messages.SUCCESS, _('Changes saved!'))
|
||||
return super(ExternalRecipeUpdate, self).form_valid(form)
|
||||
@@ -227,7 +210,5 @@ class ExternalRecipeUpdate(GroupRequiredMixin, UpdateView, SpaceFormMixing):
|
||||
context['title'] = _("Recipe")
|
||||
context['view_url'] = reverse('view_recipe', args=[self.object.pk])
|
||||
if self.object.storage:
|
||||
context['delete_external_url'] = reverse(
|
||||
'delete_recipe_source', args=[self.object.pk]
|
||||
)
|
||||
context['delete_external_url'] = reverse('delete_recipe_source', args=[self.object.pk])
|
||||
return context
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
from io import StringIO
|
||||
from uuid import UUID
|
||||
import subprocess
|
||||
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
@@ -23,17 +23,14 @@ 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.forms import CommentForm, Recipe, SearchPreferenceForm, SpaceCreateForm, SpaceJoinForm, User, UserCreateForm, UserPreference
|
||||
from cookbook.helper.HelperFunctions import str2bool
|
||||
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.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.templatetags.theming_tags import get_theming_values
|
||||
from cookbook.version_info import VERSION_INFO
|
||||
from recipes.settings import PLUGINS, BASE_DIR
|
||||
from recipes.settings import BASE_DIR, PLUGINS
|
||||
|
||||
|
||||
def index(request):
|
||||
@@ -44,11 +41,7 @@ def index(request):
|
||||
return HttpResponseRedirect(reverse_lazy('view_search'))
|
||||
|
||||
try:
|
||||
page_map = {
|
||||
UserPreference.SEARCH: reverse_lazy('view_search'),
|
||||
UserPreference.PLAN: reverse_lazy('view_plan'),
|
||||
UserPreference.BOOKS: reverse_lazy('view_books'),
|
||||
}
|
||||
page_map = {UserPreference.SEARCH: reverse_lazy('view_search'), UserPreference.PLAN: reverse_lazy('view_plan'), UserPreference.BOOKS: reverse_lazy('view_books'), }
|
||||
|
||||
return HttpResponseRedirect(page_map.get(request.user.userpreference.default_page))
|
||||
except UserPreference.DoesNotExist:
|
||||
@@ -57,7 +50,7 @@ def index(request):
|
||||
|
||||
# TODO need to deprecate
|
||||
def search(request):
|
||||
if has_group_permission(request.user, ('guest',)):
|
||||
if has_group_permission(request.user, ('guest', )):
|
||||
return render(request, 'search.html', {})
|
||||
else:
|
||||
if request.user.is_authenticated:
|
||||
@@ -84,14 +77,13 @@ def space_overview(request):
|
||||
_('You have the reached the maximum amount of spaces that can be owned by you.') + f' ({request.user.userpreference.max_owned_spaces})')
|
||||
return HttpResponseRedirect(reverse('view_space_overview'))
|
||||
|
||||
created_space = Space.objects.create(
|
||||
name=create_form.cleaned_data['name'],
|
||||
created_by=request.user,
|
||||
max_file_storage_mb=settings.SPACE_DEFAULT_MAX_FILES,
|
||||
max_recipes=settings.SPACE_DEFAULT_MAX_RECIPES,
|
||||
max_users=settings.SPACE_DEFAULT_MAX_USERS,
|
||||
allow_sharing=settings.SPACE_DEFAULT_ALLOW_SHARING,
|
||||
)
|
||||
created_space = Space.objects.create(name=create_form.cleaned_data['name'],
|
||||
created_by=request.user,
|
||||
max_file_storage_mb=settings.SPACE_DEFAULT_MAX_FILES,
|
||||
max_recipes=settings.SPACE_DEFAULT_MAX_RECIPES,
|
||||
max_users=settings.SPACE_DEFAULT_MAX_USERS,
|
||||
allow_sharing=settings.SPACE_DEFAULT_ALLOW_SHARING,
|
||||
)
|
||||
|
||||
user_space = UserSpace.objects.create(space=created_space, user=request.user, active=False)
|
||||
user_space.groups.add(Group.objects.filter(name='admin').get())
|
||||
@@ -135,23 +127,18 @@ def recipe_view(request, pk, share=None):
|
||||
recipe = get_object_or_404(Recipe, pk=pk)
|
||||
|
||||
if not request.user.is_authenticated and not share_link_valid(recipe, share):
|
||||
messages.add_message(request, messages.ERROR,
|
||||
_('You do not have the required permissions to view this page!'))
|
||||
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
|
||||
return HttpResponseRedirect(reverse('account_login') + '?next=' + request.path)
|
||||
|
||||
if not (has_group_permission(request.user,
|
||||
('guest',)) and recipe.space == request.space) and not share_link_valid(recipe,
|
||||
share):
|
||||
messages.add_message(request, messages.ERROR,
|
||||
_('You do not have the required permissions to view this page!'))
|
||||
if not (has_group_permission(request.user, ('guest', )) and recipe.space == request.space) and not share_link_valid(recipe, share):
|
||||
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to view this page!'))
|
||||
return HttpResponseRedirect(reverse('index'))
|
||||
|
||||
comments = Comment.objects.filter(recipe__space=request.space, recipe=recipe)
|
||||
|
||||
if request.method == "POST":
|
||||
if not request.user.is_authenticated:
|
||||
messages.add_message(request, messages.ERROR,
|
||||
_('You do not have the required permissions to perform this action!'))
|
||||
messages.add_message(request, messages.ERROR, _('You do not have the required permissions to perform this action!'))
|
||||
return HttpResponseRedirect(reverse('view_recipe', kwargs={'pk': recipe.pk, 'share': share}))
|
||||
|
||||
comment_form = CommentForm(request.POST, prefix='comment')
|
||||
@@ -167,16 +154,16 @@ def recipe_view(request, pk, share=None):
|
||||
comment_form = CommentForm()
|
||||
|
||||
if request.user.is_authenticated:
|
||||
if not ViewLog.objects.filter(recipe=recipe, created_by=request.user,
|
||||
created_at__gt=(timezone.now() - timezone.timedelta(minutes=5)),
|
||||
space=request.space).exists():
|
||||
if not ViewLog.objects.filter(recipe=recipe, created_by=request.user, created_at__gt=(timezone.now() - timezone.timedelta(minutes=5)), space=request.space).exists():
|
||||
ViewLog.objects.create(recipe=recipe, created_by=request.user, space=request.space)
|
||||
|
||||
if request.method == "GET":
|
||||
servings = request.GET.get("servings")
|
||||
return render(request, 'recipe_view.html',
|
||||
{'recipe': recipe, 'comments': comments, 'comment_form': comment_form, 'share': share, 'servings': servings })
|
||||
|
||||
|
||||
|
||||
@group_required('user')
|
||||
def books(request):
|
||||
return render(request, 'books.html', {})
|
||||
@@ -239,12 +226,8 @@ def shopping_settings(request):
|
||||
if search_form.is_valid():
|
||||
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'])
|
||||
)
|
||||
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']))
|
||||
if search_form.cleaned_data['preset'] == 'fuzzy':
|
||||
sp.search = SearchPreference.SIMPLE
|
||||
sp.lookup = True
|
||||
@@ -269,13 +252,10 @@ def shopping_settings(request):
|
||||
elif fields_searched == 0:
|
||||
search_form.add_error(None, _('You must select at least one field to search!'))
|
||||
search_error = True
|
||||
elif search_form.cleaned_data['search'] in ['websearch', 'raw'] and len(
|
||||
search_form.cleaned_data['fulltext']) == 0:
|
||||
search_form.add_error('search',
|
||||
_('To use this search method you must select at least one full text search field!'))
|
||||
elif search_form.cleaned_data['search'] in ['websearch', 'raw'] and len(search_form.cleaned_data['fulltext']) == 0:
|
||||
search_form.add_error('search', _('To use this search method you must select at least one full text search field!'))
|
||||
search_error = True
|
||||
elif search_form.cleaned_data['search'] in ['websearch', 'raw'] and len(
|
||||
search_form.cleaned_data['trigram']) > 0:
|
||||
elif search_form.cleaned_data['search'] in ['websearch', 'raw'] and len(search_form.cleaned_data['trigram']) > 0:
|
||||
search_form.add_error(None, _('Fuzzy search is not compatible with this search method!'))
|
||||
search_error = True
|
||||
else:
|
||||
@@ -291,8 +271,7 @@ def shopping_settings(request):
|
||||
else:
|
||||
search_error = True
|
||||
|
||||
fields_searched = len(sp.icontains.all()) + len(sp.istartswith.all()) + len(sp.trigram.all()) + len(
|
||||
sp.fulltext.all())
|
||||
fields_searched = len(sp.icontains.all()) + len(sp.istartswith.all()) + len(sp.trigram.all()) + len(sp.fulltext.all())
|
||||
if sp and not search_error and fields_searched > 0:
|
||||
search_form = SearchPreferenceForm(instance=sp)
|
||||
elif not search_error:
|
||||
@@ -305,23 +284,13 @@ def shopping_settings(request):
|
||||
sp.fulltext.clear()
|
||||
sp.save()
|
||||
|
||||
return render(request, 'settings.html', {
|
||||
'search_form': search_form,
|
||||
})
|
||||
return render(request, 'settings.html', {'search_form': search_form, })
|
||||
|
||||
|
||||
@group_required('guest')
|
||||
def history(request):
|
||||
view_log = ViewLogTable(
|
||||
ViewLog.objects.filter(
|
||||
created_by=request.user, space=request.space
|
||||
).order_by('-created_at').all()
|
||||
)
|
||||
cook_log = CookLogTable(
|
||||
CookLog.objects.filter(
|
||||
created_by=request.user
|
||||
).order_by('-created_at').all()
|
||||
)
|
||||
view_log = ViewLogTable(ViewLog.objects.filter(created_by=request.user, space=request.space).order_by('-created_at').all())
|
||||
cook_log = CookLogTable(CookLog.objects.filter(created_by=request.user).order_by('-created_at').all())
|
||||
return render(request, 'history.html', {'view_log': view_log, 'cook_log': cook_log})
|
||||
|
||||
|
||||
@@ -344,12 +313,10 @@ def system(request):
|
||||
database_message = _('Everything is fine!')
|
||||
elif postgres_ver < postgres_current - 2:
|
||||
database_status = 'danger'
|
||||
database_message = _('PostgreSQL %(v)s is deprecated. Upgrade to a fully supported version!') % {
|
||||
'v': postgres_ver}
|
||||
database_message = _('PostgreSQL %(v)s is deprecated. Upgrade to a fully supported version!') % {'v': postgres_ver}
|
||||
else:
|
||||
database_status = 'info'
|
||||
database_message = _('You are running PostgreSQL %(v1)s. PostgreSQL %(v2)s is recommended') % {
|
||||
'v1': postgres_ver, 'v2': postgres_current}
|
||||
database_message = _('You are running PostgreSQL %(v1)s. PostgreSQL %(v2)s is recommended') % {'v1': postgres_ver, 'v2': postgres_current}
|
||||
else:
|
||||
database_status = 'info'
|
||||
database_message = _(
|
||||
@@ -378,34 +345,26 @@ def system(request):
|
||||
pass
|
||||
else:
|
||||
current_app = row
|
||||
migration_info[current_app] = {'app': current_app, 'unapplied_migrations': [], 'applied_migrations': [],
|
||||
'total': 0}
|
||||
migration_info[current_app] = {'app': current_app, 'unapplied_migrations': [], 'applied_migrations': [], 'total': 0}
|
||||
|
||||
for key in migration_info.keys():
|
||||
migration_info[key]['total'] = len(migration_info[key]['unapplied_migrations']) + len(
|
||||
migration_info[key]['applied_migrations'])
|
||||
migration_info[key]['total'] = len(migration_info[key]['unapplied_migrations']) + len(migration_info[key]['applied_migrations'])
|
||||
|
||||
return render(request, 'system.html', {
|
||||
'gunicorn_media': settings.GUNICORN_MEDIA,
|
||||
'debug': settings.DEBUG,
|
||||
'postgres': postgres,
|
||||
'postgres_version': postgres_ver,
|
||||
'postgres_status': database_status,
|
||||
'postgres_message': database_message,
|
||||
'version_info': VERSION_INFO,
|
||||
'plugins': PLUGINS,
|
||||
'secret_key': secret_key,
|
||||
'orphans': orphans,
|
||||
'migration_info': migration_info,
|
||||
'missing_migration': missing_migration,
|
||||
})
|
||||
return render(
|
||||
request, 'system.html', {
|
||||
'gunicorn_media': settings.GUNICORN_MEDIA, 'debug': settings.DEBUG, 'postgres': postgres, 'postgres_version': postgres_ver, 'postgres_status': database_status,
|
||||
'postgres_message': database_message, 'version_info': VERSION_INFO, 'plugins': PLUGINS, 'secret_key': secret_key, 'orphans': orphans, 'migration_info': migration_info,
|
||||
'missing_migration': missing_migration,
|
||||
})
|
||||
|
||||
|
||||
def setup(request):
|
||||
with scopes_disabled():
|
||||
if User.objects.count() > 0 or 'django.contrib.auth.backends.RemoteUserBackend' in settings.AUTHENTICATION_BACKENDS:
|
||||
messages.add_message(request, messages.ERROR,
|
||||
_('The setup page can only be used to create the first user! If you have forgotten your superuser credentials please consult the django documentation on how to reset passwords.'))
|
||||
messages.add_message(
|
||||
request, messages.ERROR,
|
||||
_('The setup page can only be used to create the first user! If you have forgotten your superuser credentials please consult the django documentation on how to reset passwords.'
|
||||
))
|
||||
return HttpResponseRedirect(reverse('account_login'))
|
||||
|
||||
if request.method == 'POST':
|
||||
@@ -445,8 +404,7 @@ def invite_link(request, token):
|
||||
link.used_by = request.user
|
||||
link.save()
|
||||
|
||||
user_space = UserSpace.objects.create(user=request.user, space=link.space,
|
||||
internal_note=link.internal_note, invite_link=link, active=False)
|
||||
user_space = UserSpace.objects.create(user=request.user, space=link.space, internal_note=link.internal_note, invite_link=link, active=False)
|
||||
|
||||
if request.user.userspace_set.count() == 1:
|
||||
user_space.active = True
|
||||
@@ -476,66 +434,36 @@ def space_manage(request, space_id):
|
||||
|
||||
def report_share_abuse(request, token):
|
||||
if not settings.SHARING_ABUSE:
|
||||
messages.add_message(request, messages.WARNING,
|
||||
_('Reporting share links is not enabled for this instance. Please notify the page administrator to report problems.'))
|
||||
messages.add_message(request, messages.WARNING, _('Reporting share links is not enabled for this instance. Please notify the page administrator to report problems.'))
|
||||
else:
|
||||
if link := ShareLink.objects.filter(uuid=token).first():
|
||||
link.abuse_blocked = True
|
||||
link.save()
|
||||
messages.add_message(request, messages.WARNING,
|
||||
_('Recipe sharing link has been disabled! For additional information please contact the page administrator.'))
|
||||
messages.add_message(request, messages.WARNING, _('Recipe sharing link has been disabled! For additional information please contact the page administrator.'))
|
||||
return HttpResponseRedirect(reverse('index'))
|
||||
|
||||
|
||||
def web_manifest(request):
|
||||
theme_values = get_theming_values(request)
|
||||
|
||||
icons = [
|
||||
{"src": theme_values['logo_color_svg'], "sizes": "any"},
|
||||
{"src": theme_values['logo_color_144'], "type": "image/png", "sizes": "144x144"},
|
||||
{"src": theme_values['logo_color_512'], "type": "image/png", "sizes": "512x512"}
|
||||
]
|
||||
icons = [{"src": theme_values['logo_color_svg'], "sizes": "any"}, {"src": theme_values['logo_color_144'], "type": "image/png", "sizes": "144x144"},
|
||||
{"src": theme_values['logo_color_512'], "type": "image/png", "sizes": "512x512"}]
|
||||
|
||||
manifest_info = {
|
||||
"name": theme_values['app_name'],
|
||||
"short_name": theme_values['app_name'],
|
||||
"description": _("Manage recipes, shopping list, meal plans and more."),
|
||||
"icons": icons,
|
||||
"start_url": "./search",
|
||||
"background_color": theme_values['nav_bg_color'],
|
||||
"display": "standalone",
|
||||
"scope": ".",
|
||||
"theme_color": theme_values['nav_bg_color'],
|
||||
"shortcuts": [
|
||||
{
|
||||
"name": _("Plan"),
|
||||
"short_name": _("Plan"),
|
||||
"description": _("View your meal Plan"),
|
||||
"url": "./plan"
|
||||
},
|
||||
{
|
||||
"name": _("Books"),
|
||||
"short_name": _("Books"),
|
||||
"description": _("View your cookbooks"),
|
||||
"url": "./books"
|
||||
},
|
||||
{
|
||||
"name": _("Shopping"),
|
||||
"short_name": _("Shopping"),
|
||||
"description": _("View your shopping lists"),
|
||||
"url": "./list/shopping-list/"
|
||||
}
|
||||
],
|
||||
"share_target": {
|
||||
"action": "/data/import/url",
|
||||
"method": "GET",
|
||||
"params": {
|
||||
"title": "title",
|
||||
"url": "url",
|
||||
"text": "text"
|
||||
|
||||
}
|
||||
}
|
||||
"name":
|
||||
theme_values['app_name'], "short_name":
|
||||
theme_values['app_name'], "description":
|
||||
_("Manage recipes, shopping list, meal plans and more."), "icons":
|
||||
icons, "start_url":
|
||||
"./search", "background_color":
|
||||
theme_values['nav_bg_color'], "display":
|
||||
"standalone", "scope":
|
||||
".", "theme_color":
|
||||
theme_values['nav_bg_color'], "shortcuts":
|
||||
[{"name": _("Plan"), "short_name": _("Plan"), "description": _("View your meal Plan"), "url":
|
||||
"./plan"}, {"name": _("Books"), "short_name": _("Books"), "description": _("View your cookbooks"), "url": "./books"},
|
||||
{"name": _("Shopping"), "short_name": _("Shopping"), "description": _("View your shopping lists"), "url":
|
||||
"./list/shopping-list/"}], "share_target": {"action": "/data/import/url", "method": "GET", "params": {"title": "title", "url": "url", "text": "text"}}
|
||||
}
|
||||
|
||||
return JsonResponse(manifest_info, json_dumps_params={'indent': 4})
|
||||
@@ -565,9 +493,7 @@ def test(request):
|
||||
from cookbook.helper.ingredient_parser import IngredientParser
|
||||
parser = IngredientParser(request, False)
|
||||
|
||||
data = {
|
||||
'original': '90g golden syrup'
|
||||
}
|
||||
data = {'original': '90g golden syrup'}
|
||||
data['parsed'] = parser.parse(data['original'])
|
||||
|
||||
return render(request, 'test.html', {'data': data})
|
||||
|
||||
Reference in New Issue
Block a user