diff --git a/application/models/Schedule.php b/application/models/Schedule.php index 1bff6cf76..5fe66f2ca 100644 --- a/application/models/Schedule.php +++ b/application/models/Schedule.php @@ -733,7 +733,8 @@ class Schedule { } $result = array(); - $result['status'] = array('range' => array('start' => $range_start, 'end' => $range_end), 'version' => "1.1"); + $result['status'] = array('range' => array('start' => $range_start, 'end' => $range_end), + 'version' => "1.1"); $result['playlists'] = $playlists; $result['check'] = 1; diff --git a/pypo/api_clients/api_client.py b/pypo/api_clients/api_client.py index 5fd04b522..6994cf3fd 100644 --- a/pypo/api_clients/api_client.py +++ b/pypo/api_clients/api_client.py @@ -115,7 +115,6 @@ class AirTimeApiClient(ApiClientInterface): url = url.replace("%%api_key%%", self.config["api_key"]) try: - logger.debug("Trying to contact %s", url) response = urllib.urlopen(url) data = response.read() logger.debug("Data: %s", data) @@ -278,7 +277,7 @@ class AirTimeApiClient(ApiClientInterface): logger.info("API-Message %s", response['message']) except Exception, e: - logger.critical("Unable to connect - %s", e) + logger.error("Unable to connect - %s", e) return response @@ -304,7 +303,7 @@ class AirTimeApiClient(ApiClientInterface): logger.info("API-Message %s", response['message']) except Exception, e: - logger.critical("Exception: %s", e) + logger.error("Exception: %s", e) return response @@ -475,7 +474,7 @@ class ObpApiClient(): except Exception, e: print e api_status = False - logger.critical("Unable to connect to the OBP API - %s", e) + logger.error("Unable to connect to the OBP API - %s", e) return response @@ -510,7 +509,7 @@ class ObpApiClient(): except Exception, e: print e api_status = False - logger.critical("Unable to connect to the OBP API - %s", e) + logger.error("Unable to connect to the OBP API - %s", e) return response @@ -530,7 +529,7 @@ class ObpApiClient(): except Exception, e: print e api_status = False - logger.critical("Unable to handle the OBP API request - %s", e) + logger.error("Unable to handle the OBP API request - %s", e) return response diff --git a/pypo/config.cfg b/pypo/config.cfg index cbe7f38d7..638558fbf 100644 --- a/pypo/config.cfg +++ b/pypo/config.cfg @@ -42,7 +42,7 @@ cache_for = 24 #how long to hold the cache, in hours # the time you expect to "lock-in" your schedule. So if your schedule is set # 24 hours in advance, this can be set to poll every 12 hours. # -poll_interval = 30 # in seconds. +poll_interval = 5 # in seconds. # Push interval in seconds. @@ -52,7 +52,7 @@ poll_interval = 30 # in seconds. # # It's hard to imagine a situation where this should be more than 1 second. # -push_interval = 1 # in seconds +push_interval = 2 # in seconds # 'pre' or 'otf'. 'pre' cues while playlist preparation # while 'otf' (on the fly) cues while loading into ls diff --git a/pypo/install/pypo-uninstall.py b/pypo/install/pypo-uninstall.py index 3d698faac..0b225cc7e 100644 --- a/pypo/install/pypo-uninstall.py +++ b/pypo/install/pypo-uninstall.py @@ -15,7 +15,7 @@ def remove_path(path): os.system("rm -rf " + path) def remove_user(username): - os.system("killall -u " + username) + os.system("killall -u %s 2>&1 1>/dev/null" % username) #allow all process to be completely closed before we attempt to delete user print "Waiting for processes to close..." diff --git a/pypo/pypo-cli.py b/pypo/pypo-cli.py index 7a27b13be..3c0402908 100755 --- a/pypo/pypo-cli.py +++ b/pypo/pypo-cli.py @@ -67,8 +67,7 @@ logging.config.fileConfig("logging.cfg") try: config = ConfigObj('config.cfg') POLL_INTERVAL = float(config['poll_interval']) - PUSH_INTERVAL = 0.5 - #PUSH_INTERVAL = float(config['push_interval']) + PUSH_INTERVAL = float(config['push_interval']) LS_HOST = config['ls_host'] LS_PORT = config['ls_port'] except Exception, e: diff --git a/pypo/pypofetch.py b/pypo/pypofetch.py index d1665ae3e..aaeda54f5 100644 --- a/pypo/pypofetch.py +++ b/pypo/pypofetch.py @@ -91,14 +91,15 @@ class PypoFetch: tn = telnetlib.Telnet(LS_HOST, LS_PORT) - #encode in latin-1 due to this bug: http://bugs.python.org/issue1772794 + #encode in latin-1 due to telnet protocol not supporting utf-8 tn.write(('vars.stream_metadata_type %s\n' % stream_metadata['format']).encode('latin-1')) tn.write(('vars.station_name %s\n' % stream_metadata['station_name']).encode('latin-1')) + tn.write('exit\n') logger.debug(tn.read_all()) except Exception, e: - logger.critical("Exception %s", e) + logger.error("Exception %s", e) status = 0 return status diff --git a/pypo/pypopush.py b/pypo/pypopush.py index 6da24da72..266443b8f 100644 --- a/pypo/pypopush.py +++ b/pypo/pypopush.py @@ -36,8 +36,8 @@ class PypoPush: gives the number of seconds of the window of opportunity for the scheduler to catch when a playlist is to be played. """ - self.push_ahead = 15 - self.push_ahead2 = 10 + self.push_ahead = 10 + self.push_ahead2 = self.push_ahead -5 def set_export_source(self, export_source): self.export_source = export_source @@ -59,23 +59,30 @@ class PypoPush: tcoming = time.localtime(time.time() + self.push_ahead) tcoming2 = time.localtime(time.time() + self.push_ahead2) - tnow = time.localtime(time.time()) + str_tcoming_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming[0], tcoming[1], tcoming[2], tcoming[3], tcoming[4], tcoming[5]) str_tcoming2_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tcoming2[0], tcoming2[1], tcoming2[2], tcoming2[3], tcoming2[4], tcoming2[5]) + currently_on_air = False if self.schedule == None: logger.warn('Unable to loop schedule - maybe write in progress?') logger.warn('Will try again in next loop.') else: for pkey in self.schedule: + plstart = pkey[0:19] + start = self.schedule[pkey]['start'] + end = self.schedule[pkey]['end'] + playedFlag = (pkey in playedItems) and playedItems[pkey].get("played", 0) - if pkey[0:19] == str_tcoming_s or (pkey[0:19] < str_tcoming_s and pkey[0:19] > str_tcoming2_s and not playedFlag): + + if plstart == str_tcoming_s or (plstart < str_tcoming_s and plstart > str_tcoming2_s and not playedFlag): logger.debug('Preparing to push playlist scheduled at: %s', pkey) playlist = self.schedule[pkey] ptype = playlist['subtype'] + currently_on_air = True # We have a match, replace the current playlist and # force liquidsoap to refresh. @@ -95,6 +102,23 @@ class PypoPush: logger.debug("Doing callback to server to update 'played' status.") self.api_client.notify_scheduled_item_start_playing(pkey, self.schedule) + if self.schedule != None: + tnow = time.localtime(time.time()) + str_tnow_s = "%04d-%02d-%02d-%02d-%02d-%02d" % (tnow[0], tnow[1], tnow[2], tnow[3], tnow[4], tnow[5]) + for pkey in self.schedule: + start = self.schedule[pkey]['start'] + end = self.schedule[pkey]['end'] + + if start <= str_tnow_s and str_tnow_s < end: + currently_on_air = True + + if not currently_on_air: + tn = telnetlib.Telnet(LS_HOST, LS_PORT) + tn.write('source.skip\n'.encode('latin-1')) + tn.write('exit\n') + tn.read_all() + #logger.info('source.skip') + #logger.debug(tn.read_all()) def push_liquidsoap(self, pkey, schedule, ptype): logger = logging.getLogger() diff --git a/pypo/scripts/ls_lib.liq b/pypo/scripts/ls_lib.liq index f9cfd58ce..27ed94f06 100644 --- a/pypo/scripts/ls_lib.liq +++ b/pypo/scripts/ls_lib.liq @@ -42,8 +42,19 @@ end def add_skip_command(s) # A command to skip def skip(_) - source.skip(s) - "Done!" + # get playing (active) queue and flush it + l = list.hd(server.execute("queue.secondary_queue")) + l = string.split(separator=" ",l) + list.iter(fun (rid) -> ignore(server.execute("queue.ignore #{rid}")), l) + + l = list.hd(server.execute("queue.primary_queue")) + l = string.split(separator=" ", l) + if list.length(l) > 0 then + source.skip(s) + "Skipped" + else + "Not skipped" + end end # Register the command: server.register(namespace="source", diff --git a/pypo/scripts/ls_script.liq b/pypo/scripts/ls_script.liq index 571a00b25..a35495839 100644 --- a/pypo/scripts/ls_script.liq +++ b/pypo/scripts/ls_script.liq @@ -4,8 +4,9 @@ set("log.file.path", log_file) set("log.stdout", true) set("server.telnet", true) +set("server.telnet.port", 1234) -queue = request.queue(id="queue", conservative=true) +queue = request.queue(id="queue", length=0.5) queue = audio_to_stereo(queue) pypo_data = ref '0' @@ -31,22 +32,22 @@ s = fallback(track_sensitive=false, [queue, default]) s = on_metadata(notify, s) s = crossfade(s) # Attach a skip command to the source s: -add_skip_command(s) -web_stream_source = input.http(id="web_stream", autostart = false, buffer=0.5, max=20., "") +#web_stream_source = input.http(id="web_stream", autostart = false, buffer=0.5, max=20., "") #once the stream is started, give it a sink so that liquidsoap doesn't #create buffer overflow warnings in the log file. -output.dummy(fallible=true, web_stream_source) +#output.dummy(fallible=true, web_stream_source) -s = switch(track_sensitive = false, - transitions=[to_live,to_live], - [ - ({ !web_stream_enabled }, web_stream_source), - ({ true }, s) - ] -) +#s = switch(track_sensitive = false, +# transitions=[to_live,to_live], +# [ +# ({ !web_stream_enabled }, web_stream_source), +# ({ true }, s) +# ] +#) +add_skip_command(s) s = map_metadata(append_title, s)