class CleanupForm(forms.Form):
zone = forms.ChoiceField(label=_('Nonstop Zone'), choices=get_optional_nonstop_zones)
-
-
-
-def get_optional_jingle():
- return [('', '')] + [(x.id, x.label) for x in Jingle.objects.all()]
-
-
-class AddDiffusionForm(forms.Form):
- jingle = forms.ChoiceField(label=_('Jingle'), choices=get_optional_jingle, required=False)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.29 on 2020-05-16 10:34
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('nonstop', '0018_auto_20200106_1927'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='streameddiffusion',
+ name='added_to_nonstop_timestamp',
+ field=models.DateTimeField(null=True),
+ ),
+ migrations.AddField(
+ model_name='streameddiffusion',
+ name='creation_timestamp',
+ field=models.DateTimeField(auto_now_add=True, null=True),
+ ),
+ migrations.AlterField(
+ model_name='streameddiffusion',
+ name='diffusion',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='emissions.Diffusion'),
+ ),
+ migrations.AlterField(
+ model_name='streameddiffusion',
+ name='stream',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='nonstop.Stream'),
+ ),
+ ]
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
+from django.db.models.signals import post_delete
+from django.dispatch import receiver
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
verbose_name = _('Streamed diffusion')
verbose_name_plural = _('Streamed diffusions')
- diffusion = models.ForeignKey('emissions.Diffusion')
+ diffusion = models.ForeignKey('emissions.Diffusion', null=True, blank=True, on_delete=models.SET_NULL)
jingle = models.ForeignKey(Jingle, null=True, blank=True)
- stream = models.ForeignKey(Stream)
+ stream = models.ForeignKey(Stream, null=True, blank=True)
+ creation_timestamp = models.DateTimeField(auto_now_add=True, null=True)
+ added_to_nonstop_timestamp = models.DateTimeField(null=True)
+
+ @property
+ def datetime(self):
+ return self.diffusion.datetime
+
+ @property
+ def end_datetime(self):
+ return self.diffusion.end_datetime
+
+ @property
+ def episode(self):
+ return self.diffusion.episode
+
+ @property
+ def soma_id(self):
+ if self.is_stream():
+ return '[stream:%s]' % self.id
+ else:
+ return '[sound:%s]' % self.id
+
+ def is_stream(self):
+ return bool(self.stream_id)
+
+
+@receiver(post_delete)
+def remove_soundfile(sender, instance=None, **kwargs):
+ from emissions.models import SoundFile
+ if not issubclass(sender, SoundFile):
+ return
+ StreamedDiffusion.objects.filter(
+ diffusion__episode_id=instance.episode_id,
+ stream_id=None).update(
+ diffusion=None)
{% load l10n nonstop %}
{% localize off %}
<Palinsesto>
- <Description color="#FF0000">{% if streamed_diffusion %}[stream:{{streamed_diffusion.id}}] {% endif %}{{ episode.emission.title|somafix }} - {{ episode.title|somafix }}</Description>
+ <Description color="#FF0000">{{ diffusion.soma_id }} {{ episode.emission.title|somafix }} - {{ episode.title|somafix }}</Description>
<Priority>1</Priority>
<Start>{{ start|date:"Y-m-d x H:i" }}</Start>
<TimeContinued>1</TimeContinued>
<SpotController>0</SpotController>
- {% if streamed_diffusion %}
+ {% if diffusion.is_stream %}
<Type>stream</Type>
- <Stream>{{streamed_diffusion.stream.url}}</Stream>
+ <Stream>{{diffusion.stream.url}}</Stream>
{% else %}
<Type>files</Type>
<Stream></Stream>
<ModuleData></ModuleData>
<Random>0</Random>
- {% if streamed_diffusion %}
+ {% if diffusion.is_stream %}
<SoftStop>0</SoftStop>
{% else %}
<SoftStop>1</SoftStop>
{% load i18n %}
{% block appbar %}
-<h2>{% trans "New Streamed Diffusion" %}</h2>
+<h2>{% trans "Diffusion Details" %}</h2>
{% endblock %}
{% block content %}
from .views import (SomaDayArchiveView, SomaDayArchiveCsvView, RedirectTodayView,
TrackDetailView, ArtistDetailView, ArtistListView, StatisticsView,
UploadTracksView, RecentTracksView, QuickLinksView, SearchView, CleanupView,
- SearchCsvView, AddDiffusionView, AddStreamedDiffusionView,
- DelStreamedDiffusionView,
+ SearchCsvView, AddSomaDiffusionView, DelSomaDiffusionView,
jingle_audio_view)
urlpatterns = [
url(r'^cleanup/$', CleanupView.as_view(), name='nonstop-cleanup'),
# soma management for episodes
- url(r'^diffusion/(?P<pk>\d+)/add/$', AddDiffusionView.as_view(), name='nonstop-add-diffusion'),
- url(r'^diffusion/(?P<pk>\d+)/add-stream/$', AddStreamedDiffusionView.as_view(), name='nonstop-add-streamed-diffusion'),
- url(r'^diffusion/(?P<pk>\d+)/del-stream/$', DelStreamedDiffusionView.as_view(), name='nonstop-del-streamed-diffusion'),
+ url(r'^diffusion/(?P<pk>\d+)/add/$', AddSomaDiffusionView.as_view(), name='nonstop-add-diffusion'),
+ url(r'^diffusion/(?P<pk>\d+)/del/$', DelSomaDiffusionView.as_view(), name='nonstop-del-diffusion'),
url(r'^api/jingle/(?P<pk>\d+)/$', jingle_audio_view),
]
diffusion.datetime.strftime('%Y%m%d-%H%M'),
diffusion.episode.emission.slug)
-def is_already_in_soma(diffusion):
- if StreamedDiffusion.objects.filter(diffusion=diffusion).count():
- return True
- return os.path.exists(os.path.join(LOCAL_BASE_PATH, get_diffusion_file_path(diffusion)))
-class DuplicateDiffusionSlot(Exception):
- pass
+def is_already_in_soma(diffusion):
+ return StreamedDiffusion.objects.filter(diffusion=diffusion).exists()
def soma_connection():
def add_diffusion(diffusion, **kwargs):
context = {}
- streamed_diffusion = StreamedDiffusion.objects.filter(diffusion=diffusion).first()
- if streamed_diffusion:
- # program a stream
- context['streamed_diffusion'] = streamed_diffusion
- context['end'] = diffusion.end_datetime
- context['jingle'] = streamed_diffusion.jingle
- else:
+ context['diffusion'] = diffusion
+ context['jingle'] = diffusion.jingle
+ context['episode'] = diffusion.episode
+ context['start'] = diffusion.datetime
+ context['end'] = diffusion.end_datetime
+
+ if not diffusion.is_stream():
# program a soundfile
soundfile = diffusion.episode.soundfile_set.filter(fragment=False)[0]
diffusion_path = get_diffusion_file_path(diffusion)
# copy file
if not os.path.exists(LOCAL_BASE_PATH):
raise SomaException('soma directory is not available')
- if os.path.exists(os.path.join(LOCAL_BASE_PATH, diffusion_path)):
- raise DuplicateDiffusionSlot()
- os.mkdir(os.path.join(LOCAL_BASE_PATH, diffusion_path))
+ local_diffusion_path = os.path.join(LOCAL_BASE_PATH, diffusion_path)
+ if os.path.exists(local_diffusion_path):
+ for filename in os.listdir(local_diffusion_path):
+ os.unlink(os.path.join(local_diffusion_path, filename))
+ else:
+ os.mkdir(os.path.join(LOCAL_BASE_PATH, diffusion_path))
try:
shutil.copyfile(soundfile.file.path,
os.path.join(LOCAL_BASE_PATH, diffusion_path, os.path.basename(soundfile.file.path)))
context['end'] = diffusion.datetime + datetime.timedelta(seconds=
max(((soundfile.duration or 480) - 180), 60))
- if kwargs.get('jingle_id'):
- context['jingle'] = Jingle.objects.get(id=kwargs['jingle_id'])
-
# create palinsesti
palinsesti_template = loader.get_template('nonstop/soma_palinsesti.xml')
- context['episode'] = diffusion.episode
- context['start'] = diffusion.datetime
palinsesti = palinsesti_template.render(context)
+ open('/tmp/soma.xml', 'w').write(palinsesti)
+ return
palinsesti_xml = ET.fromstring(palinsesti.encode('utf-8'))
palinsesto_xml = get_palinsesto_xml()
send_palinsesto_xml(palinsesto_xml)
-def remove_streamed_diffusion(streamed_diffusion):
+def remove_soma_diffusion(diffusion):
palinsesto_xml = get_palinsesto_xml()
- stream_marker = '[stream:%s]' % streamed_diffusion.id
for palinsesto in palinsesto_xml.findall('Palinsesto'):
- if palinsesto.findall('Description')[0].text.startswith(stream_marker):
+ if palinsesto.findall('Description')[0].text.startswith(diffusion.soma_id):
palinsesto_xml.remove(palinsesto)
send_palinsesto_xml(palinsesto_xml)
from django.views.generic.edit import CreateView, FormView
from django.views.generic.list import ListView
-from .forms import UploadTracksForm, TrackMetaForm, TrackSearchForm, CleanupForm, AddDiffusionForm
-from .models import SomaLogLine, Track, Artist, NonstopFile, StreamedDiffusion, Jingle, Stream, LOCAL_BASE_PATH
+from .forms import UploadTracksForm, TrackMetaForm, TrackSearchForm, CleanupForm
+from .models import (SomaLogLine, Track, Artist, NonstopFile, StreamedDiffusion, Jingle,
+ Stream, LOCAL_BASE_PATH)
from emissions.models import Nonstop, Diffusion
from . import utils
return HttpResponseRedirect('.')
-class AddDiffusionView(FormView):
- template_name = 'nonstop/add-diffusion.html'
- form_class = AddDiffusionForm
-
- def get_initial(self):
- initial = super(AddDiffusionView, self).get_initial()
- jingle = Jingle.objects.filter(default_for_initial_diffusions=True).first()
- if jingle:
- initial['jingle'] = jingle.id
- return initial
-
- def form_valid(self, form):
- diffusion = Diffusion.objects.get(id=self.kwargs['pk'])
- episode = diffusion.episode
- try:
- utils.add_diffusion(diffusion, jingle_id=form.cleaned_data.get('jingle'))
- except utils.DuplicateDiffusionSlot:
- messages.error(self.request, _('soma slot already in use, the diffusion could not be added.'))
- except utils.SomaException as e:
- messages.error(self.request, _('technical soma error (%s)') % e)
- else:
- messages.info(self.request, _('%s added to soma') % episode.emission.title)
-
- return super(AddDiffusionView, self).form_valid(form)
-
- def get_success_url(self):
- diffusion = Diffusion.objects.get(id=self.kwargs['pk'])
- episode = diffusion.episode
- return reverse('episode-view', kwargs={
- 'emission_slug': episode.emission.slug,
- 'slug': episode.slug})
-
-
-
-class AddStreamedDiffusionView(CreateView):
+class AddSomaDiffusionView(CreateView):
model = StreamedDiffusion
fields = ['jingle', 'stream']
template_name = 'nonstop/streamed-diffusion.html'
+ @property
+ def fields(self):
+ diffusion = Diffusion.objects.get(id=self.kwargs['pk'])
+ fields = ['jingle']
+ if not diffusion.episode.soundfile_set.filter(fragment=False).exists():
+ fields.append('stream')
+ return fields
+
def get_initial(self):
- initial = super(AddStreamedDiffusionView, self).get_initial()
+ initial = super(AddSomaDiffusionView, self).get_initial()
initial['jingle'] = Jingle.objects.filter(default_for_streams=True).first()
initial['stream'] = Stream.objects.all().first()
return initial
def form_valid(self, form):
form.instance.diffusion_id = self.kwargs['pk']
- response = super(AddStreamedDiffusionView, self).form_valid(form)
episode = form.instance.diffusion.episode
+ if 'stream' in self.fields and form.instance.stream_id is None:
+ messages.error(self.request, _('missing stream'))
+ return HttpResponseRedirect(reverse('episode-view', kwargs={
+ 'emission_slug': episode.emission.slug,
+ 'slug': episode.slug}))
+ response = super(AddSomaDiffusionView, self).form_valid(form)
try:
- utils.add_diffusion(form.instance.diffusion)
+ utils.add_diffusion(form.instance)
except utils.SomaException as e:
messages.error(self.request, _('technical soma error (%s)') % e)
else:
'slug': episode.slug})
-class DelStreamedDiffusionView(RedirectView):
+class DelSomaDiffusionView(RedirectView):
def get_redirect_url(self, pk):
- diffusion = Diffusion.objects.get(id=pk)
- streamed_diffusion = diffusion.streameddiffusion_set.first()
- utils.remove_streamed_diffusion(streamed_diffusion)
- streamed_diffusion.delete()
- episode = diffusion.episode
+ soma_diffusion = StreamedDiffusion.objects.filter(diffusion_id=pk).first()
+ episode = soma_diffusion.episode
+ StreamedDiffusion.objects.filter(diffusion_id=pk).delete()
return reverse('episode-view', kwargs={
'emission_slug': episode.emission.slug,
'slug': episode.slug})