diff --git a/pretalx_media_ccc_de/forms.py b/pretalx_media_ccc_de/forms.py index 7a6ad5c..ebe6694 100644 --- a/pretalx_media_ccc_de/forms.py +++ b/pretalx_media_ccc_de/forms.py @@ -2,6 +2,8 @@ from django.utils.translation import gettext_lazy as _ from hierarkey.forms import HierarkeyForm +from .models import MediaCccDeLink + class MediaCCCDeSettingsForm(HierarkeyForm): media_ccc_de_id = forms.CharField(required=False) @@ -31,21 +33,31 @@ def __init__(self, *args, event=None, **kwargs): .filter(is_visible=True, submission__isnull=False) .order_by("start") ) + video_data = { + v.submission.code: v.url + for v in MediaCccDeLink.objects.filter(submission__event=event) + } s = _("Go to video.") p = _("Go to talk page.") for talk in self.talks: - initial = event.settings.get(f"media_ccc_de_url_{talk.submission.code}") + link = video_data.get(talk.submission.code) help_text = f'{p}' - if initial: - help_text += f' | {s}' - self.fields[f"media_ccc_de_url_{talk.submission.code}"] = forms.URLField( + if link: + help_text += f' | {s}' + self.fields[f"video_id_{talk.submission.code}"] = forms.URLField( required=False, label=talk.submission.title, widget=forms.URLInput(attrs={"placeholder": ""}), - initial=initial, + initial=link, help_text=help_text, ) def save(self): - for key, value in self.cleaned_data.items(): - self.event.settings.set(key, value) + for talk in self.talks: + url = self.cleaned_data.get(f"video_id_{talk.submission.code}") + if url: + MediaCccDeLink.objects.update_or_create( + submission=talk.submission, defaults={"url": url} + ) + else: + MediaCccDeLink.objects.filter(submission=talk.submission).delete() diff --git a/pretalx_media_ccc_de/migrations/0001_initial.py b/pretalx_media_ccc_de/migrations/0001_initial.py new file mode 100644 index 0000000..ac4bd29 --- /dev/null +++ b/pretalx_media_ccc_de/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.4 on 2023-09-26 14:58 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + ("submission", "0073_track_position"), + ] + + operations = [ + migrations.CreateModel( + name="MediaCccDeLink", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, primary_key=True, serialize=False + ), + ), + ("url", models.URLField(max_length=400)), + ("release_date", models.DateTimeField(blank=True, null=True)), + ("duration_seconds", models.IntegerField(null=True)), + ("thumbnail_url", models.URLField(null=True)), + ( + "submission", + models.OneToOneField( + on_delete=django.db.models.deletion.CASCADE, + related_name="media_ccc_de_link", + to="submission.submission", + ), + ), + ], + ), + ] diff --git a/pretalx_media_ccc_de/migrations/0002_populate_media_ccc_de.py b/pretalx_media_ccc_de/migrations/0002_populate_media_ccc_de.py new file mode 100644 index 0000000..34d0eb6 --- /dev/null +++ b/pretalx_media_ccc_de/migrations/0002_populate_media_ccc_de.py @@ -0,0 +1,35 @@ +# Generated by Django 4.2.4 on 2023-09-26 14:58 +from django.db import migrations + + +def migrate_data(apps, schema_editor): + Event = apps.get_model("event", "Event") + EventSettings = apps.get_model("event", "Event_SettingsStore") + Submission = apps.get_model("submission", "Submission") + MediaCccDeLink = apps.get_model("pretalx_media_ccc_de", "MediaCccDeLink") + for event in Event.objects.all().filter(plugins__contains="pretalx_media_ccc_de"): + settings = { + s.key: s.value + for s in EventSettings.objects.filter( + object=event, key__startswith="media_ccc_de_url_" + ) + } + for key, value in settings.items(): + submission = Submission.objects.filter( + event=event, code=key.split("_")[-1] + ).first() + if submission: + MediaCccDeLink.objects.create(submission=submission, url=value) + + +def delete_all_links(apps, schema_editor): + MediaCccDeLink = apps.get_model("pretalx_media_ccc_de", "MediaCccDeLink") + MediaCccDeLink.objects.all().delete() + + +class Migration(migrations.Migration): + dependencies = [ + ("pretalx_media_ccc_de", "0001_initial"), + ] + + operations = [migrations.RunPython(migrate_data, migrations.RunPython.noop)] diff --git a/pretalx_media_ccc_de/migrations/__init__.py b/pretalx_media_ccc_de/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pretalx_media_ccc_de/models.py b/pretalx_media_ccc_de/models.py new file mode 100644 index 0000000..0a8ae32 --- /dev/null +++ b/pretalx_media_ccc_de/models.py @@ -0,0 +1,28 @@ +from django.db import models + + +class MediaCccDeLink(models.Model): + submission = models.OneToOneField( + to="submission.Submission", + on_delete=models.CASCADE, + related_name="media_ccc_de_link", + ) + url = models.URLField(max_length=400) + release_date = models.DateTimeField(null=True, blank=True) + duration_seconds = models.IntegerField(null=True, blank=True) + thumbnail_url = models.URLField(null=True, blank=True) + + @property + def iframe(self): + return f'
' + + def serialize(self): + return { + "submission": self.submission.code, + "url": self.url, + "release_date": self.release_date.isoformat() + if self.release_date + else None, + "duration_seconds": self.duration_seconds, + "thumbnail_url": self.thumbnail_url, + } diff --git a/pretalx_media_ccc_de/recording.py b/pretalx_media_ccc_de/recording.py index ef91076..a5d7e89 100644 --- a/pretalx_media_ccc_de/recording.py +++ b/pretalx_media_ccc_de/recording.py @@ -8,9 +8,9 @@ def fill_recording_urls(self): task_refresh_recording_urls.apply_async(kwargs={"event_slug": self.event.slug}) def get_recording(self, submission): - path = self.event.settings.get(f"media_ccc_de_url_{submission.code}") - if not path: - return None - iframe = f'
' - csp_header = "https://media.ccc.de" - return {"iframe": iframe, "csp_header": csp_header} + data = getattr(submission, "media_ccc_de_link", None) + if data: + return { + "iframe": data.iframe, + "csp_header": "https://media.ccc.de", + } diff --git a/pretalx_media_ccc_de/tasks.py b/pretalx_media_ccc_de/tasks.py index 3dc6c88..76ea672 100644 --- a/pretalx_media_ccc_de/tasks.py +++ b/pretalx_media_ccc_de/tasks.py @@ -7,6 +7,8 @@ from pretalx.event.models import Event from pretalx.submission.models import Submission +from .models import MediaCccDeLink + @app.task() def task_refresh_recording_urls(event_slug): @@ -27,32 +29,37 @@ def task_refresh_recording_urls(event_slug): return None structure = json.loads(response.content.decode()) - apply_api_response(event=event, response=structure) - - -def apply_api_response(event, response): - for talk in response.get("events", []): - if talk.get("frontend_link"): - submission = None - link = talk.get("link") - if link: - with suppress(Submission.DoesNotExist): - submission = Submission.objects.get( - event=event, - code__iexact=talk["link"] - .rstrip("/") - .rsplit("/", maxsplit=1)[-1], - ) - if not submission: - with suppress(Submission.DoesNotExist): - submission = Submission.objects.get( - event=event, pk__iexact=talk["slug"].split("-")[1] - ) - with suppress(Submission.DoesNotExist): - submission = Submission.objects.get( - event=event, code__iexact=talk["slug"].split("-")[1] - ) + + for api_data in structure.get("events", []): + if not api_data.get("frontend_link"): + continue + + submission = find_submission(event, api_data) if submission: - key = f"media_ccc_de_url_{submission.code}" - if not event.settings.get(key): - event.settings.set(key, talk["frontend_link"]) + MediaCccDeLink.objects.update_or_create( + submission=submission, + defaults={ + "url": api_data["frontend_link"], + "release_date": api_data["release_date"], + "duration_seconds": api_data["duration"], + "thumbnail_url": api_data["poster_url"], + }, + ) + + +def find_submission(event, api_data): + link = api_data.get("link") + if link: + with suppress(Submission.DoesNotExist): + return Submission.objects.get( + event=event, + code__iexact=link.rstrip("/").rsplit("/", maxsplit=1)[-1], + ) + with suppress(Submission.DoesNotExist): + return Submission.objects.get( + event=event, pk__iexact=api_data["slug"].split("-")[1] + ) + with suppress(Submission.DoesNotExist): + return Submission.objects.get( + event=event, code__iexact=api_data["slug"].split("-")[1] + )