@@ -96,25 +96,7 @@ def invalid_token_error_handler(request, exc: InvalidToken): def invalid_password_error_handler(request, exc: InvalidPassword): return api.create_response(request, {'message': _('Wrong password')}, status=401) - -urlpatterns = ( - [ - path('admin/', admin.site.urls), - path('api/v1/ml_models/', include('ml_model.urls', namespace='ml_model')), - path('api/v1/auth/', include('authentication.urls')), - path('api/v1/payments/', include('payments.urls')), - path('api/v1/reports/', include('reports.urls')), - path('api/v1/chats/', include('tools.chats.urls')), - path('api/v1/media/', include('tools.media.urls')), - path('api/v1/public/', include('tools.public_api.urls')), - path('api/v1/api/', api.urls), - path('api/v1/', compatibility_api.urls), - path('api/v1/v2/', compatibility_api_v2.urls), - path('public/', public_api.urls), - ] - + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) - + public_urlpatterns -) +urlpatterns = [] if settings.DEBUG: urlpatterns += [ @@ -137,3 +119,22 @@ if settings.DEBUG: compatibility_api.docs_url = '/docs' compatibility_api_v2.docs_url = '/docs' public_api.docs_url = '/docs' + +urlpatterns += ( + [ + path('admin/', admin.site.urls), + path('api/v1/ml_models/', include('ml_model.urls', namespace='ml_model')), + path('api/v1/auth/', include('authentication.urls')), + path('api/v1/payments/', include('payments.urls')), + path('api/v1/reports/', include('reports.urls')), + path('api/v1/chats/', include('tools.chats.urls')), + path('api/v1/media/', include('tools.media.urls')), + path('api/v1/public/', include('tools.public_api.urls')), + path('api/v1/api/', api.urls), + path('api/v1/', compatibility_api.urls), + path('api/v1/v2/', compatibility_api_v2.urls), + path('public/', public_api.urls), + ] + + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + + public_urlpatterns +) @@ -1,19 +1,30 @@ from typing import List +from django.contrib.contenttypes.models import ContentType +from django.contrib.contenttypes.prefetch import GenericPrefetch from django.core.exceptions import ValidationError +from django.db.models import Subquery from django.utils.translation import gettext as _ from ninja import File, Form, Router, UploadedFile from ninja.errors import HttpError +from ninja.pagination import paginate, CursorPagination from authentication.security import SyncAuthBearer from ml_model.models import NeuronModel from ml_model.schemas import NeuronModelLink -from tools.media.models import Preset, Voice + +from messages.models import Message +from tools.chats.schemas import MessageSchema + +from tools.media.models import Audio, Image, Preset, Video, Voice, VoiceClone from tools.media.schemas import PresetSchema, UpdateVoiceSchema, VoiceSchema -from tools.media.typing import PresetKindEnum +from tools.media.typing import PresetKindEnum, StoreEnum router = Router(auth=SyncAuthBearer(), tags=['media']) +STORES = {'audio': Audio, 'image': Image, 'video': Video, 'voice_clone': VoiceClone} +MEDIA_CONTENT_TYPES = {store: ContentType.objects.get_for_model(model) for store, model in STORES.items()} + @router.get( 'images/links/', @@ -30,6 +41,44 @@ def get_links(request): ) +@router.get( + 'generations/', + tags=['media/'], + response=List[MessageSchema], +) +@paginate(CursorPagination, ordering=('-created_at', 'uid'), page_size=10, max_page_size=50) +def list_gallery_generations(request, store: StoreEnum): + store_model = STORES[store] + store_ids = store_model.objects.filter(user=request.auth).values('uid') + return ( + Message.objects.filter( + content_type_id=MEDIA_CONTENT_TYPES[store].pk, + object_id__in=Subquery(store_ids), + from_model=True, + is_deleted=False, + ) + .prefetch_related( + GenericPrefetch( + 'content_object', + [store_model.objects.select_related('model').only('uid', 'model__slug', 'model__category_id')], + ) + ) + .only( + 'uid', + 'content', + 'file', + 'from_model', + 'created_at', + 'elapsed_time', + 'is_favourite', + 'is_sent', + 'info', + 'content_type', + 'object_id', + ) + ) + + @router.post('voices/', tags=['media/voices'], auth=SyncAuthBearer(), response={201: None, 400: str}) def upload_voice( request, @@ -3,4 +3,11 @@ from enum import Enum class PresetKindEnum(str, Enum): voice = 'voice' - instrumental = 'instrumental' \ No newline at end of file + instrumental = 'instrumental' + + +class StoreEnum(str, Enum): + audio = 'audio' + image = 'image' + video = 'video' + voice_clone = 'voice_clone' @@ -15,7 +15,7 @@ dependencies = [ "django-filter==23.2", "django-import-export==4.0.9", "django-minio-backend", - "django-ninja==1.3.0", + "django-ninja==1.6.2", "django-oauth-toolkit==2.3.0", "django-ordered-model==3.7.4", "django-polymorphic==3.1.0", @@ -340,7 +340,7 @@ requires-dist = [ { name = "django-filter", specifier = "==23.2" }, { name = "django-import-export", specifier = "==4.0.9" }, { name = "django-minio-backend", git = "https://github.com/theriverman/django-minio-backend?tag=3.7.0" }, - { name = "django-ninja", specifier = "==1.3.0" }, + { name = "django-ninja", specifier = "==1.6.2" }, { name = "django-oauth-toolkit", specifier = "==2.3.0" }, { name = "django-ordered-model", specifier = "==3.7.4" }, { name = "django-polymorphic", specifier = "==3.1.0" }, @@ -963,15 +963,15 @@ dependencies = [ [[package]] name = "django-ninja" -version = "1.3.0" +version = "1.6.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "django" }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9c/77/89ee4ebaa5151b7d85cebaf8d6ec0b9e5074326c3ad8259c763763306d51/django_ninja-1.3.0.tar.gz", hash = "sha256:5b320e2dc0f41a6032bfa7e1ebc33559ae1e911a426f0c6be6674a50b20819be", size = 3702324, upload-time = "2024-08-15T09:15:04.464Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/7c/3307e17b872f545c88314b2737a22f965785dfb5a120d739b0131d0492c3/django_ninja-1.6.2.tar.gz", hash = "sha256:d56ae5aa4791068ef4ac9a66cfdf2fc11f507413ded35abb79c51d0d52ad6412", size = 3685599, upload-time = "2026-03-18T20:06:47.284Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/72/fd2589323b40893d3224e174eeec0c4ce5a42c7d2d384d11ba269ad4d050/django_ninja-1.3.0-py3-none-any.whl", hash = "sha256:f58096b6c767d1403dfd6c49743f82d780d7b9688d9302ecab316ac1fa6131bb", size = 2423381, upload-time = "2024-08-15T09:15:02.396Z" }, + { url = "https://files.pythonhosted.org/packages/21/0c/25f72060a39632fbd2d90e9c8b6052a09cd45b0598fc06c0758d313f0052/django_ninja-1.6.2-py3-none-any.whl", hash = "sha256:20095f5900bada22ea00cf1a58af50bdb285b2354c61a9d9b47d0dc89ac462d6", size = 2374994, upload-time = "2026-03-18T20:06:45.676Z" }, ] [[package]]