diff --git a/django/thunderstore/repository/admin/__init__.py b/django/thunderstore/repository/admin/__init__.py index 2428632fb..17773c1fd 100644 --- a/django/thunderstore/repository/admin/__init__.py +++ b/django/thunderstore/repository/admin/__init__.py @@ -3,4 +3,5 @@ from .package import PackageAdmin from .package_rating import PackageRatingAdmin from .package_version import PackageVersionAdmin +from .submission import AsyncPackageSubmissionAdmin from .team import TeamAdmin diff --git a/django/thunderstore/repository/admin/submission.py b/django/thunderstore/repository/admin/submission.py new file mode 100644 index 000000000..f076795fe --- /dev/null +++ b/django/thunderstore/repository/admin/submission.py @@ -0,0 +1,35 @@ +from django.contrib import admin +from django.http import HttpRequest + +from thunderstore.repository.models import AsyncPackageSubmission + + +@admin.register(AsyncPackageSubmission) +class AsyncPackageSubmissionAdmin(admin.ModelAdmin): + raw_id_fields = ( + "owner", + "file", + ) + list_select_related = ( + "owner", + "file", + ) + list_display = ( + "owner", + "file", + "status", + "datetime_scheduled", + "datetime_polled", + "datetime_finished", + ) + list_filter = ("status",) + search_fields = ("owner__username",) + + def has_add_permission(self, request: HttpRequest, obj=None) -> bool: + return False + + def has_change_permission(self, request: HttpRequest, obj=None) -> bool: + return False + + def has_delete_permission(self, request: HttpRequest, obj=None) -> bool: + return False diff --git a/django/thunderstore/repository/admin/tests/test_submission.py b/django/thunderstore/repository/admin/tests/test_submission.py new file mode 100644 index 000000000..69714a548 --- /dev/null +++ b/django/thunderstore/repository/admin/tests/test_submission.py @@ -0,0 +1,36 @@ +import pytest +from django.conf import settings +from django.test import Client + +from thunderstore.repository.factories import AsyncPackageSubmissionFactory + + +@pytest.mark.django_db +def test_admin_asyncpackagesubmission_search(admin_client: Client) -> None: + username = AsyncPackageSubmissionFactory().owner.username + resp = admin_client.get( + path=f"/djangoadmin/repository/asyncpackagesubmission/?q={username}", + HTTP_HOST=settings.PRIMARY_HOST, + ) + assert resp.status_code == 200 + + +@pytest.mark.django_db +def test_admin_asyncpackagesubmission_list(admin_client: Client) -> None: + AsyncPackageSubmissionFactory() + resp = admin_client.get( + path="/djangoadmin/repository/asyncpackagesubmission/", + HTTP_HOST=settings.PRIMARY_HOST, + ) + assert resp.status_code == 200 + + +@pytest.mark.django_db +def test_admin_asyncpackagesubmission_detail(admin_client: Client) -> None: + pk = AsyncPackageSubmissionFactory().pk + path = f"/djangoadmin/repository/asyncpackagesubmission/{pk}/change/" + resp = admin_client.get( + path=path, + HTTP_HOST=settings.PRIMARY_HOST, + ) + assert resp.status_code == 200 diff --git a/django/thunderstore/repository/api/experimental/views/submit_async.py b/django/thunderstore/repository/api/experimental/views/submit_async.py index b65a29a63..dcc9e4245 100644 --- a/django/thunderstore/repository/api/experimental/views/submit_async.py +++ b/django/thunderstore/repository/api/experimental/views/submit_async.py @@ -9,7 +9,7 @@ PackageSubmissionResult, ) from thunderstore.repository.api.experimental.views.submit import get_usermedia_or_404 -from thunderstore.repository.models.async_submission import AsyncPackageSubmission +from thunderstore.repository.models.submission import AsyncPackageSubmission class PackageSubmissionStatusSerializer(serializers.Serializer): diff --git a/django/thunderstore/repository/models/__init__.py b/django/thunderstore/repository/models/__init__.py index c93037d89..04ad1b97b 100644 --- a/django/thunderstore/repository/models/__init__.py +++ b/django/thunderstore/repository/models/__init__.py @@ -1,4 +1,3 @@ -from .async_submission import * from .cache import * from .discord_bot import * from .namespace import * @@ -6,5 +5,6 @@ from .package_download import * from .package_rating import * from .package_version import * +from .submission import * from .team import * from .wiki import * diff --git a/django/thunderstore/repository/models/async_submission.py b/django/thunderstore/repository/models/submission.py similarity index 100% rename from django/thunderstore/repository/models/async_submission.py rename to django/thunderstore/repository/models/submission.py diff --git a/django/thunderstore/usermedia/cleanup.py b/django/thunderstore/usermedia/cleanup.py index f90df56c8..3c1d61ded 100644 --- a/django/thunderstore/usermedia/cleanup.py +++ b/django/thunderstore/usermedia/cleanup.py @@ -6,7 +6,7 @@ def cleanup_expired_uploads(): client = get_s3_client() - for entry in UserMedia.objects.expired(): + for entry in UserMedia.objects.expired().filter(async_package_submissions=None): try: cleanup_expired_upload(entry, client) except Exception as e: diff --git a/django/thunderstore/usermedia/migrations/0003_usermedia_owner_set_null.py b/django/thunderstore/usermedia/migrations/0003_usermedia_owner_set_null.py new file mode 100644 index 000000000..633369bfb --- /dev/null +++ b/django/thunderstore/usermedia/migrations/0003_usermedia_owner_set_null.py @@ -0,0 +1,27 @@ +# Generated by Django 3.1.7 on 2024-01-04 15:48 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("usermedia", "0002_add_cleanup_schedule"), + ] + + operations = [ + migrations.AlterField( + model_name="usermedia", + name="owner", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="usermedia", + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/django/thunderstore/usermedia/migrations/0004_usermedia_size_bigint.py b/django/thunderstore/usermedia/migrations/0004_usermedia_size_bigint.py new file mode 100644 index 000000000..cdcc52b00 --- /dev/null +++ b/django/thunderstore/usermedia/migrations/0004_usermedia_size_bigint.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.7 on 2024-01-04 15:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("usermedia", "0003_usermedia_owner_set_null"), + ] + + operations = [ + migrations.AlterField( + model_name="usermedia", + name="size", + field=models.PositiveBigIntegerField(), + ), + ] diff --git a/django/thunderstore/usermedia/models/usermedia.py b/django/thunderstore/usermedia/models/usermedia.py index a33974799..0229b2444 100644 --- a/django/thunderstore/usermedia/models/usermedia.py +++ b/django/thunderstore/usermedia/models/usermedia.py @@ -41,13 +41,13 @@ class UserMedia(TimestampMixin, models.Model): owner = models.ForeignKey( settings.AUTH_USER_MODEL, related_name="usermedia", - on_delete=models.PROTECT, + on_delete=models.SET_NULL, blank=True, null=True, ) filename = models.CharField(max_length=1024) key = models.CharField(max_length=2048) - size = models.PositiveIntegerField() + size = models.PositiveBigIntegerField() uuid = models.UUIDField(default=ulid2.generate_ulid_as_uuid, primary_key=True) # Prefix is the S3 storage bucket location prefix, only ever used for @@ -127,6 +127,9 @@ def has_expired(self) -> bool: def can_user_write(self, user: Optional[UserType]): return user == self.owner + def __str__(self): + return self.filename + class Meta: verbose_name = "user media" verbose_name_plural = "user media" diff --git a/python-packages b/python-packages index f31e692c4..5de258e6a 160000 --- a/python-packages +++ b/python-packages @@ -1 +1 @@ -Subproject commit f31e692c4d2a62f07256a24d740723043776751a +Subproject commit 5de258e6ad9978cfac09e3c1ceb4b3f2fc7b7d1d