Merge branch '2.1.x' into devel
Conflicts: airtime_mvc/application/controllers/ApiController.php airtime_mvc/application/controllers/LibraryController.php airtime_mvc/application/controllers/PlaylistController.php airtime_mvc/application/models/Playlist.php python_apps/media-monitor/airtimefilemonitor/airtimemediamonitorbootstrap.py python_apps/media-monitor/airtimefilemonitor/airtimemetadata.py
This commit is contained in:
commit
4ebcb1b1f9
|
@ -90,12 +90,7 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
|
|||
$userType = "";
|
||||
}
|
||||
$view->headScript()->appendScript("var userType = '$userType';");
|
||||
if (Application_Model_Preference::GetPlanLevel() != "disabled"
|
||||
&& !($_SERVER['REQUEST_URI'] == '/Dashboard/stream-player' || $_SERVER['REQUEST_URI'] == '/audiopreview/audio-preview-player')) {
|
||||
$client_id = Application_Model_Preference::GetClientId();
|
||||
$view->headScript()->appendScript("var livechat_client_id = '$client_id';");
|
||||
$view->headScript()->appendFile($baseUrl . '/js/airtime/common/livechat.js?'.$CC_CONFIG['airtime_version'], 'text/javascript');
|
||||
}
|
||||
|
||||
if(isset($CC_CONFIG['demo']) && $CC_CONFIG['demo'] == 1){
|
||||
$view->headScript()->appendFile($baseUrl.'/js/libs/google-analytics.js?'.$CC_CONFIG['airtime_version'],'text/javascript');
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
define('AIRTIME_COPYRIGHT_DATE', '2010-2012');
|
||||
define('AIRTIME_REST_VERSION', '1.1');
|
||||
define('AIRTIME_API_VERSION', '1.0');
|
||||
define('AIRTIME_API_VERSION', '1.1');
|
||||
|
||||
// Metadata Keys for files
|
||||
define('MDATA_KEY_FILEPATH', 'filepath');
|
||||
|
|
|
@ -261,30 +261,28 @@ class ApiController extends Zend_Controller_Action
|
|||
$request = $this->getRequest();
|
||||
$type = $request->getParam('type');
|
||||
if ($type == "endofday") {
|
||||
// make getNextShows use end of day
|
||||
$limit = $request->getParam('limit');
|
||||
if($limit == "" || !is_numeric($limit)) {
|
||||
$limit = "5";
|
||||
}
|
||||
|
||||
// make GetNextShows use end of day
|
||||
$utcTimeEnd = Application_Common_DateHelper::GetDayEndTimestampInUtc();
|
||||
$result = array("env"=>APPLICATION_ENV,
|
||||
"schedulerTime"=>gmdate("Y-m-d H:i:s"),
|
||||
"nextShow"=>Application_Model_Show::getNextShows($utcTimeNow, 5, $utcTimeEnd));
|
||||
|
||||
"nextShow"=>Application_Model_Show::getNextShows($utcTimeNow, $limit, $utcTimeEnd));
|
||||
|
||||
Application_Model_Show::convertToLocalTimeZone($result["nextShow"], array("starts", "ends", "start_timestamp", "end_timestamp"));
|
||||
} else {
|
||||
|
||||
$limit = $request->getParam('limit');
|
||||
if ($limit == "" || !is_numeric($limit)) {
|
||||
$limit = "5";
|
||||
}
|
||||
|
||||
$result = Application_Model_Schedule::GetPlayOrderRange();
|
||||
|
||||
//Convert from UTC to localtime for user.
|
||||
//Convert from UTC to localtime for Web Browser.
|
||||
Application_Model_Show::convertToLocalTimeZone($result["currentShow"], array("starts", "ends", "start_timestamp", "end_timestamp"));
|
||||
Application_Model_Show::convertToLocalTimeZone($result["nextShow"], array("starts", "ends", "start_timestamp", "end_timestamp"));
|
||||
}
|
||||
|
||||
$result['AIRTIME_API_VERSION'] = AIRTIME_API_VERSION; //used by caller to determine if the airtime they are running or widgets in use is out of date.
|
||||
|
||||
//echo json_encode($result);
|
||||
header("Content-type: text/javascript");
|
||||
echo $_GET['callback'].'('.json_encode($result).')';
|
||||
} else {
|
||||
|
|
|
@ -125,28 +125,11 @@ class LibraryController extends Zend_Controller_Action
|
|||
}
|
||||
}
|
||||
|
||||
$hasPermission = true;
|
||||
if (count($playlists)) {
|
||||
// make sure use has permission to delete all playslists in the list
|
||||
if (!$isAdminOrPM) {
|
||||
foreach ($playlists as $pid) {
|
||||
$pl = new Application_Model_Playlist($pid);
|
||||
if ($pl->getCreatorId() != $user->getId()) {
|
||||
$hasPermission = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$isAdminOrPM && count($files)) {
|
||||
$hasPermission = false;
|
||||
}
|
||||
if (!$hasPermission) {
|
||||
$this->view->message = "You don't have a permission to delete all playlists/files that are selected.";
|
||||
|
||||
try {
|
||||
Application_Model_Playlist::deletePlaylists($playlists, $user->getId());
|
||||
} catch (PlaylistNoPermissionException $e) {
|
||||
$this->view->message = "You don't have permission to delete selected playlists/files.";
|
||||
return;
|
||||
} else {
|
||||
Application_Model_Playlist::DeletePlaylists($playlists);
|
||||
}
|
||||
|
||||
foreach ($files as $id) {
|
||||
|
|
|
@ -82,7 +82,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
}
|
||||
}
|
||||
|
||||
private function playlistOutdated($pl, $e)
|
||||
private function playlistOutdated($e)
|
||||
{
|
||||
$this->view->error = $e->getMessage();
|
||||
}
|
||||
|
@ -95,6 +95,10 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$this->changePlaylist(null);
|
||||
$this->createFullResponse(null);
|
||||
}
|
||||
|
||||
private function playlistNoPermission(){
|
||||
$this->view->error = "You don't have permission to delete selected playlist(s).";
|
||||
}
|
||||
|
||||
private function playlistUnknownError($e)
|
||||
{
|
||||
|
@ -137,7 +141,13 @@ class PlaylistController extends Zend_Controller_Action
|
|||
try {
|
||||
if (isset($this->pl_sess->id)) {
|
||||
$pl = new Application_Model_Playlist($this->pl_sess->id);
|
||||
$this->view->pl = $pl;
|
||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
$user = new Application_Model_User($userInfo->id);
|
||||
$isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER));
|
||||
|
||||
if($isAdminOrPM || $pl->getCreatorId() == $userInfo->id){
|
||||
$this->view->pl = $pl;
|
||||
}
|
||||
|
||||
$formatter = new LengthFormatter($pl->getLength());
|
||||
$this->view->length = $formatter->format();
|
||||
|
@ -186,6 +196,9 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$ids = $this->_getParam('ids');
|
||||
$ids = (!is_array($ids)) ? array($ids) : $ids;
|
||||
$pl = null;
|
||||
|
||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||
$user = new Application_Model_User($userInfo->id);
|
||||
|
||||
try {
|
||||
|
||||
|
@ -198,9 +211,13 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$pl = new Application_Model_Playlist($this->pl_sess->id);
|
||||
}
|
||||
|
||||
Application_Model_Playlist::DeletePlaylists($ids);
|
||||
Application_Model_Playlist::deletePlaylists($ids, $userInfo->id);
|
||||
$this->createFullResponse($pl);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
}
|
||||
catch (PlaylistNoPermissionException $e) {
|
||||
$this->playlistNoPermission();
|
||||
}
|
||||
catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
$this->playlistUnknownError($e);
|
||||
|
@ -219,7 +236,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$pl->addAudioClips($ids, $afterItem, $addType);
|
||||
$this->createUpdateResponse($pl);
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -239,7 +256,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$pl->moveAudioClips($ids, $afterItem);
|
||||
$this->createUpdateResponse($pl);
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -258,7 +275,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$pl->delAudioClips($ids);
|
||||
$this->createUpdateResponse($pl);
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -283,7 +300,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$this->view->cue_error = $response["error"];
|
||||
}
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -308,7 +325,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$this->view->fade_error = $response["error"];
|
||||
}
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -326,7 +343,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$fades = $pl->getFadeInfo($pl->getSize()-1);
|
||||
$this->view->fadeOut = $fades[1];
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -349,7 +366,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$pl->setPlaylistfades($fadeIn, $fadeOut);
|
||||
$this->view->modified = $pl->getLastModified("U");
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -367,7 +384,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$this->view->playlistName = $name;
|
||||
$this->view->modified = $pl->getLastModified("U");
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
@ -385,7 +402,7 @@ class PlaylistController extends Zend_Controller_Action
|
|||
$this->view->description = $pl->getDescription();
|
||||
$this->view->modified = $pl->getLastModified("U");
|
||||
} catch (PlaylistOutDatedException $e) {
|
||||
$this->playlistOutdated($pl, $e);
|
||||
$this->playlistOutdated($e);
|
||||
} catch (PlaylistNotFoundException $e) {
|
||||
$this->playlistNotFound();
|
||||
} catch (Exception $e) {
|
||||
|
|
|
@ -453,13 +453,14 @@ class Application_Model_Playlist
|
|||
->filterByDbPlaylistId($this->id)
|
||||
->filterByDbPosition($pos)
|
||||
->findOne();
|
||||
|
||||
|
||||
|
||||
#Propel returns values in form 00.000000 format which is for only seconds.
|
||||
$fadeIn = $row->getDbFadein();
|
||||
$fadeOut = $row->getDbFadeout();
|
||||
|
||||
return array($fadeIn, $fadeOut);
|
||||
}
|
||||
#Propel returns values in form 00.000000 format which is for only seconds.
|
||||
$fadeIn = $row->getDbFadein();
|
||||
$fadeOut = $row->getDbFadeout();
|
||||
return array($fadeIn, $fadeOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change fadeIn and fadeOut values for playlist Element
|
||||
|
@ -800,12 +801,33 @@ class Application_Model_Playlist
|
|||
* Delete playlists that match the ids..
|
||||
* @param array $p_ids
|
||||
*/
|
||||
public static function DeletePlaylists($p_ids)
|
||||
public static function deletePlaylists($p_ids, $p_userId)
|
||||
{
|
||||
CcPlaylistQuery::create()->findPKs($p_ids)->delete();
|
||||
$leftOver = self::playlistsNotOwnedByUser($p_ids, $p_userId);
|
||||
if (count($leftOver) == 0) {
|
||||
CcPlaylistQuery::create()->findPKs($p_ids)->delete();
|
||||
} else {
|
||||
throw new PlaylistNoPermissionException;
|
||||
}
|
||||
}
|
||||
|
||||
// This function returns that are not owen by $p_user_id among $p_ids
|
||||
private static function playlistsNotOwnedByUser($p_ids, $p_userId){
|
||||
$ownedByUser = CcPlaylistQuery::create()->filterByDbCreatorId($p_userId)->find()->getData();
|
||||
$selectedPls = $p_ids;
|
||||
$ownedPls = array();
|
||||
foreach ($ownedByUser as $pl) {
|
||||
if (in_array($pl->getDbId(), $selectedPls)) {
|
||||
$ownedPls[] = $pl->getDbId();
|
||||
}
|
||||
}
|
||||
|
||||
$leftOvers = array_diff($selectedPls, $ownedPls);
|
||||
return $leftOvers;
|
||||
}
|
||||
|
||||
} // class Playlist
|
||||
|
||||
class PlaylistNotFoundException extends Exception {}
|
||||
class PlaylistNoPermissionException extends Exception {}
|
||||
class PlaylistOutDatedException extends Exception {}
|
||||
|
|
|
@ -32,6 +32,7 @@ class Application_Model_Schedule
|
|||
{
|
||||
if (!is_int($p_prev) || !is_int($p_next)) {
|
||||
//must enter integers to specify ranges
|
||||
Logging::log("Invalid range parameters: $p_prev or $p_next");
|
||||
return array();
|
||||
}
|
||||
|
||||
|
@ -49,7 +50,6 @@ class Application_Model_Schedule
|
|||
"schedulerTime"=>$timeNow,
|
||||
"previous"=>$results['previous'] !=null?$results['previous']:(count($shows['previousShow'])>0?$shows['previousShow'][0]:null),
|
||||
"current"=>$results['current'] !=null?$results['current']:((count($shows['currentShow'])>0 && $shows['currentShow'][0]['record'] == 1)?$shows['currentShow'][0]:null),
|
||||
//"current"=>$results['current'] !=null?$results['current']:(count($shows['currentShow'])>0?$shows['currentShow'][0]:null),
|
||||
"next"=> $results['next'] !=null?$results['next']:(count($shows['nextShow'])>0?$shows['nextShow'][0]:null),
|
||||
"currentShow"=>$shows['currentShow'],
|
||||
"nextShow"=>$shows['nextShow'],
|
||||
|
|
|
@ -1876,9 +1876,9 @@ class Application_Model_Show
|
|||
|
||||
/**
|
||||
* Given a start time $timeStart and end time $timeEnd, returns the next $limit
|
||||
* number of shows within the time interval;
|
||||
* If $timeEnd not given, shows within next 48 hours from $timeStart are returned;
|
||||
* If $limit not given, all shows within the intervals are returns;
|
||||
* number of shows within the time interval
|
||||
* If $timeEnd not given, shows within next 48 hours from $timeStart are returned
|
||||
* If $limit not given, all shows within the intervals are returned
|
||||
* Times are all in UTC time.
|
||||
*
|
||||
* @param String $timeStart - interval start time (in UTC)
|
||||
|
|
|
@ -118,6 +118,14 @@ function stringToColor(s)
|
|||
return intToRGB(hashCode(s));
|
||||
}
|
||||
|
||||
function getContrastYIQ(hexcolor){
|
||||
var r = parseInt(hexcolor.substr(0,2),16);
|
||||
var g = parseInt(hexcolor.substr(2,2),16);
|
||||
var b = parseInt(hexcolor.substr(4,2),16);
|
||||
var yiq = ((r*299)+(g*587)+(b*114))/1000;
|
||||
return (yiq >= 128) ? '000000' : 'ffffff';
|
||||
}
|
||||
|
||||
|
||||
function setAddShowEvents() {
|
||||
|
||||
|
@ -578,9 +586,11 @@ function setAddShowEvents() {
|
|||
}
|
||||
|
||||
var bgColorEle = $("#add_show_background_color");
|
||||
var textColorEle = $("#add_show_color");
|
||||
$('#add_show_name').bind('input', 'change', function(){
|
||||
var colorCode = stringToColor($(this).val());
|
||||
bgColorEle.val(colorCode);
|
||||
textColorEle.val(getContrastYIQ(colorCode));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ function findViewportDimensions() {
|
|||
|
||||
return {
|
||||
width: viewportwidth,
|
||||
height: viewportheight
|
||||
height: viewportheight-45
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1136,13 +1136,11 @@ var AIRTIME = (function(AIRTIME){
|
|||
if (oItems.del !== undefined) {
|
||||
|
||||
callback = function() {
|
||||
if (confirm("Delete selected item?")) {
|
||||
AIRTIME.showbuilder.fnRemove([{
|
||||
id: data.id,
|
||||
timestamp: data.timestamp,
|
||||
instance: data.instance
|
||||
}]);
|
||||
}
|
||||
AIRTIME.showbuilder.fnRemove([{
|
||||
id: data.id,
|
||||
timestamp: data.timestamp,
|
||||
instance: data.instance
|
||||
}]);
|
||||
};
|
||||
|
||||
oItems.del.callback = callback;
|
||||
|
|
|
@ -107,12 +107,28 @@ echo "* Making sure /etc/default/locale is set properly"
|
|||
set +e
|
||||
update-locale
|
||||
cat /etc/default/locale | grep -i "LANG=.*UTF-\?8"
|
||||
set -e
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "non UTF-8 default locale found in /etc/default/locale."
|
||||
echo -e " * Fail\n"
|
||||
echo "A non UTF-8 default locale found in /etc/default/locale. Airtime requires
|
||||
a UTF-8 locale to run. To fix this please do the following:
|
||||
|
||||
Ubuntu:
|
||||
Put line 'en_US.UTF-8 UTF-8' (or similar) without quotes to '/var/lib/locales/supported.d/local',
|
||||
replacing any existing lines.
|
||||
A list of supported locales is available in '/usr/share/i18n/SUPPORTED'
|
||||
Then run 'sudo dpkg-reconfigure locales'
|
||||
|
||||
Debian:
|
||||
Run 'sudo dpkg-reconfigure locales' and use the interface to select 'en_US.UTF-8 UTF-8' (or similar).
|
||||
On the second page select this new locale as the default.
|
||||
|
||||
After these changes have been made simply run install again.
|
||||
|
||||
Now exiting install...
|
||||
"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
# Check if airtime exists already
|
||||
set +e
|
||||
|
|
|
@ -6,6 +6,28 @@ if [[ $EUID -ne 0 ]]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
options=$(getopt -o p -l purge -- "$@")
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "only -p or --purge parameter allowed"
|
||||
exit 1
|
||||
fi
|
||||
eval set -- "$options"
|
||||
|
||||
purge='f'
|
||||
|
||||
while true
|
||||
do
|
||||
case "$1" in
|
||||
-p|--purge) purge='t'; shift;;
|
||||
--) shift 1; break ;;
|
||||
*) break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
#Make 'purge' env variable available to sub bash script
|
||||
export purge
|
||||
|
||||
echo -e "\n******************************* Uninstall Begin ********************************"
|
||||
|
||||
# Absolute path to this script, e.g. /home/user/bin/foo.sh
|
||||
|
|
|
@ -19,7 +19,6 @@ set +e
|
|||
monit unmonitor airtime-media-monitor >/dev/null 2>&1
|
||||
monit unmonitor airtime-liquidsoap >/dev/null 2>&1
|
||||
monit unmonitor airtime-playout >/dev/null 2>&1
|
||||
#monit unmonitor airtime-show-recorder >/dev/null 2>&1
|
||||
monit unmonitor rabbitmq-server
|
||||
set -e
|
||||
|
||||
|
@ -31,5 +30,7 @@ python $AIRTIMEROOT/python_apps/pypo/install/pypo-uninitialize.py
|
|||
python $AIRTIMEROOT/python_apps/media-monitor/install/media-monitor-uninitialize.py
|
||||
#python $AIRTIMEROOT/python_apps/show-recorder/install/recorder-uninitialize.py
|
||||
|
||||
if [ "$purge" = "t" ]; then
|
||||
#call Airtime uninstall script
|
||||
php --php-ini ${SCRIPTPATH}/../airtime-php.ini ${SCRIPTPATH}/airtime-uninstall.php
|
||||
fi
|
||||
|
|
|
@ -362,10 +362,10 @@ class AirTimeApiClient():
|
|||
|
||||
return response
|
||||
|
||||
#returns a list of all db files for a given directory in JSON format:
|
||||
#{"files":["path/to/file1", "path/to/file2"]}
|
||||
#Note that these are relative paths to the given directory. The full
|
||||
#path is not returned.
|
||||
# returns a list of all db files for a given directory in JSON format:
|
||||
# ["path/to/file1", "path/to/file2"]
|
||||
# Note that these are relative paths to the given directory. The full
|
||||
# path is not returned.
|
||||
def list_all_db_files(self, dir_id):
|
||||
logger = self.logger
|
||||
try:
|
||||
|
@ -377,10 +377,14 @@ class AirTimeApiClient():
|
|||
response = self.get_response_from_server(url)
|
||||
response = json.loads(response)
|
||||
except Exception, e:
|
||||
response = None
|
||||
response = {}
|
||||
logger.error("Exception: %s", e)
|
||||
|
||||
return response
|
||||
|
||||
try:
|
||||
return response["files"]
|
||||
except KeyError:
|
||||
self.logger.error("Could not find index 'files' in dictionary: %s", str(response))
|
||||
return []
|
||||
|
||||
def list_all_watched_dirs(self):
|
||||
logger = self.logger
|
||||
|
|
|
@ -40,8 +40,7 @@ class AirtimeMediaMonitorBootstrap():
|
|||
went offline.
|
||||
"""
|
||||
def scan(self):
|
||||
directories = self.get_list_of_watched_dirs();
|
||||
|
||||
directories = self.get_list_of_watched_dirs()
|
||||
self.logger.info("watched directories found: %s", directories)
|
||||
|
||||
for id, dir in directories.iteritems():
|
||||
|
@ -57,12 +56,21 @@ class AirtimeMediaMonitorBootstrap():
|
|||
return self.api_client.list_all_db_files(dir_id)
|
||||
|
||||
"""
|
||||
returns the path and the database row id for this path for all watched directories. Also
|
||||
returns the path and its corresponding database row idfor all watched directories. Also
|
||||
returns the Stor directory, which can be identified by its row id (always has value of "1")
|
||||
|
||||
Return type is a dictionary similar to:
|
||||
{"1":"/srv/airtime/stor/"}
|
||||
"""
|
||||
def get_list_of_watched_dirs(self):
|
||||
json = self.api_client.list_all_watched_dirs()
|
||||
return json["dirs"]
|
||||
|
||||
try:
|
||||
return json["dirs"]
|
||||
except KeyError as e:
|
||||
self.logger.error("Could not find index 'dirs' in dictionary: %s", str(json))
|
||||
self.logger.error(e)
|
||||
return {}
|
||||
|
||||
"""
|
||||
This function takes in a path name provided by the database (and its corresponding row id)
|
||||
|
@ -86,8 +94,9 @@ class AirtimeMediaMonitorBootstrap():
|
|||
|
||||
db_known_files_set = set()
|
||||
files = self.list_db_files(dir_id)
|
||||
for file in files['files']:
|
||||
db_known_files_set.add(file)
|
||||
|
||||
for f in files:
|
||||
db_known_files_set.add(f)
|
||||
|
||||
all_files = self.mmc.clean_dirty_file_paths( self.mmc.scan_dir_for_new_files(dir) )
|
||||
|
||||
|
@ -111,10 +120,9 @@ class AirtimeMediaMonitorBootstrap():
|
|||
stdout = self.mmc.exec_command(command)
|
||||
|
||||
if stdout is None:
|
||||
self.logger.error("Unrecoverable error when syncing db to filesystem.")
|
||||
return
|
||||
|
||||
new_files = self.mmc.clean_dirty_file_paths(stdout.splitlines())
|
||||
new_files = []
|
||||
else:
|
||||
new_files = stdout.splitlines()
|
||||
|
||||
new_and_modified_files = set()
|
||||
for file_path in new_files:
|
||||
|
|
|
@ -12,8 +12,17 @@ import traceback
|
|||
|
||||
"""
|
||||
list of supported easy tags in mutagen version 1.20
|
||||
['albumartistsort', 'musicbrainz_albumstatus', 'lyricist', 'releasecountry', 'date', 'performer', 'musicbrainz_albumartistid', 'composer', 'encodedby', 'tracknumber', 'musicbrainz_albumid', 'album', 'asin', 'musicbrainz_artistid', 'mood', 'copyright', 'author', 'media', 'length', 'version', 'artistsort', 'titlesort', 'discsubtitle', 'website', 'musicip_fingerprint', 'conductor', 'compilation', 'barcode', 'performer:*', 'composersort', 'musicbrainz_discid', 'musicbrainz_albumtype', 'genre', 'isrc', 'discnumber', 'musicbrainz_trmid', 'replaygain_*_gain', 'musicip_puid', 'artist', 'title', 'bpm', 'musicbrainz_trackid', 'arranger', 'albumsort', 'replaygain_*_peak', 'organization']
|
||||
['albumartistsort', 'musicbrainz_albumstatus', 'lyricist', 'releasecountry',
|
||||
'date', 'performer', 'musicbrainz_albumartistid', 'composer', 'encodedby',
|
||||
'tracknumber', 'musicbrainz_albumid', 'album', 'asin', 'musicbrainz_artistid',
|
||||
'mood', 'copyright', 'author', 'media', 'length', 'version', 'artistsort',
|
||||
'titlesort', 'discsubtitle', 'website', 'musicip_fingerprint', 'conductor',
|
||||
'compilation', 'barcode', 'performer:*', 'composersort', 'musicbrainz_discid',
|
||||
'musicbrainz_albumtype', 'genre', 'isrc', 'discnumber', 'musicbrainz_trmid',
|
||||
'replaygain_*_gain', 'musicip_puid', 'artist', 'title', 'bpm', 'musicbrainz_trackid',
|
||||
'arranger', 'albumsort', 'replaygain_*_peak', 'organization']
|
||||
"""
|
||||
|
||||
class AirtimeMetadata:
|
||||
|
||||
def __init__(self):
|
||||
|
@ -57,10 +66,17 @@ class AirtimeMetadata:
|
|||
self.logger = logging.getLogger()
|
||||
|
||||
def get_md5(self, filepath):
|
||||
f = open(filepath, 'rb')
|
||||
m = hashlib.md5()
|
||||
m.update(f.read())
|
||||
md5 = m.hexdigest()
|
||||
"""
|
||||
Returns an md5 of the file located at filepath. Returns an empty string
|
||||
if there was an error reading the file.
|
||||
"""
|
||||
try:
|
||||
f = open(filepath, 'rb')
|
||||
m = hashlib.md5()
|
||||
m.update(f.read())
|
||||
md5 = m.hexdigest()
|
||||
except Exception, e:
|
||||
return ""
|
||||
|
||||
return md5
|
||||
|
||||
|
@ -121,6 +137,10 @@ class AirtimeMetadata:
|
|||
return item
|
||||
|
||||
def get_md_from_file(self, filepath):
|
||||
"""
|
||||
Returns None if error retrieving metadata. Otherwise returns a dictionary
|
||||
representing the file's metadata
|
||||
"""
|
||||
|
||||
self.logger.info("getting info from filepath %s", filepath)
|
||||
|
||||
|
@ -136,7 +156,6 @@ class AirtimeMetadata:
|
|||
md['MDATA_KEY_MD5'] = md5
|
||||
|
||||
file_info = mutagen.File(filepath, easy=True)
|
||||
|
||||
except Exception, e:
|
||||
self.logger.error("failed getting metadata from %s", filepath)
|
||||
self.logger.error("Exception %s", e)
|
||||
|
@ -146,18 +165,16 @@ class AirtimeMetadata:
|
|||
#check if file has any metadata
|
||||
if file_info is None:
|
||||
return None
|
||||
#check if file has any metadata
|
||||
if file_info is not None:
|
||||
for key in file_info.keys() :
|
||||
if key in self.mutagen2airtime:
|
||||
val = file_info[key]
|
||||
try:
|
||||
if val is not None and len(val) > 0 and val[0] is not None and len(val[0]) > 0:
|
||||
md[self.mutagen2airtime[key]] = val[0]
|
||||
except Exception, e:
|
||||
self.logger.error('Exception: %s', e)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
|
||||
for key in file_info.keys() :
|
||||
if key in self.mutagen2airtime:
|
||||
val = file_info[key]
|
||||
try:
|
||||
if val is not None and len(val) > 0 and val[0] is not None and len(val[0]) > 0:
|
||||
md[self.mutagen2airtime[key]] = val[0]
|
||||
except Exception, e:
|
||||
self.logger.error('Exception: %s', e)
|
||||
self.logger.error("traceback: %s", traceback.format_exc())
|
||||
if 'MDATA_KEY_TITLE' not in md:
|
||||
#get rid of file extension from original name, name might have more than 1 '.' in it.
|
||||
original_name = os.path.basename(filepath)
|
||||
|
@ -228,18 +245,24 @@ class AirtimeMetadata:
|
|||
md['MDATA_KEY_COPYRIGHT'] = self.truncate_to_length(md['MDATA_KEY_COPYRIGHT'], 512)
|
||||
#end of db truncation checks.
|
||||
|
||||
md['MDATA_KEY_BITRATE'] = getattr(file_info.info, "bitrate", None)
|
||||
md['MDATA_KEY_SAMPLERATE'] = getattr(file_info.info, "sample_rate", None)
|
||||
self.logger.info("Bitrate: %s , Samplerate: %s", md['MDATA_KEY_BITRATE'], md['MDATA_KEY_SAMPLERATE'])
|
||||
try: md['MDATA_KEY_DURATION'] = self.format_length(file_info.info.length)
|
||||
except Exception as e: self.logger.warn("File: '%s' raises: %s", filepath, str(e))
|
||||
|
||||
try: md['MDATA_KEY_MIME'] = file_info.mime[0]
|
||||
except Exception as e: self.logger.warn("File: '%s' has no mime type", filepath, str(e))
|
||||
try:
|
||||
md['MDATA_KEY_BITRATE'] = getattr(file_info.info, "bitrate", 0)
|
||||
md['MDATA_KEY_SAMPLERATE'] = getattr(file_info.info, "sample_rate", 0)
|
||||
|
||||
md['MDATA_KEY_DURATION'] = self.format_length(getattr(file_info.info, "length", 0.0))
|
||||
|
||||
md['MDATA_KEY_MIME'] = ""
|
||||
if len(file_info.mime) > 0:
|
||||
md['MDATA_KEY_MIME'] = file_info.mime[0]
|
||||
except Exception as e:
|
||||
self.logger.warn(e)
|
||||
|
||||
if "mp3" in md['MDATA_KEY_MIME']:
|
||||
md['MDATA_KEY_FTYPE'] = "audioclip"
|
||||
elif "vorbis" in md['MDATA_KEY_MIME']:
|
||||
md['MDATA_KEY_FTYPE'] = "audioclip"
|
||||
else:
|
||||
self.logger.error("File %s of mime type %s does not appear to be a valid vorbis or mp3 file." % (filepath, md['MDATA_KEY_MIME']))
|
||||
return None
|
||||
|
||||
return md
|
||||
|
|
|
@ -36,6 +36,11 @@ class AirtimeNotifier(Notifier):
|
|||
time.sleep(5)
|
||||
|
||||
def init_rabbit_mq(self):
|
||||
"""
|
||||
This function will attempt to connect to RabbitMQ Server and if successful
|
||||
return 'True'. Returns 'False' otherwise.
|
||||
"""
|
||||
|
||||
self.logger.info("Initializing RabbitMQ stuff")
|
||||
try:
|
||||
schedule_exchange = Exchange("airtime-media-monitor", "direct", durable=True, auto_delete=True)
|
||||
|
|
|
@ -292,7 +292,10 @@ class MediaMonitorCommon:
|
|||
self.logger.debug(command)
|
||||
stdout = self.exec_command(command)
|
||||
|
||||
return stdout.splitlines()
|
||||
if stdout is None:
|
||||
return []
|
||||
else:
|
||||
return stdout.splitlines()
|
||||
|
||||
def touch_index_file(self):
|
||||
dirname = os.path.dirname(self.timestamp_file)
|
||||
|
|
|
@ -73,7 +73,7 @@ monit_restart() {
|
|||
start-stop-daemon --stop --oknodo --retry TERM/5/0/30 --quiet --pidfile $PIDFILE1
|
||||
rm -f $PIDFILE1
|
||||
|
||||
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0
|
||||
start-stop-daemon --start --background --quiet --chuid $ROOTUSERID:$ROOTUSERID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0
|
||||
|
||||
start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID \
|
||||
--nicelevel -15 --make-pidfile --pidfile $PIDFILE1 --startas $DAEMON1
|
||||
|
|
|
@ -25,6 +25,8 @@ def printUsage():
|
|||
print " -u user (default: source) "
|
||||
print " -p password (default: hackme) "
|
||||
print " -m mount (default: test) "
|
||||
print " -h show help menu"
|
||||
|
||||
|
||||
def find_liquidsoap_binary():
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var AIRTIME_API_VERSION = "1.0";
|
||||
var AIRTIME_API_VERSION = "1.1";
|
||||
|
||||
(function($){
|
||||
$.fn.airtimeShowSchedule = function(options) {
|
||||
|
@ -6,7 +6,8 @@
|
|||
var defaults = {
|
||||
updatePeriod: 20, //seconds
|
||||
sourceDomain: "http://localhost/", //where to get show status from
|
||||
text: {onAirToday:"On air today"}
|
||||
text: {onAirToday:"On air today"},
|
||||
showLimit: 5
|
||||
};
|
||||
options = $.extend(true, defaults, options);
|
||||
options.sourceDomain = addEndingBackslash(options.sourceDomain);
|
||||
|
@ -56,7 +57,7 @@
|
|||
|
||||
function getServerData(){
|
||||
$.ajax({url: options.sourceDomain + "api/live-info/",
|
||||
data: {type:"endofday",limit:"5"},
|
||||
data: {type:"endofday",limit: options.showLimit},
|
||||
dataType: "jsonp",
|
||||
success:function(data) {
|
||||
processData(data);
|
||||
|
|
|
@ -17,7 +17,8 @@ $(document).ready(function() {
|
|||
$("#onAirToday").airtimeShowSchedule({
|
||||
sourceDomain: "http://localhost",
|
||||
text: {onAirToday:"On air today"},
|
||||
updatePeriod: 5 //seconds
|
||||
updatePeriod: 5, //seconds
|
||||
showLimit: 10
|
||||
});
|
||||
$("#scheduleTabs").airtimeWeekSchedule({
|
||||
sourceDomain:"http://localhost",
|
||||
|
|
Loading…
Reference in New Issue