Fixed airtime-import to work without the virtualenv
This commit is contained in:
parent
0eebd182dd
commit
19de887efb
|
@ -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/"
|
||||
. ${virtualenv_bin}activate
|
||||
#sys.path.append('/usr/lib/airtime/media-monitor/mm2/')
|
||||
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/"
|
||||
airtime_import_script="airtime-import.py"
|
||||
# no logging
|
||||
ch = logging.StreamHandler()
|
||||
logging.disable(50)
|
||||
|
||||
api_client_path="/usr/lib/airtime/"
|
||||
cd ${airtime_import_path}
|
||||
# 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 = 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()
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue