From 832e210609aa05a5ea2a4d01c8658475a9d2b6aa Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 15:20:26 -0400 Subject: [PATCH 01/57] CC-3994: Install script hard-codes storage path, instead of using value in airtime-install.ini - done --- install_minimal/DoctrineMigrations/Version20110711161043.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/install_minimal/DoctrineMigrations/Version20110711161043.php b/install_minimal/DoctrineMigrations/Version20110711161043.php index ec11eeeb2..7c0de0ee3 100644 --- a/install_minimal/DoctrineMigrations/Version20110711161043.php +++ b/install_minimal/DoctrineMigrations/Version20110711161043.php @@ -15,8 +15,11 @@ class Version20110711161043 extends AbstractMigration { public function up(Schema $schema) { + $ini = parse_ini_file(__DIR__."../include/airtime-install.ini"); + $stor_dir = $ini["storage_dir"]; + /* 1) update cc_files table to include to "directory" column */ - $this->_addSql("INSERT INTO cc_music_dirs (type, directory) VALUES ('stor', '/srv/airtime/stor/');"); + $this->_addSql("INSERT INTO cc_music_dirs (type, directory) VALUES ('stor', $stor_dir);"); $this->_addSql("INSERT INTO cc_music_dirs (type, directory) VALUES ('link', '');"); From 6a75fd6c76d8fe98e611c3268fdd47764713d68e Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 16:35:34 -0400 Subject: [PATCH 02/57] CC-3979: Playout History export should include date range in file and/or filename - done --- .../js/airtime/playouthistory/historytable.js | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/public/js/airtime/playouthistory/historytable.js b/airtime_mvc/public/js/airtime/playouthistory/historytable.js index 35c8fdb96..6e6df0be2 100644 --- a/airtime_mvc/public/js/airtime/playouthistory/historytable.js +++ b/airtime_mvc/public/js/airtime/playouthistory/historytable.js @@ -1,3 +1,22 @@ +function getFileName(){ + var filename = $("#his_date_start").val()+"_"+$("#his_time_start").val()+"m--"+$("#his_date_end").val()+"_"+$("#his_time_end").val()+"m" + filename = filename.replace(/:/g,"h") + return filename; +} + +function setFlashFileName( nButton, oConfig, oFlash ) { + var filename = getFileName() + oFlash.setFileName( filename ); + this.fnSetText( oFlash, + "title:"+ this.fnGetTitle(oConfig) +"\n"+ + "message:"+ oConfig.sPdfMessage +"\n"+ + "colWidth:"+ this.fnCalcColRatios(oConfig) +"\n"+ + "orientation:"+ oConfig.sPdfOrientation +"\n"+ + "size:"+ oConfig.sPdfSize +"\n"+ + "--/TableToolsOpts--\n" + + this.fnGetTableData(oConfig)); +} + var AIRTIME = (function(AIRTIME) { var mod; @@ -65,7 +84,23 @@ var AIRTIME = (function(AIRTIME) { "sDom": 'lf<"dt-process-rel"r><"H"T><"dataTables_scrolling"t><"F"ip>', "oTableTools": { - "sSwfPath": "/js/datatables/plugin/TableTools/swf/copy_cvs_xls_pdf.swf" + "sSwfPath": "/js/datatables/plugin/TableTools/swf/copy_cvs_xls_pdf.swf", + "aButtons": [ + "copy", + { + "sExtends": "csv", + "fnClick": setFlashFileName + }, + { + "sExtends": "xls", + "fnClick": setFlashFileName + }, + { + "sExtends": "pdf", + "fnClick": setFlashFileName + }, + "print" + ] } }); oTable.fnSetFilteringDelay(350); From e40d9731a2dbb68c9ce8954dd6e45eaa2126e293 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 16:47:11 -0400 Subject: [PATCH 03/57] CC-3979: Playout History export should include date range in file and/or filename - fix --- .../js/airtime/playouthistory/historytable.js | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/airtime_mvc/public/js/airtime/playouthistory/historytable.js b/airtime_mvc/public/js/airtime/playouthistory/historytable.js index 6e6df0be2..082927375 100644 --- a/airtime_mvc/public/js/airtime/playouthistory/historytable.js +++ b/airtime_mvc/public/js/airtime/playouthistory/historytable.js @@ -1,20 +1,30 @@ -function getFileName(){ +function getFileName(ext){ var filename = $("#his_date_start").val()+"_"+$("#his_time_start").val()+"m--"+$("#his_date_end").val()+"_"+$("#his_time_end").val()+"m" filename = filename.replace(/:/g,"h") + if(ext == "pdf"){ + filename = filename+".pdf" + }else{ + filename = filename+".csv" + } return filename; } function setFlashFileName( nButton, oConfig, oFlash ) { - var filename = getFileName() + var filename = getFileName(oConfig.sExtends) oFlash.setFileName( filename ); - this.fnSetText( oFlash, - "title:"+ this.fnGetTitle(oConfig) +"\n"+ - "message:"+ oConfig.sPdfMessage +"\n"+ - "colWidth:"+ this.fnCalcColRatios(oConfig) +"\n"+ - "orientation:"+ oConfig.sPdfOrientation +"\n"+ - "size:"+ oConfig.sPdfSize +"\n"+ - "--/TableToolsOpts--\n" + - this.fnGetTableData(oConfig)); + if(oConfig.sExtends == "pdf"){ + this.fnSetText( oFlash, + "title:"+ this.fnGetTitle(oConfig) +"\n"+ + "message:"+ oConfig.sPdfMessage +"\n"+ + "colWidth:"+ this.fnCalcColRatios(oConfig) +"\n"+ + "orientation:"+ oConfig.sPdfOrientation +"\n"+ + "size:"+ oConfig.sPdfSize +"\n"+ + "--/TableToolsOpts--\n" + + this.fnGetTableData(oConfig)); + }else{ + this.fnSetText( oFlash, + this.fnGetTableData(oConfig)); + } } var AIRTIME = (function(AIRTIME) { From 3a32e7240add7bc6ab3fd74d4a5596689bf82eee Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 16:49:41 -0400 Subject: [PATCH 04/57] CC-3984: Now Playing scissor and trashcan buttons are incorrectly labelled in tooltips - fixed --- airtime_mvc/public/js/airtime/showbuilder/builder.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 94ce25608..4649a0415 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -890,8 +890,8 @@ var AIRTIME = (function(AIRTIME){ $ul = $("
    "); $ul.append('
  • ') - .append('
  • ') - .append('
  • '); + .append('
  • ') + .append('
  • '); $toolbar.append($ul); $ul = $("
      "); From 5c43fa5a7b4972f5aabecc9283b8c251d25687e6 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 16:51:34 -0400 Subject: [PATCH 05/57] CC-3978: Playout History table says Artist when it should say Creator - fixed --- airtime_mvc/public/js/airtime/playouthistory/historytable.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/public/js/airtime/playouthistory/historytable.js b/airtime_mvc/public/js/airtime/playouthistory/historytable.js index 082927375..69c2781da 100644 --- a/airtime_mvc/public/js/airtime/playouthistory/historytable.js +++ b/airtime_mvc/public/js/airtime/playouthistory/historytable.js @@ -66,7 +66,7 @@ var AIRTIME = (function(AIRTIME) { "aoColumns": [ {"sTitle": "Title", "mDataProp": "title", "sClass": "his_title"}, /* Title */ - {"sTitle": "Artist", "mDataProp": "artist", "sClass": "his_artist"}, /* Creator */ + {"sTitle": "Creator", "mDataProp": "artist", "sClass": "his_artist"}, /* Creator */ {"sTitle": "Played", "mDataProp": "played", "sClass": "his_artist"}, /* times played */ {"sTitle": "Length", "mDataProp": "length", "sClass": "his_length library_length"}, /* Length */ {"sTitle": "Composer", "mDataProp": "composer", "sClass": "his_composer"}, /* Composer */ From 10fc5038c8403b1bf0c9a5f697f3f73febed9f9e Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 17:39:52 -0400 Subject: [PATCH 06/57] CC-3965: Clarify input/output stream settings by addding appropriate labels - fixed --- .../views/scripts/preference/stream-setting.phtml | 5 ++++- .../application/views/scripts/schedule/add-show-form.phtml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/views/scripts/preference/stream-setting.phtml b/airtime_mvc/application/views/scripts/preference/stream-setting.phtml index 5e9d94333..654149d3b 100644 --- a/airtime_mvc/application/views/scripts/preference/stream-setting.phtml +++ b/airtime_mvc/application/views/scripts/preference/stream-setting.phtml @@ -69,16 +69,19 @@ form->getSubform('live_stream_subform'); ?>
      +
      + Output Stream Settings num_stream;$i++){ echo $this->form->getSubform("s".$i."_subform"); } ?> +
      enable_stream_conf == "true"){?>
      -
      + diff --git a/airtime_mvc/application/views/scripts/schedule/add-show-form.phtml b/airtime_mvc/application/views/scripts/schedule/add-show-form.phtml index be1c5d694..b5acbc546 100644 --- a/airtime_mvc/application/views/scripts/schedule/add-show-form.phtml +++ b/airtime_mvc/application/views/scripts/schedule/add-show-form.phtml @@ -16,7 +16,7 @@ when; ?> repeats; ?> -

      Live Stream

      +

      Live Stream Input

      live; ?>
      From 2480639e58f73ae7fed4dc0d9c95696094831e5c Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 17:42:49 -0400 Subject: [PATCH 07/57] CC-3980: Excel export button in Playout History does not really export Excel format - removed xls option --- airtime_mvc/public/js/airtime/playouthistory/historytable.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/airtime_mvc/public/js/airtime/playouthistory/historytable.js b/airtime_mvc/public/js/airtime/playouthistory/historytable.js index 69c2781da..9a0db2680 100644 --- a/airtime_mvc/public/js/airtime/playouthistory/historytable.js +++ b/airtime_mvc/public/js/airtime/playouthistory/historytable.js @@ -101,10 +101,6 @@ var AIRTIME = (function(AIRTIME) { "sExtends": "csv", "fnClick": setFlashFileName }, - { - "sExtends": "xls", - "fnClick": setFlashFileName - }, { "sExtends": "pdf", "fnClick": setFlashFileName From c669d3cb47a3092ac27fb3995f0dc72955f0740d Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 18:02:46 -0400 Subject: [PATCH 08/57] CC-3969: Reset Password: specifying wrong e-mail keeps you on the same page without possibility to navigate back gracefully - done --- airtime_mvc/application/controllers/LoginController.php | 6 ++++++ airtime_mvc/application/forms/PasswordRestore.php | 8 ++++++++ .../application/views/scripts/form/password-restore.phtml | 3 +++ airtime_mvc/public/css/styles.css | 6 ++++++ airtime_mvc/public/js/airtime/login/password-restore.js | 3 +++ 5 files changed, 26 insertions(+) create mode 100644 airtime_mvc/public/js/airtime/login/password-restore.js diff --git a/airtime_mvc/application/controllers/LoginController.php b/airtime_mvc/application/controllers/LoginController.php index 5aab66d38..6cef61761 100644 --- a/airtime_mvc/application/controllers/LoginController.php +++ b/airtime_mvc/application/controllers/LoginController.php @@ -100,6 +100,12 @@ class LoginController extends Zend_Controller_Action public function passwordRestoreAction() { + global $CC_CONFIG; + + $request = $this->getRequest(); + $baseUrl = $request->getBaseUrl(); + $this->view->headScript()->appendFile($baseUrl.'/js/airtime/login/password-restore.js?'.$CC_CONFIG['airtime_version'],'text/javascript'); + if (!Application_Model_Preference::GetEnableSystemEmail()) { $this->_redirect('login'); } diff --git a/airtime_mvc/application/forms/PasswordRestore.php b/airtime_mvc/application/forms/PasswordRestore.php index 54bfbd47a..5544e0ec1 100644 --- a/airtime_mvc/application/forms/PasswordRestore.php +++ b/airtime_mvc/application/forms/PasswordRestore.php @@ -29,5 +29,13 @@ class Application_Form_PasswordRestore extends Zend_Form 'ViewHelper' ) )); + + $cancel = new Zend_Form_Element_Button("cancel"); + $cancel->class = 'ui-button ui-widget ui-state-default ui-button-text-only center'; + $cancel->setLabel("Cancel") + ->setIgnore(True) + ->setAttrib('onclick', 'redirectToLogin();') + ->setDecorators(array('ViewHelper')); + $this->addElement($cancel); } } \ No newline at end of file diff --git a/airtime_mvc/application/views/scripts/form/password-restore.phtml b/airtime_mvc/application/views/scripts/form/password-restore.phtml index 5c8d099ac..a617ec971 100644 --- a/airtime_mvc/application/views/scripts/form/password-restore.phtml +++ b/airtime_mvc/application/views/scripts/form/password-restore.phtml @@ -21,5 +21,8 @@
      element->getElement('submit') ?>
      +
      + element->getElement('cancel') ?> +
      \ No newline at end of file diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index 81d165a92..4f17a5d40 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -808,6 +808,12 @@ dt.block-display, dd.block-display { font-size:14px; padding: 6px 10px 6px; } + +.login-content dd button.ui-button, .login-content dd button.btn { + width:100%; + font-size:14px; + padding: 6px 10px 6px; +} .login-content .hidden, .hidden { display:none; } diff --git a/airtime_mvc/public/js/airtime/login/password-restore.js b/airtime_mvc/public/js/airtime/login/password-restore.js new file mode 100644 index 000000000..ac8e62e28 --- /dev/null +++ b/airtime_mvc/public/js/airtime/login/password-restore.js @@ -0,0 +1,3 @@ +function redirectToLogin(){ + window.location = "/Login" +} \ No newline at end of file From b081a9eb5fd099f42f1751d918ac85c73d976989 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 20 Jun 2012 18:24:28 -0400 Subject: [PATCH 09/57] CC-3955: System -> Preferences: Timezone setting is the first one in the list, not the current (local) timezone. - fixed --- install_minimal/include/AirtimeInstall.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/install_minimal/include/AirtimeInstall.php b/install_minimal/include/AirtimeInstall.php index 304cd6b35..e656bf983 100644 --- a/install_minimal/include/AirtimeInstall.php +++ b/install_minimal/include/AirtimeInstall.php @@ -318,8 +318,9 @@ class AirtimeInstall public static function SetDefaultTimezone() { - $con = Propel::getConnection(); - $defaultTimezone = exec("cat /etc/timezone"); + $con = Propel::getConnection(); + // we need to run php as commandline because we want to get the timezone in cli php.ini file + $defaultTimezone = exec("php -r 'echo date_default_timezone_get().PHP_EOL;'"); $sql = "INSERT INTO cc_pref (keystr, valstr) VALUES ('timezone', '$defaultTimezone')"; $result = $con->exec($sql); if ($result < 1) { From ffb7f2ff65e08db5524291a3d6ee026cf4a37494 Mon Sep 17 00:00:00 2001 From: denise Date: Fri, 22 Jun 2012 18:01:00 -0400 Subject: [PATCH 10/57] CC-3933: Replace Airtime version number in source code with a hash of the version + uniqueId. -done --- airtime_mvc/application/Bootstrap.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index f2ae6fe86..d7ba2d192 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -23,7 +23,9 @@ date_default_timezone_set('UTC'); date_default_timezone_set(Application_Model_Preference::GetTimezone()); global $CC_CONFIG; -$CC_CONFIG['airtime_version'] = Application_Model_Preference::GetAirtimeVersion(); +$airtime_version = Application_Model_Preference::GetAirtimeVersion(); +$uniqueid = Application_Model_Preference::GetUniqueId(); +$CC_CONFIG['airtime_version'] = md5($airtime_version + $uniqueid); require_once __DIR__."/configs/navigation.php"; From 8005049bdcf9201fc47bddc060ffec739508920d Mon Sep 17 00:00:00 2001 From: denise Date: Mon, 25 Jun 2012 12:22:34 -0400 Subject: [PATCH 11/57] CC-3996: Undefined offset: 0 in StoredFile.php (Apache error) -fixed --- airtime_mvc/application/models/StoredFile.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index 4e37a2bad..d69e28e19 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -888,7 +888,7 @@ Logging::log("getting media! - 2"); // Check if file is playable $command = sprintf("/usr/bin/airtime-liquidsoap -c 'output.dummy(audio_to_stereo(single(\"%s\")))' 2>&1", $audio_file); exec($command, $output, $rv); - if ($rv != 0 || $output[0] == 'TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.') { + if ($rv != 0 || (!empty($output) && $output[0] == 'TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.')) { $result = array("code" => 110, "message" => "This file appears to be corrupted and will not be added to media library."); } else { From 8a2d548d5c6c2b3ec95c6268086c35d3466c712f Mon Sep 17 00:00:00 2001 From: James Date: Mon, 25 Jun 2012 17:25:57 -0400 Subject: [PATCH 12/57] CC-4001: Warnings in apache error log - upgrade script for 2.1.3 --- .../upgrades/airtime-2.1.3/DbUpgrade.php | 24 +++++++++++++++++++ .../airtime-2.1.3/airtime-upgrade.php | 8 +++++++ .../upgrades/airtime-2.1.3/data/upgrade.sql | 4 ++++ 3 files changed, 36 insertions(+) create mode 100644 install_minimal/upgrades/airtime-2.1.3/DbUpgrade.php create mode 100644 install_minimal/upgrades/airtime-2.1.3/airtime-upgrade.php create mode 100644 install_minimal/upgrades/airtime-2.1.3/data/upgrade.sql diff --git a/install_minimal/upgrades/airtime-2.1.3/DbUpgrade.php b/install_minimal/upgrades/airtime-2.1.3/DbUpgrade.php new file mode 100644 index 000000000..bda71b900 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.1.3/DbUpgrade.php @@ -0,0 +1,24 @@ +&1 | grep -v \"will create implicit index\""); + } +} diff --git a/install_minimal/upgrades/airtime-2.1.3/airtime-upgrade.php b/install_minimal/upgrades/airtime-2.1.3/airtime-upgrade.php new file mode 100644 index 000000000..042b92d05 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.1.3/airtime-upgrade.php @@ -0,0 +1,8 @@ + Date: Mon, 25 Jun 2012 18:30:33 -0400 Subject: [PATCH 13/57] add time to our version so cache is never used in dev branch --- airtime_mvc/application/models/Preference.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 81d449ee6..54168bced 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -618,7 +618,7 @@ class Application_Model_Preference if (defined('APPLICATION_ENV') && APPLICATION_ENV == "development" && function_exists('exec')){ $version = exec("git rev-parse --short HEAD 2>/dev/null", $out, $return_code); if ($return_code == 0){ - return self::GetValue("system_version")."+".$version; + return self::GetValue("system_version")."+".$version.":".time(); } } return self::GetValue("system_version"); From a63b765621bda8b047f7ab62c37b6b1c77d31786 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Mon, 25 Jun 2012 23:40:07 -0400 Subject: [PATCH 14/57] CC-4011: System -> Media Folders: Changing page will stop removing a watched folder with lots of files (50,000) -Changed doing 50,000 database calls to 1. --- airtime_mvc/application/models/MusicDir.php | 22 +++++++------------ airtime_mvc/application/models/StoredFile.php | 3 +-- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/airtime_mvc/application/models/MusicDir.php b/airtime_mvc/application/models/MusicDir.php index 3c8b64e01..70609fad3 100644 --- a/airtime_mvc/application/models/MusicDir.php +++ b/airtime_mvc/application/models/MusicDir.php @@ -82,17 +82,9 @@ class Application_Model_MusicDir { $show_instances = $con->query($sql)->fetchAll(); // get all the files on this dir - $sql = "SELECT f.id FROM cc_music_dirs as md " - ." LEFT JOIN cc_files as f on f.directory = md.id WHERE md.id = $music_dir_id"; - $files = $con->query($sql)->fetchAll(); - - // set file_exist flag to false - foreach ($files as $file_row) { - $temp_file = Application_Model_StoredFile::Recall($file_row['id']); - if($temp_file != null){ - $temp_file->setFileExistsFlag(false); - } - } + $sql = "UPDATE cc_files SET file_exists = 'f' WHERE id IN (SELECT f.id FROM cc_music_dirs as md " + ." LEFT JOIN cc_files as f on f.directory = md.id WHERE md.id = $music_dir_id)"; + $affected = $con->exec($sql); // set RemovedFlag to true if ($userAddedWatchedDir) { @@ -399,14 +391,16 @@ class Application_Model_MusicDir { * otherwise, it will set "Exists" flag to true **/ public static function removeWatchedDir($p_dir, $userAddedWatchedDir=true){ + + //make sure that $p_dir has a trailing "/" $real_path = Application_Common_OsPath::normpath($p_dir)."/"; if($real_path != "/"){ $p_dir = $real_path; } $dir = Application_Model_MusicDir::getDirByPath($p_dir); - if($dir == NULL){ - return array("code"=>1,"error"=>"'$p_dir' doesn't exist in the watched list."); - }else{ + if (is_null($dir)) { + return array("code"=>1, "error"=>"'$p_dir' doesn't exist in the watched list."); + } else { $dir->remove($userAddedWatchedDir); $data = array(); $data["directory"] = $p_dir; diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index d69e28e19..ccee5525c 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -890,8 +890,7 @@ Logging::log("getting media! - 2"); exec($command, $output, $rv); if ($rv != 0 || (!empty($output) && $output[0] == 'TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.')) { $result = array("code" => 110, "message" => "This file appears to be corrupted and will not be added to media library."); - } - else { + } else { //Martin K.: changed to rename: Much less load + quicker since this is an atomic operation $r = @rename($audio_file, $audio_stor); From 7e7f8147daaccf34ecfcf1528cc7b5e89e1d393b Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 26 Jun 2012 14:55:19 -0400 Subject: [PATCH 15/57] CC-4017: Run airtime-playour process as root user -done --- python_apps/pypo/airtime-playout-init-d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/airtime-playout-init-d b/python_apps/pypo/airtime-playout-init-d index f65ea63ca..75ea3f6d7 100755 --- a/python_apps/pypo/airtime-playout-init-d +++ b/python_apps/pypo/airtime-playout-init-d @@ -47,7 +47,7 @@ start () { chown pypo:pypo /etc/airtime chown pypo:pypo /etc/airtime/liquidsoap.cfg - start-stop-daemon --start --background --quiet --chuid $USERID:$GROUPID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0 + start-stop-daemon --start --background --quiet --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0 monit monitor airtime-playout >/dev/null 2>&1 liquidsoap_start From 05fa673e42f8df5ee6c6003e46564303fc7f97cd Mon Sep 17 00:00:00 2001 From: denise Date: Tue, 26 Jun 2012 15:36:45 -0400 Subject: [PATCH 16/57] CC-3983: Timeline cursor in Now Playing vanishes after adding a file to a show -done --- .../public/js/airtime/showbuilder/builder.js | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 4649a0415..ee885d079 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -8,7 +8,9 @@ var AIRTIME = (function(AIRTIME){ $sbTable, $toolbar, $ul, - $lib; + $lib, + cursors = [], + cursorIds = []; if (AIRTIME.showbuilder === undefined) { AIRTIME.showbuilder = {}; @@ -127,7 +129,7 @@ var AIRTIME = (function(AIRTIME){ }; mod.selectCursor = function($el) { - + $el.addClass(CURSOR_SELECTED_CLASS); mod.checkToolBarIcons(); }; @@ -208,11 +210,16 @@ var AIRTIME = (function(AIRTIME){ mod.fnItemCallback = function(json) { checkError(json); + + cursors = $(".cursor-selected-row"); + for (i = 0; i < cursors.length; i++) { + cursorIds.push(($(cursors.get(i)).attr("id"))); + } oSchedTable.fnDraw(); mod.enableUI(); }; - + mod.fnAdd = function(aMediaIds, aSchedIds) { mod.disableUI(); @@ -401,7 +408,6 @@ var AIRTIME = (function(AIRTIME){ headerIcon; fnPrepareSeparatorRow = function fnPrepareSeparatorRow(sRowContent, sClass, iNodeIndex) { - $node = $(nRow.children[iNodeIndex]); $node.html(sRowContent); $node.attr('colspan',100); @@ -413,7 +419,9 @@ var AIRTIME = (function(AIRTIME){ $nRow.addClass(sClass); }; - + + $nRow.attr("id", aData.id); + if (aData.header === true) { //remove the column classes from all tds. $nRow.find('td').removeClass(); @@ -615,6 +623,7 @@ var AIRTIME = (function(AIRTIME){ $cursorRows, $table = $(this), $parent = $table.parent(), + $tr, //use this array to cache DOM heights then we can detach the table to manipulate it to increase speed. heights = []; @@ -653,6 +662,13 @@ var AIRTIME = (function(AIRTIME){ }); $td.append(markerDiv).wrapInner(wrapperDiv); + + } + + //re-highlight selected cursors before draw took place + for (i = 0; i < cursorIds.length; i++) { + $tr = $table.find("tr[id="+cursorIds[i]+"]"); + mod.selectCursor($tr); } //if there is only 1 cursor on the page highlight it by default. From ca3d554c070b52c0d8fcb1284aa8d60fa2efcfa8 Mon Sep 17 00:00:00 2001 From: denise Date: Tue, 26 Jun 2012 15:49:17 -0400 Subject: [PATCH 17/57] CC-3983: Timeline cursor in Now Playing vanishes after adding a file to a show -empty cursorId array after every callback --- airtime_mvc/public/js/airtime/showbuilder/builder.js | 1 + 1 file changed, 1 insertion(+) diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index ee885d079..35376cb41 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -670,6 +670,7 @@ var AIRTIME = (function(AIRTIME){ $tr = $table.find("tr[id="+cursorIds[i]+"]"); mod.selectCursor($tr); } + cursorIds = []; //if there is only 1 cursor on the page highlight it by default. if ($cursorRows.length === 1) { From d892a4b5ae0855c5771f6297c8f5235dcf15a07a Mon Sep 17 00:00:00 2001 From: denise Date: Tue, 26 Jun 2012 16:43:36 -0400 Subject: [PATCH 18/57] CC-4009: Calendar icon cannot be clicked twice without clicking another icon first -fixed --- airtime_mvc/public/js/airtime/showbuilder/main_builder.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js index ca007e69c..c474e49df 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/main_builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/main_builder.js @@ -30,7 +30,7 @@ AIRTIME = (function(AIRTIME) { oBaseDatePickerSettings = { dateFormat: 'yy-mm-dd', - onSelect: function(sDate, oDatePicker) { + onClick: function(sDate, oDatePicker) { $(this).datepicker( "setDate", sDate ); } }; @@ -277,4 +277,4 @@ AIRTIME = (function(AIRTIME) { } (AIRTIME || {})); $(document).ready(AIRTIME.builderMain.onReady); -$(window).resize(AIRTIME.builderMain.onResize); \ No newline at end of file +$(window).resize(AIRTIME.builderMain.onResize); From 9a14051f0bcc2ac88651ae9a0815589303f32658 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 26 Jun 2012 16:55:43 -0400 Subject: [PATCH 19/57] CC-4019: Library: When "Add content" is clicked, "Proccessing" image is keep flickering - fixed --- airtime_mvc/public/js/airtime/showbuilder/builder.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 4649a0415..f0a02be81 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -678,8 +678,14 @@ var AIRTIME = (function(AIRTIME){ if (temp.length > 0) { aData = temp.data("aData"); - - mod.timeout = setTimeout(mod.refresh, aData.refresh * 1000); //need refresh in milliseconds + // max time interval + // setTimeout allow only up to 2^21 millisecs timeout value + maxRefreshInterval = Math.pow(2, 31) - 1; + refreshInterval = aData.refresh * 1000; + if(refreshInterval > maxRefreshInterval){ + refreshInterval = maxRefreshInterval; + } + mod.timeout = setTimeout(mod.refresh, refreshInterval); //need refresh in milliseconds break; } } From a6eb74b1fdc57c11e1dc7675f9ba118d96185218 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 26 Jun 2012 17:00:14 -0400 Subject: [PATCH 20/57] CC-4017: Run airtime-playour process as root user -Done --- python_apps/pypo/airtime-playout-init-d | 5 +-- python_apps/pypo/pypofile.py | 43 ++++++++++++++----------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/python_apps/pypo/airtime-playout-init-d b/python_apps/pypo/airtime-playout-init-d index 75ea3f6d7..0723a657d 100755 --- a/python_apps/pypo/airtime-playout-init-d +++ b/python_apps/pypo/airtime-playout-init-d @@ -10,6 +10,7 @@ ### END INIT INFO USERID=pypo +ROOTUSERID=root GROUPID=pypo NAME=Airtime\ Playout @@ -47,7 +48,7 @@ start () { chown pypo:pypo /etc/airtime chown pypo:pypo /etc/airtime/liquidsoap.cfg - start-stop-daemon --start --background --quiet --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0 + start-stop-daemon --start --background --quiet --chuid $ROOTUSERID:$ROOTUSERID --make-pidfile --pidfile $PIDFILE0 --startas $DAEMON0 monit monitor airtime-playout >/dev/null 2>&1 liquidsoap_start @@ -80,7 +81,7 @@ monit_restart() { } start_no_monit() { - 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 liquidsoap_start } diff --git a/python_apps/pypo/pypofile.py b/python_apps/pypo/pypofile.py index 7b948000c..eb19fbcd2 100644 --- a/python_apps/pypo/pypofile.py +++ b/python_apps/pypo/pypofile.py @@ -9,6 +9,7 @@ import logging.config import shutil import os import sys +import stat from std_err_override import LogWriter @@ -33,21 +34,21 @@ except Exception, e: class PypoFile(Thread): - + def __init__(self, schedule_queue): Thread.__init__(self) self.logger = logging.getLogger() self.media_queue = schedule_queue self.media = None self.cache_dir = os.path.join(config["cache_dir"], "scheduler") - + def copy_file(self, media_item): """ Copy media_item from local library directory to local cache directory. - """ + """ src = media_item['uri'] dst = media_item['dst'] - + try: src_size = os.path.getsize(src) except Exception, e: @@ -59,14 +60,14 @@ class PypoFile(Thread): dst_size = os.path.getsize(dst) except Exception, e: dst_exists = False - + do_copy = False if dst_exists: if src_size != dst_size: do_copy = True else: do_copy = True - + if do_copy: self.logger.debug("copying from %s to local cache %s" % (src, dst)) try: @@ -74,9 +75,13 @@ class PypoFile(Thread): copy will overwrite dst if it already exists """ shutil.copy(src, dst) - except: + + #make file world readable + os.chmod(dst, stat.S_IRUSR | stat.S_IRGRP | stat.S_IXOTH) + except Exception, e: self.logger.error("Could not copy from %s to %s" % (src, dst)) - + self.logger.error(e) + def get_highest_priority_media_item(self, schedule): """ Get highest priority media_item in the queue. Currently the highest @@ -84,17 +89,17 @@ class PypoFile(Thread): """ if schedule is None or len(schedule) == 0: return None - + sorted_keys = sorted(schedule.keys()) - + if len(sorted_keys) == 0: return None - + highest_priority = sorted_keys[0] media_item = schedule[highest_priority] - + self.logger.debug("Highest priority item: %s" % highest_priority) - + """ Remove this media_item from the dictionary. On the next iteration (from the main function) we won't consider it for prioritization @@ -103,11 +108,11 @@ class PypoFile(Thread): again. In this situation, the worst possible case is that we try to copy the file again and realize we already have it (thus aborting the copy). """ - del schedule[highest_priority] - + del schedule[highest_priority] + return media_item - - + + def main(self): while True: try: @@ -128,7 +133,7 @@ class PypoFile(Thread): self.media = self.media_queue.get_nowait() except Empty, e: pass - + media_item = self.get_highest_priority_media_item(self.media) if media_item is not None: @@ -139,7 +144,7 @@ class PypoFile(Thread): self.logger.error(str(e)) self.logger.error(top) raise - + def run(self): """ Entry point of the thread From 576c13963d3ffc595a11d4617609be51666749b4 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 26 Jun 2012 17:35:07 -0400 Subject: [PATCH 21/57] CC-3998: Now Playing -> Time Line: confirm message for user 'delete' track by context menu is misleading - fixed --- airtime_mvc/public/js/airtime/showbuilder/builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 0ea7b943d..88b49eb8f 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -1088,7 +1088,7 @@ var AIRTIME = (function(AIRTIME){ if (oItems.del !== undefined) { callback = function() { - if (confirm("Delete selected Items?")) { + if (confirm("Delete selected item?")) { AIRTIME.showbuilder.fnRemove([{ id: data.id, timestamp: data.timestamp, From 31d643cee1a16cc2f62fb057e3efd0f79a91a8d9 Mon Sep 17 00:00:00 2001 From: James Date: Tue, 26 Jun 2012 17:43:15 -0400 Subject: [PATCH 22/57] CC-3997: Now Playing -> Time Line: different behaviour between 'delete' button and 'delete' menu items - added confirm box on clicking delete button on now playing table - also added confirm box on library delete button as well --- .../public/js/airtime/library/library.js | 30 ++++++++++--------- .../public/js/airtime/showbuilder/builder.js | 13 ++++---- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/airtime_mvc/public/js/airtime/library/library.js b/airtime_mvc/public/js/airtime/library/library.js index a05445629..5e286fbc9 100644 --- a/airtime_mvc/public/js/airtime/library/library.js +++ b/airtime_mvc/public/js/airtime/library/library.js @@ -252,20 +252,22 @@ var AIRTIME = (function(AIRTIME) { }; mod.fnDeleteSelectedItems = function() { - var aData = AIRTIME.library.getSelectedData(), - item, - temp, - aMedia = []; - - //process selected files/playlists. - for (item in aData) { - temp = aData[item]; - if (temp !== null && temp.hasOwnProperty('id') ) { - aMedia.push({"id": temp.id, "type": temp.ftype}); - } - } - - AIRTIME.library.fnDeleteItems(aMedia); + if (confirm('Are you sure you want to delete the selected item(s)?')) { + var aData = AIRTIME.library.getSelectedData(), + item, + temp, + aMedia = []; + + //process selected files/playlists. + for (item in aData) { + temp = aData[item]; + if (temp !== null && temp.hasOwnProperty('id') ) { + aMedia.push({"id": temp.id, "type": temp.ftype}); + } + } + + AIRTIME.library.fnDeleteItems(aMedia); + } }; libraryInit = function() { diff --git a/airtime_mvc/public/js/airtime/showbuilder/builder.js b/airtime_mvc/public/js/airtime/showbuilder/builder.js index 88b49eb8f..c4a58cc07 100644 --- a/airtime_mvc/public/js/airtime/showbuilder/builder.js +++ b/airtime_mvc/public/js/airtime/showbuilder/builder.js @@ -243,11 +243,14 @@ var AIRTIME = (function(AIRTIME){ mod.fnRemove = function(aItems) { mod.disableUI(); - - $.post( "/showbuilder/schedule-remove", - {"items": aItems, "format": "json"}, - mod.fnItemCallback - ); + if (confirm("Delete selected item(s)?")) { + $.post( "/showbuilder/schedule-remove", + {"items": aItems, "format": "json"}, + mod.fnItemCallback + ); + }else{ + mod.enableUI(); + } }; mod.fnRemoveSelectedItems = function() { From 43c4b943f2e0f2620f816497d7125a97443d56b7 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 26 Jun 2012 17:50:26 -0400 Subject: [PATCH 23/57] CC-4017: Run airtime-playour process as root user fixed world readable permissions when caching file --- python_apps/pypo/pypofile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/pypo/pypofile.py b/python_apps/pypo/pypofile.py index eb19fbcd2..e120af835 100644 --- a/python_apps/pypo/pypofile.py +++ b/python_apps/pypo/pypofile.py @@ -77,7 +77,7 @@ class PypoFile(Thread): shutil.copy(src, dst) #make file world readable - os.chmod(dst, stat.S_IRUSR | stat.S_IRGRP | stat.S_IXOTH) + os.chmod(dst, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) except Exception, e: self.logger.error("Could not copy from %s to %s" % (src, dst)) self.logger.error(e) From 4061059d3a01daa606d1adc212a9c9eee66eb243 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 26 Jun 2012 18:04:05 -0400 Subject: [PATCH 24/57] CC-3938: Mono sources don't work for stream rebroadcasting -fixed --- .../pypo/liquidsoap_scripts/ls_script.liq | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/python_apps/pypo/liquidsoap_scripts/ls_script.liq b/python_apps/pypo/liquidsoap_scripts/ls_script.liq index efbd221de..482a60a5e 100644 --- a/python_apps/pypo/liquidsoap_scripts/ls_script.liq +++ b/python_apps/pypo/liquidsoap_scripts/ls_script.liq @@ -130,21 +130,21 @@ end def append_dj_inputs(master_harbor_input_port, master_harbor_input_mount_point, dj_harbor_input_port, dj_harbor_input_mount_point, s) = if master_harbor_input_port != 0 and master_harbor_input_mount_point != "" and dj_harbor_input_port != 0 and dj_harbor_input_mount_point != "" then - master_dj = mksafe(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client, - max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect)) - dj_live = mksafe(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client, - max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect)) + master_dj = mksafe(audio_to_stereo(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client, + max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect))) + dj_live = mksafe(audio_to_stereo(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client, + max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect))) ignore(output.dummy(master_dj, fallible=true)) ignore(output.dummy(dj_live, fallible=true)) switch(id="master_dj_switch", track_sensitive=false, transitions=[transition, transition, transition], [({!master_dj_enabled},master_dj), ({!live_dj_enabled},dj_live), ({true}, s)]) elsif master_harbor_input_port != 0 and master_harbor_input_mount_point != "" then - master_dj = mksafe(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client, - max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect)) + master_dj = mksafe(audio_to_stereo(input.harbor(id="master_harbor", master_harbor_input_mount_point, port=master_harbor_input_port, auth=check_master_dj_client, + max=40., on_connect=master_dj_connect, on_disconnect=master_dj_disconnect))) ignore(output.dummy(master_dj, fallible=true)) switch(id="master_dj_switch", track_sensitive=false, transitions=[transition, transition], [({!master_dj_enabled},master_dj), ({true}, s)]) elsif dj_harbor_input_port != 0 and dj_harbor_input_mount_point != "" then - dj_live = mksafe(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client, - max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect)) + dj_live = mksafe(audio_to_stereo(input.harbor(id="live_dj_harbor", dj_harbor_input_mount_point, port=dj_harbor_input_port, auth=check_dj_client, + max=40., on_connect=live_dj_connect, on_disconnect=live_dj_disconnect))) ignore(output.dummy(dj_live, fallible=true)) switch(id="live_dj_switch", track_sensitive=false, transitions=[transition, transition], [({!live_dj_enabled},dj_live), ({true}, s)]) else From b6483cd952224b148b05185428d01112632a03c8 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 26 Jun 2012 22:39:17 -0400 Subject: [PATCH 25/57] CC-4023: Make clearer install error when Airtime fails due to incorrect postgresql encoding -done --- install_minimal/include/airtime-install.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/install_minimal/include/airtime-install.php b/install_minimal/include/airtime-install.php index cb9189a4f..6fddb7bfa 100644 --- a/install_minimal/include/airtime-install.php +++ b/install_minimal/include/airtime-install.php @@ -61,6 +61,16 @@ AirtimeInstall::InstallStorageDirectory(); $db_install = getenv("nodb")!="t"; if ($db_install) { + + echo "* Checking database for correct encoding".PHP_EOL; + exec('su -c \'psql -t -c "SHOW SERVER_ENCODING"\' postgres | grep -i "UTF.*8"', $out, $return_code); + if ($return_code != 0){ + echo " * Unfortunately your postgresql database has not been created using a UTF-8 encoding.".PHP_EOL; + echo " * As of Airtime 2.1, installs will fail unless the encoding has been set to UTF-8. Please verify this is the case".PHP_EOL; + echo " * and try the install again".PHP_EOL; + exit(1); + } + if($newInstall) { //call external script. "y" argument means force creation of database tables. passthru('php '.__DIR__.'/airtime-db-install.php y'); From 0a3c9c73519e36038df4fad105fad56119885645 Mon Sep 17 00:00:00 2001 From: Martin Konecny Date: Tue, 26 Jun 2012 22:41:11 -0400 Subject: [PATCH 26/57] clean up indentation + imports for python apps --- python_apps/pypo/install/pypo-initialize.py | 14 -- python_apps/pypo/pypocli.py | 40 +++-- python_apps/pypo/pypofetch.py | 120 +++++++------- python_apps/pypo/pypofile.py | 1 - python_apps/pypo/pypomessagehandler.py | 21 ++- python_apps/pypo/pypopush.py | 168 ++++++++++---------- python_apps/pypo/recorder.py | 31 ++-- 7 files changed, 183 insertions(+), 212 deletions(-) diff --git a/python_apps/pypo/install/pypo-initialize.py b/python_apps/pypo/install/pypo-initialize.py index bbefe7ddb..12eb870ca 100644 --- a/python_apps/pypo/install/pypo-initialize.py +++ b/python_apps/pypo/install/pypo-initialize.py @@ -109,20 +109,6 @@ try: print e sys.exit(1) - """ - logging.basicConfig(format='%(message)s') - - #generate liquidsoap config file - #access the DB and generate liquidsoap.cfg under /etc/airtime/ - ac = api_client.api_client_factory(config, logging.getLogger()) - ss = ac.get_stream_setting() - - if ss is not None: - generate_liquidsoap_config(ss) - else: - print "Unable to connect to the Airtime server." - """ - #initialize init.d scripts subprocess.call("update-rc.d airtime-playout defaults >/dev/null 2>&1", shell=True) diff --git a/python_apps/pypo/pypocli.py b/python_apps/pypo/pypocli.py index 1cc8ff2c8..eb528c176 100644 --- a/python_apps/pypo/pypocli.py +++ b/python_apps/pypo/pypocli.py @@ -3,12 +3,10 @@ Python part of radio playout (pypo) """ import time -from optparse import * +from optparse import OptionParser import sys import signal import logging -import logging.config -import logging.handlers import locale import os from Queue import Queue @@ -53,11 +51,11 @@ parser.add_option("-c", "--check", help="Check the cached schedule and exit", de def configure_locale(): logger.debug("Before %s", locale.nl_langinfo(locale.CODESET)) current_locale = locale.getlocale() - + if current_locale[1] is None: logger.debug("No locale currently set. Attempting to get default locale.") default_locale = locale.getdefaultlocale() - + if default_locale[1] is None: logger.debug("No default locale exists. Let's try loading from /etc/default/locale") if os.path.exists("/etc/default/locale"): @@ -69,17 +67,17 @@ def configure_locale(): sys.exit(1) else: new_locale = default_locale - + logger.info("New locale set to: %s", locale.setlocale(locale.LC_ALL, new_locale)) - - - + + + reload(sys) sys.setdefaultencoding("UTF-8") current_locale_encoding = locale.getlocale()[1].lower() logger.debug("sys default encoding %s", sys.getdefaultencoding()) logger.debug("After %s", locale.nl_langinfo(locale.CODESET)) - + if current_locale_encoding not in ['utf-8', 'utf8']: logger.error("Need a UTF-8 locale. Currently '%s'. Exiting..." % current_locale_encoding) sys.exit(1) @@ -92,7 +90,7 @@ try: except Exception, e: print "Couldn't configure logging" sys.exit() - + configure_locale() # loading config file @@ -105,11 +103,11 @@ except Exception, e: class Global: def __init__(self): self.api_client = api_client.api_client_factory(config) - + def selfcheck(self): self.api_client = api_client.api_client_factory(config) return self.api_client.is_server_compatible() - + def test_api(self): self.api_client.test() @@ -160,7 +158,7 @@ if __name__ == '__main__': g = Global() while not g.selfcheck(): time.sleep(5) - + logger = logging.getLogger() if options.test: @@ -173,9 +171,9 @@ if __name__ == '__main__': pypoFetch_q = Queue() recorder_q = Queue() pypoPush_q = Queue() - + telnet_lock = Lock() - + """ This queue is shared between pypo-fetch and pypo-file, where pypo-file is the receiver. Pypo-fetch will send every schedule it gets to pypo-file @@ -183,19 +181,19 @@ if __name__ == '__main__': priority, and will retrieve it. """ media_q = Queue() - + pmh = PypoMessageHandler(pypoFetch_q, recorder_q) pmh.daemon = True pmh.start() - + pfile = PypoFile(media_q) pfile.daemon = True pfile.start() - + pf = PypoFetch(pypoFetch_q, pypoPush_q, media_q, telnet_lock) pf.daemon = True pf.start() - + pp = PypoPush(pypoPush_q, telnet_lock) pp.daemon = True pp.start() @@ -210,7 +208,7 @@ if __name__ == '__main__': #recorder.join() #pp.join() pf.join() - + logger.info("pypo fetch exit") sys.exit() """ diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index b9cb6e76b..2e3ab4280 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -3,9 +3,7 @@ import os import sys import time -import logging import logging.config -import shutil import json import telnetlib import copy @@ -44,11 +42,11 @@ class PypoFetch(Thread): self.media_prepare_queue = media_q self.last_update_schedule_timestamp = time.time() self.listener_timeout = 3600 - + self.telnet_lock = telnet_lock - + self.logger = logging.getLogger(); - + self.cache_dir = os.path.join(config["cache_dir"], "scheduler") self.logger.debug("Cache dir %s", self.cache_dir) @@ -63,24 +61,24 @@ class PypoFetch(Thread): os.makedirs(dir) except Exception, e: pass - + self.schedule_data = [] self.logger.info("PypoFetch: init complete") - + """ Handle a message from RabbitMQ, put it into our yucky global var. Hopefully there is a better way to do this. """ def handle_message(self, message): - try: + try: self.logger.info("Received event from Pypo Message Handler: %s" % message) - - m = json.loads(message) + + m = json.loads(message) command = m['event_type'] self.logger.info("Handling command: " + command) - + if command == 'update_schedule': - self.schedule_data = m['schedule'] + self.schedule_data = m['schedule'] self.process_schedule(self.schedule_data) elif command == 'update_stream_setting': self.logger.info("Updating stream setting...") @@ -100,7 +98,7 @@ class PypoFetch(Thread): elif command == 'disconnect_source': self.logger.info("disconnect_on_source show command received...") self.disconnect_source(self.logger, self.telnet_lock, m['sourcename']) - + # update timeout value if command == 'update_schedule': self.listener_timeout = 3600 @@ -115,7 +113,7 @@ class PypoFetch(Thread): self.logger.error('Exception: %s', e) self.logger.error("traceback: %s", top) self.logger.error("Exception in handling Message Handler message: %s", e) - + @staticmethod def disconnect_source(logger, lock, sourcename): logger.debug('Disconnecting source: %s', sourcename) @@ -124,7 +122,7 @@ class PypoFetch(Thread): command += "master_harbor.kick\n" elif(sourcename == "live_dj"): command += "live_dj_harbor.kick\n" - + lock.acquire() try: tn = telnetlib.Telnet(LS_HOST, LS_PORT) @@ -135,7 +133,7 @@ class PypoFetch(Thread): logger.error(str(e)) finally: lock.release() - + @staticmethod def switch_source(logger, lock, sourcename, status): logger.debug('Switching source: %s to "%s" status', sourcename, status) @@ -146,12 +144,12 @@ class PypoFetch(Thread): command += "live_dj_" elif(sourcename == "scheduled_play"): command += "scheduled_play_" - + if(status == "on"): command += "start\n" else: command += "stop\n" - + lock.acquire() try: tn = telnetlib.Telnet(LS_HOST, LS_PORT) @@ -162,7 +160,7 @@ class PypoFetch(Thread): logger.error(str(e)) finally: lock.release() - + """ grabs some information that are needed to be set on bootstrap time and configures them @@ -174,13 +172,13 @@ class PypoFetch(Thread): self.logger.error('Unable to get bootstrap info.. Existing pypo...') sys.exit(0) else: - self.logger.debug('info:%s',info) + self.logger.debug('info:%s', info) for k, v in info['switch_status'].iteritems(): self.switch_source(self.logger, self.telnet_lock, k, v) self.update_liquidsoap_stream_format(info['stream_label']) self.update_liquidsoap_station_name(info['station_name']) self.update_liquidsoap_transition_fade(info['transition_fade']) - + def write_liquidsoap_config(self, setting): fh = open('/etc/airtime/liquidsoap.cfg', 'w') self.logger.info("Rewriting liquidsoap.cfg...") @@ -197,7 +195,7 @@ class PypoFetch(Thread): if temp == "": temp = "0" buffer_str += temp - + buffer_str += "\n" fh.write(api_client.encode_to(buffer_str)) fh.write("log_file = \"/var/log/airtime/pypo-liquidsoap/