Merge branch '2.4.x' into 2.4.x-saas
Conflicts: python_apps/pypo/liquidsoap_scripts/ls_script.liq utils/phone_home_stat.php
This commit is contained in:
commit
f2d5fa96da
114 changed files with 9850 additions and 9170 deletions
|
@ -138,8 +138,8 @@ class ApiRequest(object):
|
|||
content_type = f.info().getheader('Content-Type')
|
||||
response = f.read()
|
||||
except Exception, e:
|
||||
self.logger.error('Exception: %s', e)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
#self.logger.error('Exception: %s', e)
|
||||
#self.logger.error("traceback: %s", traceback.format_exc())
|
||||
raise
|
||||
|
||||
try:
|
||||
|
@ -149,8 +149,8 @@ class ApiRequest(object):
|
|||
else:
|
||||
raise InvalidContentType()
|
||||
except Exception:
|
||||
self.logger.error(response)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
#self.logger.error(response)
|
||||
#self.logger.error("traceback: %s", traceback.format_exc())
|
||||
raise
|
||||
|
||||
def req(self, *args, **kwargs):
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: airtime-media-monitor
|
||||
# Required-Start: $local_fs $remote_fs $network $syslog
|
||||
# Required-Start: $local_fs $remote_fs $network $syslog $all
|
||||
# Required-Stop: $local_fs $remote_fs $network $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import pyinotify
|
||||
import time
|
||||
import os
|
||||
from pydispatch import dispatcher
|
||||
|
||||
from os.path import normpath
|
||||
|
@ -186,13 +187,12 @@ class Manager(Loggable):
|
|||
try: mmp.create_dir(path)
|
||||
except mmp.FailedToCreateDir as e: self.unexpected_exception(e)
|
||||
|
||||
os.chmod(store_paths['organize'], 0775)
|
||||
|
||||
self.set_problem_files_path(store_paths['problem_files'])
|
||||
self.set_imported_path(store_paths['imported'])
|
||||
self.set_recorded_path(store_paths['recorded'])
|
||||
self.set_organize_path(store_paths['organize'])
|
||||
mmp.create_dir(store)
|
||||
for p in store_paths.values():
|
||||
mmp.create_dir(p)
|
||||
|
||||
def has_watch(self, path):
|
||||
""" returns true if the path is being watched or not. Any kind
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: airtime-liquidsoap
|
||||
# Required-Start: $local_fs $remote_fs $network $syslog
|
||||
# Required-Start: $local_fs $remote_fs $network $syslog $all
|
||||
# Required-Stop: $local_fs $remote_fs $network $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
|
@ -18,7 +18,6 @@ PIDFILE=/var/run/airtime-liquidsoap.pid
|
|||
EXEC='/usr/bin/airtime-liquidsoap'
|
||||
|
||||
start () {
|
||||
|
||||
mkdir -p /var/log/airtime/pypo-liquidsoap
|
||||
chown $USERID:$GROUPID /var/log/airtime/pypo-liquidsoap
|
||||
|
||||
|
@ -36,9 +35,19 @@ start () {
|
|||
}
|
||||
|
||||
stop () {
|
||||
timeout --version >/dev/null 2>&1
|
||||
RESULT="$?"
|
||||
|
||||
#send term signal after 10 seconds
|
||||
timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \
|
||||
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
|
||||
if [ "$RESULT" = "0" ]; then
|
||||
timeout -s9 10s /usr/lib/airtime/airtime_virtualenv/bin/python \
|
||||
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
|
||||
else
|
||||
#some earlier versions of Ubuntu (Lucid) had a different timeout
|
||||
#command that takes different input parameters.
|
||||
timeout 10 /usr/lib/airtime/airtime_virtualenv/bin/python \
|
||||
/usr/lib/airtime/pypo/bin/liquidsoap_scripts/liquidsoap_prepare_terminate.py
|
||||
fi
|
||||
# Send TERM after 5 seconds, wait at most 30 seconds.
|
||||
#start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --pidfile $PIDFILE
|
||||
start-stop-daemon --stop --oknodo --retry=TERM/10/KILL/5 --quiet --exec $EXEC
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: airtime-playout
|
||||
# Required-Start: $local_fs $remote_fs $network $syslog
|
||||
# Required-Start: $local_fs $remote_fs $network $syslog $all
|
||||
# Required-Stop: $local_fs $remote_fs $network $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
|
|
|
@ -88,8 +88,8 @@ try:
|
|||
|
||||
if "airtime_service_start" in os.environ and os.environ["airtime_service_start"] == "t":
|
||||
print "* Waiting for pypo processes to start..."
|
||||
subprocess.call("invoke-rc.d airtime-playout start > /dev/null 2>&1", shell=True)
|
||||
subprocess.call("invoke-rc.d airtime-liquidsoap start > /dev/null 2>&1", shell=True)
|
||||
subprocess.call("invoke-rc.d airtime-playout start > /dev/null 2>&1", shell=True)
|
||||
|
||||
except Exception, e:
|
||||
print e
|
||||
|
|
24
python_apps/pypo/liquidsoap_scripts/fdkaac.liq
Normal file
24
python_apps/pypo/liquidsoap_scripts/fdkaac.liq
Normal file
|
@ -0,0 +1,24 @@
|
|||
if bitrate == 24 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 24, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 32 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 32, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 48 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 48, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 64 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 64, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 96 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 96, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 128 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 128, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 160 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 160, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 192 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 192, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 224 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 224, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 256 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 256, aot="mpeg4_he_aac_v2"), !source))
|
||||
elsif bitrate == 320 then
|
||||
ignore(output_stereo(%fdkaac(bitrate = 320, aot="mpeg4_he_aac_v2"), !source))
|
||||
end
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import logging
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
from api_clients.api_client import AirtimeApiClient
|
||||
|
||||
def generate_liquidsoap_config(ss):
|
||||
|
@ -26,19 +27,21 @@ def generate_liquidsoap_config(ss):
|
|||
fh.close()
|
||||
|
||||
logging.basicConfig(format='%(message)s')
|
||||
ac = AirtimeApiClient(logging.getLogger())
|
||||
attempts = 0
|
||||
max_attempts = 5
|
||||
max_attempts = 10
|
||||
successful = False
|
||||
|
||||
while True:
|
||||
while not successful:
|
||||
try:
|
||||
ac = AirtimeApiClient(logging.getLogger())
|
||||
ss = ac.get_stream_setting()
|
||||
generate_liquidsoap_config(ss)
|
||||
break
|
||||
successful = True
|
||||
except Exception, e:
|
||||
if attempts == max_attempts:
|
||||
print "Unable to connect to the Airtime server."
|
||||
logging.error(str(e))
|
||||
logging.error("traceback: %s", traceback.format_exc())
|
||||
sys.exit(1)
|
||||
else:
|
||||
time.sleep(3)
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
def notify(m)
|
||||
#current_media_id := string_of(m['schedule_table_id'])
|
||||
command = "/usr/lib/airtime/pypo/bin/liquidsoap_scripts/notify.sh --media-id=#{m['schedule_table_id']} &"
|
||||
log(command)
|
||||
system(command)
|
||||
end
|
||||
|
||||
def notify_queue(m)
|
||||
f = !dynamic_metadata_callback
|
||||
ignore(f(m))
|
||||
notify(m)
|
||||
end
|
||||
|
||||
def notify_stream(m)
|
||||
json_str = string.replace(pattern="\n",(fun (s) -> ""), json_of(m))
|
||||
#if a string has a single apostrophe in it, let's comment it out by ending the string before right before it
|
||||
|
@ -18,12 +23,19 @@ end
|
|||
# A function applied to each metadata chunk
|
||||
def append_title(m) =
|
||||
log("Using stream_format #{!stream_metadata_type}")
|
||||
if !stream_metadata_type == 1 then
|
||||
[("title", "#{!show_name} - #{m['artist']} - #{m['title']}")]
|
||||
elsif !stream_metadata_type == 2 then
|
||||
[("title", "#{!station_name} - #{!show_name}")]
|
||||
|
||||
if list.mem_assoc("mapped", m) then
|
||||
#protection against applying this function twice. It shouldn't be happening
|
||||
#and bug file with Liquidsoap.
|
||||
m
|
||||
else
|
||||
[("title", "#{m['artist']} - #{m['title']}")]
|
||||
if !stream_metadata_type == 1 then
|
||||
[("title", "#{!show_name} - #{m['artist']} - #{m['title']}"), ("mapped", "true")]
|
||||
elsif !stream_metadata_type == 2 then
|
||||
[("title", "#{!station_name} - #{!show_name}"), ("mapped", "true")]
|
||||
else
|
||||
[("title", "#{m['artist']} - #{m['title']}"), ("mapped", "true")]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -146,6 +158,12 @@ def output_to(output_type, type, bitrate, host, port, pass, mount_point, url, de
|
|||
%include "aacplus.liq"
|
||||
end
|
||||
%endif
|
||||
|
||||
%ifencoder %fdkaac
|
||||
if type == "fdkaac" then
|
||||
%include "fdkaac.liq"
|
||||
end
|
||||
%endif
|
||||
else
|
||||
user_ref = ref user
|
||||
if user == "" then
|
||||
|
|
|
@ -24,6 +24,8 @@ default_dj_fade = ref 0.
|
|||
station_name = ref ''
|
||||
show_name = ref ''
|
||||
|
||||
dynamic_metadata_callback = ref fun (s) -> begin () end
|
||||
|
||||
s1_connected = ref ''
|
||||
s2_connected = ref ''
|
||||
s3_connected = ref ''
|
||||
|
@ -47,7 +49,8 @@ def create_source()
|
|||
# the crossfade function controls fade in/out
|
||||
l = crossfade_airtime(l)
|
||||
|
||||
l = on_metadata(notify, l)
|
||||
l = on_metadata(notify_queue, l)
|
||||
|
||||
sources := list.append([l], !sources)
|
||||
server.register(namespace="queues",
|
||||
"s#{!source_id}_skip",
|
||||
|
@ -69,12 +72,10 @@ create_source()
|
|||
create_source()
|
||||
|
||||
queue = add(!sources, normalize=false)
|
||||
pair = insert_metadata(queue)
|
||||
dynamic_metadata_callback := fst(pair)
|
||||
queue = snd(pair)
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
# the crossfade function controls fade in/out
|
||||
|
||||
>>>>>>> 551d65ebf04d877bdba009a92c62bfa4f08eea9c
|
||||
output.dummy(fallible=true, queue)
|
||||
|
||||
http = input.http_restart(id="http")
|
||||
|
|
|
@ -56,8 +56,8 @@ class SilanAnalyzer(Thread):
|
|||
try: data['cueout'] = str('{0:f}'.format(info['sound'][-1][1]))
|
||||
except: pass
|
||||
except Exception, e:
|
||||
self.logger.error(str(command))
|
||||
self.logger.error(e)
|
||||
self.logger.warn(str(command))
|
||||
self.logger.warn(e)
|
||||
processed_data.append((f['id'], data))
|
||||
total += 1
|
||||
if total % 5 == 0:
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
set httpd port 2812
|
||||
|
||||
check process airtime-liquidsoap matching "airtime-liquidsoap.*airtime.*ls_script"
|
||||
if does not exist for 3 cycles then restart
|
||||
|
||||
start program = "/etc/init.d/airtime-liquidsoap start" with timeout 30 seconds
|
||||
stop program = "/etc/init.d/airtime-liquidsoap stop"
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
set httpd port 2812
|
||||
|
||||
check process airtime-liquidsoap
|
||||
with pidfile "/var/run/airtime-liquidsoap.pid"
|
||||
check process airtime-liquidsoap with pidfile "/var/run/airtime-liquidsoap.pid"
|
||||
start program = "/etc/init.d/airtime-liquidsoap start" with timeout 5 seconds
|
||||
stop program = "/etc/init.d/airtime-liquidsoap stop"
|
||||
|
|
|
@ -25,6 +25,7 @@ from recorder import Recorder
|
|||
from listenerstat import ListenerStat
|
||||
from pypomessagehandler import PypoMessageHandler
|
||||
from pypoliquidsoap import PypoLiquidsoap
|
||||
from timeout import ls_timeout
|
||||
|
||||
from media.update.replaygainupdater import ReplayGainUpdater
|
||||
from media.update.silananalyzer import SilanAnalyzer
|
||||
|
@ -156,6 +157,7 @@ def keyboardInterruptHandler(signum, frame):
|
|||
logger.info('\nKeyboard Interrupt\n')
|
||||
sys.exit(0)
|
||||
|
||||
@ls_timeout
|
||||
def liquidsoap_get_info(telnet_lock, host, port, logger):
|
||||
logger.debug("Checking to see if Liquidsoap is running")
|
||||
try:
|
||||
|
|
|
@ -19,6 +19,7 @@ from subprocess import Popen, PIPE
|
|||
|
||||
from api_clients import api_client
|
||||
from std_err_override import LogWriter
|
||||
from timeout import ls_timeout
|
||||
|
||||
|
||||
# configure logging
|
||||
|
@ -38,12 +39,13 @@ signal.signal(signal.SIGINT, keyboardInterruptHandler)
|
|||
|
||||
POLL_INTERVAL = 1800
|
||||
|
||||
config_static = None
|
||||
|
||||
class PypoFetch(Thread):
|
||||
|
||||
def __init__(self, pypoFetch_q, pypoPush_q, media_q, telnet_lock, pypo_liquidsoap, config):
|
||||
Thread.__init__(self)
|
||||
global config_static
|
||||
|
||||
#Hacky...
|
||||
PypoFetch.ref = self
|
||||
|
||||
self.api_client = api_client.AirtimeApiClient()
|
||||
self.fetch_queue = pypoFetch_q
|
||||
|
@ -51,7 +53,6 @@ class PypoFetch(Thread):
|
|||
self.media_prepare_queue = media_q
|
||||
self.last_update_schedule_timestamp = time.time()
|
||||
self.config = config
|
||||
config_static = config
|
||||
self.listener_timeout = POLL_INTERVAL
|
||||
|
||||
self.telnet_lock = telnet_lock
|
||||
|
@ -176,11 +177,19 @@ class PypoFetch(Thread):
|
|||
commands.append(('vars.default_dj_fade %s\n' % fade).encode('utf-8'))
|
||||
self.pypo_liquidsoap.get_telnet_dispatcher().telnet_send(commands)
|
||||
|
||||
self.pypo_liquidsoap.clear_all_queues()
|
||||
self.pypo_liquidsoap.clear_queue_tracker()
|
||||
|
||||
def restart_liquidsoap(self):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
"""do not block - if we receive the lock then good - no other thread
|
||||
will try communicating with Liquidsoap. If we don't receive, it may
|
||||
mean some thread blocked and is still holding the lock. Restarting
|
||||
Liquidsoap will cause that thread to release the lock as an Exception
|
||||
will be thrown."""
|
||||
self.telnet_lock.acquire(False)
|
||||
|
||||
|
||||
self.logger.info("Restarting Liquidsoap")
|
||||
subprocess.call('/etc/init.d/airtime-liquidsoap restart', shell=True)
|
||||
|
||||
|
@ -202,14 +211,6 @@ class PypoFetch(Thread):
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
try:
|
||||
self.set_bootstrap_variables()
|
||||
#get the most up to date schedule, which will #initiate the process
|
||||
#of making sure Liquidsoap is playing the schedule
|
||||
self.persistent_manual_schedule_fetch(max_attempts=5)
|
||||
except Exception, e:
|
||||
self.logger.error(str(e))
|
||||
|
||||
"""
|
||||
TODO: This function needs to be way shorter, and refactored :/ - MK
|
||||
"""
|
||||
|
@ -307,6 +308,7 @@ class PypoFetch(Thread):
|
|||
self.logger.info("No change detected in setting...")
|
||||
self.update_liquidsoap_connection_status()
|
||||
|
||||
@ls_timeout
|
||||
def update_liquidsoap_connection_status(self):
|
||||
"""
|
||||
updates the status of Liquidsoap connection to the streaming server
|
||||
|
@ -353,6 +355,7 @@ class PypoFetch(Thread):
|
|||
self.api_client.notify_liquidsoap_status("OK", stream_id, str(fake_time))
|
||||
|
||||
|
||||
@ls_timeout
|
||||
def update_liquidsoap_stream_format(self, stream_format):
|
||||
# Push stream metadata to liquidsoap
|
||||
# TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!!
|
||||
|
@ -369,6 +372,7 @@ class PypoFetch(Thread):
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def update_liquidsoap_transition_fade(self, fade):
|
||||
# Push stream metadata to liquidsoap
|
||||
# TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!!
|
||||
|
@ -385,6 +389,7 @@ class PypoFetch(Thread):
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def update_liquidsoap_station_name(self, station_name):
|
||||
# Push stream metadata to liquidsoap
|
||||
# TODO: THIS LIQUIDSOAP STUFF NEEDS TO BE MOVED TO PYPO-PUSH!!!
|
||||
|
@ -441,9 +446,11 @@ class PypoFetch(Thread):
|
|||
media_item['file_ready'] = False
|
||||
media_filtered[key] = media_item
|
||||
|
||||
media_item['start'] = datetime.strptime(media_item['start'], "%Y-%m-%d-%H-%M-%S")
|
||||
media_item['end'] = datetime.strptime(media_item['end'], "%Y-%m-%d-%H-%M-%S")
|
||||
media_copy[media_item['start']] = media_item
|
||||
media_item['start'] = datetime.strptime(media_item['start'],
|
||||
"%Y-%m-%d-%H-%M-%S")
|
||||
media_item['end'] = datetime.strptime(media_item['end'],
|
||||
"%Y-%m-%d-%H-%M-%S")
|
||||
media_copy[key] = media_item
|
||||
|
||||
|
||||
self.media_prepare_queue.put(copy.copy(media_filtered))
|
||||
|
|
|
@ -63,14 +63,6 @@ class PypoFile(Thread):
|
|||
self.logger.debug("copying from %s to local cache %s" % (src, dst))
|
||||
try:
|
||||
|
||||
"""
|
||||
List file as "ready" before it starts copying because by the time
|
||||
Liquidsoap is ready to play this file, it should have at least started
|
||||
copying (and can continue copying while Liquidsoap reads from the beginning
|
||||
of the file)
|
||||
"""
|
||||
media_item['file_ready'] = True
|
||||
|
||||
"""
|
||||
copy will overwrite dst if it already exists
|
||||
"""
|
||||
|
@ -78,6 +70,8 @@ class PypoFile(Thread):
|
|||
|
||||
#make file world readable
|
||||
os.chmod(dst, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
|
||||
|
||||
media_item['file_ready'] = True
|
||||
except Exception, e:
|
||||
self.logger.error("Could not copy from %s to %s" % (src, dst))
|
||||
self.logger.error(e)
|
||||
|
|
|
@ -61,8 +61,10 @@ class PypoLiqQueue(Thread):
|
|||
schedule_deque.append(media_schedule[i])
|
||||
|
||||
if len(keys):
|
||||
time_until_next_play = self.date_interval_to_seconds(\
|
||||
keys[0] - datetime.utcnow())
|
||||
time_until_next_play = self.date_interval_to_seconds(
|
||||
media_schedule[keys[0]]['start'] -
|
||||
datetime.utcnow())
|
||||
|
||||
else:
|
||||
time_until_next_play = None
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
from datetime import datetime
|
||||
from datetime import timedelta
|
||||
from configobj import ConfigObj
|
||||
|
||||
import sys
|
||||
import time
|
||||
|
@ -21,7 +22,7 @@ from threading import Thread
|
|||
|
||||
from api_clients import api_client
|
||||
from std_err_override import LogWriter
|
||||
from configobj import ConfigObj
|
||||
from timeout import ls_timeout
|
||||
|
||||
|
||||
# configure logging
|
||||
|
@ -110,48 +111,10 @@ class PypoPush(Thread):
|
|||
if diff_sec >= 0:
|
||||
present.append(media_item)
|
||||
else:
|
||||
future[media_item['start']] = media_item
|
||||
future[mkey] = media_item
|
||||
|
||||
return present, future
|
||||
|
||||
def get_current_stream_id_from_liquidsoap(self):
|
||||
response = "-1"
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
tn = telnetlib.Telnet(self.config['ls_host'], self.config['ls_port'])
|
||||
|
||||
msg = 'dynamic_source.get_id\n'
|
||||
tn.write(msg)
|
||||
response = tn.read_until("\r\n").strip(" \r\n")
|
||||
tn.write('exit\n')
|
||||
tn.read_all()
|
||||
except Exception, e:
|
||||
self.logger.error("Error connecting to Liquidsoap: %s", e)
|
||||
response = []
|
||||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
return response
|
||||
|
||||
#def is_correct_current_item(self, media_item, liquidsoap_queue_approx, liquidsoap_stream_id):
|
||||
#correct = False
|
||||
#if media_item is None:
|
||||
#correct = (len(liquidsoap_queue_approx) == 0 and liquidsoap_stream_id == "-1")
|
||||
#else:
|
||||
#if is_file(media_item):
|
||||
#if len(liquidsoap_queue_approx) == 0:
|
||||
#correct = False
|
||||
#else:
|
||||
#correct = liquidsoap_queue_approx[0]['start'] == media_item['start'] and \
|
||||
#liquidsoap_queue_approx[0]['row_id'] == media_item['row_id'] and \
|
||||
#liquidsoap_queue_approx[0]['end'] == media_item['end'] and \
|
||||
#liquidsoap_queue_approx[0]['replay_gain'] == media_item['replay_gain']
|
||||
#elif is_stream(media_item):
|
||||
#correct = liquidsoap_stream_id == str(media_item['row_id'])
|
||||
|
||||
#self.logger.debug("Is current item correct?: %s", str(correct))
|
||||
#return correct
|
||||
|
||||
def date_interval_to_seconds(self, interval):
|
||||
"""
|
||||
Convert timedelta object into int representing the number of seconds. If
|
||||
|
@ -162,6 +125,7 @@ class PypoPush(Thread):
|
|||
|
||||
return seconds
|
||||
|
||||
@ls_timeout
|
||||
def stop_web_stream_all(self):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import telnetlib
|
||||
from timeout import ls_timeout
|
||||
|
||||
def create_liquidsoap_annotation(media):
|
||||
# We need liq_start_next value in the annotate. That is the value that controls overlap duration of crossfade.
|
||||
|
@ -38,6 +39,7 @@ class TelnetLiquidsoap:
|
|||
else:
|
||||
raise Exception("Unexpected list length returned: %s" % output)
|
||||
|
||||
@ls_timeout
|
||||
def queue_clear_all(self):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -55,6 +57,7 @@ class TelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def queue_remove(self, queue_id):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -72,6 +75,7 @@ class TelnetLiquidsoap:
|
|||
self.telnet_lock.release()
|
||||
|
||||
|
||||
@ls_timeout
|
||||
def queue_push(self, queue_id, media_item):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -98,6 +102,7 @@ class TelnetLiquidsoap:
|
|||
self.telnet_lock.release()
|
||||
|
||||
|
||||
@ls_timeout
|
||||
def stop_web_stream_buffer(self):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -120,6 +125,7 @@ class TelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def stop_web_stream_output(self):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -138,6 +144,7 @@ class TelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def start_web_stream(self, media_item):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -160,6 +167,7 @@ class TelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def start_web_stream_buffer(self, media_item):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -182,6 +190,7 @@ class TelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def get_current_stream_id(self):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -201,6 +210,7 @@ class TelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def disconnect_source(self, sourcename):
|
||||
self.logger.debug('Disconnecting source: %s', sourcename)
|
||||
command = ""
|
||||
|
@ -221,6 +231,7 @@ class TelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def telnet_send(self, commands):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -265,6 +276,7 @@ class DummyTelnetLiquidsoap:
|
|||
for i in range(4):
|
||||
self.liquidsoap_mock_queues["s"+str(i)] = []
|
||||
|
||||
@ls_timeout
|
||||
def queue_push(self, queue_id, media_item):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
@ -280,6 +292,7 @@ class DummyTelnetLiquidsoap:
|
|||
finally:
|
||||
self.telnet_lock.release()
|
||||
|
||||
@ls_timeout
|
||||
def queue_remove(self, queue_id):
|
||||
try:
|
||||
self.telnet_lock.acquire()
|
||||
|
|
36
python_apps/pypo/timeout.py
Normal file
36
python_apps/pypo/timeout.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
import threading
|
||||
import pypofetch
|
||||
|
||||
def __timeout(func, timeout_duration, default, args, kwargs):
|
||||
|
||||
class InterruptableThread(threading.Thread):
|
||||
def __init__(self):
|
||||
threading.Thread.__init__(self)
|
||||
self.result = default
|
||||
def run(self):
|
||||
self.result = func(*args, **kwargs)
|
||||
|
||||
first_attempt = True
|
||||
|
||||
while True:
|
||||
it = InterruptableThread()
|
||||
it.start()
|
||||
it.join(timeout_duration)
|
||||
|
||||
if it.isAlive():
|
||||
"""Restart Liquidsoap and try the command one more time. If it
|
||||
fails again then there is something critically wrong..."""
|
||||
if first_attempt:
|
||||
#restart liquidsoap
|
||||
pypofetch.PypoFetch.ref.restart_liquidsoap()
|
||||
else:
|
||||
raise Exception("Thread did not terminate")
|
||||
else:
|
||||
return it.result
|
||||
|
||||
first_attempt = False
|
||||
|
||||
def ls_timeout(f, timeout=4, default=None):
|
||||
def new_f(*args, **kwargs):
|
||||
return __timeout(f, timeout, default, args, kwargs)
|
||||
return new_f
|
Loading…
Add table
Add a link
Reference in a new issue