moved search settings to frontend

This commit is contained in:
vabene1111
2025-06-22 13:37:02 +02:00
parent edcc5f6441
commit f4a7ef144f
49 changed files with 17772 additions and 16336 deletions

View File

@@ -173,38 +173,3 @@ class UserCreateForm(forms.Form):
name = forms.CharField(label='Username')
password = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
password_confirm = forms.CharField(widget=forms.TextInput(attrs={'autocomplete': 'new-password', 'type': 'password'}))
class SearchPreferenceForm(forms.ModelForm):
prefix = 'search'
trigram_threshold = forms.DecimalField(min_value=0.01,
max_value=1,
decimal_places=2,
widget=NumberInput(attrs={'class': "form-control-range", 'type': 'range'}),
help_text=_('Determines how fuzzy a search is if it uses trigram similarity matching (e.g. low values mean more typos are ignored).'))
preset = forms.CharField(widget=forms.HiddenInput(), required=False)
class Meta:
model = SearchPreference
fields = ('search', 'lookup', 'unaccent', 'icontains', 'istartswith', 'trigram', 'fulltext', 'trigram_threshold')
help_texts = {
'search': _('Select type method of search. Click <a href="/docs/search/">here</a> for full description of choices.'), 'lookup':
_('Use fuzzy matching on units, keywords and ingredients when editing and importing recipes.'), 'unaccent':
_('Fields to search ignoring accents. Selecting this option can improve or degrade search quality depending on language'), 'icontains':
_("Fields to search for partial matches. (e.g. searching for 'Pie' will return 'pie' and 'piece' and 'soapie')"), 'istartswith':
_("Fields to search for beginning of word matches. (e.g. searching for 'sa' will return 'salad' and 'sandwich')"), 'trigram':
_("Fields to 'fuzzy' search. (e.g. searching for 'recpie' will find 'recipe'.) Note: this option will conflict with 'web' and 'raw' methods of search."),
'fulltext':
_("Fields to full text search. Note: 'web', 'phrase', and 'raw' search methods only function with fulltext fields."),
}
labels = {
'search': _('Search Method'), 'lookup': _('Fuzzy Lookups'), 'unaccent': _('Ignore Accent'), 'icontains': _("Partial Match"), 'istartswith': _("Starts With"),
'trigram': _("Fuzzy Search"), 'fulltext': _("Full Text")
}
widgets = {
'search': SelectWidget, 'unaccent': MultiSelectWidget, 'icontains': MultiSelectWidget, 'istartswith': MultiSelectWidget, 'trigram': MultiSelectWidget, 'fulltext':
MultiSelectWidget,
}

View File

@@ -36,7 +36,7 @@ from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, Cu
ShareLink, ShoppingListEntry, ShoppingListRecipe, Space,
Step, Storage, Supermarket, SupermarketCategory,
SupermarketCategoryRelation, Sync, SyncLog, Unit, UnitConversion,
UserFile, UserPreference, UserSpace, ViewLog, ConnectorConfig)
UserFile, UserPreference, UserSpace, ViewLog, ConnectorConfig, SearchPreference, SearchFields)
from cookbook.templatetags.custom_tags import markdown
from recipes.settings import AWS_ENABLED, MEDIA_URL, EMAIL_HOST
@@ -452,6 +452,40 @@ class UserPreferenceSerializer(WritableNestedModelSerializer):
read_only_fields = ('user',)
class SearchFieldsSerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
name = serializers.CharField(allow_null=True, allow_blank=True, required=False)
field = serializers.CharField(allow_null=True, allow_blank=True, required=False)
def create(self, validated_data):
raise ValidationError('Cannot create using this endpoint')
def update(self, instance, validated_data):
return instance
class Meta:
model = SearchFields
fields = ('id', 'name', 'field',)
read_only_fields = ('id',)
class SearchPreferenceSerializer(WritableNestedModelSerializer):
user = UserSerializer(read_only=True)
unaccent = SearchFieldsSerializer(many=True, allow_null=True, required=False)
icontains = SearchFieldsSerializer(many=True, allow_null=True, required=False)
istartswith = SearchFieldsSerializer(many=True, allow_null=True, required=False)
trigram = SearchFieldsSerializer(many=True, allow_null=True, required=False)
fulltext = SearchFieldsSerializer(many=True, allow_null=True, required=False)
def create(self, validated_data):
raise ValidationError('Cannot create using this endpoint')
class Meta:
model = SearchPreference
fields = ('user', 'search', 'lookup', 'unaccent', 'icontains', 'istartswith', 'trigram', 'fulltext', 'trigram_threshold')
read_only_fields = ('user',)
class ConnectorConfigSerializer(SpacedModelSerializer):
def create(self, validated_data):

View File

@@ -56,6 +56,8 @@ router.register(r'unit', api.UnitViewSet)
router.register(r'user-file', api.UserFileViewSet)
router.register(r'user', api.UserViewSet)
router.register(r'user-preference', api.UserPreferenceViewSet)
router.register(r'search-fields', api.SearchFieldsViewSet)
router.register(r'search-preference', api.SearchPreferenceViewSet)
router.register(r'user-space', api.UserSpaceViewSet)
router.register(r'view-log', api.ViewLogViewSet)
router.register(r'access-token', api.AccessTokenViewSet)

View File

@@ -85,7 +85,7 @@ from cookbook.models import (Automation, BookmarkletImport, ConnectorConfig, Coo
RecipeBookEntry, ShareLink, ShoppingListEntry,
ShoppingListRecipe, Space, Step, Storage, Supermarket, SupermarketCategory,
SupermarketCategoryRelation, Sync, SyncLog, Unit, UnitConversion,
UserFile, UserPreference, UserSpace, ViewLog, RecipeImport
UserFile, UserPreference, UserSpace, ViewLog, RecipeImport, SearchPreference, SearchFields
)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
@@ -110,7 +110,7 @@ from cookbook.serializer import (AccessTokenSerializer, AutomationSerializer, Au
UserSerializer, UserSpaceSerializer, ViewLogSerializer,
LocalizationSerializer, ServerSettingsSerializer, RecipeFromSourceResponseSerializer, ShoppingListEntryBulkCreateSerializer, FdcQuerySerializer,
AiImportSerializer, ImportOpenDataSerializer, ImportOpenDataMetaDataSerializer, ImportOpenDataResponseSerializer, ExportRequestSerializer,
RecipeImportSerializer, ConnectorConfigSerializer
RecipeImportSerializer, ConnectorConfigSerializer, SearchPreferenceSerializer, SearchFieldsSerializer
)
from cookbook.version_info import TANDOOR_VERSION
from cookbook.views.import_export import get_integration
@@ -577,7 +577,30 @@ class UserPreferenceViewSet(LoggingMixin, viewsets.ModelViewSet):
http_method_names = ['get', 'patch', ]
def get_queryset(self):
with scopes_disabled(): # need to disable scopes as user preference is no longer a spaced method
with scopes_disabled(): # need to disable scopes as user preferences are not scoped
return self.queryset.filter(user=self.request.user)
class SearchFieldsViewSet(LoggingMixin, viewsets.ReadOnlyModelViewSet):
queryset = SearchFields.objects
serializer_class = SearchFieldsSerializer
permission_classes = [CustomIsGuest & CustomTokenHasReadWriteScope]
pagination_disabled = True
def get_queryset(self):
with scopes_disabled(): # need to disable scopes as fields are global
return self.queryset
class SearchPreferenceViewSet(LoggingMixin, viewsets.ModelViewSet):
queryset = SearchPreference.objects
serializer_class = SearchPreferenceSerializer
permission_classes = [CustomIsOwner & CustomTokenHasReadWriteScope]
pagination_disabled = True
http_method_names = ['get', 'patch', ]
def get_queryset(self):
with scopes_disabled(): # need to disable scopes as search preferences are not scoped
return self.queryset.filter(user=self.request.user)
@@ -2296,7 +2319,7 @@ def get_external_file_link(request, pk):
@api_view(['GET'])
@permission_classes([CustomRecipePermission & CustomTokenHasReadWriteScope])
def get_recipe_file(request, pk):
recipe = get_object_or_404(Recipe, pk=pk) # space check handled by CustomRecipePermission
recipe = get_object_or_404(Recipe, pk=pk) # space check handled by CustomRecipePermission
if recipe.storage:
return FileResponse(get_recipe_provider(recipe).get_file(recipe), filename=f'{recipe.name}.pdf')
else: