merge diffusions and episode, work on different fixes, duration are timefield, make it work
This commit is contained in:
@ -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 =
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user