diff --git a/cookbook/admin.py b/cookbook/admin.py index 0e903999..f512121c 100644 --- a/cookbook/admin.py +++ b/cookbook/admin.py @@ -47,9 +47,9 @@ admin.site.register(Space, SpaceAdmin) class UserPreferenceAdmin(admin.ModelAdmin): - list_display = ('name', 'theme', 'nav_color', 'default_page', 'search_style',) # TODO add new fields + list_display = ('name', 'theme', 'nav_color', 'default_page',) search_fields = ('user__username',) - list_filter = ('theme', 'nav_color', 'default_page', 'search_style') + list_filter = ('theme', 'nav_color', 'default_page',) date_hierarchy = 'created_at' @staticmethod diff --git a/cookbook/filters.py b/cookbook/filters.py deleted file mode 100644 index ac377abc..00000000 --- a/cookbook/filters.py +++ /dev/null @@ -1,62 +0,0 @@ -import django_filters -from django.conf import settings -from django.contrib.postgres.search import TrigramSimilarity -from django.db.models import Q -from django.utils.translation import gettext as _ -from django_scopes import scopes_disabled - -from cookbook.forms import MultiSelectWidget -from cookbook.models import Food, Keyword, Recipe - -with scopes_disabled(): - class RecipeFilter(django_filters.FilterSet): - name = django_filters.CharFilter(method='filter_name') - keywords = django_filters.ModelMultipleChoiceFilter( - queryset=Keyword.objects.none(), - widget=MultiSelectWidget, - method='filter_keywords' - ) - foods = django_filters.ModelMultipleChoiceFilter( - queryset=Food.objects.none(), - widget=MultiSelectWidget, - method='filter_foods', - label=_('Ingredients') - ) - - def __init__(self, data=None, *args, **kwargs): - space = kwargs.pop('space') - super().__init__(data, *args, **kwargs) - self.filters['foods'].queryset = Food.objects.filter(space=space).all() - self.filters['keywords'].queryset = Keyword.objects.filter(space=space).all() - - @staticmethod - def filter_keywords(queryset, name, value): - if not name == 'keywords': - return queryset - for x in value: - queryset = queryset.filter(keywords=x) - return queryset - - @staticmethod - def filter_foods(queryset, name, value): - if not name == 'foods': - return queryset - for x in value: - queryset = queryset.filter(steps__ingredients__food__name=x).distinct() - return queryset - - @staticmethod - def filter_name(queryset, name, value): - if not name == 'name': - return queryset - if settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2', - 'django.db.backends.postgresql']: - queryset = queryset.annotate(similarity=TrigramSimilarity('name', value), ).filter( - Q(similarity__gt=0.1) | Q(name__unaccent__icontains=value)).order_by('-similarity') - else: - queryset = queryset.filter(name__icontains=value) - return queryset - - class Meta: - model = Recipe - fields = ['name', 'keywords', 'foods', 'internal'] diff --git a/cookbook/forms.py b/cookbook/forms.py index 50f88228..5ef9e6b9 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -45,8 +45,7 @@ class UserPreferenceForm(forms.ModelForm): model = UserPreference fields = ( 'default_unit', 'use_fractions', 'use_kj', 'theme', 'nav_color', - 'sticky_navbar', 'default_page', 'show_recent', 'search_style', - 'plan_share', 'ingredient_decimals', 'comments', 'left_handed', + 'sticky_navbar', 'default_page', 'plan_share', 'ingredient_decimals', 'comments', 'left_handed', ) labels = { @@ -57,8 +56,6 @@ class UserPreferenceForm(forms.ModelForm): 'nav_color': _('Navbar color'), 'sticky_navbar': _('Sticky navbar'), 'default_page': _('Default page'), - 'show_recent': _('Show recent recipes'), - 'search_style': _('Search style'), 'plan_share': _('Plan sharing'), 'ingredient_decimals': _('Ingredient decimal places'), 'shopping_auto_sync': _('Shopping list auto sync period'), @@ -68,23 +65,21 @@ class UserPreferenceForm(forms.ModelForm): help_texts = { 'nav_color': _('Color of the top navigation bar. Not all colors work with all themes, just try them out!'), - # noqa: E501 - 'default_unit': _('Default Unit to be used when inserting a new ingredient into a recipe.'), # noqa: E501 + + 'default_unit': _('Default Unit to be used when inserting a new ingredient into a recipe.'), 'use_fractions': _( 'Enables support for fractions in ingredient amounts (e.g. convert decimals to fractions automatically)'), - # noqa: E501 - 'use_kj': _('Display nutritional energy amounts in joules instead of calories'), # noqa: E501 + + 'use_kj': _('Display nutritional energy amounts in joules instead of calories'), 'plan_share': _('Users with whom newly created meal plans should be shared by default.'), 'shopping_share': _('Users with whom to share shopping lists.'), - # noqa: E501 - 'show_recent': _('Show recently viewed recipes on search page.'), # noqa: E501 - 'ingredient_decimals': _('Number of decimals to round ingredients.'), # noqa: E501 - 'comments': _('If you want to be able to create and see comments underneath recipes.'), # noqa: E501 + 'ingredient_decimals': _('Number of decimals to round ingredients.'), + 'comments': _('If you want to be able to create and see comments underneath recipes.'), 'shopping_auto_sync': _( - 'Setting to 0 will disable auto sync. When viewing a shopping list the list is updated every set seconds to sync changes someone else might have made. Useful when shopping with multiple people but might use a little bit ' # noqa: E501 - 'of mobile data. If lower than instance limit it is reset when saving.' # noqa: E501 + 'Setting to 0 will disable auto sync. When viewing a shopping list the list is updated every set seconds to sync changes someone else might have made. Useful when shopping with multiple people but might use a little bit ' + 'of mobile data. If lower than instance limit it is reset when saving.' ), - 'sticky_navbar': _('Makes the navbar stick to the top of the page.'), # noqa: E501 + 'sticky_navbar': _('Makes the navbar stick to the top of the page.'), 'mealplan_autoadd_shopping': _('Automatically add meal plan ingredients to shopping list.'), 'mealplan_autoexclude_onhand': _('Exclude ingredients that are on hand.'), 'left_handed': _('Will optimize the UI for use with your left hand.') @@ -336,9 +331,9 @@ class MealPlanForm(forms.ModelForm): ) help_texts = { - 'shared': _('You can list default users to share recipes with in the settings.'), # noqa: E501 + 'shared': _('You can list default users to share recipes with in the settings.'), 'note': _('You can use markdown to format this field. See the docs here') - # noqa: E501 + } widgets = { @@ -493,8 +488,8 @@ class ShoppingPreferenceForm(forms.ModelForm): help_texts = { 'shopping_share': _('Users will see all items you add to your shopping list. They must add you to see items on their list.'), 'shopping_auto_sync': _( - 'Setting to 0 will disable auto sync. When viewing a shopping list the list is updated every set seconds to sync changes someone else might have made. Useful when shopping with multiple people but might use a little bit ' # noqa: E501 - 'of mobile data. If lower than instance limit it is reset when saving.' # noqa: E501 + 'Setting to 0 will disable auto sync. When viewing a shopping list the list is updated every set seconds to sync changes someone else might have made. Useful when shopping with multiple people but might use a little bit ' + 'of mobile data. If lower than instance limit it is reset when saving.' ), 'mealplan_autoadd_shopping': _('Automatically add meal plan ingredients to shopping list.'), 'mealplan_autoinclude_related': _('When adding a meal plan to the shopping list (manually or automatically), include all related recipes.'), diff --git a/cookbook/helper/recipe_search.py b/cookbook/helper/recipe_search.py index 3f361af0..d651a6ee 100644 --- a/cookbook/helper/recipe_search.py +++ b/cookbook/helper/recipe_search.py @@ -4,17 +4,14 @@ from datetime import date, timedelta from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector, TrigramSimilarity from django.core.cache import caches -from django.db.models import (Avg, Case, Count, Exists, F, Func, Max, OuterRef, Q, Subquery, Sum, - Value, When) +from django.db.models import (Avg, Case, Count, Exists, F, Func, Max, OuterRef, Q, Subquery, Value, When) from django.db.models.functions import Coalesce, Lower, Substr from django.utils import timezone, translation from django.utils.translation import gettext as _ -from cookbook.filters import RecipeFilter from cookbook.helper.HelperFunctions import Round, str2bool -from cookbook.helper.permission_helper import has_group_permission from cookbook.managers import DICTIONARY -from cookbook.models import (CookLog, CustomFilter, Food, Keyword, Recipe, RecipeBook, SearchFields, +from cookbook.models import (CookLog, CustomFilter, Food, Keyword, Recipe, SearchFields, SearchPreference, ViewLog) from recipes import settings @@ -759,12 +756,3 @@ class RecipeFacet(): else: return queryset.filter(depth__lte=depth).values('id', 'name', 'numchild').order_by(Lower('name').asc()) - -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.space).all().order_by(Lower('name').asc()), - space=request.space) - return f.qs diff --git a/cookbook/migrations/0178_remove_userpreference_search_style_and_more.py b/cookbook/migrations/0178_remove_userpreference_search_style_and_more.py new file mode 100644 index 00000000..73447a95 --- /dev/null +++ b/cookbook/migrations/0178_remove_userpreference_search_style_and_more.py @@ -0,0 +1,21 @@ +# Generated by Django 4.0.6 on 2022-07-12 18:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0177_recipe_show_ingredient_overview'), + ] + + operations = [ + migrations.RemoveField( + model_name='userpreference', + name='search_style', + ), + migrations.RemoveField( + model_name='userpreference', + name='show_recent', + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 89795be0..a0457ef2 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -355,13 +355,6 @@ class UserPreference(models.Model, PermissionModelMixin): (BOOKS, _('Books')), ) - # Search Style - SMALL = 'SMALL' - LARGE = 'LARGE' - NEW = 'NEW' - - SEARCH_STYLE = ((SMALL, _('Small')), (LARGE, _('Large')), (NEW, _('New'))) - user = AutoOneToOneField(User, on_delete=models.CASCADE, primary_key=True) theme = models.CharField(choices=THEMES, max_length=128, default=TANDOOR) nav_color = models.CharField( @@ -373,10 +366,6 @@ class UserPreference(models.Model, PermissionModelMixin): default_page = models.CharField( choices=PAGES, max_length=64, default=SEARCH ) - search_style = models.CharField( - choices=SEARCH_STYLE, max_length=64, default=NEW - ) - show_recent = models.BooleanField(default=True) plan_share = models.ManyToManyField( User, blank=True, related_name='plan_share_default' ) diff --git a/cookbook/serializer.py b/cookbook/serializer.py index a4b8b2fe..718964f1 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -258,8 +258,8 @@ class UserPreferenceSerializer(WritableNestedModelSerializer): class Meta: model = UserPreference fields = ( - 'user', 'theme', 'nav_color', 'default_unit', 'default_page', 'use_fractions', 'use_kj', 'search_style', - 'show_recent', 'plan_share', + 'user', 'theme', 'nav_color', 'default_unit', 'default_page', 'use_fractions', 'use_kj', + 'plan_share', 'ingredient_decimals', 'comments', 'shopping_auto_sync', 'mealplan_autoadd_shopping', 'food_inherit_default', 'default_delay', 'mealplan_autoinclude_related', 'mealplan_autoexclude_onhand', 'shopping_share', 'shopping_recent_days', diff --git a/cookbook/tables.py b/cookbook/tables.py index be05fb44..4fa1a731 100644 --- a/cookbook/tables.py +++ b/cookbook/tables.py @@ -1,4 +1,3 @@ - import django_tables2 as tables from django.utils.html import format_html from django.utils.translation import gettext as _ @@ -8,60 +7,6 @@ from .models import (CookLog, InviteLink, Recipe, RecipeImport, Storage, Sync, SyncLog, ViewLog) -class ImageUrlColumn(tables.Column): - def render(self, value): - if value.url: - return value.url - return None - - -class RecipeTableSmall(tables.Table): - id = tables.LinkColumn('edit_recipe', args=[A('id')]) - name = tables.LinkColumn('view_recipe', args=[A('id')]) - all_tags = tables.Column( - attrs={ - 'td': {'class': 'd-none d-lg-table-cell'}, - 'th': {'class': 'd-none d-lg-table-cell'} - } - ) - - class Meta: - model = Recipe - template_name = 'generic/table_template.html' - fields = ('id', 'name', 'all_tags') - - -class RecipeTable(tables.Table): - edit = tables.TemplateColumn( - "" + _('Edit') + "" # noqa: E501 - ) - name = tables.LinkColumn('view_recipe', args=[A('id')]) - all_tags = tables.Column( - attrs={ - 'td': {'class': 'd-none d-lg-table-cell'}, - 'th': {'class': 'd-none d-lg-table-cell'} - } - ) - image = ImageUrlColumn() - - class Meta: - model = Recipe - template_name = 'recipes_table.html' - fields = ( - 'id', 'name', 'all_tags', 'description', 'image', 'instructions', - 'working_time', 'waiting_time', 'internal' - ) - - -# class IngredientTable(tables.Table): -# id = tables.LinkColumn('edit_food', args=[A('id')]) - -# class Meta: -# model = Keyword -# template_name = 'generic/table_template.html' -# fields = ('id', 'name') - - class StorageTable(tables.Table): id = tables.LinkColumn('edit_storage', args=[A('id')]) @@ -122,7 +67,6 @@ class RecipeImportTable(tables.Table): fields = ('id', 'name', 'file_path') - class InviteLinkTable(tables.Table): link = tables.TemplateColumn( "" diff --git a/cookbook/urls.py b/cookbook/urls.py index 2c0acd29..92592681 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -63,7 +63,6 @@ urlpatterns = [ path('invite/', views.invite_link, name='view_invite'), path('system/', views.system, name='view_system'), path('search/', views.search, name='view_search'), - path('search/v2/', views.search_v2, name='view_search_v2'), path('books/', views.books, name='view_books'), path('plan/', views.meal_plan, name='view_plan'), path('plan/entry/', views.meal_plan_entry, name='view_plan_entry'), diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 54df51bf..111048cf 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -52,7 +52,7 @@ from cookbook.helper.permission_helper import (CustomIsAdmin, CustomIsGuest, Cus CustomIsOwnerReadOnly, CustomIsShare, CustomIsShared, CustomIsSpaceOwner, CustomIsUser, group_required, is_space_owner, switch_user_active_space) -from cookbook.helper.recipe_search import RecipeFacet, RecipeSearch, old_search +from cookbook.helper.recipe_search import RecipeFacet, RecipeSearch from cookbook.helper.recipe_url_import import get_from_youtube_scraper, get_images_from_soup from cookbook.helper.scrapers.scrapers import text_scraper from cookbook.helper.shopping_helper import RecipeShoppingEditor, shopping_helper @@ -797,7 +797,6 @@ class RecipeViewSet(viewsets.ModelViewSet): 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) diff --git a/cookbook/views/views.py b/cookbook/views/views.py index dd2a77ca..db9266b5 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -11,28 +11,22 @@ from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.models import Group from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ValidationError -from django.db.models import Avg, Q -from django.db.models.functions import Lower +from django.db.models import Q from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse, reverse_lazy from django.utils import timezone from django.utils.translation import gettext as _ from django_scopes import scopes_disabled -from django_tables2 import RequestConfig from rest_framework.authtoken.models import Token -from cookbook.filters import RecipeFilter from cookbook.forms import (CommentForm, Recipe, SearchPreferenceForm, ShoppingPreferenceForm, - SpaceCreateForm, SpaceJoinForm, SpacePreferenceForm, User, + SpaceCreateForm, SpaceJoinForm, User, UserCreateForm, UserNameForm, UserPreference, UserPreferenceForm) from cookbook.helper.permission_helper import group_required, has_group_permission, share_link_valid, switch_user_active_space -from cookbook.models import (Comment, CookLog, Food, InviteLink, Keyword, - MealPlan, RecipeImport, SearchFields, SearchPreference, ShareLink, - Space, Unit, ViewLog, UserSpace) -from cookbook.tables import (CookLogTable, InviteLinkTable, RecipeTable, RecipeTableSmall, - ViewLogTable) -from cookbook.views.data import Object +from cookbook.models import (Comment, CookLog, InviteLink, MealPlan, SearchFields, SearchPreference, ShareLink, + Space, ViewLog, UserSpace) +from cookbook.tables import (CookLogTable, ViewLogTable) from recipes.version import BUILD_REF, VERSION_NUMBER @@ -58,46 +52,13 @@ def index(request): # TODO need to deprecate def search(request): if has_group_permission(request.user, ('guest',)): - if request.user.userpreference.search_style == UserPreference.NEW: - return search_v2(request) - f = RecipeFilter(request.GET, - queryset=Recipe.objects.filter(space=request.space).all().order_by( - Lower('name').asc()), - space=request.space) - if request.user.userpreference.search_style == UserPreference.LARGE: - table = RecipeTable(f.qs) - else: - table = RecipeTableSmall(f.qs) - RequestConfig(request, paginate={'per_page': 25}).configure(table) - - if request.GET == {} and request.user.userpreference.show_recent: - qs = Recipe.objects.filter(viewlog__created_by=request.user).filter( - space=request.space).order_by('-viewlog__created_at').all() - - recent_list = [] - for r in qs: - if r not in recent_list: - recent_list.append(r) - if len(recent_list) >= 5: - break - - last_viewed = RecipeTable(recent_list) - else: - last_viewed = None - - return render(request, 'index.html', {'recipes': table, 'filter': f, 'last_viewed': last_viewed}) + return render(request, 'search.html', {}) else: if request.user.is_authenticated: return HttpResponseRedirect(reverse('view_no_group')) else: return HttpResponseRedirect(reverse('account_login') + '?next=' + request.path) - -@group_required('guest') -def search_v2(request): - return render(request, 'search.html', {}) - - def no_groups(request): return render(request, 'no_groups_info.html') @@ -270,8 +231,6 @@ def user_settings(request): up.nav_color = form.cleaned_data['nav_color'] up.default_unit = form.cleaned_data['default_unit'] up.default_page = form.cleaned_data['default_page'] - up.show_recent = form.cleaned_data['show_recent'] - up.search_style = form.cleaned_data['search_style'] up.plan_share.set(form.cleaned_data['plan_share']) up.ingredient_decimals = form.cleaned_data['ingredient_decimals'] # noqa: E501 up.comments = form.cleaned_data['comments'] diff --git a/requirements.txt b/requirements.txt index 5004d80f..3956181a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,6 @@ django-annoying==0.10.6 django-autocomplete-light==3.9.4 django-cleanup==6.0.0 django-crispy-forms==1.14.0 -django-filter==22.1 django-tables2==2.4.1 djangorestframework==3.13.1 drf-writable-nested==0.6.3