diff --git a/src/wagtail_bynder/__init__.py b/src/wagtail_bynder/__init__.py index 7c57950..ee09036 100644 --- a/src/wagtail_bynder/__init__.py +++ b/src/wagtail_bynder/__init__.py @@ -1,6 +1,7 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured + def get_video_model_string(): """ Get the dotted ``app.Model`` name for the video model as a string. diff --git a/src/wagtail_bynder/management/commands/base.py b/src/wagtail_bynder/management/commands/base.py index 10c491c..615186b 100644 --- a/src/wagtail_bynder/management/commands/base.py +++ b/src/wagtail_bynder/management/commands/base.py @@ -60,8 +60,9 @@ def get_assets(self) -> Generator[dict[str, Any]]: results = self.bynder_client.asset_bank_client.media_list(query) if not results: break - for asset in results: - yield asset + + yield from results + page += 1 def get_outdated_objects(self, assets: dict[str, dict[str, Any]]) -> QuerySet: diff --git a/src/wagtail_bynder/models.py b/src/wagtail_bynder/models.py index a11c52e..9c2a66a 100644 --- a/src/wagtail_bynder/models.py +++ b/src/wagtail_bynder/models.py @@ -1,6 +1,7 @@ import logging import math import os + from datetime import datetime from mimetypes import guess_type from typing import Any @@ -19,6 +20,7 @@ from wagtail_bynder import utils + logger = logging.getLogger("wagtail.images") @@ -27,21 +29,21 @@ class BynderAssetMixin(models.Model): bynder_id = models.CharField( verbose_name=_("Bynder asset ID"), max_length=36, - null=True, + blank=True, unique=True, editable=False, db_index=True, ) - bynder_id_hash = models.CharField(max_length=100, null=True, editable=False) + bynder_id_hash = models.CharField(max_length=100, blank=True, editable=False) bynder_original_filename = models.CharField( - max_length=255, null=True, editable=False + max_length=255, blank=True, editable=False ) bynder_last_modified = models.DateTimeField( null=True, editable=False, db_index=True ) - # Fields for more broader use - description = models.TextField(verbose_name=_("descripton"), blank=True) + # Fields for broader use + description = models.TextField(verbose_name=_("description"), blank=True) copyright = models.TextField(verbose_name=_("copyright info"), blank=True) is_archived = models.BooleanField( verbose_name=_("asset is archived"), default=False @@ -274,7 +276,6 @@ class BynderSyncedVideo( ) fallback_source_url = models.URLField( blank=True, - null=True, verbose_name=_("fallback source URL"), help_text=( "A derivative using an MP4 container and the AVC (H.264) video codec, ideally with " diff --git a/src/wagtail_bynder/templatetags/bynder_tags.py b/src/wagtail_bynder/templatetags/bynder_tags.py index dc561b5..c190ee3 100644 --- a/src/wagtail_bynder/templatetags/bynder_tags.py +++ b/src/wagtail_bynder/templatetags/bynder_tags.py @@ -1,6 +1,7 @@ from django import template from django.conf import settings + register = template.Library() diff --git a/src/wagtail_bynder/utils.py b/src/wagtail_bynder/utils.py index 52101f5..c3a9539 100644 --- a/src/wagtail_bynder/utils.py +++ b/src/wagtail_bynder/utils.py @@ -1,14 +1,17 @@ import mimetypes import os + from io import BytesIO import requests + from asgiref.local import Local from bynder_sdk import BynderClient from django.conf import settings from django.core.files.uploadedfile import InMemoryUploadedFile from wagtail.models import Collection + _DEFAULT_COLLECTION = Local() @@ -20,7 +23,7 @@ class DownloadedFile(BytesIO): def download_file(url: str) -> DownloadedFile: - raw_bytes = requests.get(url).content + raw_bytes = requests.get(url, timeout=20).content f = DownloadedFile(raw_bytes) f.name = os.path.basename(url) f.size = len(raw_bytes) diff --git a/src/wagtail_bynder/views/document.py b/src/wagtail_bynder/views/document.py index a41ab9f..0cadda2 100644 --- a/src/wagtail_bynder/views/document.py +++ b/src/wagtail_bynder/views/document.py @@ -9,6 +9,7 @@ from .mixins import BynderAssetCopyMixin, RedirectToBynderMixin + if TYPE_CHECKING: from django.http import HttpRequest, JsonResponse diff --git a/src/wagtail_bynder/views/image.py b/src/wagtail_bynder/views/image.py index 77c8d6c..f2d6054 100644 --- a/src/wagtail_bynder/views/image.py +++ b/src/wagtail_bynder/views/image.py @@ -9,6 +9,7 @@ from .mixins import BynderAssetCopyMixin, RedirectToBynderMixin + if TYPE_CHECKING: from django.http import HttpRequest, JsonResponse diff --git a/src/wagtail_bynder/views/mixins.py b/src/wagtail_bynder/views/mixins.py index 4d11388..19b9c8a 100644 --- a/src/wagtail_bynder/views/mixins.py +++ b/src/wagtail_bynder/views/mixins.py @@ -6,6 +6,7 @@ from wagtail_bynder.models import BynderAssetMixin from wagtail_bynder.utils import get_bynder_client + if TYPE_CHECKING: from django.http import HttpRequest, HttpResponse diff --git a/src/wagtail_bynder/views/video.py b/src/wagtail_bynder/views/video.py index b499291..334b275 100644 --- a/src/wagtail_bynder/views/video.py +++ b/src/wagtail_bynder/views/video.py @@ -10,6 +10,7 @@ from .mixins import BynderAssetCopyMixin, RedirectToBynderMixin + if TYPE_CHECKING: from django.http import HttpRequest, JsonResponse diff --git a/src/wagtail_bynder/wagtail_hooks.py b/src/wagtail_bynder/wagtail_hooks.py index 3cdfb04..3681402 100644 --- a/src/wagtail_bynder/wagtail_hooks.py +++ b/src/wagtail_bynder/wagtail_hooks.py @@ -66,7 +66,7 @@ def editor_js(): if get_video_model(): - try: + try: # noqa: SIM105 register_snippet(VideoViewSet) - except Exception: + except Exception: # noqa: S110 pass diff --git a/tests/test_bynderassetcopymixin.py b/tests/test_bynderassetcopymixin.py index 7ad144d..f620d56 100644 --- a/tests/test_bynderassetcopymixin.py +++ b/tests/test_bynderassetcopymixin.py @@ -1,6 +1,7 @@ from unittest import mock import responses + from django.test import TestCase from wagtail.images import get_image_model from wagtail_factories import ImageFactory @@ -9,6 +10,7 @@ from .utils import TEST_ASSET_ID, get_test_asset_data + TEST_ASSET_DATA = get_test_asset_data(id=TEST_ASSET_ID) @@ -30,12 +32,14 @@ def test_create_object(self): # After fetching the data from bynder, the method should create a # new object, call update_from_asset_data() to populate some # fields values, then save the changes. - with mock.patch.object( - self.view.model, "update_from_asset_data" - ) as update_from_asset_data_mock: - with mock.patch.object(self.view.model, "save") as save_mock: - # Run the code to be tested! - obj = self.view.create_object(TEST_ASSET_ID) + with ( + mock.patch.object( + self.view.model, "update_from_asset_data" + ) as update_from_asset_data_mock, + mock.patch.object(self.view.model, "save") as save_mock, + ): + # Run the code to be tested! + obj = self.view.create_object(TEST_ASSET_ID) # Assertions update_from_asset_data_mock.assert_called_once_with(TEST_ASSET_DATA) @@ -50,15 +54,17 @@ def test_update_object_when_object_is_up_to_date(self): # After fetching the data from bynder, the method should call the object's # 'is_up_to_date()' method, then will only update and save the object if # `False` is returned - with mock.patch.object( - obj, "is_up_to_date", return_value=True - ) as is_up_to_date_mock: - with mock.patch.object( + with ( + mock.patch.object( + obj, "is_up_to_date", return_value=True + ) as is_up_to_date_mock, + mock.patch.object( obj, "update_from_asset_data" - ) as update_from_asset_data_mock: - with mock.patch.object(obj, "save") as save_mock: - # Run the code to be tested! - self.view.update_object(TEST_ASSET_ID, obj) + ) as update_from_asset_data_mock, + mock.patch.object(obj, "save") as save_mock, + ): + # Run the code to be tested! + self.view.update_object(TEST_ASSET_ID, obj) # Assertions is_up_to_date_mock.assert_called_once_with(TEST_ASSET_DATA) @@ -73,15 +79,17 @@ def test_update_object_when_object_is_outdated(self): # After fetching the data from bynder, the method should call the object's # 'is_up_to_date()' method, then will only update and save the object if # `False` is returned - with mock.patch.object( - obj, "is_up_to_date", return_value=False - ) as is_up_to_date_mock: - with mock.patch.object( + with ( + mock.patch.object( + obj, "is_up_to_date", return_value=False + ) as is_up_to_date_mock, + mock.patch.object( obj, "update_from_asset_data" - ) as update_from_asset_data_mock: - with mock.patch.object(obj, "save") as save_mock: - # Run the code to be tested! - self.view.update_object(TEST_ASSET_ID, obj) + ) as update_from_asset_data_mock, + mock.patch.object(obj, "save") as save_mock, + ): + # Run the code to be tested! + self.view.update_object(TEST_ASSET_ID, obj) is_up_to_date_mock.assert_called_once_with(TEST_ASSET_DATA) update_from_asset_data_mock.assert_called_once_with(TEST_ASSET_DATA) diff --git a/tests/test_document_chooser_views.py b/tests/test_document_chooser_views.py index fd29dd0..8afbded 100644 --- a/tests/test_document_chooser_views.py +++ b/tests/test_document_chooser_views.py @@ -2,9 +2,8 @@ from django.test import TestCase, override_settings from django.urls import reverse, reverse_lazy -from wagtail.test.utils import WagtailTestUtils - from testapp.factories import CustomDocumentFactory +from wagtail.test.utils import WagtailTestUtils from .utils import TEST_ASSET_ID diff --git a/tests/test_image_chooser_views.py b/tests/test_image_chooser_views.py index 298f1c9..22d1797 100644 --- a/tests/test_image_chooser_views.py +++ b/tests/test_image_chooser_views.py @@ -2,9 +2,8 @@ from django.test import TestCase, TransactionTestCase, override_settings from django.urls import reverse, reverse_lazy -from wagtail.test.utils import WagtailTestUtils - from testapp.factories import CustomImageFactory +from wagtail.test.utils import WagtailTestUtils from .utils import TEST_ASSET_ID diff --git a/tests/test_wagtail_overrides.py b/tests/test_wagtail_overrides.py index 4d2cf8a..49262cd 100644 --- a/tests/test_wagtail_overrides.py +++ b/tests/test_wagtail_overrides.py @@ -23,7 +23,7 @@ def assertNotRaises(self, exc_type): try: yield None except exc_type as e: - raise self.failureException("{} raised".format(exc_type.__name__)) from e + raise self.failureException(f"{exc_type.__name__} raised") from e def test_wagtail_views_names_have_not_changed(self): """ @@ -32,9 +32,8 @@ def test_wagtail_views_names_have_not_changed(self): if they change, our custom views will not be loaded. """ for url_name, args in self.urls: - with self.subTest(url_name=url_name): - with self.assertNotRaises(NoReverseMatch): - reverse(url_name, args=args) + with self.subTest(url_name=url_name), self.assertNotRaises(NoReverseMatch): + reverse(url_name, args=args) @override_settings( BYNDER_DISABLE_WAGTAIL_EDITING_FOR_ASSETS=True, diff --git a/tests/testapp/factories.py b/tests/testapp/factories.py index 57baea9..548f2f1 100644 --- a/tests/testapp/factories.py +++ b/tests/testapp/factories.py @@ -1,4 +1,8 @@ -from wagtail_factories.factories import DocumentFactory, ImageFactory, CollectionMemberFactory +from wagtail_factories.factories import ( + CollectionMemberFactory, + DocumentFactory, + ImageFactory, +) from .models import CustomDocument, CustomImage, Video diff --git a/tests/testapp/migrations/0001_initial.py b/tests/testapp/migrations/0001_initial.py index 443ddae..16d2a33 100644 --- a/tests/testapp/migrations/0001_initial.py +++ b/tests/testapp/migrations/0001_initial.py @@ -6,123 +6,441 @@ import wagtail.images.models import wagtail.models.collections import wagtail.search.index + from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): - initial = True dependencies = [ - ('taggit', '0005_auto_20220424_2025'), - ('wagtailcore', '0089_log_entry_data_json_null_to_object'), + ("taggit", "0005_auto_20220424_2025"), + ("wagtailcore", "0089_log_entry_data_json_null_to_object"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( - name='CustomDocument', + name="CustomDocument", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255, verbose_name='title')), - ('file', models.FileField(upload_to='documents', verbose_name='file')), - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='created at')), - ('file_size', models.PositiveIntegerField(editable=False, null=True)), - ('file_hash', models.CharField(blank=True, editable=False, max_length=40)), - ('bynder_id', models.CharField(db_index=True, editable=False, max_length=36, null=True, unique=True, verbose_name='Bynder asset ID')), - ('bynder_id_hash', models.CharField(editable=False, max_length=100, null=True)), - ('bynder_original_filename', models.CharField(editable=False, max_length=255, null=True)), - ('bynder_last_modified', models.DateTimeField(db_index=True, editable=False, null=True)), - ('description', models.TextField(blank=True, verbose_name='descripton')), - ('copyright', models.TextField(blank=True, verbose_name='copyright info')), - ('is_archived', models.BooleanField(default=False, verbose_name='asset is archived')), - ('is_limited_use', models.BooleanField(default=False, verbose_name="asset is marked as 'limited use'")), - ('is_public', models.BooleanField(default=False, verbose_name='asset is marked as public')), - ('metadata', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder, verbose_name='additional metadata')), - ('collection', models.ForeignKey(default=wagtail.models.collections.get_root_collection_id, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.collection', verbose_name='collection')), - ('tags', taggit.managers.TaggableManager(blank=True, help_text=None, through='taggit.TaggedItem', to='taggit.Tag', verbose_name='tags')), - ('uploaded_by_user', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='uploaded by user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=255, verbose_name="title")), + ("file", models.FileField(upload_to="documents", verbose_name="file")), + ( + "created_at", + models.DateTimeField(auto_now_add=True, verbose_name="created at"), + ), + ("file_size", models.PositiveIntegerField(editable=False, null=True)), + ( + "file_hash", + models.CharField(blank=True, editable=False, max_length=40), + ), + ( + "bynder_id", + models.CharField( + db_index=True, + editable=False, + max_length=36, + blank=True, + unique=True, + verbose_name="Bynder asset ID", + ), + ), + ( + "bynder_id_hash", + models.CharField(editable=False, max_length=100, blank=True), + ), + ( + "bynder_original_filename", + models.CharField(editable=False, max_length=255, blank=True), + ), + ( + "bynder_last_modified", + models.DateTimeField(db_index=True, editable=False, null=True), + ), + ( + "description", + models.TextField(blank=True, verbose_name="description"), + ), + ( + "copyright", + models.TextField(blank=True, verbose_name="copyright info"), + ), + ( + "is_archived", + models.BooleanField( + default=False, verbose_name="asset is archived" + ), + ), + ( + "is_limited_use", + models.BooleanField( + default=False, verbose_name="asset is marked as 'limited use'" + ), + ), + ( + "is_public", + models.BooleanField( + default=False, verbose_name="asset is marked as public" + ), + ), + ( + "metadata", + models.JSONField( + blank=True, + default=dict, + encoder=django.core.serializers.json.DjangoJSONEncoder, + verbose_name="additional metadata", + ), + ), + ( + "collection", + models.ForeignKey( + default=wagtail.models.collections.get_root_collection_id, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.collection", + verbose_name="collection", + ), + ), + ( + "tags", + taggit.managers.TaggableManager( + blank=True, + help_text=None, + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="tags", + ), + ), + ( + "uploaded_by_user", + models.ForeignKey( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="uploaded by user", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, bases=(wagtail.search.index.Indexed, models.Model), ), migrations.CreateModel( - name='CustomImage', + name="CustomImage", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=255, verbose_name='title')), - ('file', wagtail.images.models.WagtailImageField(height_field='height', upload_to=wagtail.images.models.get_upload_to, verbose_name='file', width_field='width')), - ('width', models.IntegerField(editable=False, verbose_name='width')), - ('height', models.IntegerField(editable=False, verbose_name='height')), - ('created_at', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='created at')), - ('focal_point_x', models.PositiveIntegerField(blank=True, null=True)), - ('focal_point_y', models.PositiveIntegerField(blank=True, null=True)), - ('focal_point_width', models.PositiveIntegerField(blank=True, null=True)), - ('focal_point_height', models.PositiveIntegerField(blank=True, null=True)), - ('file_size', models.PositiveIntegerField(editable=False, null=True)), - ('file_hash', models.CharField(blank=True, db_index=True, editable=False, max_length=40)), - ('bynder_id', models.CharField(db_index=True, editable=False, max_length=36, null=True, unique=True, verbose_name='Bynder asset ID')), - ('bynder_id_hash', models.CharField(editable=False, max_length=100, null=True)), - ('bynder_original_filename', models.CharField(editable=False, max_length=255, null=True)), - ('bynder_last_modified', models.DateTimeField(db_index=True, editable=False, null=True)), - ('description', models.TextField(blank=True, verbose_name='descripton')), - ('copyright', models.TextField(blank=True, verbose_name='copyright info')), - ('is_archived', models.BooleanField(default=False, verbose_name='asset is archived')), - ('is_limited_use', models.BooleanField(default=False, verbose_name="asset is marked as 'limited use'")), - ('is_public', models.BooleanField(default=False, verbose_name='asset is marked as public')), - ('metadata', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder, verbose_name='additional metadata')), - ('collection', models.ForeignKey(default=wagtail.models.collections.get_root_collection_id, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.collection', verbose_name='collection')), - ('tags', taggit.managers.TaggableManager(blank=True, help_text=None, through='taggit.TaggedItem', to='taggit.Tag', verbose_name='tags')), - ('uploaded_by_user', models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='uploaded by user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=255, verbose_name="title")), + ( + "file", + wagtail.images.models.WagtailImageField( + height_field="height", + upload_to=wagtail.images.models.get_upload_to, + verbose_name="file", + width_field="width", + ), + ), + ("width", models.IntegerField(editable=False, verbose_name="width")), + ("height", models.IntegerField(editable=False, verbose_name="height")), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, db_index=True, verbose_name="created at" + ), + ), + ("focal_point_x", models.PositiveIntegerField(blank=True, null=True)), + ("focal_point_y", models.PositiveIntegerField(blank=True, null=True)), + ( + "focal_point_width", + models.PositiveIntegerField(blank=True, null=True), + ), + ( + "focal_point_height", + models.PositiveIntegerField(blank=True, null=True), + ), + ("file_size", models.PositiveIntegerField(editable=False, null=True)), + ( + "file_hash", + models.CharField( + blank=True, db_index=True, editable=False, max_length=40 + ), + ), + ( + "bynder_id", + models.CharField( + db_index=True, + editable=False, + max_length=36, + blank=True, + unique=True, + verbose_name="Bynder asset ID", + ), + ), + ( + "bynder_id_hash", + models.CharField(editable=False, max_length=100, blank=True), + ), + ( + "bynder_original_filename", + models.CharField(editable=False, max_length=255, blank=True), + ), + ( + "bynder_last_modified", + models.DateTimeField(db_index=True, editable=False, null=True), + ), + ( + "description", + models.TextField(blank=True, verbose_name="description"), + ), + ( + "copyright", + models.TextField(blank=True, verbose_name="copyright info"), + ), + ( + "is_archived", + models.BooleanField( + default=False, verbose_name="asset is archived" + ), + ), + ( + "is_limited_use", + models.BooleanField( + default=False, verbose_name="asset is marked as 'limited use'" + ), + ), + ( + "is_public", + models.BooleanField( + default=False, verbose_name="asset is marked as public" + ), + ), + ( + "metadata", + models.JSONField( + blank=True, + default=dict, + encoder=django.core.serializers.json.DjangoJSONEncoder, + verbose_name="additional metadata", + ), + ), + ( + "collection", + models.ForeignKey( + default=wagtail.models.collections.get_root_collection_id, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.collection", + verbose_name="collection", + ), + ), + ( + "tags", + taggit.managers.TaggableManager( + blank=True, + help_text=None, + through="taggit.TaggedItem", + to="taggit.Tag", + verbose_name="tags", + ), + ), + ( + "uploaded_by_user", + models.ForeignKey( + blank=True, + editable=False, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + verbose_name="uploaded by user", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, - bases=(wagtail.images.models.ImageFileMixin, wagtail.search.index.Indexed, models.Model), + bases=( + wagtail.images.models.ImageFileMixin, + wagtail.search.index.Indexed, + models.Model, + ), ), migrations.CreateModel( - name='Video', + name="Video", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('bynder_id', models.CharField(db_index=True, editable=False, max_length=36, null=True, unique=True, verbose_name='Bynder asset ID')), - ('bynder_id_hash', models.CharField(editable=False, max_length=100, null=True)), - ('bynder_original_filename', models.CharField(editable=False, max_length=255, null=True)), - ('bynder_last_modified', models.DateTimeField(db_index=True, editable=False, null=True)), - ('description', models.TextField(blank=True, verbose_name='descripton')), - ('copyright', models.TextField(blank=True, verbose_name='copyright info')), - ('is_archived', models.BooleanField(default=False, verbose_name='asset is archived')), - ('is_limited_use', models.BooleanField(default=False, verbose_name="asset is marked as 'limited use'")), - ('is_public', models.BooleanField(default=False, verbose_name='asset is marked as public')), - ('metadata', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder, verbose_name='additional metadata')), - ('title', models.CharField(max_length=255, verbose_name='title')), - ('created_at', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='created at')), - ('updated_at', models.DateTimeField(auto_now=True, db_index=True, verbose_name='last updated at')), - ('primary_source_url', models.URLField(help_text='A derivative using a WebM container using the VP9 codec for video and the Opus codec for audio. These are all open, royalty-free formats which are generally well-supported, although only in quite recent browsers, which is why a fallback is a good idea.', verbose_name='primary source URL')), - ('fallback_source_url', models.URLField(blank=True, help_text='A derivative using an MP4 container and the AVC (H.264) video codec, ideally with AAC as your audio codec. This is because the MP4 container with AVC and AAC codecs within is a broadly-supported combination—by every major browser, in fact—and the quality is typically good for most use cases.', null=True, verbose_name='fallback source URL')), - ('poster_image_url', models.URLField(verbose_name='poster image URL')), - ('collection', models.ForeignKey(default=wagtail.models.collections.get_root_collection_id, on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.collection', verbose_name='collection')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "bynder_id", + models.CharField( + db_index=True, + editable=False, + max_length=36, + blank=True, + unique=True, + verbose_name="Bynder asset ID", + ), + ), + ( + "bynder_id_hash", + models.CharField(editable=False, max_length=100, blank=True), + ), + ( + "bynder_original_filename", + models.CharField(editable=False, max_length=255, blank=True), + ), + ( + "bynder_last_modified", + models.DateTimeField(db_index=True, editable=False, null=True), + ), + ( + "description", + models.TextField(blank=True, verbose_name="description"), + ), + ( + "copyright", + models.TextField(blank=True, verbose_name="copyright info"), + ), + ( + "is_archived", + models.BooleanField( + default=False, verbose_name="asset is archived" + ), + ), + ( + "is_limited_use", + models.BooleanField( + default=False, verbose_name="asset is marked as 'limited use'" + ), + ), + ( + "is_public", + models.BooleanField( + default=False, verbose_name="asset is marked as public" + ), + ), + ( + "metadata", + models.JSONField( + blank=True, + default=dict, + encoder=django.core.serializers.json.DjangoJSONEncoder, + verbose_name="additional metadata", + ), + ), + ("title", models.CharField(max_length=255, verbose_name="title")), + ( + "created_at", + models.DateTimeField( + auto_now_add=True, db_index=True, verbose_name="created at" + ), + ), + ( + "updated_at", + models.DateTimeField( + auto_now=True, db_index=True, verbose_name="last updated at" + ), + ), + ( + "primary_source_url", + models.URLField( + help_text="A derivative using a WebM container using the VP9 codec for video and the Opus codec for audio. These are all open, royalty-free formats which are generally well-supported, although only in quite recent browsers, which is why a fallback is a good idea.", + verbose_name="primary source URL", + ), + ), + ( + "fallback_source_url", + models.URLField( + blank=True, + help_text="A derivative using an MP4 container and the AVC (H.264) video codec, ideally with AAC as your audio codec. This is because the MP4 container with AVC and AAC codecs within is a broadly-supported combination—by every major browser, in fact—and the quality is typically good for most use cases.", + verbose_name="fallback source URL", + ), + ), + ("poster_image_url", models.URLField(verbose_name="poster image URL")), + ( + "collection", + models.ForeignKey( + default=wagtail.models.collections.get_root_collection_id, + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="wagtailcore.collection", + verbose_name="collection", + ), + ), ], options={ - 'abstract': False, + "abstract": False, }, bases=(wagtail.search.index.Indexed, models.Model), ), migrations.CreateModel( - name='Rendition', + name="Rendition", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('filter_spec', models.CharField(db_index=True, max_length=255)), - ('file', wagtail.images.models.WagtailImageField(height_field='height', storage=wagtail.images.models.get_rendition_storage, upload_to=wagtail.images.models.get_rendition_upload_to, width_field='width')), - ('width', models.IntegerField(editable=False)), - ('height', models.IntegerField(editable=False)), - ('focal_point_key', models.CharField(blank=True, default='', editable=False, max_length=16)), - ('image', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='renditions', to='testapp.customimage')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("filter_spec", models.CharField(db_index=True, max_length=255)), + ( + "file", + wagtail.images.models.WagtailImageField( + height_field="height", + storage=wagtail.images.models.get_rendition_storage, + upload_to=wagtail.images.models.get_rendition_upload_to, + width_field="width", + ), + ), + ("width", models.IntegerField(editable=False)), + ("height", models.IntegerField(editable=False)), + ( + "focal_point_key", + models.CharField( + blank=True, default="", editable=False, max_length=16 + ), + ), + ( + "image", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="renditions", + to="testapp.customimage", + ), + ), ], options={ - 'unique_together': {('image', 'filter_spec', 'focal_point_key')}, + "unique_together": {("image", "filter_spec", "focal_point_key")}, }, bases=(wagtail.images.models.ImageFileMixin, models.Model), ), diff --git a/tests/testapp/models.py b/tests/testapp/models.py index 2371a75..78a19ec 100644 --- a/tests/testapp/models.py +++ b/tests/testapp/models.py @@ -2,7 +2,11 @@ from django.db import models from wagtail.images.models import AbstractRendition -from wagtail_bynder.models import BynderSyncedDocument, BynderSyncedImage, BynderSyncedVideo +from wagtail_bynder.models import ( + BynderSyncedDocument, + BynderSyncedImage, + BynderSyncedVideo, +) class CustomDocument(BynderSyncedDocument): diff --git a/tests/testapp/settings.py b/tests/testapp/settings.py index fbdc70c..f4db547 100644 --- a/tests/testapp/settings.py +++ b/tests/testapp/settings.py @@ -12,6 +12,7 @@ import dj_database_url + env = os.environ.copy() # Build paths inside the project like this: os.path.join(PROJECT_DIR, ...) @@ -22,7 +23,7 @@ # See https://docs.djangoproject.com/en/stable/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = "not-a-secret" +SECRET_KEY = "not-a-secret" # noqa: S105 # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True diff --git a/tests/testapp/urls.py b/tests/testapp/urls.py index 7bdc6ba..1f38909 100644 --- a/tests/testapp/urls.py +++ b/tests/testapp/urls.py @@ -11,5 +11,5 @@ path("admin/", include(wagtailadmin_urls)), path("documents/", include(wagtaildocs_urls)), path("images/", include(wagtailimages_urls)), - path("", include(wagtail_urls)) + path("", include(wagtail_urls)), ] diff --git a/tests/utils.py b/tests/utils.py index 872ff00..57185ba 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,5 +1,6 @@ from datetime import datetime + TEST_ASSET_ID = "1A7BA172-97B9-44A4-8C0AA41D9E8AE6A2"