Merge branch '2.5.x-installer' of https://github.com/sourcefabric/Airtime into 2.5.x-installer
This commit is contained in:
commit
0a3d8ea515
8
install
8
install
|
@ -466,7 +466,10 @@ for i in /etc/init/airtime*.template; do
|
||||||
mv $i ${i%.template}
|
mv $i ${i%.template}
|
||||||
done
|
done
|
||||||
|
|
||||||
#loudCmd "initctl reload-configuration"
|
set +e
|
||||||
|
loudCmd "initctl reload-configuration"
|
||||||
|
loudCmd "systemctl daemon-reload" #systemd hipsters
|
||||||
|
set -e
|
||||||
|
|
||||||
if [ ! -d /var/log/airtime ]; then
|
if [ ! -d /var/log/airtime ]; then
|
||||||
loud "\n-----------------------------------------------------"
|
loud "\n-----------------------------------------------------"
|
||||||
|
@ -504,6 +507,9 @@ loud "\n-----------------------------------------------------"
|
||||||
loud " * Configuring PostgreSQL * "
|
loud " * Configuring PostgreSQL * "
|
||||||
loud "-----------------------------------------------------"
|
loud "-----------------------------------------------------"
|
||||||
|
|
||||||
|
# Ensure postgres is running - It isn't after you install the postgres package on Ubuntu 15.04
|
||||||
|
loudCmd "service postgresql start"
|
||||||
|
|
||||||
setupAirtimePostgresUser() {
|
setupAirtimePostgresUser() {
|
||||||
# here-doc to execute this block as postgres user
|
# here-doc to execute this block as postgres user
|
||||||
su postgres <<'EOF'
|
su postgres <<'EOF'
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
apache2
|
||||||
|
libapache2-mod-php5
|
||||||
|
php5
|
||||||
|
libzend-framework-php
|
||||||
|
php-pear
|
||||||
|
php5-gd
|
||||||
|
|
||||||
|
lsb-release
|
||||||
|
|
||||||
|
rabbitmq-server
|
||||||
|
|
||||||
|
postgresql
|
||||||
|
postgresql-client
|
||||||
|
php5-pgsql
|
||||||
|
|
||||||
|
python
|
||||||
|
python-virtualenv
|
||||||
|
python-pip
|
||||||
|
|
||||||
|
libsoundtouch-ocaml
|
||||||
|
libtaglib-ocaml
|
||||||
|
libao-ocaml
|
||||||
|
libmad-ocaml
|
||||||
|
ecasound
|
||||||
|
libportaudio2
|
||||||
|
libsamplerate0
|
||||||
|
|
||||||
|
patch
|
||||||
|
|
||||||
|
php5-curl
|
||||||
|
mpg123
|
||||||
|
|
||||||
|
icecast2
|
||||||
|
|
||||||
|
libcamomile-ocaml-data
|
||||||
|
libpulse0
|
||||||
|
vorbis-tools
|
||||||
|
lsb-release
|
||||||
|
lsof
|
||||||
|
vorbisgain
|
||||||
|
flac
|
||||||
|
vorbis-tools
|
||||||
|
pwgen
|
||||||
|
libfaad2
|
||||||
|
php-apc
|
||||||
|
|
||||||
|
lame
|
||||||
|
|
||||||
|
coreutils
|
||||||
|
|
||||||
|
liquidsoap
|
||||||
|
liquidsoap-plugin-alsa
|
||||||
|
liquidsoap-plugin-ao
|
||||||
|
liquidsoap-plugin-faad
|
||||||
|
liquidsoap-plugin-flac
|
||||||
|
liquidsoap-plugin-icecast
|
||||||
|
liquidsoap-plugin-lame
|
||||||
|
liquidsoap-plugin-mad
|
||||||
|
liquidsoap-plugin-ogg
|
||||||
|
liquidsoap-plugin-portaudio
|
||||||
|
liquidsoap-plugin-pulseaudio
|
||||||
|
liquidsoap-plugin-taglib
|
||||||
|
liquidsoap-plugin-voaacenc
|
||||||
|
liquidsoap-plugin-vorbis
|
||||||
|
|
||||||
|
silan
|
||||||
|
libopus0
|
||||||
|
|
||||||
|
sysvinit-utils
|
|
@ -1,13 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# This script for a correct system environment for Airtime.
|
|
||||||
#
|
|
||||||
# Absolute path to this script
|
|
||||||
SCRIPT=`readlink -f $0`
|
|
||||||
# Absolute directory this script is in
|
|
||||||
SCRIPTPATH=`dirname $SCRIPT`
|
|
||||||
|
|
||||||
invokePwd=$PWD
|
|
||||||
cd $SCRIPTPATH
|
|
||||||
|
|
||||||
php -q airtime-check-system.php "$@" || exit 1
|
|
|
@ -1,270 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
AirtimeCheck::ExitIfNotRoot();
|
|
||||||
|
|
||||||
date_default_timezone_set("UTC");
|
|
||||||
|
|
||||||
$sapi_type = php_sapi_name();
|
|
||||||
|
|
||||||
$showColor = !in_array("--no-color", $argv);
|
|
||||||
|
|
||||||
//detect if we are running via the command line
|
|
||||||
if (substr($sapi_type, 0, 3) == 'cli') {
|
|
||||||
//we are running from the command-line
|
|
||||||
|
|
||||||
$airtimeIni = AirtimeCheck::GetAirtimeConf();
|
|
||||||
$apiKey = $airtimeIni['general']['api_key'];
|
|
||||||
$baseUrl = $airtimeIni['general']['base_url'];
|
|
||||||
$base_port = $airtimeIni['general']['base_port'];
|
|
||||||
$base_dir = $airtimeIni['general']['base_dir'];
|
|
||||||
|
|
||||||
$status = AirtimeCheck::GetStatus($baseUrl, $base_port, $base_dir, $apiKey);
|
|
||||||
AirtimeCheck::PrintStatus($baseUrl, $base_port, $status);
|
|
||||||
//AirtimeCheck::PrintStatus($baseUrl, $status);
|
|
||||||
}
|
|
||||||
|
|
||||||
class AirtimeCheck {
|
|
||||||
|
|
||||||
private static $AIRTIME_STATUS_OK = true;
|
|
||||||
CONST UNKNOWN = "UNKNOWN";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that the user is running this PHP script with root
|
|
||||||
* permissions. If not running with root permissions, causes the
|
|
||||||
* script to exit.
|
|
||||||
*/
|
|
||||||
public static function ExitIfNotRoot()
|
|
||||||
{
|
|
||||||
// Need to check that we are superuser before running this.
|
|
||||||
$euid = posix_geteuid();
|
|
||||||
$user = exec('whoami');
|
|
||||||
if($euid != 0 && $user != "www-data"){
|
|
||||||
echo "Must be root user.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function GetCpuInfo()
|
|
||||||
{
|
|
||||||
$command = "cat /proc/cpuinfo |grep -m 1 'model name' ";
|
|
||||||
exec($command, $output, $rv);
|
|
||||||
|
|
||||||
if ($rv != 0 || !isset($output[0]))
|
|
||||||
return self::UNKNOWN;
|
|
||||||
|
|
||||||
$choppedStr = explode(":", $output[0]);
|
|
||||||
|
|
||||||
if (!isset($choppedStr[1]))
|
|
||||||
return self::UNKNOWN;
|
|
||||||
|
|
||||||
$status = trim($choppedStr[1]);
|
|
||||||
return $status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function CheckOsTypeVersion(){
|
|
||||||
|
|
||||||
exec("lsb_release -ds", $output, $rv);
|
|
||||||
if ($rv != 0 || !isset($output[0])){
|
|
||||||
$os_string = self::UNKNOWN;
|
|
||||||
} else {
|
|
||||||
$os_string = $output[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($output);
|
|
||||||
|
|
||||||
// Figure out if 32 or 64 bit
|
|
||||||
exec("uname -m", $output, $rv);
|
|
||||||
if ($rv != 0 || !isset($output[0])){
|
|
||||||
$machine = self::UNKNOWN;
|
|
||||||
} else {
|
|
||||||
$machine = $output[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $os_string." ".$machine;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function GetServerType($p_baseUrl, $p_basePort)
|
|
||||||
{
|
|
||||||
$headerInfo = get_headers("http://$p_baseUrl:$p_basePort",1);
|
|
||||||
|
|
||||||
if (!isset($headerInfo['Server'][0])) {
|
|
||||||
return self::UNKNOWN;
|
|
||||||
} else if (is_array($headerInfo['Server'])) {
|
|
||||||
return $headerInfo['Server'][0];
|
|
||||||
} else {
|
|
||||||
return $headerInfo['Server'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function GetStatus($p_baseUrl, $p_basePort, $p_baseDir, $p_apiKey){
|
|
||||||
if ($p_baseDir == '/') {
|
|
||||||
$url = "http://$p_baseUrl:$p_basePort/api/status/format/json/api_key/%%api_key%%";
|
|
||||||
} else {
|
|
||||||
$url = "http://$p_baseUrl:$p_basePort/$p_baseDir"."api/status/format/json/api_key/%%api_key%%";
|
|
||||||
}
|
|
||||||
self::output_status("AIRTIME_STATUS_URL", $url);
|
|
||||||
$url = str_replace("%%api_key%%", $p_apiKey, $url);
|
|
||||||
|
|
||||||
$ch = curl_init($url);
|
|
||||||
|
|
||||||
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
|
|
||||||
|
|
||||||
$data = curl_exec($ch);
|
|
||||||
|
|
||||||
//$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function PrintStatus($p_baseUrl, $p_basePort, $p_status){
|
|
||||||
|
|
||||||
if ($p_status === false){
|
|
||||||
self::output_status("AIRTIME_SERVER_RESPONDING", "FAILED");
|
|
||||||
} else {
|
|
||||||
self::output_status("AIRTIME_SERVER_RESPONDING", "OK");
|
|
||||||
|
|
||||||
$p_status = json_decode($p_status);
|
|
||||||
|
|
||||||
if (isset($p_status->status)) {
|
|
||||||
$data = $p_status->status;
|
|
||||||
} else {
|
|
||||||
$data = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($data->platform)) {
|
|
||||||
self::output_status("KERNEL_VERSION", $data->platform->release);
|
|
||||||
self::output_status("MACHINE_ARCHITECTURE", $data->platform->machine);
|
|
||||||
self::output_status("TOTAL_MEMORY_MBYTES", $data->platform->memory);
|
|
||||||
self::output_status("TOTAL_SWAP_MBYTES", $data->platform->swap);
|
|
||||||
self::output_status("AIRTIME_VERSION", $data->airtime_version);
|
|
||||||
} else {
|
|
||||||
self::output_status("KERNEL_VERSION", "UNKNOWN");
|
|
||||||
self::output_status("MACHINE_ARCHITECTURE", "UNKNOWN");
|
|
||||||
self::output_status("TOTAL_MEMORY_MBYTES", "UNKNOWN");
|
|
||||||
self::output_status("TOTAL_SWAP_MBYTES", "UNKNOWN");
|
|
||||||
self::output_status("AIRTIME_VERSION", "UNKNOWN");
|
|
||||||
}
|
|
||||||
self::output_status("OS", self::CheckOsTypeVersion());
|
|
||||||
self::output_status("CPU", self::GetCpuInfo());
|
|
||||||
self::output_status("WEB_SERVER", self::GetServerType($p_baseUrl, $p_basePort));
|
|
||||||
|
|
||||||
if (isset($data->services)) {
|
|
||||||
$services = $data->services;
|
|
||||||
} else {
|
|
||||||
$services = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($services->pypo) && $services->pypo->process_id != "FAILED") {
|
|
||||||
self::output_status("PLAYOUT_ENGINE_PROCESS_ID", $data->services->pypo->process_id);
|
|
||||||
self::output_status("PLAYOUT_ENGINE_RUNNING_SECONDS", $data->services->pypo->uptime_seconds);
|
|
||||||
self::output_status("PLAYOUT_ENGINE_MEM_PERC", $data->services->pypo->memory_perc);
|
|
||||||
self::output_status("PLAYOUT_ENGINE_CPU_PERC", $data->services->pypo->cpu_perc);
|
|
||||||
} else {
|
|
||||||
self::output_status("PLAYOUT_ENGINE_PROCESS_ID", "FAILED");
|
|
||||||
self::output_status("PLAYOUT_ENGINE_RUNNING_SECONDS", "0");
|
|
||||||
self::output_status("PLAYOUT_ENGINE_MEM_PERC", "0%");
|
|
||||||
self::output_status("PLAYOUT_ENGINE_CPU_PERC", "0%");
|
|
||||||
$log = "/var/log/airtime/pypo/pypo.log";
|
|
||||||
self::show_log_file($log);
|
|
||||||
|
|
||||||
}
|
|
||||||
if (isset($services->liquidsoap) && $services->liquidsoap->process_id != "FAILED") {
|
|
||||||
self::output_status("LIQUIDSOAP_PROCESS_ID", $data->services->liquidsoap->process_id);
|
|
||||||
self::output_status("LIQUIDSOAP_RUNNING_SECONDS", $data->services->liquidsoap->uptime_seconds);
|
|
||||||
self::output_status("LIQUIDSOAP_MEM_PERC", $data->services->liquidsoap->memory_perc);
|
|
||||||
self::output_status("LIQUIDSOAP_CPU_PERC", $data->services->liquidsoap->cpu_perc);
|
|
||||||
} else {
|
|
||||||
self::output_status("LIQUIDSOAP_PROCESS_ID", "FAILED");
|
|
||||||
self::output_status("LIQUIDSOAP_RUNNING_SECONDS", "0");
|
|
||||||
self::output_status("LIQUIDSOAP_MEM_PERC", "0%");
|
|
||||||
self::output_status("LIQUIDSOAP_CPU_PERC", "0%");
|
|
||||||
$log = "/var/log/airtime/pypo-liquidsoap/ls_script.log";
|
|
||||||
self::show_log_file($log);
|
|
||||||
}
|
|
||||||
if (isset($services->media_monitor) && $services->media_monitor->process_id != "FAILED") {
|
|
||||||
self::output_status("MEDIA_MONITOR_PROCESS_ID", $data->services->media_monitor->process_id);
|
|
||||||
self::output_status("MEDIA_MONITOR_RUNNING_SECONDS", $data->services->media_monitor->uptime_seconds);
|
|
||||||
self::output_status("MEDIA_MONITOR_MEM_PERC", $data->services->media_monitor->memory_perc);
|
|
||||||
self::output_status("MEDIA_MONITOR_CPU_PERC", $data->services->media_monitor->cpu_perc);
|
|
||||||
} else {
|
|
||||||
self::output_status("MEDIA_MONITOR_PROCESS_ID", "FAILED");
|
|
||||||
self::output_status("MEDIA_MONITOR_RUNNING_SECONDS", "0");
|
|
||||||
self::output_status("MEDIA_MONITOR_MEM_PERC", "0%");
|
|
||||||
self::output_status("MEDIA_MONITOR_CPU_PERC", "0%");
|
|
||||||
$log = "/var/log/airtime/media-monitor/media-monitor.log";
|
|
||||||
self::show_log_file($log);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self::$AIRTIME_STATUS_OK){
|
|
||||||
self::output_comment("Your installation of Airtime looks OK!");
|
|
||||||
exit(0);
|
|
||||||
} else {
|
|
||||||
self::output_comment("There appears to be a problem with your Airtime installation.");
|
|
||||||
self::output_comment("Please visit http://wiki.sourcefabric.org/x/HABQ");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function show_log_file($log) {
|
|
||||||
self::output_comment("Check the log file $log");
|
|
||||||
self::output_comment("");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function output_comment($comment){
|
|
||||||
if (!is_array($comment)) {
|
|
||||||
$comment = array($comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($comment as $c) {
|
|
||||||
echo "-- $c".PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function output_status($key, $value){
|
|
||||||
global $showColor;
|
|
||||||
|
|
||||||
$RED = "[0;31m";
|
|
||||||
$ORANGE = "[0;33m";
|
|
||||||
$GREEN = "[1;32m";
|
|
||||||
|
|
||||||
$color = $GREEN;
|
|
||||||
|
|
||||||
if ($value == "FAILED"){
|
|
||||||
$color = $RED;
|
|
||||||
self::$AIRTIME_STATUS_OK = false;
|
|
||||||
} else if ($value == "NOT MONITORED"){
|
|
||||||
$color = $ORANGE;
|
|
||||||
self::$AIRTIME_STATUS_OK = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($showColor)
|
|
||||||
echo sprintf("%-31s= %s", $key, self::term_color($value, $color)).PHP_EOL;
|
|
||||||
else
|
|
||||||
echo sprintf("%-31s= %s", $key, $value).PHP_EOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function term_color($text, $color){
|
|
||||||
|
|
||||||
if($color == ""){
|
|
||||||
$color = "[0m";
|
|
||||||
}
|
|
||||||
|
|
||||||
return chr(27)."$color$text".chr(27)."[0m";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +1,326 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/python2 import sys
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from configobj import ConfigObj
|
||||||
|
from optparse import OptionParser, OptionValueError
|
||||||
|
from api_clients import api_client as apc
|
||||||
|
import json
|
||||||
|
import shutil
|
||||||
|
import commands
|
||||||
|
|
||||||
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
|
#sys.path.append('/usr/lib/airtime/media-monitor/mm2/')
|
||||||
. ${virtualenv_bin}activate
|
from mm2.media.monitor.pure import is_file_supported
|
||||||
|
|
||||||
invokePwd=$PWD
|
# create logger
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
airtime_import_path="/usr/lib/airtime/utils/airtime-import/"
|
# no logging
|
||||||
airtime_import_script="airtime-import.py"
|
ch = logging.StreamHandler()
|
||||||
|
logging.disable(50)
|
||||||
|
|
||||||
api_client_path="/usr/lib/airtime/"
|
# add ch to logger
|
||||||
cd ${airtime_import_path}
|
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.")
|
||||||
|
# sucess
|
||||||
|
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.")
|
||||||
|
# sucess
|
||||||
|
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 direcory? (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 direcory? (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()
|
||||||
|
|
||||||
exec 2>&1
|
|
||||||
|
|
||||||
export PYTHONPATH=${api_client_path}
|
|
||||||
|
|
||||||
# Note the -u when calling python! we need it to get unbuffered binary stdout and stderr
|
|
||||||
exec python -u ${airtime_import_path}${airtime_import_script} --dir "$invokePwd" "$@"
|
|
||||||
|
|
||||||
# EOF
|
|
||||||
|
|
|
@ -1,326 +0,0 @@
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
from configobj import ConfigObj
|
|
||||||
from optparse import OptionParser, OptionValueError
|
|
||||||
from api_clients import api_client as apc
|
|
||||||
import json
|
|
||||||
import shutil
|
|
||||||
import commands
|
|
||||||
|
|
||||||
sys.path.append('/usr/lib/airtime/media-monitor/mm2/')
|
|
||||||
from 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.")
|
|
||||||
# sucess
|
|
||||||
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.")
|
|
||||||
# sucess
|
|
||||||
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 direcory? (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 direcory? (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 = 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,42 +1,79 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/python
|
||||||
#-------------------------------------------------------------------------------
|
from configobj import ConfigObj
|
||||||
# Copyright (c) 2011 Sourcefabric O.P.S.
|
from api_clients import api_client as apc
|
||||||
#
|
|
||||||
# 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 handles update cue-in/cue-out points for files that already exist
|
|
||||||
# in Airtime's library.
|
|
||||||
#
|
|
||||||
exec 2>&1
|
|
||||||
airtime_silan_script="airtime-silan.py"
|
|
||||||
api_client_path="/usr/lib/airtime/"
|
|
||||||
|
|
||||||
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
|
import logging
|
||||||
. ${virtualenv_bin}activate
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import traceback
|
||||||
|
|
||||||
export PYTHONPATH=${api_client_path}
|
# create logger
|
||||||
|
logger = logging.getLogger()
|
||||||
|
|
||||||
# Absolute path to this script
|
# no logging
|
||||||
SCRIPT=`readlink -f $0`
|
ch = logging.StreamHandler()
|
||||||
# Absolute directory this script is in
|
logging.disable(50)
|
||||||
SCRIPTPATH=`dirname $SCRIPT`
|
|
||||||
|
|
||||||
cd $SCRIPTPATH
|
# add ch to logger
|
||||||
python ${airtime_silan_script}
|
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('{0:f}'.format(info['sound'][0][0]))
|
||||||
|
data['cueout'] = str('{0:f}'.format(info['sound'][-1][1]))
|
||||||
|
data['length'] = str('{0: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,78 +0,0 @@
|
||||||
from configobj import ConfigObj
|
|
||||||
from api_clients import api_client as apc
|
|
||||||
|
|
||||||
import logging
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
# 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('{0:f}'.format(info['sound'][0][0]))
|
|
||||||
data['cueout'] = str('{0:f}'.format(info['sound'][-1][1]))
|
|
||||||
data['length'] = str('{0: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,18 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Determine directories, files
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
virtualenv_bin="/usr/lib/airtime/airtime_virtualenv/bin/"
|
|
||||||
. ${virtualenv_bin}activate
|
|
||||||
|
|
||||||
# Absolute path to this script
|
|
||||||
SCRIPT=`readlink -f $0`
|
|
||||||
# Absolute directory this script is in
|
|
||||||
SCRIPTPATH=`dirname $SCRIPT`
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
# Do import
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
invokePwd=$PWD
|
|
||||||
cd $SCRIPTPATH && python airtime-update-db-settings.py
|
|
|
@ -1,87 +0,0 @@
|
||||||
"""
|
|
||||||
The purpose of this script is to consolidate into one location where
|
|
||||||
we need to update database host, dbname, username and password.
|
|
||||||
|
|
||||||
This script reads from /etc/airtime/airtime.conf.
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import ConfigParser
|
|
||||||
import xml.dom.minidom
|
|
||||||
from xml.dom.minidom import Node
|
|
||||||
|
|
||||||
if os.geteuid() != 0:
|
|
||||||
print "Please run this as root."
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
airtime_conf = '/etc/airtime/airtime.conf'
|
|
||||||
|
|
||||||
#Read the universal values
|
|
||||||
parser = ConfigParser.SafeConfigParser()
|
|
||||||
parser.read(airtime_conf)
|
|
||||||
|
|
||||||
host = 'resources.db.params.host'
|
|
||||||
dbname = 'resources.db.params.dbname'
|
|
||||||
username = 'resources.db.params.username'
|
|
||||||
password = 'resources.db.params.password'
|
|
||||||
|
|
||||||
airtime_dir = parser.get('general', 'airtime_dir')
|
|
||||||
if os.path.exists(airtime_dir):
|
|
||||||
print 'Airtime root folder found at %s' % airtime_dir
|
|
||||||
else:
|
|
||||||
print 'Could not find Airtime root folder specified by "airtime_dir" in %s' % airtime_conf
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
print ("Updating %s/application/configs/application.ini" % airtime_dir)
|
|
||||||
f = file('%s/application/configs/application.ini' % airtime_dir,'r')
|
|
||||||
file_lines = []
|
|
||||||
|
|
||||||
for line in f:
|
|
||||||
if line[0:len(host)] == host:
|
|
||||||
line= '%s = "%s"\n' % (host, parser.get('database', 'host'))
|
|
||||||
elif line[0:len(dbname)] == dbname:
|
|
||||||
line= '%s = "%s"\n' % (dbname, parser.get('database', 'dbname'))
|
|
||||||
elif line[0:len(username)] == username:
|
|
||||||
line= '%s = "%s"\n' % (username, parser.get('database', 'dbuser'))
|
|
||||||
elif line[0:len(password)] == password:
|
|
||||||
line= '%s = "%s"\n' % (password, parser.get('database', 'dbpass'))
|
|
||||||
file_lines.append(line)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
f = file('%s/application/configs/application.ini' % airtime_dir, 'w')
|
|
||||||
f.writelines(file_lines)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
|
|
||||||
print ("Updating %s/build/build.properties" % airtime_dir)
|
|
||||||
|
|
||||||
f = file('%s/build/build.properties' % airtime_dir, 'r')
|
|
||||||
file_lines = []
|
|
||||||
|
|
||||||
db_url = 'propel.database.url'
|
|
||||||
|
|
||||||
for line in f:
|
|
||||||
if line[0:len(db_url)] == db_url:
|
|
||||||
line = '%s = pgsql:host=%s dbname=%s user=%s password=%s\n' % \
|
|
||||||
(db_url, parser.get('database', 'host'), parser.get('database', 'dbname'), parser.get('database', 'dbuser'), \
|
|
||||||
parser.get('database', 'dbpass'))
|
|
||||||
file_lines.append(line)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
f = file('%s/build/build.properties' % airtime_dir, 'w')
|
|
||||||
f.writelines(file_lines)
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
print ("Updating %s/build/runtime-conf.xml" % airtime_dir)
|
|
||||||
|
|
||||||
doc = xml.dom.minidom.parse('%s/build/runtime-conf.xml' % airtime_dir)
|
|
||||||
|
|
||||||
node = doc.getElementsByTagName("dsn")[0]
|
|
||||||
node.firstChild.nodeValue = 'pgsql:host=%s;port=5432;dbname=%s;user=%s;password=%s' % (parser.get('database', 'host'), \
|
|
||||||
parser.get('database', 'dbname'), parser.get('database', 'dbuser'), parser.get('database', 'dbpass'))
|
|
||||||
|
|
||||||
xml_file = open('%s/build/runtime-conf.xml' % airtime_dir, "w")
|
|
||||||
xml_file.writelines(doc.toxml('utf-8'))
|
|
||||||
xml_file.close()
|
|
||||||
|
|
||||||
print "Success!"
|
|
Loading…
Reference in New Issue