parent
89c845b269
commit
c56492357b
|
@ -1,410 +0,0 @@
|
|||
#!/usr/bin/python2 import sys
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from optparse import OptionParser, OptionValueError
|
||||
|
||||
import commands
|
||||
from libretime_api_client import api_client as apc
|
||||
from configobj import ConfigObj
|
||||
|
||||
# sys.path.append('/usr/lib/airtime/media-monitor/mm2/')
|
||||
from mm2.media.monitor.pure import is_file_supported
|
||||
|
||||
# create logger
|
||||
logger = logging.getLogger()
|
||||
|
||||
# no logging
|
||||
ch = logging.StreamHandler()
|
||||
logging.disable(50)
|
||||
|
||||
# add ch to logger
|
||||
logger.addHandler(ch)
|
||||
|
||||
if os.geteuid() != 0:
|
||||
print "Must be a root user."
|
||||
sys.exit()
|
||||
|
||||
# loading config file
|
||||
try:
|
||||
config = ConfigObj("/etc/airtime/airtime.conf")
|
||||
except Exception, e:
|
||||
print ("Error loading config file: %s", e)
|
||||
sys.exit()
|
||||
|
||||
api_client = apc.AirtimeApiClient(config)
|
||||
|
||||
# helper functions
|
||||
# copy or move files
|
||||
# flag should be 'copy' or 'move'
|
||||
def copy_or_move_files_to(paths, dest, flag):
|
||||
try:
|
||||
for path in paths:
|
||||
if path[0] == "/" or path[0] == "~":
|
||||
path = os.path.realpath(path)
|
||||
else:
|
||||
path = currentDir + path
|
||||
path = apc.encode_to(path, "utf-8")
|
||||
dest = apc.encode_to(dest, "utf-8")
|
||||
if os.path.exists(path):
|
||||
if os.path.isdir(path):
|
||||
path = format_dir_string(path)
|
||||
# construct full path
|
||||
sub_path = []
|
||||
for temp in os.listdir(path):
|
||||
sub_path.append(path + temp)
|
||||
copy_or_move_files_to(sub_path, dest, flag)
|
||||
elif os.path.isfile(path):
|
||||
# copy file to dest
|
||||
if is_file_supported(path):
|
||||
destfile = dest + os.path.basename(path)
|
||||
if flag == "copy":
|
||||
print "Copying %(src)s to %(dest)s..." % {
|
||||
"src": path,
|
||||
"dest": destfile,
|
||||
}
|
||||
shutil.copyfile(path, destfile)
|
||||
elif flag == "move":
|
||||
print "Moving %(src)s to %(dest)s..." % {
|
||||
"src": path,
|
||||
"dest": destfile,
|
||||
}
|
||||
shutil.move(path, destfile)
|
||||
else:
|
||||
print "Cannot find file or path: %s" % path
|
||||
except Exception as e:
|
||||
print "Error: ", e
|
||||
|
||||
|
||||
def format_dir_string(path):
|
||||
if path[-1] != "/":
|
||||
path = path + "/"
|
||||
return path
|
||||
|
||||
|
||||
def helper_get_stor_dir():
|
||||
try:
|
||||
res = api_client.list_all_watched_dirs()
|
||||
except Exception, e:
|
||||
return res
|
||||
|
||||
if res["dirs"]["1"][-1] != "/":
|
||||
out = res["dirs"]["1"] + "/"
|
||||
return out
|
||||
else:
|
||||
return res["dirs"]["1"]
|
||||
|
||||
|
||||
def checkOtherOption(args):
|
||||
for i in args:
|
||||
if i[0] == "-":
|
||||
return True
|
||||
|
||||
|
||||
def errorIfMultipleOption(args, msg=""):
|
||||
if checkOtherOption(args):
|
||||
if msg != "":
|
||||
raise OptionValueError(msg)
|
||||
else:
|
||||
raise OptionValueError("This option cannot be combined with other options")
|
||||
|
||||
|
||||
def printHelp():
|
||||
storage_dir = helper_get_stor_dir()
|
||||
if storage_dir is None:
|
||||
storage_dir = "Unknown"
|
||||
else:
|
||||
storage_dir += "imported/"
|
||||
print """
|
||||
========================
|
||||
Airtime Import Script
|
||||
========================
|
||||
There are two ways to import audio files into Airtime:
|
||||
|
||||
1) Use airtime-import to copy or move files into the storage folder.
|
||||
|
||||
Copied or moved files will be placed into the folder:
|
||||
%s
|
||||
|
||||
Files will be automatically organized into the structure
|
||||
"Artist/Album/TrackNumber-TrackName-Bitrate.file_extension".
|
||||
|
||||
2) Use airtime-import to add a folder to the Airtime library ("watch" a folder).
|
||||
|
||||
All the files in the watched folder will be imported to Airtime and the
|
||||
folder will be monitored to automatically detect any changes. Hence any
|
||||
changes done in the folder(add, delete, edit a file) will trigger
|
||||
updates in Airtime library.
|
||||
""" % storage_dir
|
||||
parser.print_help()
|
||||
print ""
|
||||
|
||||
|
||||
def CopyAction(option, opt, value, parser):
|
||||
errorIfMultipleOption(parser.rargs)
|
||||
if len(parser.rargs) == 0:
|
||||
raise OptionValueError(
|
||||
"No argument found. This option requires at least one argument."
|
||||
)
|
||||
stor = helper_get_stor_dir()
|
||||
if stor is None:
|
||||
print "Unable to connect to the Airtime server."
|
||||
return
|
||||
dest = stor + "organize/"
|
||||
copy_or_move_files_to(parser.rargs, dest, "copy")
|
||||
|
||||
|
||||
def MoveAction(option, opt, value, parser):
|
||||
errorIfMultipleOption(parser.rargs)
|
||||
if len(parser.rargs) == 0:
|
||||
raise OptionValueError(
|
||||
"No argument found. This option requires at least one argument."
|
||||
)
|
||||
stor = helper_get_stor_dir()
|
||||
if stor is None:
|
||||
exit("Unable to connect to the Airtime server.")
|
||||
dest = stor + "organize/"
|
||||
copy_or_move_files_to(parser.rargs, dest, "move")
|
||||
|
||||
|
||||
def WatchAddAction(option, opt, value, parser):
|
||||
errorIfMultipleOption(parser.rargs)
|
||||
if len(parser.rargs) > 1:
|
||||
raise OptionValueError(
|
||||
"Too many arguments. This option requires exactly one argument."
|
||||
)
|
||||
elif len(parser.rargs) == 0:
|
||||
raise OptionValueError(
|
||||
"No argument found. This option requires exactly one argument."
|
||||
)
|
||||
path = parser.rargs[0]
|
||||
if path[0] == "/" or path[0] == "~":
|
||||
path = os.path.realpath(path)
|
||||
else:
|
||||
path = currentDir + path
|
||||
path = apc.encode_to(path, "utf-8")
|
||||
if os.path.isdir(path):
|
||||
# os.chmod(path, 0765)
|
||||
try:
|
||||
res = api_client.add_watched_dir(path)
|
||||
except Exception, e:
|
||||
exit("Unable to connect to the server.")
|
||||
# success
|
||||
if res["msg"]["code"] == 0:
|
||||
print "%s added to watched folder list successfully" % path
|
||||
else:
|
||||
print "Adding a watched folder failed: %s" % res["msg"]["error"]
|
||||
print "This error most likely caused by wrong permissions"
|
||||
print "Try fixing this error by chmodding the parent directory(ies)"
|
||||
else:
|
||||
print "Given path is not a directory: %s" % path
|
||||
|
||||
|
||||
def WatchListAction(option, opt, value, parser):
|
||||
errorIfMultipleOption(parser.rargs)
|
||||
if len(parser.rargs) > 0:
|
||||
raise OptionValueError("This option doesn't take any arguments.")
|
||||
try:
|
||||
res = api_client.list_all_watched_dirs()
|
||||
except Exception, e:
|
||||
exit("Unable to connect to the Airtime server.")
|
||||
dirs = res["dirs"].items()
|
||||
# there will be always 1 which is storage folder
|
||||
if len(dirs) == 1:
|
||||
print "No watch folders found"
|
||||
else:
|
||||
for key, v in dirs:
|
||||
if key != "1":
|
||||
print v
|
||||
|
||||
|
||||
def WatchRemoveAction(option, opt, value, parser):
|
||||
errorIfMultipleOption(parser.rargs)
|
||||
if len(parser.rargs) > 1:
|
||||
raise OptionValueError(
|
||||
"Too many arguments. This option requires exactly one argument."
|
||||
)
|
||||
elif len(parser.rargs) == 0:
|
||||
raise OptionValueError(
|
||||
"No argument found. This option requires exactly one argument."
|
||||
)
|
||||
path = parser.rargs[0]
|
||||
if path[0] == "/" or path[0] == "~":
|
||||
path = os.path.realpath(path)
|
||||
else:
|
||||
path = currentDir + path
|
||||
path = apc.encode_to(path, "utf-8")
|
||||
if os.path.isdir(path):
|
||||
try:
|
||||
res = api_client.remove_watched_dir(path)
|
||||
except Exception, e:
|
||||
exit("Unable to connect to the Airtime server.")
|
||||
# success
|
||||
if res["msg"]["code"] == 0:
|
||||
print "%s removed from watch folder list successfully." % path
|
||||
else:
|
||||
print "Removing the watch folder failed: %s" % res["msg"]["error"]
|
||||
else:
|
||||
print "The given path is not a directory: %s" % path
|
||||
|
||||
|
||||
def StorageSetAction(option, opt, value, parser):
|
||||
bypass = False
|
||||
isF = "-f" in parser.rargs
|
||||
isForce = "--force" in parser.rargs
|
||||
if isF or isForce:
|
||||
bypass = True
|
||||
if isF:
|
||||
parser.rargs.remove("-f")
|
||||
if isForce:
|
||||
parser.rargs.remove("--force")
|
||||
if not bypass:
|
||||
errorIfMultipleOption(
|
||||
parser.rargs, "Only [-f] and [--force] option is allowed with this option."
|
||||
)
|
||||
possibleInput = ["y", "Y", "n", "N"]
|
||||
confirm = raw_input(
|
||||
"Are you sure you want to change the storage directory? (y/N)"
|
||||
)
|
||||
confirm = confirm or "N"
|
||||
while confirm not in possibleInput:
|
||||
print "Not an acceptable input: %s\n" % confirm
|
||||
confirm = raw_input(
|
||||
"Are you sure you want to change the storage directory? (y/N) "
|
||||
)
|
||||
confirm = confirm or "N"
|
||||
if confirm == "n" or confirm == "N":
|
||||
sys.exit(1)
|
||||
|
||||
if len(parser.rargs) > 1:
|
||||
raise OptionValueError(
|
||||
"Too many arguments. This option requires exactly one argument."
|
||||
)
|
||||
elif len(parser.rargs) == 0:
|
||||
raise OptionValueError(
|
||||
"No argument found. This option requires exactly one argument."
|
||||
)
|
||||
|
||||
path = parser.rargs[0]
|
||||
if path[0] == "/" or path[0] == "~":
|
||||
path = os.path.realpath(path)
|
||||
else:
|
||||
path = currentDir + path
|
||||
path = apc.encode_to(path, "utf-8")
|
||||
if os.path.isdir(path):
|
||||
try:
|
||||
res = api_client.set_storage_dir(path)
|
||||
except Exception, e:
|
||||
exit("Unable to connect to the Airtime server.")
|
||||
# success
|
||||
if res["msg"]["code"] == 0:
|
||||
print "Successfully set storage folder to %s" % path
|
||||
else:
|
||||
print "Setting storage folder failed: %s" % res["msg"]["error"]
|
||||
else:
|
||||
print "The given path is not a directory: %s" % path
|
||||
|
||||
|
||||
def StorageGetAction(option, opt, value, parser):
|
||||
errorIfMultipleOption(parser.rargs)
|
||||
if len(parser.rargs) > 0:
|
||||
raise OptionValueError("This option does not take any arguments.")
|
||||
print helper_get_stor_dir()
|
||||
|
||||
|
||||
class OptionValueError(RuntimeError):
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
|
||||
|
||||
usage = """[-c|--copy FILE/DIR [FILE/DIR...]] [-m|--move FILE/DIR [FILE/DIR...]]
|
||||
[--watch-add DIR] [--watch-list] [--watch-remove DIR]
|
||||
[--storage-dir-set DIR] [--storage-dir-get]"""
|
||||
|
||||
parser = OptionParser(usage=usage, add_help_option=False)
|
||||
parser.add_option(
|
||||
"-c",
|
||||
"--copy",
|
||||
action="callback",
|
||||
callback=CopyAction,
|
||||
metavar="FILE",
|
||||
help="Copy FILE(s) into the storage directory.\nYou can specify multiple files or directories.",
|
||||
)
|
||||
parser.add_option(
|
||||
"-m",
|
||||
"--move",
|
||||
action="callback",
|
||||
callback=MoveAction,
|
||||
metavar="FILE",
|
||||
help="Move FILE(s) into the storage directory.\nYou can specify multiple files or directories.",
|
||||
)
|
||||
parser.add_option(
|
||||
"--watch-add",
|
||||
action="callback",
|
||||
callback=WatchAddAction,
|
||||
help="Add DIR to the watched folders list.",
|
||||
)
|
||||
parser.add_option(
|
||||
"--watch-list",
|
||||
action="callback",
|
||||
callback=WatchListAction,
|
||||
help="Show the list of folders that are watched.",
|
||||
)
|
||||
parser.add_option(
|
||||
"--watch-remove",
|
||||
action="callback",
|
||||
callback=WatchRemoveAction,
|
||||
help="Remove DIR from the watched folders list.",
|
||||
)
|
||||
parser.add_option(
|
||||
"--storage-dir-set",
|
||||
action="callback",
|
||||
callback=StorageSetAction,
|
||||
help="Set storage dir to DIR.",
|
||||
)
|
||||
parser.add_option(
|
||||
"--storage-dir-get",
|
||||
action="callback",
|
||||
callback=StorageGetAction,
|
||||
help="Show the current storage dir.",
|
||||
)
|
||||
parser.add_option(
|
||||
"-h",
|
||||
"--help",
|
||||
dest="help",
|
||||
action="store_true",
|
||||
help="show this help message and exit",
|
||||
)
|
||||
|
||||
# pop "--dir"
|
||||
# sys.argv.pop(1)
|
||||
# pop "invoked pwd"
|
||||
currentDir = os.getcwd() # sys.argv.pop(1)+'/'
|
||||
|
||||
if "-l" in sys.argv or "--link" in sys.argv:
|
||||
print "\nThe [-l][--link] option is deprecated. Please use the --watch-add option.\nTry 'airtime-import -h' for more detail.\n"
|
||||
sys.exit()
|
||||
if "-h" in sys.argv:
|
||||
printHelp()
|
||||
sys.exit()
|
||||
if len(sys.argv) == 1 or "-" not in sys.argv[1]:
|
||||
printHelp()
|
||||
sys.exit()
|
||||
|
||||
try:
|
||||
(option, args) = parser.parse_args()
|
||||
except Exception, e:
|
||||
printHelp()
|
||||
if hasattr(e, "msg"):
|
||||
print "Error: " + e.msg
|
||||
else:
|
||||
print "Error: ", e
|
||||
sys.exit()
|
||||
except SystemExit:
|
||||
printHelp()
|
||||
sys.exit()
|
||||
|
||||
if option.help:
|
||||
printHelp()
|
||||
sys.exit()
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Absolute path to this script
|
||||
SCRIPT=$(readlink -f $0)
|
||||
# Absolute directory this script is in
|
||||
SCRIPTPATH=$(dirname $SCRIPT)
|
||||
|
||||
php -q $SCRIPTPATH/airtime-log.php "$@" || exit 1
|
|
@ -1,166 +0,0 @@
|
|||
<?php
|
||||
|
||||
exitIfNotRoot();
|
||||
|
||||
date_default_timezone_set("UTC");
|
||||
|
||||
$airtimeIni = getAirtimeConf();
|
||||
$airtime_base_dir = $airtimeIni['general']['airtime_dir'];
|
||||
|
||||
set_include_path("$airtime_base_dir/library" . PATH_SEPARATOR . get_include_path());
|
||||
//Zend framework
|
||||
if (file_exists('/usr/share/php/libzend-framework-php')){
|
||||
set_include_path('/usr/share/php/libzend-framework-php' . PATH_SEPARATOR . get_include_path());
|
||||
}
|
||||
|
||||
require_once('Zend/Loader/Autoloader.php');
|
||||
$autoloader = Zend_Loader_Autoloader::getInstance();
|
||||
|
||||
$log_files = array("media-monitor" => "/var/log/airtime/media-monitor/media-monitor.log",
|
||||
"recorder" => "/var/log/airtime/pypo/show-recorder.log",
|
||||
"playout" => "/var/log/airtime/pypo/pypo.log",
|
||||
"liquidsoap" => "/var/log/airtime/pypo-liquidsoap/ls_script.log",
|
||||
"web" => "/var/log/airtime/zendphp.log");
|
||||
|
||||
array_filter($log_files, "file_exists");
|
||||
|
||||
/**
|
||||
* Ensures that the user is running this PHP script with root
|
||||
* permissions. If not running with root permissions, causes the
|
||||
* script to exit.
|
||||
*/
|
||||
function exitIfNotRoot()
|
||||
{
|
||||
// Need to check that we are superuser before running this.
|
||||
if(posix_geteuid() != 0){
|
||||
echo "Must be root user.\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function printUsage($userMsg = "")
|
||||
{
|
||||
global $opts;
|
||||
|
||||
$msg = $opts->getUsageMessage();
|
||||
if (strlen($userMsg)>0)
|
||||
echo $userMsg;
|
||||
echo PHP_EOL."Usage: airtime-log [options]";
|
||||
echo substr($msg, strpos($msg, "\n")).PHP_EOL;
|
||||
}
|
||||
|
||||
function isKeyValid($key){
|
||||
global $log_files;
|
||||
return array_key_exists($key, $log_files);
|
||||
}
|
||||
|
||||
function viewSpecificLog($key){
|
||||
global $log_files;
|
||||
|
||||
if (isKeyValid($key)){
|
||||
echo "Viewing $key log\n";
|
||||
pcntl_exec(exec("which less"), array($log_files[$key]));
|
||||
pcntl_wait($status);
|
||||
} else printUsage();
|
||||
}
|
||||
|
||||
function dumpAllLogs(){
|
||||
$dateStr = gmdate("Y-m-d-H-i-s");
|
||||
|
||||
$dir = getcwd();
|
||||
|
||||
$filename = "$dir/airtime-log-all-$dateStr.tgz";
|
||||
echo "Creating Airtime logs tgz file at $filename";
|
||||
$command = "tar cfz $filename /var/log/airtime 2>/dev/null";
|
||||
exec($command);
|
||||
}
|
||||
|
||||
function dumpSpecificLog($key){
|
||||
global $log_files;
|
||||
|
||||
if (isKeyValid($key)){
|
||||
$dateStr = gmdate("Y-m-d-H-i-s");
|
||||
|
||||
$dir = getcwd();
|
||||
|
||||
$filename = "$dir/airtime-log-$key-$dateStr.tgz";
|
||||
echo "Creating Airtime logs tgz file at $filename";
|
||||
$dir = dirname($log_files[$key]);
|
||||
$command = "tar cfz $filename $dir 2>/dev/null";
|
||||
exec($command);
|
||||
} else printUsage();
|
||||
}
|
||||
|
||||
function tailAllLogs(){
|
||||
global $log_files;
|
||||
echo "Tail all Airtime logs";
|
||||
pcntl_exec(exec("which multitail"), $log_files);
|
||||
pcntl_wait($status);
|
||||
}
|
||||
|
||||
function tailSpecificLog($key){
|
||||
global $log_files;
|
||||
|
||||
if (isKeyValid($key)){
|
||||
echo "Tail $key log";
|
||||
pcntl_exec(exec("which tail"), array("-F", $log_files[$key]));
|
||||
pcntl_wait($status);
|
||||
} else printUsage();
|
||||
}
|
||||
|
||||
function getAirtimeConf()
|
||||
{
|
||||
$ini = parse_ini_file("/etc/airtime/airtime.conf", true);
|
||||
|
||||
if ($ini === false){
|
||||
echo "Error reading /etc/airtime/airtime.conf.".PHP_EOL;
|
||||
exit;
|
||||
}
|
||||
|
||||
return $ini;
|
||||
}
|
||||
|
||||
try {
|
||||
$keys = implode("|", array_keys($log_files));
|
||||
$opts = new Zend_Console_Getopt(
|
||||
array(
|
||||
'view|v=s' => "Display log file\n"
|
||||
."\t\t$keys",
|
||||
'dump|d-s' => "Collect all log files and compress into a tarball\n"
|
||||
."\t\t$keys (ALL by default)",
|
||||
'tail|t-s' => "View any new entries appended to log files in real-time\n"
|
||||
."\t\t$keys (ALL by default)"
|
||||
)
|
||||
);
|
||||
$opts->parse();
|
||||
}
|
||||
catch (Zend_Console_Getopt_Exception $e) {
|
||||
print $e->getMessage() .PHP_EOL;
|
||||
printUsage();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (isset($opts->v)){
|
||||
if ($opts->v === true){
|
||||
//Should never get here. Zend_Console_Getopt requires v to provide a string parameter.
|
||||
} else {
|
||||
viewSpecificLog($opts->v);
|
||||
}
|
||||
} else if (isset($opts->d)){
|
||||
if ($opts->d === true){
|
||||
dumpAllLogs();
|
||||
} else {
|
||||
dumpSpecificLog($opts->d);
|
||||
}
|
||||
} else if (isset($opts->t)){
|
||||
if ($opts->t === true){
|
||||
tailAllLogs();
|
||||
} else {
|
||||
tailSpecificLog($opts->t);
|
||||
}
|
||||
} else {
|
||||
printUsage();
|
||||
exit;
|
||||
}
|
||||
|
||||
echo PHP_EOL;
|
|
@ -1,84 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
from libretime_api_client import api_client as apc
|
||||
from configobj import ConfigObj
|
||||
|
||||
# create logger
|
||||
logger = logging.getLogger()
|
||||
|
||||
# no logging
|
||||
ch = logging.StreamHandler()
|
||||
logging.disable(50)
|
||||
|
||||
# add ch to logger
|
||||
logger.addHandler(ch)
|
||||
|
||||
if os.geteuid() != 0:
|
||||
print "Must be a root user."
|
||||
sys.exit(1)
|
||||
|
||||
# loading config file
|
||||
try:
|
||||
config = ConfigObj("/etc/airtime/airtime.conf")
|
||||
except Exception, e:
|
||||
print ("Error loading config file: %s", e)
|
||||
sys.exit(1)
|
||||
|
||||
api_client = apc.AirtimeApiClient(config)
|
||||
|
||||
try:
|
||||
# keep getting few rows at a time for current music_dir (stor
|
||||
# or watched folder).
|
||||
subtotal = 0
|
||||
while True:
|
||||
# return a list of pairs where the first value is the
|
||||
# file's database row id and the second value is the
|
||||
# filepath
|
||||
files = api_client.get_files_without_silan_value()
|
||||
total_files = len(files)
|
||||
if total_files == 0:
|
||||
break
|
||||
processed_data = []
|
||||
total = 0
|
||||
for f in files:
|
||||
full_path = f["fp"]
|
||||
# silence detect(set default queue in and out)
|
||||
try:
|
||||
command = ["silan", "-b" "-f", "JSON", full_path]
|
||||
proc = subprocess.Popen(command, stdout=subprocess.PIPE)
|
||||
out = proc.communicate()[0].strip("\r\n")
|
||||
info = json.loads(out)
|
||||
data = {}
|
||||
data["cuein"] = str("{:f}".format(info["sound"][0][0]))
|
||||
data["cueout"] = str("{:f}".format(info["sound"][-1][1]))
|
||||
data["length"] = str("{:f}".format(info["file duration"]))
|
||||
processed_data.append((f["id"], data))
|
||||
total += 1
|
||||
if total % 5 == 0:
|
||||
print "Total %s / %s files has been processed.." % (
|
||||
total,
|
||||
total_files,
|
||||
)
|
||||
except Exception, e:
|
||||
print e
|
||||
print traceback.format_exc()
|
||||
print "Processed: %d songs" % total
|
||||
subtotal += total
|
||||
|
||||
try:
|
||||
print api_client.update_cue_values_by_silan(processed_data)
|
||||
except Exception, e:
|
||||
print e
|
||||
print traceback.format_exc()
|
||||
print "Total %d songs Processed" % subtotal
|
||||
|
||||
except Exception, e:
|
||||
print e
|
||||
print traceback.format_exc()
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2011 Sourcefabric O.P.S.
|
||||
#
|
||||
# This file is part of the Airtime project.
|
||||
# http://airtime.sourcefabric.org/
|
||||
#
|
||||
# Airtime is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Airtime is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Airtime; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# This script send data to data collection server
|
||||
#
|
||||
# Absolute path to this script
|
||||
SCRIPT=$(readlink -f $0)
|
||||
# Absolute directory this script is in
|
||||
SCRIPTPATH=$(dirname $SCRIPT)
|
||||
|
||||
cd $SCRIPTPATH || exit 1
|
||||
|
||||
python airtime-test-soundcard.py "$@" || exit 1
|
|
@ -1,89 +0,0 @@
|
|||
import getopt
|
||||
import grp
|
||||
import os
|
||||
import pwd
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
"""
|
||||
we need to run the program as non-root because Liquidsoap refuses to run as root.
|
||||
It is possible to run change the effective user id (seteuid) before calling Liquidsoap
|
||||
but this introduces other problems (fake root user is not part of audio group after calling seteuid)
|
||||
"""
|
||||
if os.geteuid() == 0:
|
||||
print "Please run this program as non-root"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def printUsage():
|
||||
print "airtime-test-soundcard [-v] [-o alsa | ao | oss | portaudio | pulseaudio ] [-h]"
|
||||
print " Where: "
|
||||
print " -v verbose mode"
|
||||
print " -o Linux Sound API (default: alsa)"
|
||||
print " -h show help menu "
|
||||
|
||||
|
||||
def find_liquidsoap_binary():
|
||||
"""
|
||||
Starting with Airtime 2.0, we don't know the exact location of the Liquidsoap
|
||||
binary because it may have been installed through a debian package. Let's find
|
||||
the location of this binary.
|
||||
"""
|
||||
|
||||
rv = subprocess.call("which libretime-liquidsoap > /dev/null", shell=True)
|
||||
if rv == 0:
|
||||
return "libretime-liquidsoap"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
try:
|
||||
optlist, args = getopt.getopt(sys.argv[1:], "hvo:")
|
||||
except getopt.GetoptError, g:
|
||||
printUsage()
|
||||
sys.exit(1)
|
||||
|
||||
sound_api_types = set(["alsa", "ao", "oss", "portaudio", "pulseaudio"])
|
||||
|
||||
verbose = False
|
||||
sound_api = "alsa"
|
||||
for o, a in optlist:
|
||||
if "-v" == o:
|
||||
verbose = True
|
||||
if "-o" == o:
|
||||
if a.lower() in sound_api_types:
|
||||
sound_api = a.lower()
|
||||
else:
|
||||
print "Unknown sound api type\n"
|
||||
printUsage()
|
||||
sys.exit(1)
|
||||
if "-h" == o and len(optlist) == 1:
|
||||
printUsage()
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
print "Sound API: %s" % sound_api
|
||||
print "Outputting to soundcard. You should be able to hear a monotonous tone. Press ctrl-c to quit."
|
||||
|
||||
liquidsoap_exe = find_liquidsoap_binary()
|
||||
|
||||
if liquidsoap_exe is None:
|
||||
raise Exception("Liquidsoap not found!")
|
||||
|
||||
command = "%s 'output.%s(sine())'" % (liquidsoap_exe, sound_api)
|
||||
|
||||
if not verbose:
|
||||
command += " > /dev/null"
|
||||
|
||||
# print command
|
||||
rv = subprocess.call(command, shell=True)
|
||||
|
||||
# if we reach this point, it means that our subprocess exited without the user
|
||||
# doing a keyboard interrupt. This means there was a problem outputting to the
|
||||
# soundcard. Print appropriate message.
|
||||
print "There was an error using the selected sound API. Please select a different API " + "and run this program again. Use the -h option for help"
|
||||
|
||||
except KeyboardInterrupt, ki:
|
||||
print "\nExiting"
|
||||
except Exception, e:
|
||||
raise
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#-------------------------------------------------------------------------------
|
||||
# Copyright (c) 2011 Sourcefabric O.P.S.
|
||||
#
|
||||
# This file is part of the Airtime project.
|
||||
# http://airtime.sourcefabric.org/
|
||||
#
|
||||
# Airtime is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Airtime is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Airtime; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
#-------------------------------------------------------------------------------
|
||||
#-------------------------------------------------------------------------------
|
||||
# This script send data to data collection server
|
||||
#
|
||||
# Absolute path to this script
|
||||
SCRIPT=$(readlink -f $0)
|
||||
# Absolute directory this script is in
|
||||
SCRIPTPATH=$(dirname $SCRIPT)
|
||||
|
||||
cd $SCRIPTPATH || exit 1
|
||||
|
||||
python airtime-test-stream.py "$@" || exit 1
|
|
@ -1,128 +0,0 @@
|
|||
import getopt
|
||||
import grp
|
||||
import os
|
||||
import pwd
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
"""
|
||||
we need to run the program as non-root because Liquidsoap refuses to run as root.
|
||||
It is possible to run change the effective user id (seteuid) before calling Liquidsoap
|
||||
but this introduces other problems (fake root user is not part of audio group after calling seteuid)
|
||||
"""
|
||||
if os.geteuid() == 0:
|
||||
print "Please run this program as non-root"
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def printUsage():
|
||||
print "airtime-test-stream [-v] [-o icecast | shoutcast ] [-H hostname] [-P port] [-u username] [-p password] [-m mount]"
|
||||
print " Where: "
|
||||
print " -v verbose mode"
|
||||
print " -o stream server type (default: icecast)"
|
||||
print " -H hostname (default: localhost) "
|
||||
print " -P port (default: 8000) "
|
||||
print " -u user (default: source) "
|
||||
print " -p password (default: hackme) "
|
||||
print " -m mount (default: test) "
|
||||
print " -h show help menu"
|
||||
|
||||
|
||||
def find_liquidsoap_binary():
|
||||
"""
|
||||
With libretime 3.0 we are no longer depending upon the libretime-liquidsoap binary
|
||||
but use a generic install of liquidsoap. This takes care of checking if it is on the
|
||||
path and will lead to an error otherwise.
|
||||
"""
|
||||
|
||||
rv = subprocess.call("which liquidsoap > /dev/null", shell=True)
|
||||
if rv == 0:
|
||||
return "liquidsoap"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
optlist, args = getopt.getopt(sys.argv[1:], "hvo:H:P:u:p:m:")
|
||||
stream_types = set(["shoutcast", "icecast"])
|
||||
|
||||
verbose = False
|
||||
stream_type = "icecast"
|
||||
|
||||
host = "localhost"
|
||||
port = 8000
|
||||
user = "source"
|
||||
password = "hackme"
|
||||
mount = "test"
|
||||
|
||||
for o, a in optlist:
|
||||
if "-v" == o:
|
||||
verbose = True
|
||||
if "-o" == o:
|
||||
if a.lower() in stream_types:
|
||||
stream_type = a.lower()
|
||||
else:
|
||||
print "Unknown stream type\n"
|
||||
printUsage()
|
||||
sys.exit(1)
|
||||
if "-h" == o:
|
||||
printUsage()
|
||||
sys.exit(0)
|
||||
if "-H" == o:
|
||||
host = a
|
||||
if "-P" == o:
|
||||
port = a
|
||||
if "-u" == o:
|
||||
user = a
|
||||
if "-p" == o:
|
||||
password = a
|
||||
if "-m" == o:
|
||||
mount = a
|
||||
|
||||
try:
|
||||
|
||||
print "Protocol: %s " % stream_type
|
||||
print "Host: %s" % host
|
||||
print "Port: %s" % port
|
||||
print "User: %s" % user
|
||||
print "Password: %s" % password
|
||||
if stream_type == "icecast":
|
||||
print "Mount: %s\n" % mount
|
||||
|
||||
url = "http://%s:%s/%s" % (host, port, mount)
|
||||
print "Outputting to %s streaming server. You should be able to hear a monotonous tone on '%s'. Press ctrl-c to quit." % (
|
||||
stream_type,
|
||||
url,
|
||||
)
|
||||
|
||||
liquidsoap_exe = find_liquidsoap_binary()
|
||||
if liquidsoap_exe is None:
|
||||
raise Exception("Liquidsoap not found!")
|
||||
|
||||
if stream_type == "icecast":
|
||||
command = (
|
||||
'%s \'output.icecast(%%vorbis, host = "%s", port = %s, user= "%s", password = "%s", mount="%s", sine())\''
|
||||
% (liquidsoap_exe, host, port, user, password, mount)
|
||||
)
|
||||
else:
|
||||
command = (
|
||||
'%s \'output.shoutcast(%%mp3, host="%s", port = %s, user= "%s", password = "%s", sine())\''
|
||||
% (liquidsoap_exe, host, port, user, password)
|
||||
)
|
||||
|
||||
if not verbose:
|
||||
command += ' 2>/dev/null | grep "failed"'
|
||||
else:
|
||||
print command
|
||||
|
||||
# print command
|
||||
rv = subprocess.call(command, shell=True)
|
||||
|
||||
# if we reach this point, it means that our subprocess exited without the user
|
||||
# doing a keyboard interrupt. This means there was a problem outputting to the
|
||||
# stream server. Print appropriate message.
|
||||
print "There was an error with your stream configuration. Please review your configuration " + "and run this program again. Use the -h option for help"
|
||||
|
||||
except KeyboardInterrupt, ki:
|
||||
print "\nExiting"
|
||||
except Exception, e:
|
||||
raise
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
## Use config
|
||||
backup_folder=~/libretime_backup/
|
||||
else
|
||||
## User arg as config
|
||||
backup_folder=$1
|
||||
fi
|
||||
|
||||
airtime_conf_path=/etc/airtime/airtime.conf
|
||||
uploads_folder=/srv/airtime/stor/
|
||||
|
||||
psql_db=$(grep dbname ${airtime_conf_path} | awk '{print $3;}')
|
||||
psql_user=$(grep dbuser ${airtime_conf_path} | awk '{print $3;}')
|
||||
psql_password=$(grep dbpass ${airtime_conf_path} | awk '{print $3;}')
|
||||
|
||||
## Remove old backup
|
||||
rm -rf "$backup_folder"
|
||||
mkdir "$backup_folder"
|
||||
|
||||
## Backup of database
|
||||
|
||||
echo "db: Getting database..."
|
||||
pg_dump --dbname="postgresql://$psql_user:$psql_password@localhost/$psql_db" > "${backup_folder}database"
|
||||
echo "db: Complete"
|
||||
|
||||
## Backup of sounds
|
||||
|
||||
mkdir "${backup_folder}uploads/"
|
||||
|
||||
echo "stor : Copying uploaded files..."
|
||||
rsync -r -a --info=progress2 $uploads_folder "${backup_folder}uploads/"
|
||||
echo "stor: Complete"
|
||||
|
||||
## Backup of libretime config
|
||||
|
||||
mkdir "${backup_folder}airtime_config/"
|
||||
|
||||
echo "config: Copying config..."
|
||||
rsync -r -a --info=progress2 /etc/airtime/ "${backup_folder}airtime_config/"
|
||||
echo "config: Complete"
|
||||
|
||||
date >> "${backup_folder}datelog.txt"
|
|
@ -1,15 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
/etc/init.d/rabbitmq-server status | grep "\[{pid"
|
||||
pid_found="$?"
|
||||
|
||||
if [ "$pid_found" == "0" ]; then
|
||||
#PID is available in the status message
|
||||
rabbitmqpid=$(/etc/init.d/rabbitmq-server status | grep "\[{pid" | sed "s/.*,\(.*\)\}.*/\1/")
|
||||
else
|
||||
#PID should be available from file
|
||||
rabbitmqpid=$(sed "s/.*,\(.*\)\}.*/\1/" /var/lib/rabbitmq/pids)
|
||||
fi
|
||||
|
||||
echo "RabbitMQ PID: $rabbitmqpid"
|
||||
echo "$rabbitmqpid" > /var/run/airtime/rabbitmq.pid
|
|
@ -1,43 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# A bash script to convert all Rivendell's audio-library to MP3, extract meta-tags from Rivendell's
|
||||
# database and set appropriate tags to each MP3 file.
|
||||
|
||||
# Notes:
|
||||
# 1 - Rivendell store files in .wav format, airtime uses .mp3 format
|
||||
# 2 - WAV does not have Meta-tag support so all meta-tags need to be fetched from Rivendell database.
|
||||
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "usage: $0 <rivendell_dir> <final_dir>"
|
||||
exit
|
||||
fi
|
||||
|
||||
#*** MySql data ***#
|
||||
user="INSERT_MYSQL_USERNAME_HERE"
|
||||
pass="INSERT_MYSQL_PASSWORD_HERE"
|
||||
db="Rivendell" #Edit this only if you changed Rivendell's database name :-)
|
||||
#*** End ***#
|
||||
|
||||
rivendell_dir=$1
|
||||
end_dir=$2
|
||||
|
||||
cd "$rivendell_dir" || (echo "could not cd in $rivendell_dir" && exit 1)
|
||||
|
||||
for file in *; do
|
||||
lame "$file"
|
||||
done
|
||||
|
||||
mv "$rivendell_dir"/*.mp3 "$end_dir"
|
||||
cd "$end_dir" || (echo "could not cd in $end_dir" && exit 1)
|
||||
|
||||
for file in *; do
|
||||
id=$(echo "$file" | head -c 10)
|
||||
title=$(mysql -u $user -p$pass -sN -e "SELECT CU.DESCRIPTION FROM CUTS CU, CART CA WHERE CA.NUMBER=CU.CART_NUMBER AND CU.CUT_NAME=\"${id}\"" $db)
|
||||
artist=$(mysql -u $user -p$pass -sN -e "SELECT CA.ARTIST FROM CUTS CU, CART CA WHERE CA.NUMBER=CU.CART_NUMBER AND CU.CUT_NAME=\"${id}\"" $db)
|
||||
album=$(mysql -u $user -p$pass -sN -e "SELECT CA.ALBUM FROM CUTS CU, CART CA WHERE CA.NUMBER=CU.CART_NUMBER AND CU.CUT_NAME=\"${id}\"" $db)
|
||||
year=$(mysql -u $user -p$pass -sN -e "SELECT CA.YEAR FROM CUTS CU, CART CA WHERE CA.NUMBER=CU.CART_NUMBER AND CU.CUT_NAME=\"${id}\"" $db)
|
||||
id3 -t "$title" -a "$artist" -A "$album" -y "$year" $file
|
||||
mv "$file" "$artist-$title.mp3"
|
||||
done
|
||||
|
||||
exit
|
|
@ -1,22 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
|
||||
error() {
|
||||
echo >&2 "error: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Make sure only root can run our script
|
||||
(($( id -u) == 0)) || error "this script must be run as root!"
|
||||
|
||||
command -v sudo > /dev/null || error "sudo command not found!"
|
||||
command -v openssl > /dev/null || error "openssl command not found!"
|
||||
command -v psql > /dev/null || error "psql command not found!"
|
||||
|
||||
typeset -r DB_USER="airtime"
|
||||
DB_PASSWORD=$(openssl rand -hex 16)
|
||||
typeset -r DB_PASSWORD
|
||||
|
||||
echo "Changing password for database user '$DB_USER' to '$DB_PASSWORD'"
|
||||
sudo -u postgres psql -c "ALTER USER $DB_USER WITH PASSWORD '$DB_PASSWORD';"
|
|
@ -1,22 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -u
|
||||
|
||||
error() {
|
||||
echo >&2 "error: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Make sure only root can run our script
|
||||
(($( id -u) == 0)) || error "this script must be run as root!"
|
||||
|
||||
command -v openssl > /dev/null || error "openssl command not found!"
|
||||
command -v rabbitmqctl > /dev/null || error "rabbitmqctl command not found!"
|
||||
|
||||
typeset -r RMQ_USER="airtime"
|
||||
RMQ_PASSWORD=$(openssl rand -hex 16)
|
||||
typeset -r RMQ_PASSWORD
|
||||
|
||||
# RabbitMQ
|
||||
echo "Changing password for rabbitmq user '$RMQ_USER' to '$RMQ_PASSWORD'"
|
||||
rabbitmqctl change_password "$RMQ_USER" "$RMQ_PASSWORD"
|
|
@ -1,63 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
import ConfigParser
|
||||
import requests
|
||||
from urlparse import urlparse
|
||||
|
||||
CONFIG_PATH = "/etc/airtime/airtime.conf"
|
||||
GENERAL_CONFIG_SECTION = "general"
|
||||
|
||||
|
||||
def read_config_file(config_path):
|
||||
"""Parse the application's config file located at config_path."""
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
try:
|
||||
config.readfp(open(config_path))
|
||||
except IOError as e:
|
||||
print "Failed to open config file at " + config_path + ": " + e.strerror
|
||||
exit(-1)
|
||||
except Exception:
|
||||
print e.strerror
|
||||
exit(-1)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
config = read_config_file(CONFIG_PATH)
|
||||
api_key = config.get(GENERAL_CONFIG_SECTION, "api_key")
|
||||
base_url = config.get(GENERAL_CONFIG_SECTION, "base_url")
|
||||
base_dir = config.get(GENERAL_CONFIG_SECTION, "base_dir")
|
||||
base_port = config.get(GENERAL_CONFIG_SECTION, "base_port", 80)
|
||||
action = "upgrade"
|
||||
station_url = ""
|
||||
|
||||
default_url = "http://%s:%s%s" % (base_url, base_port, base_dir)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--downgrade", help="Downgrade the station", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"station_url", help="station URL", nargs="?", default=default_url
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.downgrade:
|
||||
action = "downgrade"
|
||||
|
||||
if args.station_url:
|
||||
station_url = args.station_url
|
||||
|
||||
# Add http:// if you were lazy and didn't pass a scheme to this script
|
||||
url = urlparse(station_url)
|
||||
if not url.scheme:
|
||||
station_url = "http://%s" % station_url
|
||||
|
||||
print "Requesting %s..." % action
|
||||
r = requests.get("%s/%s" % (station_url, action), auth=(api_key, ""))
|
||||
print r.text
|
||||
r.raise_for_status()
|
Loading…
Reference in New Issue