From 88620b99af6025dd9efa90caee9c4a96a97aa666 Mon Sep 17 00:00:00 2001 From: Jan Koppe Date: Sun, 31 May 2020 12:16:09 +0200 Subject: [PATCH] dynamically update tasks on saved changes to restream configs --- concierge/admin.py | 2 +- concierge/migrations/0006_task_config_id.py | 19 ++++++++++ concierge/models.py | 1 + restream/models.py | 10 ++++++ restream/signals.py | 34 ++++++++++++------ rtmp/migrations/0005_auto_20200531_0951.py | 39 +++++++++++++++++++++ 6 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 concierge/migrations/0006_task_config_id.py create mode 100644 rtmp/migrations/0005_auto_20200531_0951.py diff --git a/concierge/admin.py b/concierge/admin.py index 887586f..6eb526d 100644 --- a/concierge/admin.py +++ b/concierge/admin.py @@ -7,7 +7,7 @@ class IdentityAdmin(admin.ModelAdmin): class TaskAdmin(admin.ModelAdmin): - fields = ['stream', 'type', 'configuration', 'claimed_by'] + fields = ['stream', 'type', 'config_id', 'configuration', 'claimed_by'] admin.site.register(Identity, IdentityAdmin) diff --git a/concierge/migrations/0006_task_config_id.py b/concierge/migrations/0006_task_config_id.py new file mode 100644 index 0000000..9fea2c7 --- /dev/null +++ b/concierge/migrations/0006_task_config_id.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.6 on 2020-05-31 09:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('concierge', '0005_auto_20200426_2007'), + ] + + operations = [ + migrations.AddField( + model_name='task', + name='config_id', + field=models.IntegerField(default=0), + preserve_default=False, + ), + ] diff --git a/concierge/models.py b/concierge/models.py index c809964..4944f5c 100644 --- a/concierge/models.py +++ b/concierge/models.py @@ -21,5 +21,6 @@ class Task(models.Model): uuid = models.UUIDField(unique=True, default=uuid.uuid4) stream = models.ForeignKey(Stream, on_delete=models.CASCADE) type = models.CharField(max_length=100) + config_id = models.IntegerField() configuration = models.TextField() claimed_by = models.ForeignKey(Identity, null=True, blank=True, on_delete=models.CASCADE) diff --git a/restream/models.py b/restream/models.py index 0f7682f..3f20fa2 100644 --- a/restream/models.py +++ b/restream/models.py @@ -3,6 +3,7 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.db.models.signals import pre_delete from portier.common import handlers +import json from rtmp.models import Stream @@ -26,5 +27,14 @@ class RestreamConfig(models.Model): def __str__(self): return '{} to {}'.format(self.stream, self.name) + def get_json_config(self): + config = { + 'name': self.name, + 'app': self.stream.application.name, + 'stream': str(self.stream.stream), + 'target': self.target + } + return json.dumps(config) + pre_delete.connect(handlers.remove_obj_perms_connected_with_user, sender=RestreamConfig) diff --git a/restream/signals.py b/restream/signals.py index fba6a33..0ba466a 100644 --- a/restream/signals.py +++ b/restream/signals.py @@ -1,23 +1,35 @@ from django.dispatch import receiver +from django.db.models.signals import post_save from rtmp.signals import stream_active from .models import RestreamConfig from rtmp.models import Stream from concierge.models import Task -import json @receiver(stream_active) def create_tasks(sender, **kwargs): stream = Stream.objects.get(stream=kwargs['stream']) instances = RestreamConfig.objects.filter(active=True, stream=stream) - for inst in instances: - config = { - 'name': inst.name, - 'app': inst.stream.application.name, - 'stream': str(inst.stream.stream), - 'target': inst.target - } - - json_config = json.dumps(config) - task = Task(stream=stream, type='restream', configuration=json_config) + for instance in instances: + task = Task(stream=instance.stream, type='restream', config_id=instance.id, + configuration=instance.get_json_config()) + task.save() + + +@receiver(post_save, sender=RestreamConfig) +def update_tasks(sender, **kwargs): + instance = kwargs['instance'] + # TODO: check for breaking changes using update_fields. This needs custom save_model functions though. + + # Get the current task instance if it exists, and remove it + try: + task = Task.objects.filter(config_id=instance.id).get() + task.delete() + except Task.DoesNotExist: + pass + + # If the configuration is set to be active, and the stream is published, (re)create new task + if instance.active and instance.stream.publish_counter > 0: + task = Task(stream=instance.stream, type='restream', config_id=instance.id, + configuration=instance.get_json_config()) task.save() diff --git a/rtmp/migrations/0005_auto_20200531_0951.py b/rtmp/migrations/0005_auto_20200531_0951.py new file mode 100644 index 0000000..a104ce3 --- /dev/null +++ b/rtmp/migrations/0005_auto_20200531_0951.py @@ -0,0 +1,39 @@ +# Generated by Django 3.0.6 on 2020-05-31 09:51 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('rtmp', '0004_auto_20200501_1302'), + ] + + operations = [ + migrations.AlterModelOptions( + name='application', + options={'verbose_name': 'RTMP application', 'verbose_name_plural': 'RTMP applications'}, + ), + migrations.AlterField( + model_name='application', + name='name', + field=models.CharField(help_text='RTMP application name', max_length=100, unique=True), + ), + migrations.AlterField( + model_name='stream', + name='application', + field=models.ForeignKey(help_text='Application which the stream is assigned to', on_delete=django.db.models.deletion.CASCADE, to='rtmp.Application'), + ), + migrations.AlterField( + model_name='stream', + name='name', + field=models.CharField(help_text='Name for this stream', max_length=100), + ), + migrations.AlterField( + model_name='stream', + name='stream', + field=models.UUIDField(default=uuid.uuid4, help_text='Stream ID for this stream', unique=True), + ), + ]