From ad4b1393dd7c8072ac5dbbf0ceab344292930698 Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Thu, 11 Sep 2025 18:58:44 +0200 Subject: [PATCH] various improvements --- cookbook/helper/scope_middleware.py | 11 +- cookbook/serializer.py | 12 +- cookbook/views/api.py | 2 +- .../settings/OpenDataImportSettings.vue | 16 +- .../components/settings/UserSpaceSettings.vue | 19 ++- vue3/src/locales/ar.json | 7 + vue3/src/locales/bg.json | 7 + vue3/src/locales/ca.json | 7 + vue3/src/locales/cs.json | 7 + vue3/src/locales/da.json | 7 + vue3/src/locales/de.json | 7 + vue3/src/locales/el.json | 7 + vue3/src/locales/en.json | 7 + vue3/src/locales/es.json | 7 + vue3/src/locales/fi.json | 7 + vue3/src/locales/fr.json | 7 + vue3/src/locales/he.json | 7 + vue3/src/locales/hr.json | 7 + vue3/src/locales/hu.json | 7 + vue3/src/locales/hy.json | 7 + vue3/src/locales/id.json | 7 + vue3/src/locales/is.json | 7 + vue3/src/locales/it.json | 7 + vue3/src/locales/lt.json | 7 + vue3/src/locales/lv.json | 7 + vue3/src/locales/nb_NO.json | 7 + vue3/src/locales/nl.json | 7 + vue3/src/locales/pl.json | 7 + vue3/src/locales/pt.json | 7 + vue3/src/locales/pt_BR.json | 7 + vue3/src/locales/ro.json | 7 + vue3/src/locales/ru.json | 7 + vue3/src/locales/sl.json | 7 + vue3/src/locales/sv.json | 7 + vue3/src/locales/tr.json | 7 + vue3/src/locales/uk.json | 7 + vue3/src/locales/zh_Hans.json | 7 + vue3/src/locales/zh_Hant.json | 7 + vue3/src/openapi/apis/ApiApi.ts | 37 +++++ vue3/src/openapi/models/Space.ts | 7 +- vue3/src/pages/StartPage.vue | 60 ++++--- vue3/src/pages/WelcomePage.vue | 150 ++++++++++++++++-- 42 files changed, 491 insertions(+), 54 deletions(-) diff --git a/cookbook/helper/scope_middleware.py b/cookbook/helper/scope_middleware.py index ff10980bb..11e59a130 100644 --- a/cookbook/helper/scope_middleware.py +++ b/cookbook/helper/scope_middleware.py @@ -81,6 +81,10 @@ def create_space_for_user(user, name=None): with scopes_disabled(): if not name: name = f"{user.username}'s Space" + + if Space.objects.filter(name=name).exists(): + name = f'{name} #{random.randrange(1, 10 ** 5)}' + created_space = Space(name=name, created_by=user, max_file_storage_mb=settings.SPACE_DEFAULT_MAX_FILES, @@ -90,12 +94,9 @@ def create_space_for_user(user, name=None): ai_enabled=settings.SPACE_AI_ENABLED, ai_credits_monthly=settings.SPACE_AI_CREDITS_MONTHLY, space_setup_completed=False, ) - try: - created_space.save() - except UniqueViolation: - created_space.name = f'{name} #{random.randrange(1, 10 ** 5)}' - created_space.save() + created_space.save() + UserSpace.objects.filter(user=user).update(active=False) user_space = UserSpace.objects.create(space=created_space, user=user, active=True) user_space.groups.add(Group.objects.filter(name='admin').get()) diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 902da4e95..c561f2186 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -28,6 +28,7 @@ from cookbook.helper.ai_helper import get_monthly_token_usage from cookbook.helper.image_processing import is_file_type_allowed from cookbook.helper.permission_helper import above_space_limit from cookbook.helper.property_helper import FoodPropertyHelper +from cookbook.helper.scope_middleware import create_space_for_user from cookbook.helper.shopping_helper import RecipeShoppingEditor from cookbook.helper.unit_conversion_helper import UnitConversionHelper from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, CustomFilter, @@ -372,7 +373,7 @@ class SpaceSerializer(WritableNestedModelSerializer): file_size_mb = serializers.SerializerMethodField('get_file_size_mb') ai_monthly_credits_used = serializers.SerializerMethodField('get_ai_monthly_credits_used') ai_default_provider = AiProviderSerializer(required=False, allow_null=True) - food_inherit = FoodInheritFieldSerializer(many=True) + food_inherit = FoodInheritFieldSerializer(many=True, required=False) image = UserFileViewSerializer(required=False, many=False, allow_null=True) nav_logo = UserFileViewSerializer(required=False, many=False, allow_null=True) custom_space_theme = UserFileViewSerializer(required=False, many=False, allow_null=True) @@ -404,7 +405,11 @@ class SpaceSerializer(WritableNestedModelSerializer): return 0 def create(self, validated_data): - raise ValidationError('Cannot create using this endpoint') + name = None + if 'name' in validated_data: + name = validated_data['name'] + space = create_space_for_user(self.context['request'].user, name) + return space def update(self, instance, validated_data): if 'ai_enabled' in validated_data and not self.context['request'].user.is_superuser: @@ -416,6 +421,9 @@ class SpaceSerializer(WritableNestedModelSerializer): if 'ai_credits_balance' in validated_data and not self.context['request'].user.is_superuser: del validated_data['ai_credits_balance'] + if Space.objects.filter(Q(name=validated_data['name']), ~Q(pk=instance.pk)).exists(): + raise ValidationError(_('Space Name must be unique.')) + return super().update(instance, validated_data) class Meta: diff --git a/cookbook/views/api.py b/cookbook/views/api.py index c07ad6e76..097c120cd 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -545,7 +545,7 @@ class SpaceViewSet(LoggingMixin, viewsets.ModelViewSet): serializer_class = SpaceSerializer permission_classes = [IsReadOnlyDRF & CustomIsGuest | CustomIsOwner & CustomIsAdmin & CustomTokenHasReadWriteScope] pagination_class = DefaultPagination - http_method_names = ['get', 'patch'] + http_method_names = ['get', 'post', 'patch'] def get_queryset(self): return self.queryset.filter( diff --git a/vue3/src/components/settings/OpenDataImportSettings.vue b/vue3/src/components/settings/OpenDataImportSettings.vue index 3156a0504..f0fb19e46 100644 --- a/vue3/src/components/settings/OpenDataImportSettings.vue +++ b/vue3/src/components/settings/OpenDataImportSettings.vue @@ -1,10 +1,9 @@