merge diffusions and episode, work on different fixes, duration are timefield, make it work

This commit is contained in:
bkfox
2015-11-22 23:24:19 +01:00
parent 44fc4dae31
commit 25e3d4cb53
10 changed files with 357 additions and 189 deletions

View File

@ -3,15 +3,84 @@ Control Liquidsoap
"""
import os
import re
import datetime
import collections
from argparse import RawTextHelpFormatter
from django.core.management.base import BaseCommand, CommandError
from django.views.generic.base import View
from django.template.loader import render_to_string
from django.utils import timezone as tz
import aircox_liquidsoap.settings as settings
import aircox_liquidsoap.utils as utils
import aircox_programs.models as models
class DiffusionInfo:
date = None
original = None
sounds = None
duration = 0
def __init__ (self, diffusion):
episode = diffusion.episode
self.original = diffusion
self.sounds = [ sound for sound in episode.sounds
if sound.type = models.Sound.Type['archive'] ]
self.sounds.sort(key = 'path')
self.date = diffusion.date
self.duration = episode.get_duration()
self.end = self.date + tz.datetime.timedelta(seconds = self.duration)
def __eq___ (self, info):
return self.original.id == info.original.id
class ControllerMonitor:
current = None
queue = None
def get_next (self, controller):
upcoming = models.Diffusion.get_next(
station = controller.station,
# diffusion__episode__not blank
# diffusion__episode__sounds not blank
)
return Monitor.Info(upcoming[0]) if upcoming else None
def playlist (self, controller):
dealer = controller.dealer
on_air = dealer.current_sound
playlist = dealer.playlist
next = self.queue[0]
# last track: time to reload playlist
if on_air == playlist[-1] or on_air not in playlist:
dealer.playlist = [sound.path for sound in next.sounds]
dealer.on = False
def current (self, controller):
# time to switch...
if on_air not in self.current.sounds:
self.current = self.queue.popleft()
if self.current.date <= tz.datetime.now() and not dealer.on:
dealer.on = True
print('start ', self.current.original)
# HERE
upcoming = self.get_next(controller)
if upcoming.date <= tz.datetime.now() and not self.current:
self.current = upcoming
if not self.upcoming or upcoming != self.upcoming:
dealer.playlist = [sound.path for sound in upcomming.sounds]
dealer.on = False
self.upcoming = upcoming
class Command (BaseCommand):
@ -24,8 +93,29 @@ class Command (BaseCommand):
'-o', '--on_air', action='store_true',
help='Print what is on air'
)
parser.add_argument(
'-m', '--monitor', action='store_true',
help='Runs in monitor mode'
)
parser.add_argument(
'-s', '--sleep', type=int,
default=1,
help='Time to sleep before update'
)
# start and run liquidsoap
def handle (self, *args, **options):
controller = utils.Controller()
controller.get()
connector = utils.Connector()
self.monitor = utils.Monitor()
self.monitor.update()
if options.get('on_air'):
for id, controller in self.monitor.controller.items():
print(id, controller.master.current_sound())
if options.get('monitor'):
sleep =

View File

@ -16,7 +16,6 @@ import aircox_programs.settings as programs_settings
import aircox_programs.models as models
class Command (BaseCommand):
help= __doc__
output_dir = settings.AIRCOX_LIQUIDSOAP_MEDIA

View File

@ -5,6 +5,7 @@ import json
from django.utils.translation import ugettext as _, ugettext_lazy
from aircox_programs.utils import to_timedelta
import aircox_programs.models as models
import aircox_liquidsoap.settings as settings
@ -25,7 +26,8 @@ class Connector:
return self.__available
def __init__ (self, address = None):
self.address = address
if address:
self.address = address
def open (self):
if self.__available:
@ -145,7 +147,8 @@ class Source:
@property
def playlist (self):
"""
The playlist as an array
Get or set the playlist as an array, and update it into
the corresponding file.
"""
try:
with open(self.path, 'r') as file:
@ -159,6 +162,12 @@ class Source:
file.write('\n'.join(sounds))
self.connector.send(self.name, '_playlist.reload')
@property
def current_sound (self):
self.update()
self.metadata['initial_uri']
def stream_info (self):
"""
Return a dict with info related to the program's stream
@ -221,12 +230,18 @@ class Dealer (Source):
diffusions = models.Diffusion.get_next(self.station)
if not diffusions.count():
return
diffusion = diffusions[0]
return diffusion
def on_air (self, value = True):
pass
@property
def on (self):
r = self.connector.send('var.get ', self.id, '_on')
return (r == 'true')
@on.setter
def on (self, value):
return self.connector.send('var.set ', self.id, '_on',
'=', 'true' if value else 'false')
@property
def playlist (self):
@ -242,6 +257,46 @@ class Dealer (Source):
file.write('\n'.join(sounds))
def __get_queue (self, date):
"""
Return a list of diffusion candidates of being running right now.
Add an attribute "sounds" with the episode's archives.
"""
r = [ models.Diffusion.get_prev(self.station, date),
models.Diffusion.get_next(self.station, date) ]
r = [ diffusion.prefetch_related('episode__sounds')[0]
for diffusion in r if diffusion.count() ]
for diffusion in r:
setattr(diffusion, 'sounds',
[ sound.path for sound in diffusion.get_sounds() ])
return r
def __what_now (self, date, on_air, queue):
"""
Return which diffusion is on_air from the given queue
"""
for diffusion in queue:
duration = diffusion.archives_duration()
end_at = diffusion.date + tz.timedelta(seconds = diffusion.archives_duration())
if end_at < date:
continue
if diffusion.sounds and on_air in diffusion.sounds:
return diffusion
def monitor (self):
"""
Monitor playlist (if it is time to load) and if it time to trigger
the button to start a diffusion.
"""
on_air = self.current_soudn
playlist = self.playlist
queue = self.__get_queue()
current_diffusion = self.__what_now()
class Controller:
connector = None
station = None # the related station