From 35c6c2f590d9dbc05016208d949ccb5846f27740 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Fri, 15 May 2020 16:46:29 +0200 Subject: [PATCH] Add multiple cards. --- .gitignore | 1 + src/youtube/admin.py | 10 ++++- .../migrations/0005_auto_20200515_1634.py | 37 ++++++++++++++++ src/youtube/migrations/0006_move_cards.py | 38 ++++++++++++++++ .../migrations/0007_auto_20200515_1645.py | 29 +++++++++++++ src/youtube/models.py | 43 ++++++++++--------- 6 files changed, 136 insertions(+), 22 deletions(-) create mode 100644 src/youtube/migrations/0005_auto_20200515_1634.py create mode 100644 src/youtube/migrations/0006_move_cards.py create mode 100644 src/youtube/migrations/0007_auto_20200515_1645.py diff --git a/.gitignore b/.gitignore index 4078890..c2357e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*~ *.pyc *.sqlite localsettings.py diff --git a/src/youtube/admin.py b/src/youtube/admin.py index e6fe370..4069b61 100644 --- a/src/youtube/admin.py +++ b/src/youtube/admin.py @@ -2,4 +2,12 @@ from django.contrib import admin from . import models -admin.site.register(models.YouTube) +class CardInline(admin.TabularInline): + model = models.Card + + +class YouTubeAdmin(admin.ModelAdmin): + inlines = [CardInline] + + +admin.site.register(models.YouTube, YouTubeAdmin) diff --git a/src/youtube/migrations/0005_auto_20200515_1634.py b/src/youtube/migrations/0005_auto_20200515_1634.py new file mode 100644 index 0000000..232c36e --- /dev/null +++ b/src/youtube/migrations/0005_auto_20200515_1634.py @@ -0,0 +1,37 @@ +# Generated by Django 3.0.4 on 2020-05-15 16:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('youtube', '0004_auto_20200504_1148'), + ] + + operations = [ + migrations.RenameField( + model_name='youtube', + old_name='card', + new_name='loop_card', + ), + migrations.AddField( + model_name='youtube', + name='thumbnail_definition', + field=models.TextField(blank=True), + ), + migrations.CreateModel( + name='Card', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('order', models.SmallIntegerField()), + ('image', models.FileField(upload_to='youtube/card')), + ('duration', models.FloatField()), + ('youtube', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='youtube.YouTube')), + ], + options={ + 'ordering': ('order',), + }, + ), + ] diff --git a/src/youtube/migrations/0006_move_cards.py b/src/youtube/migrations/0006_move_cards.py new file mode 100644 index 0000000..59466ce --- /dev/null +++ b/src/youtube/migrations/0006_move_cards.py @@ -0,0 +1,38 @@ +# Generated by Django 3.0.4 on 2020-05-15 16:34 + +from django.db import migrations + + +def move_cards(apps, schema_editor): + YouTube = apps.get_model('youtube', 'YouTube') + Card = apps.get_model('youtube', 'Card') + for yt in YouTube.objects.all(): + if yt.intro_card: + Card.objects.create( + youtube=yt, + image=yt.intro_card, + duration=yt.intro_card_duration or 0, + order=-1 + ) + if yt.outro_card: + Card.objects.create( + youtube=yt, + image=yt.outro_card, + duration=yt.outro_card_duration or 0, + order=1 + ) + yt.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('youtube', '0005_auto_20200515_1634'), + ] + + operations = [ + migrations.RunPython( + move_cards, + migrations.RunPython.noop, + ) + ] diff --git a/src/youtube/migrations/0007_auto_20200515_1645.py b/src/youtube/migrations/0007_auto_20200515_1645.py new file mode 100644 index 0000000..80ffa9b --- /dev/null +++ b/src/youtube/migrations/0007_auto_20200515_1645.py @@ -0,0 +1,29 @@ +# Generated by Django 3.0.4 on 2020-05-15 16:45 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('youtube', '0006_move_cards'), + ] + + operations = [ + migrations.RemoveField( + model_name='youtube', + name='intro_card', + ), + migrations.RemoveField( + model_name='youtube', + name='intro_card_duration', + ), + migrations.RemoveField( + model_name='youtube', + name='outro_card', + ), + migrations.RemoveField( + model_name='youtube', + name='outro_card_duration', + ), + ] diff --git a/src/youtube/models.py b/src/youtube/models.py index 9857233..30b3006 100644 --- a/src/youtube/models.py +++ b/src/youtube/models.py @@ -18,13 +18,10 @@ class YouTube(models.Model): title_template = models.CharField(max_length=1024, blank=True) description_template = models.TextField(blank=True) category = models.IntegerField(null=True, blank=True) # get categories - intro_card = models.FileField(upload_to='youtube/intro_card', blank=True) - intro_card_duration = models.FloatField(null=True, blank=True) - card = models.FileField(upload_to='youtube/card', blank=True) + loop_card = models.FileField(upload_to='youtube/card', blank=True) loop_video = models.FileField(upload_to='youtube/loop_video', blank=True) - outro_card = models.FileField(upload_to='youtube/outro_card', blank=True) - outro_card_duration = models.FloatField(null=True, blank=True) thumbnail_template = models.FileField(upload_to='youtube/thumbnail', blank=True) + thumbnail_definition = models.TextField(blank=True) genres = models.CharField(max_length=2048, blank=True) class Meta: @@ -78,6 +75,7 @@ class YouTube(models.Model): def prepare_video(self, duration): concat = [] + outro = [] delete = [] if self.loop_video: @@ -86,34 +84,27 @@ class YouTube(models.Model): fps = 25 loop_duration = duration - if self.intro_card and self.intro_card_duration: - loop_duration -= self.intro_card_duration - intro = video_from_image( - self.intro_card.path, self.intro_card_duration, fps=fps + for card in self.card_set.filter(order__lt=0, duration__gt=0): + loop_duration -= card.duration + card_video = video_from_image( + card.image.path, card.duration, fps=fps ) - concat.append(intro) + (concat if card.order < 0 else outro).append(card_video) delete.append(intro) - if self.outro_card and self.outro_card_duration: - loop_duration -= self.outro_card_duration - outro = video_from_image( - self.outro_card.path, self.outro_card_duration, fps=fps - ) - concat.append(outro) - delete.append(outro) - if self.loop_video: loop_video_duration = get_duration(self.loop_video.path) times_loop = int(loop_duration // loop_video_duration) leftover_duration = loop_duration % loop_video_duration leftover = cut_video(self.loop_video.path, leftover_duration) - concat[1:1] = [self.loop_video.path] * times_loop + [leftover] + concat.extend([self.loop_video.path] * times_loop + [leftover]) delete.append(leftover) else: - leftover = video_from_image(self.card.path, loop_duration) - concat.insert(1, video_from_image(self.card.path, loop_duration, fps=fps)) + leftover = video_from_image(self.loop_card.path, loop_duration) + concat.append(video_from_image(self.loop_card.path, loop_duration, fps=fps)) delete.append(leftover) + concat.extend(outro) output = concat_videos(concat) for p in delete: @@ -123,3 +114,13 @@ class YouTube(models.Model): # tags # license # selfDeclaredMadeForKids + + +class Card(models.Model): + youtube = models.ForeignKey(YouTube, models.CASCADE) + order = models.SmallIntegerField() + image = models.FileField(upload_to='youtube/card') + duration = models.FloatField() + + class Meta: + ordering = ('order', ) -- 2.20.1