From 44481d277607d40ee19e65a3ad61e9bb5066a489 Mon Sep 17 00:00:00 2001 From: Paul Baranowski Date: Thu, 29 Sep 2011 18:11:22 -0400 Subject: [PATCH 01/12] SAAS-41: Changed name of boolean value from disable-stream-conf to enable-stream-conf for easier logic. --- .../controllers/PreferenceController.php | 28 +++++------ .../application/forms/StreamSetting.php | 14 +++--- .../forms/StreamSettingSubForm.php | 48 +++++++++---------- airtime_mvc/application/models/Preference.php | 48 +++++++++---------- .../scripts/preference/stream-setting.phtml | 6 +-- 5 files changed, 72 insertions(+), 72 deletions(-) diff --git a/airtime_mvc/application/controllers/PreferenceController.php b/airtime_mvc/application/controllers/PreferenceController.php index 11fead872..64d7ae4a0 100644 --- a/airtime_mvc/application/controllers/PreferenceController.php +++ b/airtime_mvc/application/controllers/PreferenceController.php @@ -76,10 +76,10 @@ class PreferenceController extends Zend_Controller_Action Application_Model_Preference::SetStationWebSite($values["StationWebSite"]); Application_Model_Preference::SetSupportFeedback($values["SupportFeedback"]); Application_Model_Preference::SetPublicise($values["Publicise"]); - + $form->Logo->receive(); $imagePath = $form->Logo->getFileName(); - + Application_Model_Preference::SetStationCountry($values["Country"]); Application_Model_Preference::SetStationCity($values["City"]); Application_Model_Preference::SetStationDescription($values["Description"]); @@ -103,36 +103,36 @@ class PreferenceController extends Zend_Controller_Action $this->view->form = $form; //$form->render($this->view); } - + public function directoryConfigAction() { if(Application_Model_Preference::GetPlanLevel() == 'disabled'){ $request = $this->getRequest(); $baseUrl = $request->getBaseUrl(); - + $this->view->headScript()->appendFile($baseUrl.'/js/serverbrowse/serverbrowser.js','text/javascript'); $this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/musicdirs.js','text/javascript'); - + $watched_dirs_pref = new Application_Form_WatchedDirPreferences(); - + $this->view->form = $watched_dirs_pref; } } - + public function streamSettingAction() { $request = $this->getRequest(); $baseUrl = $request->getBaseUrl(); - + $this->view->headScript()->appendFile($baseUrl.'/js/airtime/preferences/streamsetting.js','text/javascript'); - + // get current settings $temp = Application_Model_StreamSetting::getStreamSetting(); $setting = array(); foreach ($temp as $t){ $setting[$t['keyname']] = $t['value']; } - + // get predefined type and bitrate from pref table $temp_types = Application_Model_Preference::GetStreamType(); $stream_types = array(); @@ -144,7 +144,7 @@ class PreferenceController extends Zend_Controller_Action } $stream_types[trim($type)] = $temp; } - + $temp_bitrate = Application_Model_Preference::GetStreamBitrate(); $max_bitrate = intval(Application_Model_Preference::GetMaxBitrate()); $stream_bitrates = array(); @@ -153,7 +153,7 @@ class PreferenceController extends Zend_Controller_Action $stream_bitrates[trim($type)] = strtoupper(trim($type))." Kbit/s"; } } - + $num_of_stream = intval(Application_Model_Preference::GetNumOfStreams()); $form = new Application_Form_StreamSetting(); $form->setSetting($setting); @@ -193,7 +193,7 @@ class PreferenceController extends Zend_Controller_Action } } $this->view->num_stream = $num_of_stream; - $this->view->disable_stream_conf = Application_Model_Preference::GetDisableStreamConf(); + $this->view->enable_stream_conf = Application_Model_Preference::GetEnableStreamConf(); $this->view->form = $form; } @@ -273,7 +273,7 @@ class PreferenceController extends Zend_Controller_Action $watched_dirs_form = new Application_Form_WatchedDirPreferences(); $this->view->subform = $watched_dirs_form->render(); } - + public function isImportInProgressAction(){ $now = time(); $res = false; diff --git a/airtime_mvc/application/forms/StreamSetting.php b/airtime_mvc/application/forms/StreamSetting.php index 746215b11..cb7735cb5 100644 --- a/airtime_mvc/application/forms/StreamSetting.php +++ b/airtime_mvc/application/forms/StreamSetting.php @@ -3,29 +3,29 @@ class Application_Form_StreamSetting extends Zend_Form { private $setting; - + public function init() { - + } - + public function setSetting($setting){ $this->setting = $setting; } - - public function startFrom(){ + + public function startFrom() { $setting = $this->setting; $output_sound_device = new Zend_Form_Element_Checkbox('output_sound_device'); $output_sound_device->setLabel('Enabled') ->setRequired(false) ->setValue(($setting['output_sound_device'] == "true")?1:0) ->setDecorators(array('ViewHelper')); - if(Application_Model_Preference::GetDisableStreamConf() == "true"){ + if (Application_Model_Preference::GetEnableStreamConf() == "false"){ $output_sound_device->setAttrib("readonly", true); } $this->addElement($output_sound_device); } - + public function isValid($data){ $this->populate(array("output_sound_device"=>$data)); return true; diff --git a/airtime_mvc/application/forms/StreamSettingSubForm.php b/airtime_mvc/application/forms/StreamSettingSubForm.php index 5a3e37e65..c8398d806 100644 --- a/airtime_mvc/application/forms/StreamSettingSubForm.php +++ b/airtime_mvc/application/forms/StreamSettingSubForm.php @@ -4,43 +4,43 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ private $setting; private $stream_types; private $stream_bitrates; - + public function init() { - + } - + public function setPrefix($prefix){ $this->prefix = $prefix; } - + public function setSetting($setting){ $this->setting = $setting; } - + public function setStreamTypes($stream_types){ $this->stream_types = $stream_types; } - + public function setStreamBitrates($stream_bitrates){ $this->stream_bitrates = $stream_bitrates; } - + public function startForm(){ $prefix = "s".$this->prefix; $stream_number = $this->prefix; $setting = $this->setting; $stream_types = $this->stream_types; $stream_bitrates = $this->stream_bitrates; - + $this->setIsArray(true); $this->setElementsBelongTo($prefix."_data"); - + $disable_all = false; - if(Application_Model_Preference::GetDisableStreamConf() == "true"){ + if(Application_Model_Preference::GetEnableStreamConf() == "false"){ $disable_all = true; } - + $enable = new Zend_Form_Element_Checkbox('enable'); $enable->setLabel('Enabled:') ->setValue($setting[$prefix.'_output'] != 'disabled'?1:0) @@ -49,7 +49,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $enable->setAttrib("disabled", "disabled"); } $this->addElement($enable); - + $type = new Zend_Form_Element_Select('type'); $type->setLabel("Stream Type:") ->setMultiOptions($stream_types) @@ -59,7 +59,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $type->setAttrib("disabled", "disabled"); } $this->addElement($type); - + $bitrate = new Zend_Form_Element_Select('bitrate'); $bitrate->setLabel("Bit Rate:") ->setMultiOptions($stream_bitrates) @@ -70,7 +70,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ } $this->addElement($type); $this->addElement($bitrate); - + $output = new Zend_Form_Element_Select('output'); $output->setLabel("Service Type:") ->setMultiOptions(array("icecast"=>"Icecast", "shoutcast"=>"Shoutcast")) @@ -80,7 +80,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $output->setAttrib("disabled", "disabled"); } $this->addElement($output); - + $host = new Zend_Form_Element_Text('host'); $host->setLabel("Server") ->setValue(isset($setting[$prefix.'_host'])?$setting[$prefix.'_host']:"") @@ -89,7 +89,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $host->setAttrib("disabled", "disabled"); } $this->addElement($host); - + $port = new Zend_Form_Element_Text('port'); $port->setLabel("Port") ->setValue(isset($setting[$prefix.'_port'])?$setting[$prefix.'_port']:"") @@ -100,7 +100,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $port->setAttrib("disabled", "disabled"); } $this->addElement($port); - + $pass = new Zend_Form_Element_Text('pass'); $pass->setLabel("Password") ->setValue(isset($setting[$prefix.'_pass'])?$setting[$prefix.'_pass']:"") @@ -109,7 +109,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $pass->setAttrib("disabled", "disabled"); } $this->addElement($pass); - + $genre = new Zend_Form_Element_Text('genre'); $genre->setLabel("Genre") ->setValue(isset($setting[$prefix.'_genre'])?$setting[$prefix.'_genre']:"") @@ -118,7 +118,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $genre->setAttrib("disabled", "disabled"); } $this->addElement($genre); - + $url = new Zend_Form_Element_Text('url'); $url->setLabel("URL") ->setValue(isset($setting[$prefix.'_url'])?$setting[$prefix.'_url']:"") @@ -127,7 +127,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $url->setAttrib("disabled", "disabled"); } $this->addElement($url); - + $description = new Zend_Form_Element_Text('description'); $description->setLabel("Name/Description") ->setValue(isset($setting[$prefix.'_description'])?$setting[$prefix.'_description']:"") @@ -136,7 +136,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $description->setAttrib("disabled", "disabled"); } $this->addElement($description); - + $mount = new Zend_Form_Element_Text('mount'); $mount->setLabel("Mount Point") ->setValue(isset($setting[$prefix.'_mount'])?$setting[$prefix.'_mount']:"") @@ -145,7 +145,7 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $mount->setAttrib("disabled", "disabled"); } $this->addElement($mount); - + $user = new Zend_Form_Element_Text('user'); $user->setLabel("Username") ->setValue(isset($setting[$prefix.'_user'])?$setting[$prefix.'_user']:"") @@ -154,12 +154,12 @@ class Application_Form_StreamSettingSubForm extends Zend_Form_SubForm{ $user->setAttrib("disabled", "disabled"); } $this->addElement($user); - + $this->setDecorators(array( array('ViewScript', array('viewScript' => 'form/stream-setting-form.phtml', "stream_number"=>$stream_number)) )); } - + public function isValid ($data){ $isValid = parent::isValid($data); if($data['enable'] == 1){ diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 513067b79..bd55a28eb 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -259,13 +259,13 @@ class Application_Model_Preference public static function GetStationDescription(){ return self::GetValue("description"); } - + public static function SetTimezone($timezone){ self::SetValue("timezone", $timezone); date_default_timezone_set($timezone); $md = array("timezone" => $timezone); } - + public static function GetTimezone(){ return self::GetValue("timezone"); } @@ -328,11 +328,11 @@ class Application_Model_Preference $url = $systemInfoArray["AIRTIME_VERSION_URL"]; $index = strpos($url,'/api/'); $url = substr($url, 0, $index); - + $headerInfo = get_headers(trim($url),1); $outputArray['WEB_SERVER'] = $headerInfo['Server'][0]; } - + $outputArray['NUM_OF_USERS'] = Application_Model_User::getUserCount(); $outputArray['NUM_OF_SONGS'] = Application_Model_StoredFile::getFileCount(); $outputArray['NUM_OF_PLAYLISTS'] = Application_Model_Playlist::getPlaylistCount(); @@ -365,74 +365,74 @@ class Application_Model_Preference public static function GetRemindMeDate(){ return self::GetValue("remindme"); } - + public static function SetImportTimestamp(){ $now = time(); if(self::GetImportTimestamp()+5 < $now){ self::SetValue("import_timestamp", $now); } } - + public static function GetImportTimestamp(){ return self::GetValue("import_timestamp"); } - + public static function GetStreamType(){ $st = self::GetValue("stream_type"); return explode(',', $st); } - + public static function GetStreamBitrate(){ $sb = self::GetValue("stream_bitrate"); return explode(',', $sb); } - + public static function SetPrivacyPolicyCheck($flag){ self::SetValue("privacy_policy", $flag); } - + public static function GetPrivacyPolicyCheck(){ return self::GetValue("privacy_policy"); } - + public static function SetNumOfStreams($num){ self::SetValue("num_of_streams", intval($num)); } - + public static function GetNumOfStreams(){ return self::GetValue("num_of_streams"); } - + public static function SetMaxBitrate($bitrate){ self::SetValue("max_bitrate", intval($bitrate)); } - + public static function GetMaxBitrate(){ return self::GetValue("max_bitrate"); } - + public static function SetPlanLevel($plan){ self::SetValue("plan_level", $plan); } - + public static function GetPlanLevel(){ return self::GetValue("plan_level"); } - + public static function SetTrialEndingDate($date){ self::SetValue("trial_end_date", $date); } - + public static function GetTrialEndingDate(){ return self::GetValue("trial_end_date"); } - - public static function SetDisableStreamConf($bool){ - self::SetValue("disable_stream_conf", $bool); + + public static function SetEnableStreamConf($bool){ + self::SetValue("enable_stream_conf", $bool); } - - public static function GetDisableStreamConf(){ - return self::GetValue("disable_stream_conf"); + + public static function GetEnableStreamConf(){ + return self::GetValue("enable_stream_conf"); } public static function GetAirtimeVersion(){ diff --git a/airtime_mvc/application/views/scripts/preference/stream-setting.phtml b/airtime_mvc/application/views/scripts/preference/stream-setting.phtml index 68436f7b9..aa413857b 100644 --- a/airtime_mvc/application/views/scripts/preference/stream-setting.phtml +++ b/airtime_mvc/application/views/scripts/preference/stream-setting.phtml @@ -1,6 +1,6 @@

Stream Settings

- disable_stream_conf != "true"){?> + enable_stream_conf == "true"){?>
@@ -22,11 +22,11 @@ num_stream;$i++){ + for($i=1;$i<=$this->num_stream;$i++){ echo $this->form->getSubform("s".$i."_subform"); } ?> - disable_stream_conf != "true"){?> + enable_stream_conf == "true"){?>
From b9863e660ee89d3bd71c59fd37f6d7c216766238 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 29 Sep 2011 17:50:12 -0400 Subject: [PATCH 02/12] CC-2806: Create upgrade template file -initial commit --- airtime_mvc/application/Bootstrap.php | 1 - install_minimal/airtime-install | 1 + install_minimal/include/airtime-upgrade.php | 26 + .../airtime-2.0.0/airtime-upgrade-old.php | 586 ++++++++++++++ .../airtime-2.0.0/airtime-upgrade.php | 754 +++++++++--------- install_minimal/upgrades/upgrade-template.php | 282 +++++++ 6 files changed, 1264 insertions(+), 386 deletions(-) create mode 100644 install_minimal/upgrades/airtime-2.0.0/airtime-upgrade-old.php create mode 100644 install_minimal/upgrades/upgrade-template.php diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index 8bf8d58aa..f0e9b98e9 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -28,7 +28,6 @@ $CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); date_default_timezone_set(Application_Model_Preference::GetTimezone()); Logging::setLogPath('/var/log/airtime/zendphp.log'); -Logging::log("bootstrap"); Zend_Validate::setDefaultNamespaces("Zend"); diff --git a/install_minimal/airtime-install b/install_minimal/airtime-install index 8f5f61bf6..031673c19 100755 --- a/install_minimal/airtime-install +++ b/install_minimal/airtime-install @@ -38,6 +38,7 @@ if [ "$result" -eq "2" ]; then exit 0 elif [ "$result" -ne "0" ]; then #There was an error, exit with error code. + echo "There was an error during upgrade. Exit code $result" exit 1 fi set -e diff --git a/install_minimal/include/airtime-upgrade.php b/install_minimal/include/airtime-upgrade.php index 6affb2dc0..616083c69 100644 --- a/install_minimal/include/airtime-upgrade.php +++ b/install_minimal/include/airtime-upgrade.php @@ -19,6 +19,25 @@ if(exec("whoami") != "root"){ exit(1); } + +/* This class is responsible for tasks that need to be executed only *once* + * per upgrade, even if it's upgrading over multiple versions of Airtime. */ +class AirtimeMasterUpgrade{ + const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf"; + + public static function InstallAirtimePhpServerCode($phpDir) + { + $AIRTIME_SRC = realpath(__DIR__.'/../../airtime_mvc'); + + // delete old files + exec("rm -rf \"$phpDir\""); + echo "* Installing PHP code to ".$phpDir.PHP_EOL; + exec("mkdir -p ".$phpDir); + exec("cp -R ".$AIRTIME_SRC."/* ".$phpDir); + } +} + + global $CC_DBC, $CC_CONFIG; $values = parse_ini_file('/etc/airtime/airtime.conf', true); @@ -86,6 +105,13 @@ if (strcmp($version, "2.0.0") < 0){ $sql = "DELETE FROM cc_pref WHERE keystr = 'system_version'"; $CC_DBC->query($sql); +$values = parse_ini_file(AirtimeMasterUpgrade::CONF_FILE_AIRTIME, true); +$phpDir = $values['general']['airtime_dir']; +AirtimeMasterUpgrade::InstallAirtimePhpServerCode($phpDir); +AirtimeInstall::InstallBinaries(); +AirtimeInstall::CreateSymlinksToUtils(); + + $newVersion = AIRTIME_VERSION; $sql = "INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '$newVersion')"; $CC_DBC->query($sql); diff --git a/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade-old.php b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade-old.php new file mode 100644 index 000000000..b540021dc --- /dev/null +++ b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade-old.php @@ -0,0 +1,586 @@ +query($sql); + if (PEAR::isError($result)) { + return false; + } + return true; + } + + public static function GetUtilsSrcDir() + { + return __DIR__."/../../../utils"; + } + + public static function InstallBinaries() + { + echo "* Installing binaries to ".AirtimeInstall::CONF_DIR_BINARIES.PHP_EOL; + exec("mkdir -p ".AirtimeInstall::CONF_DIR_BINARIES); + exec("cp -R ".AirtimeInstall::GetUtilsSrcDir()." ".AirtimeInstall::CONF_DIR_BINARIES); + } + + public static function CreateSymlinksToUtils() + { + echo "* Installing airtime-log".PHP_EOL; + $dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-log"; + copy(AirtimeInstall::GetUtilsSrcDir()."/airtime-log.php", AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-log.php"); + + exec("ln -s $dir /usr/bin/airtime-log"); + } + + public static function SetDefaultStreamSetting() + { + global $CC_DBC; + + echo "* Setting up default stream setting".PHP_EOL; + $sql = "INSERT INTO cc_pref(keystr, valstr) VALUES('stream_type', 'ogg, mp3'); + INSERT INTO cc_pref(keystr, valstr) VALUES('stream_bitrate', '24, 32, 48, 64, 96, 128, 160, 192, 224, 256, 320'); + INSERT INTO cc_pref(keystr, valstr) VALUES('num_of_streams', '3'); + INSERT INTO cc_pref(keystr, valstr) VALUES('max_bitrate', '128'); + INSERT INTO cc_pref(keystr, valstr) VALUES('plan_level', 'disabled'); + + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('output_sound_device', 'false', 'boolean'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('icecast_vorbis_metadata', 'false', 'boolean'); + + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_output', 'icecast', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_type', 'ogg', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_bitrate', '128', 'integer'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_host', '127.0.0.1', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_port', '8000', 'integer'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_user', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_pass', 'hackme', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_mount', 'airtime_128', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_url', 'http://airtime.sourcefabric.org', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_description', 'Airtime Radio! Stream #1', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s1_genre', 'genre', 'string'); + + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_output', 'disabled', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_type', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_bitrate', '', 'integer'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_host', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_port', '', 'integer'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_user', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_pass', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_mount', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_url', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_description', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s2_genre', '', 'string'); + + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_output', 'disabled', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_type', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_bitrate', '', 'integer'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_host', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_port', '', 'integer'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_user', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_pass', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_mount', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_url', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_description', '', 'string'); + INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s3_genre', '', 'string');"; + $result = $CC_DBC->query($sql); + if (PEAR::isError($result)) { + return false; + } + return true; + } + + public static function BypassMigrations($dir, $version) + { + $appDir = AirtimeInstall::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction --add migrations:version $version"; + system($command); + } + + public static function MigrateTablesToVersion($dir, $version) + { + $appDir = AirtimeInstall::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction migrations:migrate $version"; + system($command); + } + + public static function GetAirtimeSrcDir() + { + return __DIR__."/../../../airtime_mvc"; + } + + public static function DbTableExists($p_name) + { + global $CC_DBC; + $sql = "SELECT * FROM ".$p_name; + $result = $CC_DBC->GetOne($sql); + if (PEAR::isError($result)) { + return false; + } + return true; + } + public static function GetOldLiquidsoapCfgAndUpdate(){ + global $CC_DBC; + echo "* Retrieving old liquidsoap configuration".PHP_EOL; + $map = array(); + $fh = fopen("/etc/airtime/liquidsoap.cfg", 'r'); + $newConfigMap = array(); + + while(!feof($fh)){ + $line = fgets($fh); + if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ + continue; + }else{ + $info = explode('=', $line, 2); + $map[trim($info[0])] = trim($info[1]); + } + } + $newConfigMap['output_sound_device'] = $map['output_sound_device']; + $newConfigMap['icecast_vorbis_metadata'] = $map['output_icecast_vorbis_metadata']; + $newConfigMap['log_file'] = $map['log_file']; + + $count = 1; + if( $map['output_icecast_vorbis'] == 'true'){ + $newConfigMap['s'.$count.'_output'] = 'icecast'; + $newConfigMap['s'.$count.'_host'] = $map['icecast_host']; + $newConfigMap['s'.$count.'_port'] = $map['icecast_port']; + $newConfigMap['s'.$count.'_pass'] = $map['icecast_pass']; + $newConfigMap['s'.$count.'_mount'] = $map['mount_point_vorbis']; + $newConfigMap['s'.$count.'_url'] = $map['icecast_url']; + $newConfigMap['s'.$count.'_description'] = $map['icecast_description']; + $newConfigMap['s'.$count.'_genre'] = $map['icecast_genre']; + $newConfigMap['s'.$count.'_type'] = "ogg"; + $newConfigMap['s'.$count.'_bitrate'] = "128"; + $count++; + } + if($map['output_icecast_mp3'] == 'true'){ + $newConfigMap['s'.$count.'_output'] = 'icecast'; + $newConfigMap['s'.$count.'_host'] = $map['icecast_host']; + $newConfigMap['s'.$count.'_port'] = $map['icecast_port']; + $newConfigMap['s'.$count.'_pass'] = $map['icecast_pass']; + $newConfigMap['s'.$count.'_mount'] = $map['mount_point_mp3']; + $newConfigMap['s'.$count.'_url'] = $map['icecast_url']; + $newConfigMap['s'.$count.'_description'] = $map['icecast_description']; + $newConfigMap['s'.$count.'_genre'] = $map['icecast_genre']; + $newConfigMap['s'.$count.'_type'] = "mp3"; + $newConfigMap['s'.$count.'_bitrate'] = "128"; + $count++; + } + if($map['output_shoutcast'] == 'true'){ + $newConfigMap['s'.$count.'_output'] = 'shoutcast'; + $newConfigMap['s'.$count.'_host'] = $map['shoutcast_host']; + $newConfigMap['s'.$count.'_port'] = $map['shoutcast_port']; + $newConfigMap['s'.$count.'_pass'] = $map['shoutcast_pass']; + $newConfigMap['s'.$count.'_url'] = $map['shoutcast_url']; + $newConfigMap['s'.$count.'_genre'] = $map['shoutcast_genre']; + $newConfigMap['s'.$count.'_type'] = "mp3"; + $newConfigMap['s'.$count.'_bitrate'] = "128"; + $count++; + } + + $sql = ""; + foreach( $newConfigMap as $key=>$val){ + if(substr($val, 0, 1) == '"' && substr($val, strlen($val)-1,1)){ + $val = ltrim($val, '"'); + $val = rtrim($val, '"'); + } + $sql .= "UPDATE cc_stream_setting SET value='$val' WHERE keyname='$key';"; + } + $result = $CC_DBC->query($sql); + if (PEAR::isError($result)) { + return false; + } + return true; + } +} + +class Airtime200Upgrade{ + + public static function connectToDatabase(){ + global $CC_DBC, $CC_CONFIG; + + $values = parse_ini_file('/etc/airtime/airtime.conf', true); + + // Database config + $CC_CONFIG['dsn']['username'] = $values['database']['dbuser']; + $CC_CONFIG['dsn']['password'] = $values['database']['dbpass']; + $CC_CONFIG['dsn']['hostspec'] = $values['database']['host']; + $CC_CONFIG['dsn']['phptype'] = 'pgsql'; + $CC_CONFIG['dsn']['database'] = $values['database']['dbname']; + + $CC_DBC = DB::connect($CC_CONFIG['dsn'], FALSE); + } + + public static function InstallAirtimePhpServerCode($phpDir) + { + + $AIRTIME_SRC = realpath(__DIR__.'/../../../airtime_mvc'); + + // delete old files + exec("rm -rf ".$phpDir); + echo "* Installing PHP code to ".$phpDir.PHP_EOL; + exec("mkdir -p ".$phpDir); + exec("cp -R ".$AIRTIME_SRC."/* ".$phpDir); + } + + public static function RemoveOldMonitFile(){ + unlink("/etc/monit/conf.d/airtime-monit.cfg"); + } +} + +class ConvertToUtc{ + + public static function setPhpDefaultTimeZoneToSystemTimezone(){ + //we can get the default system timezone on debian/ubuntu by reading "/etc/timezone" + $filename = "/etc/timezone"; + $handle = fopen($filename, "r"); + $contents = trim(fread($handle, filesize($filename))); + echo "System timezone detected as: $contents".PHP_EOL; + fclose($handle); + + date_default_timezone_set($contents); + } + + public static function convert_cc_playlist(){ + /* cc_playlist has a field that keeps track of when the playlist was last modified. */ + $playlists = CcPlaylistQuery::create()->find(); + + foreach ($playlists as $pl){ + $dt = new DateTime($pl->getDbMtime(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $pl->setDbMtime($dt); + + $pl->save(); + } + } + + public static function convert_cc_schedule(){ + /* cc_schedule has start and end fields that need to be changed to UTC. */ + $schedules = CcScheduleQuery::create()->find(); + + foreach ($schedules as $s){ + $dt = new DateTime($s->getDbStarts(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $s->setDbStarts($dt); + + $dt = new DateTime($s->getDbEnds(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $s->setDbEnds($dt); + + $s->save(); + } + } + + public static function convert_cc_show_days(){ + /* cc_show_days has first_show, last_show and start_time fields that need to be changed to UTC. */ + $showDays = CcShowDaysQuery::create()->find(); + + foreach ($showDays as $sd){ + $dt = new DateTime($sd->getDbFirstShow()." ".$sd->getDbStartTime(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $sd->setDbFirstShow($dt->format("Y-m-d")); + $sd->setDbStartTime($dt->format("H:i:s")); + + $dt = new DateTime($sd->getDbLastShow()." ".$sd->getDbStartTime(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $sd->setDbLastShow($dt->format("Y-m-d")); + + $sd->save(); + } + } + + public static function convert_cc_show_instances(){ + /* convert_cc_show_instances has starts and ends fields that need to be changed to UTC. */ + $showInstances = CcShowInstancesQuery::create()->find(); + + foreach ($showInstances as $si){ + $dt = new DateTime($si->getDbStarts(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $si->setDbStarts($dt); + + $dt = new DateTime($si->getDbEnds(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $si->setDbEnds($dt); + + $si->save(); + } + } +} + +class AirtimeIni200{ + + const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf"; + const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg"; + const CONF_FILE_RECORDER = "/etc/airtime/recorder.cfg"; + const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg"; + const CONF_FILE_MEDIAMONITOR = "/etc/airtime/media-monitor.cfg"; + const CONF_FILE_API_CLIENT = "/etc/airtime/api_client.cfg"; + + const CONF_PYPO_GRP = "pypo"; + const CONF_WWW_DATA_GRP = "www-data"; + + /** + * This function updates an INI style config file. + * + * A property and the value the property should be changed to are + * supplied. If the property is not found, then no changes are made. + * + * @param string $p_filename + * The path the to the file. + * @param string $p_property + * The property to look for in order to change its value. + * @param string $p_value + * The value the property should be changed to. + * + */ + public static function UpdateIniValue($p_filename, $p_property, $p_value) + { + $lines = file($p_filename); + $n=count($lines); + foreach ($lines as &$line) { + if ($line[0] != "#"){ + $key_value = explode("=", $line); + $key = trim($key_value[0]); + + if ($key == $p_property){ + $line = "$p_property = $p_value".PHP_EOL; + } + } + } + + $fp=fopen($p_filename, 'w'); + for($i=0; $i<$n; $i++){ + fwrite($fp, $lines[$i]); + } + fclose($fp); + } + + public static function ReadPythonConfig($p_filename) + { + $values = array(); + + $fh = fopen($p_filename, 'r'); + + while(!feof($fh)){ + $line = fgets($fh); + if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ + continue; + }else{ + $info = explode('=', $line, 2); + $values[trim($info[0])] = trim($info[1]); + } + } + + return $values; + } + + public static function MergeConfigFiles($configFiles, $suffix) { + foreach ($configFiles as $conf) { + // we want to use new liquidsoap.cfg so don't merge + // also for monit + if( $conf == AirtimeIni200::CONF_FILE_LIQUIDSOAP){ + continue; + } + if (file_exists("$conf$suffix.bak")) { + + if($conf === AirtimeIni200::CONF_FILE_AIRTIME) { + // Parse with sections + $newSettings = parse_ini_file($conf, true); + $oldSettings = parse_ini_file("$conf$suffix.bak", true); + } + else { + $newSettings = AirtimeIni200::ReadPythonConfig($conf); + $oldSettings = AirtimeIni200::ReadPythonConfig("$conf$suffix.bak"); + } + + $settings = array_keys($newSettings); + + foreach($settings as $section) { + if(isset($oldSettings[$section])) { + if(is_array($oldSettings[$section])) { + $sectionKeys = array_keys($newSettings[$section]); + foreach($sectionKeys as $sectionKey) { + // skip airtim_dir as we want to use new value + if($sectionKey != "airtime_dir"){ + if(isset($oldSettings[$section][$sectionKey])) { + AirtimeIni200::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); + } + } + } + } + else { + AirtimeIni200::UpdateIniValue($conf, $section, $oldSettings[$section]); + } + } + } + } + } + } + + /* Re: http://dev.sourcefabric.org/browse/CC-2797 + * We don't want config files to be world-readable so we + * set the strictest permissions possible. */ + public static function changeConfigFilePermissions(){ + if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_AIRTIME, self::CONF_WWW_DATA_GRP)){ + echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting."; + exit(1); + } + if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_API_CLIENT, self::CONF_PYPO_GRP)){ + echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting."; + exit(1); + } + if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_PYPO, self::CONF_PYPO_GRP)){ + echo "Could not set ownership of pypo.cfg to 'pypo'. Exiting."; + exit(1); + } + if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_RECORDER, self::CONF_PYPO_GRP)){ + echo "Could not set ownership of recorder.cfg to 'pypo'. Exiting."; + exit(1); + } + if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_LIQUIDSOAP, self::CONF_PYPO_GRP)){ + echo "Could not set ownership of liquidsoap.cfg to 'pypo'. Exiting."; + exit(1); + } + if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_MEDIAMONITOR, self::CONF_PYPO_GRP)){ + echo "Could not set ownership of media-monitor.cfg to 'pypo'. Exiting."; + exit(1); + } + } + + public static function ChangeFileOwnerGroupMod($filename, $user){ + return (chown($filename, $user) && + chgrp($filename, $user) && + chmod($filename, 0640)); + } + + public static function upgradeConfigFiles(){ + + $configFiles = array(AirtimeIni200::CONF_FILE_AIRTIME, + AirtimeIni200::CONF_FILE_PYPO, + AirtimeIni200::CONF_FILE_RECORDER, + AirtimeIni200::CONF_FILE_LIQUIDSOAP, + AirtimeIni200::CONF_FILE_MEDIAMONITOR, + AirtimeIni200::CONF_FILE_API_CLIENT); + + // Backup the config files + $suffix = date("Ymdhis")."-2.0.0"; + foreach ($configFiles as $conf) { + // do not back up monit cfg + if (file_exists($conf)) { + echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; + //copy($conf, $conf.$suffix.".bak"); + exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes + } + } + + $default_suffix = "200"; + AirtimeIni200::CreateIniFiles($default_suffix); + AirtimeIni200::MergeConfigFiles($configFiles, $suffix); + } + + /** + * This function creates the /etc/airtime configuration folder + * and copies the default config files to it. + */ + public static function CreateIniFiles($suffix) + { + if (!file_exists("/etc/airtime/")){ + if (!mkdir("/etc/airtime/", 0755, true)){ + echo "Could not create /etc/airtime/ directory. Exiting."; + exit(1); + } + } + + if (!copy(__DIR__."/airtime.conf.$suffix", AirtimeIni200::CONF_FILE_AIRTIME)){ + echo "Could not copy airtime.conf to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/pypo.cfg.$suffix", AirtimeIni200::CONF_FILE_PYPO)){ + echo "Could not copy pypo.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/recorder.cfg.$suffix", AirtimeIni200::CONF_FILE_RECORDER)){ + echo "Could not copy recorder.cfg to /etc/airtime/. Exiting."; + exit(1); + } + /*if (!copy(__DIR__."/liquidsoap.cfg.$suffix", AirtimeIni200::CONF_FILE_LIQUIDSOAP)){ + echo "Could not copy liquidsoap.cfg to /etc/airtime/. Exiting."; + exit(1); + }*/ + if (!copy(__DIR__."/api_client.cfg.$suffix", AirtimeIni200::CONF_FILE_API_CLIENT)){ + echo "Could not copy airtime-monit.cfg to /etc/monit/conf.d/. Exiting."; + exit(1); + } + } +} + +Airtime200Upgrade::connectToDatabase(); +AirtimeInstall::SetDefaultTimezone(); + +AirtimeInstall::InstallBinaries(); +AirtimeInstall::CreateSymlinksToUtils(); + +/* Airtime 2.0.0 starts interpreting all database times in UTC format. Prior to this, all the times + * were stored using the local time zone. Let's convert to UTC time. */ +ConvertToUtc::setPhpDefaultTimeZoneToSystemTimezone(); +ConvertToUtc::convert_cc_playlist(); +ConvertToUtc::convert_cc_schedule(); +ConvertToUtc::convert_cc_show_days(); +ConvertToUtc::convert_cc_show_instances(); + +// merging/updating config files +echo "* Updating configFiles\n"; +AirtimeIni200::changeConfigFilePermissions(); +AirtimeIni200::upgradeConfigFiles(); + +$values = parse_ini_file(AirtimeIni200::CONF_FILE_AIRTIME, true); +$phpDir = $values['general']['airtime_dir']; +Airtime200Upgrade::InstallAirtimePhpServerCode($phpDir); + +if(AirtimeInstall::DbTableExists('doctrine_migration_versions') === false) { + $migrations = array('20110312121200', '20110331111708', '20110402164819', '20110406182005', '20110629143017', '20110711161043', '20110713161043'); + foreach($migrations as $migration) { + AirtimeInstall::BypassMigrations(__DIR__, $migration); + } +} + +AirtimeInstall::MigrateTablesToVersion(__DIR__, '20110925171256'); + +AirtimeInstall::SetDefaultStreamSetting(); + +AirtimeInstall::GetOldLiquidsoapCfgAndUpdate(); + +AirtimeUpgrade::RemoveOldMonitFile(); + +// restart monit +exec("service monit restart"); + + + + diff --git a/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php index b540021dc..1658143f6 100644 --- a/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php +++ b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php @@ -5,6 +5,17 @@ * @copyright 2010 Sourcefabric O.P.S. * @license http://www.gnu.org/licenses/gpl.txt */ + +/* + * In the future, most Airtime upgrades will involve just mutating the + * data that is stored on the system. For example, The only data + * we need to preserve between versions is the database, /etc/airtime, and + * /srv/airtime. Everything else is just binary files that can be removed/replaced + * with the new version of Airtime. Of course, the data may need to be in a new + * format, and that's what this upgrade script will be for. + */ + +const VERSION_NUMBER = "2.0"; set_include_path(__DIR__.'/../../../airtime_mvc/library' . PATH_SEPARATOR . get_include_path()); set_include_path(__DIR__.'/../../../airtime_mvc/library/pear' . PATH_SEPARATOR . get_include_path()); @@ -12,14 +23,249 @@ set_include_path(__DIR__.'/../../../airtime_mvc/application/models' . PATH_SEPAR set_include_path(__DIR__.'/../../../airtime_mvc/application/configs' . PATH_SEPARATOR . get_include_path()); require_once 'conf.php'; require_once 'DB.php'; - require_once 'propel/runtime/lib/Propel.php'; Propel::init(__DIR__."/../../../airtime_mvc/application/configs/airtime-conf.php"); -class AirtimeInstall{ - const CONF_DIR_BINARIES = "/usr/lib/airtime"; + +/* These are helper functions that are common to each upgrade such as + * creating connections to a database, backing up config files etc. + */ +class UpgradeCommon{ + const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf"; + const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg"; + const CONF_FILE_RECORDER = "/etc/airtime/recorder.cfg"; + const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg"; + const CONF_FILE_MEDIAMONITOR = "/etc/airtime/media-monitor.cfg"; + const CONF_FILE_API_CLIENT = "/etc/airtime/api_client.cfg"; + + const CONF_PYPO_GRP = "pypo"; + const CONF_WWW_DATA_GRP = "www-data"; + + public static function connectToDatabase(){ + global $CC_DBC, $CC_CONFIG; + + $values = parse_ini_file('/etc/airtime/airtime.conf', true); + + // Database config + $CC_CONFIG['dsn']['username'] = $values['database']['dbuser']; + $CC_CONFIG['dsn']['password'] = $values['database']['dbpass']; + $CC_CONFIG['dsn']['hostspec'] = $values['database']['host']; + $CC_CONFIG['dsn']['phptype'] = 'pgsql'; + $CC_CONFIG['dsn']['database'] = $values['database']['dbname']; + + $CC_DBC = DB::connect($CC_CONFIG['dsn'], FALSE); + } - public static function SetDefaultTimezone() + public static function DbTableExists($p_name) + { + global $CC_DBC; + $sql = "SELECT * FROM ".$p_name; + $result = $CC_DBC->GetOne($sql); + if (PEAR::isError($result)) { + return false; + } + return true; + } + + private static function GetAirtimeSrcDir() + { + return __DIR__."/../../../airtime_mvc"; + } + + public static function MigrateTablesToVersion($dir, $version) + { + $appDir = self::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction migrations:migrate $version"; + system($command); + } + + public static function BypassMigrations($dir, $version) + { + $appDir = self::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction --add migrations:version $version"; + system($command); + } + + public static function upgradeConfigFiles(){ + + $configFiles = array(UpgradeCommon::CONF_FILE_AIRTIME, + UpgradeCommon::CONF_FILE_PYPO, + UpgradeCommon::CONF_FILE_RECORDER, + UpgradeCommon::CONF_FILE_LIQUIDSOAP, + UpgradeCommon::CONF_FILE_MEDIAMONITOR, + UpgradeCommon::CONF_FILE_API_CLIENT); + + // Backup the config files + $suffix = date("Ymdhis")."-2.0.0"; + foreach ($configFiles as $conf) { + // do not back up monit cfg + if (file_exists($conf)) { + echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; + //copy($conf, $conf.$suffix.".bak"); + exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes + } + } + + $default_suffix = "200"; + self::CreateIniFiles($default_suffix); + self::MergeConfigFiles($configFiles, $suffix); + } + + /** + * This function creates the /etc/airtime configuration folder + * and copies the default config files to it. + */ + public static function CreateIniFiles($suffix) + { + if (!file_exists("/etc/airtime/")){ + if (!mkdir("/etc/airtime/", 0755, true)){ + echo "Could not create /etc/airtime/ directory. Exiting."; + exit(1); + } + } + + if (!copy(__DIR__."/airtime.conf.$suffix", UpgradeCommon::CONF_FILE_AIRTIME)){ + echo "Could not copy airtime.conf to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/pypo.cfg.$suffix", UpgradeCommon::CONF_FILE_PYPO)){ + echo "Could not copy pypo.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/recorder.cfg.$suffix", UpgradeCommon::CONF_FILE_RECORDER)){ + echo "Could not copy recorder.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/api_client.cfg.$suffix", UpgradeCommon::CONF_FILE_API_CLIENT)){ + echo "Could not copy airtime-monit.cfg to /etc/monit/conf.d/. Exiting."; + exit(1); + } + } + + private static function MergeConfigFiles($configFiles, $suffix) { + foreach ($configFiles as $conf) { + // we want to use new liquidsoap.cfg so don't merge + // also for monit + if( $conf == self::CONF_FILE_LIQUIDSOAP){ + continue; + } + if (file_exists("$conf$suffix.bak")) { + + if($conf === self::CONF_FILE_AIRTIME) { + // Parse with sections + $newSettings = parse_ini_file($conf, true); + $oldSettings = parse_ini_file("$conf$suffix.bak", true); + } + else { + $newSettings = self::ReadPythonConfig($conf); + $oldSettings = self::ReadPythonConfig("$conf$suffix.bak"); + } + + $settings = array_keys($newSettings); + + foreach($settings as $section) { + if(isset($oldSettings[$section])) { + if(is_array($oldSettings[$section])) { + $sectionKeys = array_keys($newSettings[$section]); + foreach($sectionKeys as $sectionKey) { + // skip airtim_dir as we want to use new value + if($sectionKey != "airtime_dir"){ + if(isset($oldSettings[$section][$sectionKey])) { + self::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); + } + } + } + } + else { + self::UpdateIniValue($conf, $section, $oldSettings[$section]); + } + } + } + } + } + } + + private static function ReadPythonConfig($p_filename) + { + $values = array(); + + $fh = fopen($p_filename, 'r'); + + while(!feof($fh)){ + $line = fgets($fh); + if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ + continue; + }else{ + $info = explode('=', $line, 2); + $values[trim($info[0])] = trim($info[1]); + } + } + + return $values; + } + + /** + * This function updates an INI style config file. + * + * A property and the value the property should be changed to are + * supplied. If the property is not found, then no changes are made. + * + * @param string $p_filename + * The path the to the file. + * @param string $p_property + * The property to look for in order to change its value. + * @param string $p_value + * The value the property should be changed to. + * + */ + private static function UpdateIniValue($p_filename, $p_property, $p_value) + { + $lines = file($p_filename); + $n=count($lines); + foreach ($lines as &$line) { + if ($line[0] != "#"){ + $key_value = explode("=", $line); + $key = trim($key_value[0]); + + if ($key == $p_property){ + $line = "$p_property = $p_value".PHP_EOL; + } + } + } + + $fp=fopen($p_filename, 'w'); + for($i=0; $i<$n; $i++){ + fwrite($fp, $lines[$i]); + } + fclose($fp); + } +} + +/* All functions other than start() should be marked as + * private. + */ +class AirtimeDatabaseUpgrade{ + + public static function start(){ + self::SetDefaultTimezone(); + self::setPhpDefaultTimeZoneToSystemTimezone(); + self::convert_cc_playlist(); + self::convert_cc_schedule(); + self::convert_cc_show_days(); + self::convert_cc_show_instances(); + + self::doDbMigration(); + self::SetDefaultStreamSetting(); + self::GetOldLiquidsoapCfgAndUpdate(); + } + + private static function SetDefaultTimezone() { global $CC_DBC; @@ -33,28 +279,94 @@ class AirtimeInstall{ return true; } - public static function GetUtilsSrcDir() - { - return __DIR__."/../../../utils"; + private static function setPhpDefaultTimeZoneToSystemTimezone(){ + //we can get the default system timezone on debian/ubuntu by reading "/etc/timezone" + $filename = "/etc/timezone"; + $handle = fopen($filename, "r"); + $contents = trim(fread($handle, filesize($filename))); + echo "System timezone detected as: $contents".PHP_EOL; + fclose($handle); + + date_default_timezone_set($contents); } - public static function InstallBinaries() - { - echo "* Installing binaries to ".AirtimeInstall::CONF_DIR_BINARIES.PHP_EOL; - exec("mkdir -p ".AirtimeInstall::CONF_DIR_BINARIES); - exec("cp -R ".AirtimeInstall::GetUtilsSrcDir()." ".AirtimeInstall::CONF_DIR_BINARIES); - } - - public static function CreateSymlinksToUtils() - { - echo "* Installing airtime-log".PHP_EOL; - $dir = AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-log"; - copy(AirtimeInstall::GetUtilsSrcDir()."/airtime-log.php", AirtimeInstall::CONF_DIR_BINARIES."/utils/airtime-log.php"); + private static function convert_cc_playlist(){ + /* cc_playlist has a field that keeps track of when the playlist was last modified. */ + $playlists = CcPlaylistQuery::create()->find(); - exec("ln -s $dir /usr/bin/airtime-log"); + foreach ($playlists as $pl){ + $dt = new DateTime($pl->getDbMtime(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $pl->setDbMtime($dt); + + $pl->save(); + } } - public static function SetDefaultStreamSetting() + private static function convert_cc_schedule(){ + /* cc_schedule has start and end fields that need to be changed to UTC. */ + $schedules = CcScheduleQuery::create()->find(); + + foreach ($schedules as $s){ + $dt = new DateTime($s->getDbStarts(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $s->setDbStarts($dt); + + $dt = new DateTime($s->getDbEnds(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $s->setDbEnds($dt); + + $s->save(); + } + } + + private static function convert_cc_show_days(){ + /* cc_show_days has first_show, last_show and start_time fields that need to be changed to UTC. */ + $showDays = CcShowDaysQuery::create()->find(); + + foreach ($showDays as $sd){ + $dt = new DateTime($sd->getDbFirstShow()." ".$sd->getDbStartTime(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $sd->setDbFirstShow($dt->format("Y-m-d")); + $sd->setDbStartTime($dt->format("H:i:s")); + + $dt = new DateTime($sd->getDbLastShow()." ".$sd->getDbStartTime(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $sd->setDbLastShow($dt->format("Y-m-d")); + + $sd->save(); + } + } + + private static function convert_cc_show_instances(){ + /* convert_cc_show_instances has starts and ends fields that need to be changed to UTC. */ + $showInstances = CcShowInstancesQuery::create()->find(); + + foreach ($showInstances as $si){ + $dt = new DateTime($si->getDbStarts(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $si->setDbStarts($dt); + + $dt = new DateTime($si->getDbEnds(), new DateTimeZone(date_default_timezone_get())); + $dt->setTimezone(new DateTimeZone("UTC")); + $si->setDbEnds($dt); + + $si->save(); + } + } + + private static function doDbMigration(){ + if(UpgradeCommon::DbTableExists('doctrine_migration_versions') === false) { + $migrations = array('20110312121200', '20110331111708', '20110402164819', '20110406182005', '20110629143017', '20110711161043', '20110713161043'); + foreach($migrations as $migration) { + UpgradeCommon::BypassMigrations(__DIR__, $migration); + } + } + + UpgradeCommon::MigrateTablesToVersion(__DIR__, '20110925171256'); + } + + private static function SetDefaultStreamSetting() { global $CC_DBC; @@ -109,43 +421,8 @@ class AirtimeInstall{ } return true; } - - public static function BypassMigrations($dir, $version) - { - $appDir = AirtimeInstall::GetAirtimeSrcDir(); - $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". - "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". - "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". - "--no-interaction --add migrations:version $version"; - system($command); - } - public static function MigrateTablesToVersion($dir, $version) - { - $appDir = AirtimeInstall::GetAirtimeSrcDir(); - $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". - "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". - "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". - "--no-interaction migrations:migrate $version"; - system($command); - } - - public static function GetAirtimeSrcDir() - { - return __DIR__."/../../../airtime_mvc"; - } - - public static function DbTableExists($p_name) - { - global $CC_DBC; - $sql = "SELECT * FROM ".$p_name; - $result = $CC_DBC->GetOne($sql); - if (PEAR::isError($result)) { - return false; - } - return true; - } - public static function GetOldLiquidsoapCfgAndUpdate(){ + private static function GetOldLiquidsoapCfgAndUpdate(){ global $CC_DBC; echo "* Retrieving old liquidsoap configuration".PHP_EOL; $map = array(); @@ -220,367 +497,74 @@ class AirtimeInstall{ } } -class Airtime200Upgrade{ +class AirtimeStorWatchedDirsUpgrade{ - public static function connectToDatabase(){ - global $CC_DBC, $CC_CONFIG; - - $values = parse_ini_file('/etc/airtime/airtime.conf', true); - - // Database config - $CC_CONFIG['dsn']['username'] = $values['database']['dbuser']; - $CC_CONFIG['dsn']['password'] = $values['database']['dbpass']; - $CC_CONFIG['dsn']['hostspec'] = $values['database']['host']; - $CC_CONFIG['dsn']['phptype'] = 'pgsql'; - $CC_CONFIG['dsn']['database'] = $values['database']['dbname']; - - $CC_DBC = DB::connect($CC_CONFIG['dsn'], FALSE); - } - - public static function InstallAirtimePhpServerCode($phpDir) - { - - $AIRTIME_SRC = realpath(__DIR__.'/../../../airtime_mvc'); - - // delete old files - exec("rm -rf ".$phpDir); - echo "* Installing PHP code to ".$phpDir.PHP_EOL; - exec("mkdir -p ".$phpDir); - exec("cp -R ".$AIRTIME_SRC."/* ".$phpDir); - } - - public static function RemoveOldMonitFile(){ - unlink("/etc/monit/conf.d/airtime-monit.cfg"); + public static function start(){ } } -class ConvertToUtc{ +/* This class deals with any modifications to config files in /etc/airtime + * as well as backups. All functions other than start() should be marked + * as private. */ +class AirtimeConfigFileUpgrade{ - public static function setPhpDefaultTimeZoneToSystemTimezone(){ - //we can get the default system timezone on debian/ubuntu by reading "/etc/timezone" - $filename = "/etc/timezone"; - $handle = fopen($filename, "r"); - $contents = trim(fread($handle, filesize($filename))); - echo "System timezone detected as: $contents".PHP_EOL; - fclose($handle); - - date_default_timezone_set($contents); - } - - public static function convert_cc_playlist(){ - /* cc_playlist has a field that keeps track of when the playlist was last modified. */ - $playlists = CcPlaylistQuery::create()->find(); - - foreach ($playlists as $pl){ - $dt = new DateTime($pl->getDbMtime(), new DateTimeZone(date_default_timezone_get())); - $dt->setTimezone(new DateTimeZone("UTC")); - $pl->setDbMtime($dt); - - $pl->save(); - } - } - - public static function convert_cc_schedule(){ - /* cc_schedule has start and end fields that need to be changed to UTC. */ - $schedules = CcScheduleQuery::create()->find(); - - foreach ($schedules as $s){ - $dt = new DateTime($s->getDbStarts(), new DateTimeZone(date_default_timezone_get())); - $dt->setTimezone(new DateTimeZone("UTC")); - $s->setDbStarts($dt); - - $dt = new DateTime($s->getDbEnds(), new DateTimeZone(date_default_timezone_get())); - $dt->setTimezone(new DateTimeZone("UTC")); - $s->setDbEnds($dt); - - $s->save(); - } - } - - public static function convert_cc_show_days(){ - /* cc_show_days has first_show, last_show and start_time fields that need to be changed to UTC. */ - $showDays = CcShowDaysQuery::create()->find(); - - foreach ($showDays as $sd){ - $dt = new DateTime($sd->getDbFirstShow()." ".$sd->getDbStartTime(), new DateTimeZone(date_default_timezone_get())); - $dt->setTimezone(new DateTimeZone("UTC")); - $sd->setDbFirstShow($dt->format("Y-m-d")); - $sd->setDbStartTime($dt->format("H:i:s")); - - $dt = new DateTime($sd->getDbLastShow()." ".$sd->getDbStartTime(), new DateTimeZone(date_default_timezone_get())); - $dt->setTimezone(new DateTimeZone("UTC")); - $sd->setDbLastShow($dt->format("Y-m-d")); - - $sd->save(); - } - } - - public static function convert_cc_show_instances(){ - /* convert_cc_show_instances has starts and ends fields that need to be changed to UTC. */ - $showInstances = CcShowInstancesQuery::create()->find(); - - foreach ($showInstances as $si){ - $dt = new DateTime($si->getDbStarts(), new DateTimeZone(date_default_timezone_get())); - $dt->setTimezone(new DateTimeZone("UTC")); - $si->setDbStarts($dt); - - $dt = new DateTime($si->getDbEnds(), new DateTimeZone(date_default_timezone_get())); - $dt->setTimezone(new DateTimeZone("UTC")); - $si->setDbEnds($dt); - - $si->save(); - } - } -} - -class AirtimeIni200{ - - const CONF_FILE_AIRTIME = "/etc/airtime/airtime.conf"; - const CONF_FILE_PYPO = "/etc/airtime/pypo.cfg"; - const CONF_FILE_RECORDER = "/etc/airtime/recorder.cfg"; - const CONF_FILE_LIQUIDSOAP = "/etc/airtime/liquidsoap.cfg"; - const CONF_FILE_MEDIAMONITOR = "/etc/airtime/media-monitor.cfg"; - const CONF_FILE_API_CLIENT = "/etc/airtime/api_client.cfg"; - - const CONF_PYPO_GRP = "pypo"; - const CONF_WWW_DATA_GRP = "www-data"; - - /** - * This function updates an INI style config file. - * - * A property and the value the property should be changed to are - * supplied. If the property is not found, then no changes are made. - * - * @param string $p_filename - * The path the to the file. - * @param string $p_property - * The property to look for in order to change its value. - * @param string $p_value - * The value the property should be changed to. - * - */ - public static function UpdateIniValue($p_filename, $p_property, $p_value) - { - $lines = file($p_filename); - $n=count($lines); - foreach ($lines as &$line) { - if ($line[0] != "#"){ - $key_value = explode("=", $line); - $key = trim($key_value[0]); - - if ($key == $p_property){ - $line = "$p_property = $p_value".PHP_EOL; - } - } - } - - $fp=fopen($p_filename, 'w'); - for($i=0; $i<$n; $i++){ - fwrite($fp, $lines[$i]); - } - fclose($fp); - } - - public static function ReadPythonConfig($p_filename) - { - $values = array(); - - $fh = fopen($p_filename, 'r'); - - while(!feof($fh)){ - $line = fgets($fh); - if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ - continue; - }else{ - $info = explode('=', $line, 2); - $values[trim($info[0])] = trim($info[1]); - } - } - - return $values; - } - - public static function MergeConfigFiles($configFiles, $suffix) { - foreach ($configFiles as $conf) { - // we want to use new liquidsoap.cfg so don't merge - // also for monit - if( $conf == AirtimeIni200::CONF_FILE_LIQUIDSOAP){ - continue; - } - if (file_exists("$conf$suffix.bak")) { - - if($conf === AirtimeIni200::CONF_FILE_AIRTIME) { - // Parse with sections - $newSettings = parse_ini_file($conf, true); - $oldSettings = parse_ini_file("$conf$suffix.bak", true); - } - else { - $newSettings = AirtimeIni200::ReadPythonConfig($conf); - $oldSettings = AirtimeIni200::ReadPythonConfig("$conf$suffix.bak"); - } - - $settings = array_keys($newSettings); - - foreach($settings as $section) { - if(isset($oldSettings[$section])) { - if(is_array($oldSettings[$section])) { - $sectionKeys = array_keys($newSettings[$section]); - foreach($sectionKeys as $sectionKey) { - // skip airtim_dir as we want to use new value - if($sectionKey != "airtime_dir"){ - if(isset($oldSettings[$section][$sectionKey])) { - AirtimeIni200::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); - } - } - } - } - else { - AirtimeIni200::UpdateIniValue($conf, $section, $oldSettings[$section]); - } - } - } - } - } + public static function start(){ + echo "* Updating configFiles\n"; + self::changeConfigFilePermissions(); + UpgradeCommon::upgradeConfigFiles(); } /* Re: http://dev.sourcefabric.org/browse/CC-2797 * We don't want config files to be world-readable so we * set the strictest permissions possible. */ - public static function changeConfigFilePermissions(){ - if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_AIRTIME, self::CONF_WWW_DATA_GRP)){ + private static function changeConfigFilePermissions(){ + if (!self::ChangeFileOwnerGroupMod(UpgradeCommon::CONF_FILE_AIRTIME, UpgradeCommon::CONF_WWW_DATA_GRP)){ echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting."; exit(1); } - if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_API_CLIENT, self::CONF_PYPO_GRP)){ + if (!self::ChangeFileOwnerGroupMod(UpgradeCommon::CONF_FILE_API_CLIENT, UpgradeCommon::CONF_PYPO_GRP)){ echo "Could not set ownership of api_client.cfg to 'pypo'. Exiting."; exit(1); } - if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_PYPO, self::CONF_PYPO_GRP)){ + if (!self::ChangeFileOwnerGroupMod(UpgradeCommon::CONF_FILE_PYPO, UpgradeCommon::CONF_PYPO_GRP)){ echo "Could not set ownership of pypo.cfg to 'pypo'. Exiting."; exit(1); } - if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_RECORDER, self::CONF_PYPO_GRP)){ + if (!self::ChangeFileOwnerGroupMod(UpgradeCommon::CONF_FILE_RECORDER, UpgradeCommon::CONF_PYPO_GRP)){ echo "Could not set ownership of recorder.cfg to 'pypo'. Exiting."; exit(1); } - if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_LIQUIDSOAP, self::CONF_PYPO_GRP)){ + if (!self::ChangeFileOwnerGroupMod(UpgradeCommon::CONF_FILE_LIQUIDSOAP, UpgradeCommon::CONF_PYPO_GRP)){ echo "Could not set ownership of liquidsoap.cfg to 'pypo'. Exiting."; exit(1); } - if (!self::ChangeFileOwnerGroupMod(AirtimeIni200::CONF_FILE_MEDIAMONITOR, self::CONF_PYPO_GRP)){ + if (!self::ChangeFileOwnerGroupMod(UpgradeCommon::CONF_FILE_MEDIAMONITOR, UpgradeCommon::CONF_PYPO_GRP)){ echo "Could not set ownership of media-monitor.cfg to 'pypo'. Exiting."; exit(1); } } - public static function ChangeFileOwnerGroupMod($filename, $user){ - return (chown($filename, $user) && - chgrp($filename, $user) && - chmod($filename, 0640)); + +} + +/* Into this class put operations that don't fit into any of the other + * 3 classes. For example, there may be stray files scattered throughout + * the filesystem that we don't need anymore. Put the functions to clean + * those out into this class. */ +class AirtimeMiscUpgrade{ + + public static function start(){ + self::RemoveOldMonitFile(); } - public static function upgradeConfigFiles(){ - - $configFiles = array(AirtimeIni200::CONF_FILE_AIRTIME, - AirtimeIni200::CONF_FILE_PYPO, - AirtimeIni200::CONF_FILE_RECORDER, - AirtimeIni200::CONF_FILE_LIQUIDSOAP, - AirtimeIni200::CONF_FILE_MEDIAMONITOR, - AirtimeIni200::CONF_FILE_API_CLIENT); - - // Backup the config files - $suffix = date("Ymdhis")."-2.0.0"; - foreach ($configFiles as $conf) { - // do not back up monit cfg - if (file_exists($conf)) { - echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; - //copy($conf, $conf.$suffix.".bak"); - exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes - } - } - - $default_suffix = "200"; - AirtimeIni200::CreateIniFiles($default_suffix); - AirtimeIni200::MergeConfigFiles($configFiles, $suffix); - } - - /** - * This function creates the /etc/airtime configuration folder - * and copies the default config files to it. - */ - public static function CreateIniFiles($suffix) - { - if (!file_exists("/etc/airtime/")){ - if (!mkdir("/etc/airtime/", 0755, true)){ - echo "Could not create /etc/airtime/ directory. Exiting."; - exit(1); - } - } - - if (!copy(__DIR__."/airtime.conf.$suffix", AirtimeIni200::CONF_FILE_AIRTIME)){ - echo "Could not copy airtime.conf to /etc/airtime/. Exiting."; - exit(1); - } - if (!copy(__DIR__."/pypo.cfg.$suffix", AirtimeIni200::CONF_FILE_PYPO)){ - echo "Could not copy pypo.cfg to /etc/airtime/. Exiting."; - exit(1); - } - if (!copy(__DIR__."/recorder.cfg.$suffix", AirtimeIni200::CONF_FILE_RECORDER)){ - echo "Could not copy recorder.cfg to /etc/airtime/. Exiting."; - exit(1); - } - /*if (!copy(__DIR__."/liquidsoap.cfg.$suffix", AirtimeIni200::CONF_FILE_LIQUIDSOAP)){ - echo "Could not copy liquidsoap.cfg to /etc/airtime/. Exiting."; - exit(1); - }*/ - if (!copy(__DIR__."/api_client.cfg.$suffix", AirtimeIni200::CONF_FILE_API_CLIENT)){ - echo "Could not copy airtime-monit.cfg to /etc/monit/conf.d/. Exiting."; - exit(1); - } + private static function RemoveOldMonitFile(){ + unlink("/etc/monit/conf.d/airtime-monit.cfg"); } } -Airtime200Upgrade::connectToDatabase(); -AirtimeInstall::SetDefaultTimezone(); +UpgradeCommon::connectToDatabase(); -AirtimeInstall::InstallBinaries(); -AirtimeInstall::CreateSymlinksToUtils(); - -/* Airtime 2.0.0 starts interpreting all database times in UTC format. Prior to this, all the times - * were stored using the local time zone. Let's convert to UTC time. */ -ConvertToUtc::setPhpDefaultTimeZoneToSystemTimezone(); -ConvertToUtc::convert_cc_playlist(); -ConvertToUtc::convert_cc_schedule(); -ConvertToUtc::convert_cc_show_days(); -ConvertToUtc::convert_cc_show_instances(); - -// merging/updating config files -echo "* Updating configFiles\n"; -AirtimeIni200::changeConfigFilePermissions(); -AirtimeIni200::upgradeConfigFiles(); - -$values = parse_ini_file(AirtimeIni200::CONF_FILE_AIRTIME, true); -$phpDir = $values['general']['airtime_dir']; -Airtime200Upgrade::InstallAirtimePhpServerCode($phpDir); - -if(AirtimeInstall::DbTableExists('doctrine_migration_versions') === false) { - $migrations = array('20110312121200', '20110331111708', '20110402164819', '20110406182005', '20110629143017', '20110711161043', '20110713161043'); - foreach($migrations as $migration) { - AirtimeInstall::BypassMigrations(__DIR__, $migration); - } -} - -AirtimeInstall::MigrateTablesToVersion(__DIR__, '20110925171256'); - -AirtimeInstall::SetDefaultStreamSetting(); - -AirtimeInstall::GetOldLiquidsoapCfgAndUpdate(); - -AirtimeUpgrade::RemoveOldMonitFile(); - -// restart monit -exec("service monit restart"); - - - - +AirtimeDatabaseUpgrade::start(); +AirtimeStorWatchedDirsUpgrade::start(); +AirtimeConfigFileUpgrade::start(); +AirtimeMiscUpgrade::start(); diff --git a/install_minimal/upgrades/upgrade-template.php b/install_minimal/upgrades/upgrade-template.php new file mode 100644 index 000000000..b8c5be683 --- /dev/null +++ b/install_minimal/upgrades/upgrade-template.php @@ -0,0 +1,282 @@ +GetOne($sql); + if (PEAR::isError($result)) { + return false; + } + return true; + } + + public static function MigrateTablesToVersion($dir, $version) + { + $appDir = AirtimeInstall::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction migrations:migrate $version"; + system($command); + } + + public static function BypassMigrations($dir, $version) + { + $appDir = AirtimeInstall::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction --add migrations:version $version"; + system($command); + } + + public static function upgradeConfigFiles(){ + + $configFiles = array(UpgradeCommon::CONF_FILE_AIRTIME, + UpgradeCommon::CONF_FILE_PYPO, + UpgradeCommon::CONF_FILE_RECORDER, + UpgradeCommon::CONF_FILE_LIQUIDSOAP, + UpgradeCommon::CONF_FILE_MEDIAMONITOR, + UpgradeCommon::CONF_FILE_API_CLIENT); + + // Backup the config files + $suffix = date("Ymdhis")."-2.0.0"; + foreach ($configFiles as $conf) { + // do not back up monit cfg + if (file_exists($conf)) { + echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; + //copy($conf, $conf.$suffix.".bak"); + exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes + } + } + + $default_suffix = "200"; + self::CreateIniFiles($default_suffix); + self::MergeConfigFiles($configFiles, $suffix); + } + + /** + * This function creates the /etc/airtime configuration folder + * and copies the default config files to it. + */ + public static function CreateIniFiles($suffix) + { + if (!file_exists("/etc/airtime/")){ + if (!mkdir("/etc/airtime/", 0755, true)){ + echo "Could not create /etc/airtime/ directory. Exiting."; + exit(1); + } + } + + if (!copy(__DIR__."/airtime.conf.$suffix", self::CONF_FILE_AIRTIME)){ + echo "Could not copy airtime.conf to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/pypo.cfg.$suffix", self::CONF_FILE_PYPO)){ + echo "Could not copy pypo.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/recorder.cfg.$suffix", self::CONF_FILE_RECORDER)){ + echo "Could not copy recorder.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/api_client.cfg.$suffix", self::CONF_FILE_API_CLIENT)){ + echo "Could not copy airtime-monit.cfg to /etc/monit/conf.d/. Exiting."; + exit(1); + } + } + + private static function MergeConfigFiles($configFiles, $suffix) { + foreach ($configFiles as $conf) { + // we want to use new liquidsoap.cfg so don't merge + // also for monit + if( $conf == self::CONF_FILE_LIQUIDSOAP){ + continue; + } + if (file_exists("$conf$suffix.bak")) { + + if($conf === self::CONF_FILE_AIRTIME) { + // Parse with sections + $newSettings = parse_ini_file($conf, true); + $oldSettings = parse_ini_file("$conf$suffix.bak", true); + } + else { + $newSettings = self::ReadPythonConfig($conf); + $oldSettings = self::ReadPythonConfig("$conf$suffix.bak"); + } + + $settings = array_keys($newSettings); + + foreach($settings as $section) { + if(isset($oldSettings[$section])) { + if(is_array($oldSettings[$section])) { + $sectionKeys = array_keys($newSettings[$section]); + foreach($sectionKeys as $sectionKey) { + // skip airtim_dir as we want to use new value + if($sectionKey != "airtime_dir"){ + if(isset($oldSettings[$section][$sectionKey])) { + self::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); + } + } + } + } + else { + self::UpdateIniValue($conf, $section, $oldSettings[$section]); + } + } + } + } + } + } + + private static function ReadPythonConfig($p_filename) + { + $values = array(); + + $fh = fopen($p_filename, 'r'); + + while(!feof($fh)){ + $line = fgets($fh); + if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ + continue; + }else{ + $info = explode('=', $line, 2); + $values[trim($info[0])] = trim($info[1]); + } + } + + return $values; + } + + /** + * This function updates an INI style config file. + * + * A property and the value the property should be changed to are + * supplied. If the property is not found, then no changes are made. + * + * @param string $p_filename + * The path the to the file. + * @param string $p_property + * The property to look for in order to change its value. + * @param string $p_value + * The value the property should be changed to. + * + */ + private static function UpdateIniValue($p_filename, $p_property, $p_value) + { + $lines = file($p_filename); + $n=count($lines); + foreach ($lines as &$line) { + if ($line[0] != "#"){ + $key_value = explode("=", $line); + $key = trim($key_value[0]); + + if ($key == $p_property){ + $line = "$p_property = $p_value".PHP_EOL; + } + } + } + + $fp=fopen($p_filename, 'w'); + for($i=0; $i<$n; $i++){ + fwrite($fp, $lines[$i]); + } + fclose($fp); + } +} + +/* All functions other than start() should be marked as + * private. + */ +class AirtimeDatabaseUpgrade{ + + public static function start(){ + //self::doDbMigration(); + } + + private static function doDbMigration(){ + if(UpgradeCommon::DbTableExists('doctrine_migration_versions') === false) { + $migrations = array('20110312121200', '20110331111708', '20110402164819', '20110406182005', '20110629143017', '20110711161043', '20110713161043'); + foreach($migrations as $migration) { + UpgradeCommon::BypassMigrations(__DIR__, $migration); + } + } + + UpgradeCommon::MigrateTablesToVersion(__DIR__, '20110925171256'); + } +} + +class AirtimeStorWatchedDirsUpgrade{ + + public static function start(){ + } +} + +/* This class deals with any modifications to config files in /etc/airtime + * as well as backups. All functions other than start() should be marked + * as private. */ +class AirtimeConfigFileUpgrade{ + + public static function start(){ + UpgradeCommon::upgradeConfigFiles(); + } +} + +/* Into this class put operations that don't fit into any of the other + * 3 classes. For example, there may be stray files scattered throughout + * the filesystem that we don't need anymore. Put the functions to clean + * those out into this class. */ +class AirtimeMiscUpgrade{1 + + public static function start(){ + } +} + +UpgradeCommonFunctions::connectToDatabase(); + +AirtimeDatabaseUpgrade::start(); +AirtimeStorWatchedDirsUpgrade::start(); +AirtimeEtcUpgrade::start(); +AirtimeMiscUpgrade::start(); From d93a9edcd2648d15f81476c459502c418cefa7d6 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 29 Sep 2011 18:27:24 -0400 Subject: [PATCH 03/12] CC-2806: Create upgrade template file -missing function -comment out redundant code --- install_minimal/airtime-install | 6 ++---- install_minimal/include/airtime-install.php | 3 +-- install_minimal/include/airtime-upgrade.php | 2 ++ install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php | 6 ++++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/install_minimal/airtime-install b/install_minimal/airtime-install index 031673c19..b395f409b 100755 --- a/install_minimal/airtime-install +++ b/install_minimal/airtime-install @@ -33,10 +33,8 @@ python ${SCRIPTPATH}/../python_apps/create-pypo-user.py set +e php --php-ini ${SCRIPTPATH}/airtime-php.ini ${SCRIPTPATH}/include/airtime-install.php $@ result=$? -if [ "$result" -eq "2" ]; then - #We've just finished an upgrade, so let's exit - exit 0 -elif [ "$result" -ne "0" ]; then + +if [ "$result" -ne "0" ]; then #There was an error, exit with error code. echo "There was an error during upgrade. Exit code $result" exit 1 diff --git a/install_minimal/include/airtime-install.php b/install_minimal/include/airtime-install.php index 6ab5e75cd..683e95293 100644 --- a/install_minimal/include/airtime-install.php +++ b/install_minimal/include/airtime-install.php @@ -64,8 +64,7 @@ if (isset($version) && ($version != false) && ($version < AIRTIME_VERSION) && !i echo "Airtime version $version found.".PHP_EOL; require_once("airtime-upgrade.php"); - - exit(2); + exit(0); } if($version === false){ diff --git a/install_minimal/include/airtime-upgrade.php b/install_minimal/include/airtime-upgrade.php index 616083c69..6281fe890 100644 --- a/install_minimal/include/airtime-upgrade.php +++ b/install_minimal/include/airtime-upgrade.php @@ -116,6 +116,7 @@ $newVersion = AIRTIME_VERSION; $sql = "INSERT INTO cc_pref (keystr, valstr) VALUES ('system_version', '$newVersion')"; $CC_DBC->query($sql); +/* echo PHP_EOL."*** Updating Api Client ***".PHP_EOL; passthru("python $SCRIPTPATH/../../python_apps/api_clients/install/api_client_install.py"); @@ -134,3 +135,4 @@ sleep(4); passthru("airtime-check-system"); echo "******************************* Update Complete *******************************".PHP_EOL; +*/ diff --git a/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php index 1658143f6..f17716bf9 100644 --- a/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php +++ b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php @@ -544,6 +544,12 @@ class AirtimeConfigFileUpgrade{ } } + private static function ChangeFileOwnerGroupMod($filename, $user){ + return (chown($filename, $user) && + chgrp($filename, $user) && + chmod($filename, 0640)); + } + } From 3c6692ebcecb8df85af15e3934c2cb7070158323 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 29 Sep 2011 18:48:34 -0400 Subject: [PATCH 04/12] CC-2806: Create upgrade template file -missing function -comment out redundant code -Create cc_component table on upgrade --- .../Version20110929184401.php | 23 +++++++++++++++++++ .../airtime-2.0.0/airtime-upgrade.php | 2 +- .../upgrades/airtime-2.0.0/api_client.cfg.200 | 8 ++++--- python_apps/api_clients/api_client.py | 1 - 4 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 install_minimal/DoctrineMigrations/Version20110929184401.php diff --git a/install_minimal/DoctrineMigrations/Version20110929184401.php b/install_minimal/DoctrineMigrations/Version20110929184401.php new file mode 100644 index 000000000..6d48740ec --- /dev/null +++ b/install_minimal/DoctrineMigrations/Version20110929184401.php @@ -0,0 +1,23 @@ +createTable('cc_component'); + $cc_component->addColumn('name', 'string', array('length' => 32)); + $cc_component->addColumn('ip', 'string', array('length' => 18)); + + $cc_component->setPrimaryKey(array('name')); + } + + public function down(Schema $schema) + { + + } +} diff --git a/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php index f17716bf9..343099b2f 100644 --- a/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php +++ b/install_minimal/upgrades/airtime-2.0.0/airtime-upgrade.php @@ -363,7 +363,7 @@ class AirtimeDatabaseUpgrade{ } } - UpgradeCommon::MigrateTablesToVersion(__DIR__, '20110925171256'); + UpgradeCommon::MigrateTablesToVersion(__DIR__, '20110929184401'); } private static function SetDefaultStreamSetting() diff --git a/install_minimal/upgrades/airtime-2.0.0/api_client.cfg.200 b/install_minimal/upgrades/airtime-2.0.0/api_client.cfg.200 index 3fcd38c64..bf04dcc26 100644 --- a/install_minimal/upgrades/airtime-2.0.0/api_client.cfg.200 +++ b/install_minimal/upgrades/airtime-2.0.0/api_client.cfg.200 @@ -13,6 +13,9 @@ api_base = 'api' # URL to get the version number of the server API version_url = 'version/api_key/%%api_key%%' +#URL to register a components IP Address with the central web server +register_component = 'register-component/format/json/api_key/%%api_key%%/component/%%component%%' + # Hostname base_url = 'localhost' base_port = 80 @@ -45,9 +48,6 @@ remove_watched_dir = 'remove-watched-dir/format/json/api_key/%%api_key%%/path/%% # URL to tell Airtime we want to add watched directory set_storage_dir = 'set-storage-dir/format/json/api_key/%%api_key%%/path/%%path%%' -# URL to tell Airtime we want to get stream setting -get_stream_setting = 'get-stream-setting/format/json/api_key/%%api_key%%/' - ############################# ## Config for Recorder ############################# @@ -89,6 +89,8 @@ update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/med # ??? generate_range_url = 'generate_range_dp.php' +# URL to tell Airtime we want to get stream setting +get_stream_setting = 'get-stream-setting/format/json/api_key/%%api_key%%/' ############## # OBP config # diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index 348cb6b53..311d08687 100755 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -561,7 +561,6 @@ class AirTimeApiClient(ApiClientInterface): response = urllib2.urlopen(req).read() except Exception, e: logger.error("Exception: %s", e) - logger.error("Response: %s", response) ################################################################################ # OpenBroadcast API Client From 41dee5d2631ef0727a1de4ca23aa022fcc200f98 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 30 Sep 2011 10:56:38 -0400 Subject: [PATCH 05/12] CC-2911: Error in /usr/lib/airtime/utils/phone_home_stat script -fixed --- utils/phone_home_stat.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/phone_home_stat.php b/utils/phone_home_stat.php index e09b442cb..65b6a57b5 100644 --- a/utils/phone_home_stat.php +++ b/utils/phone_home_stat.php @@ -33,7 +33,7 @@ require_once($CC_CONFIG['phpDir'].'/application/models/User.php'); require_once($CC_CONFIG['phpDir'].'/application/models/StoredFile.php'); require_once($CC_CONFIG['phpDir'].'/application/models/Playlist.php'); require_once($CC_CONFIG['phpDir'].'/application/models/Schedule.php'); -require_once($CC_CONFIG['phpDir'].'/application/models/Shows.php'); +require_once($CC_CONFIG['phpDir'].'/application/models/Show.php'); require_once($CC_CONFIG['phpDir'].'/application/models/Preference.php'); //Pear classes. From c469f51eb37dea1c8a3c3996907be2bbd52a4fe0 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 30 Sep 2011 11:45:51 -0400 Subject: [PATCH 06/12] CC-2908: Add "Live Stream" title to live stream popup window -done --- .../public/js/airtime/dashboard/playlist.js | 2 +- .../js/jplayer/skin/jplayer.blue.monday.css | 40 ++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/airtime_mvc/public/js/airtime/dashboard/playlist.js b/airtime_mvc/public/js/airtime/dashboard/playlist.js index be91be286..84dd47cfc 100644 --- a/airtime_mvc/public/js/airtime/dashboard/playlist.js +++ b/airtime_mvc/public/js/airtime/dashboard/playlist.js @@ -259,7 +259,7 @@ function init() { setupQtip(); $('#on-air-info').click(function() { - newwindow=window.open("Dashboard/stream-player", 'name', 'width=380,height=168'); + newwindow=window.open("/Dashboard/stream-player", 'name', 'width=400,height=216'); if (window.focus) {newwindow.focus()} return false; }); diff --git a/airtime_mvc/public/js/jplayer/skin/jplayer.blue.monday.css b/airtime_mvc/public/js/jplayer/skin/jplayer.blue.monday.css index 981f3000f..98e43f045 100644 --- a/airtime_mvc/public/js/jplayer/skin/jplayer.blue.monday.css +++ b/airtime_mvc/public/js/jplayer/skin/jplayer.blue.monday.css @@ -19,9 +19,27 @@ height: 100%; margin: 0; padding: 0; + width:400px; } + +.jp-container h1 { + background: #282828; + font-size:18px; + text-align:center; + color:#CCC; + margin: 0; + padding: 8px 0; + font-weight:normal; + border-bottom:1px solid #000; + background-color:#3D3D3D; + background: linear-gradient(top, #3c3c3c 0, #1a1a1a 100%); + background: -moz-linear-gradient(top, #3c3c3c 0, #1a1a1a 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #3c3c3c), color-stop(100%, #1a1a1a)); + text-shadow: 0px -1px 1px #000; +} + .jp-logo { - width:380px; + width:400px; height: 67px; background:#282828 url(../../../css/images/airtime_logo_jp.png) no-repeat 120px 14px; background: url(../../../css/images/airtime_logo_jp.png) no-repeat 120px 14px, -moz-radial-gradient(200px 0px, circle cover, rgba(70,70,70,1) 0%, rgba(40,40,40,1) 90%); @@ -29,7 +47,7 @@ display:block; } .jp-stream { - height: 18px; + height: 27px; display:block; border-top:1px solid #050505; color:#ff5d1a; @@ -41,6 +59,7 @@ box-shadow: rgba(248,248,248,.3) 0px 1px 0px, rgba(0, 0, 0, 0.2) 0 2px 2px inset; -moz-box-shadow: rgba(0, 0, 0, 0.7) 0 0 5px inset; -webkit-box-shadow: rgba(0, 0, 0, 0.7) 0 0 5px inset; + line-height:23px; } .jp-stream-text, .jp-stream form { @@ -56,6 +75,23 @@ } .jp-stream label input[type="radio"] { } + +.jp-stream form input[type="text"], .jp-stream form select { + background-color: #212121; + border: 1px solid #1a1a1a; + box-shadow: 0 2px 2px rgba(0, 0, 0, 0.5) inset; + -moz-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.5) inset; + -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.5) inset; + color: #767676; + font-family: Arial,Helvetica,sans-serif; + font-size: 12px; + height: 25px; + margin: 0; + padding: 2px 2px 2px 0; + vertical-align: top; + width:200px; +} + div.jp-audio, div.jp-video { From 1bd9cf84ea09e7a76dcdd49012cec6165547a4c0 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 30 Sep 2011 12:04:58 -0400 Subject: [PATCH 07/12] CC-2806: Create upgrade template file -done --- .../UpgradeCommon.php} | 92 +------- .../airtime-2.0.0/airtime-upgrade.php | 221 +----------------- .../upgrade-template/UpgradeCommon.php | 206 ++++++++++++++++ .../upgrade-template/airtime-upgrade.php | 84 +++++++ 4 files changed, 299 insertions(+), 304 deletions(-) rename install_minimal/upgrades/{upgrade-template.php => airtime-2.0.0/UpgradeCommon.php} (71%) create mode 100644 install_minimal/upgrades/upgrade-template/UpgradeCommon.php create mode 100644 install_minimal/upgrades/upgrade-template/airtime-upgrade.php diff --git a/install_minimal/upgrades/upgrade-template.php b/install_minimal/upgrades/airtime-2.0.0/UpgradeCommon.php similarity index 71% rename from install_minimal/upgrades/upgrade-template.php rename to install_minimal/upgrades/airtime-2.0.0/UpgradeCommon.php index b8c5be683..57ee794cd 100644 --- a/install_minimal/upgrades/upgrade-template.php +++ b/install_minimal/upgrades/airtime-2.0.0/UpgradeCommon.php @@ -1,31 +1,4 @@ GetOne($sql); - if (PEAR::isError($result)) { - return false; - } - return true; - } - - private static function GetAirtimeSrcDir() - { - return __DIR__."/../../../airtime_mvc"; - } - - public static function MigrateTablesToVersion($dir, $version) - { - $appDir = self::GetAirtimeSrcDir(); - $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". - "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". - "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". - "--no-interaction migrations:migrate $version"; - system($command); - } - - public static function BypassMigrations($dir, $version) - { - $appDir = self::GetAirtimeSrcDir(); - $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". - "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". - "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". - "--no-interaction --add migrations:version $version"; - system($command); - } - - public static function upgradeConfigFiles(){ - - $configFiles = array(UpgradeCommon::CONF_FILE_AIRTIME, - UpgradeCommon::CONF_FILE_PYPO, - UpgradeCommon::CONF_FILE_RECORDER, - UpgradeCommon::CONF_FILE_LIQUIDSOAP, - UpgradeCommon::CONF_FILE_MEDIAMONITOR, - UpgradeCommon::CONF_FILE_API_CLIENT); - - // Backup the config files - $suffix = date("Ymdhis")."-2.0.0"; - foreach ($configFiles as $conf) { - // do not back up monit cfg - if (file_exists($conf)) { - echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; - //copy($conf, $conf.$suffix.".bak"); - exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes - } - } - - $default_suffix = "200"; - self::CreateIniFiles($default_suffix); - self::MergeConfigFiles($configFiles, $suffix); - } - - /** - * This function creates the /etc/airtime configuration folder - * and copies the default config files to it. - */ - public static function CreateIniFiles($suffix) - { - if (!file_exists("/etc/airtime/")){ - if (!mkdir("/etc/airtime/", 0755, true)){ - echo "Could not create /etc/airtime/ directory. Exiting."; - exit(1); - } - } - - if (!copy(__DIR__."/airtime.conf.$suffix", UpgradeCommon::CONF_FILE_AIRTIME)){ - echo "Could not copy airtime.conf to /etc/airtime/. Exiting."; - exit(1); - } - if (!copy(__DIR__."/pypo.cfg.$suffix", UpgradeCommon::CONF_FILE_PYPO)){ - echo "Could not copy pypo.cfg to /etc/airtime/. Exiting."; - exit(1); - } - if (!copy(__DIR__."/recorder.cfg.$suffix", UpgradeCommon::CONF_FILE_RECORDER)){ - echo "Could not copy recorder.cfg to /etc/airtime/. Exiting."; - exit(1); - } - if (!copy(__DIR__."/api_client.cfg.$suffix", UpgradeCommon::CONF_FILE_API_CLIENT)){ - echo "Could not copy airtime-monit.cfg to /etc/monit/conf.d/. Exiting."; - exit(1); - } - } - - private static function MergeConfigFiles($configFiles, $suffix) { - foreach ($configFiles as $conf) { - // we want to use new liquidsoap.cfg so don't merge - // also for monit - if( $conf == self::CONF_FILE_LIQUIDSOAP){ - continue; - } - if (file_exists("$conf$suffix.bak")) { - - if($conf === self::CONF_FILE_AIRTIME) { - // Parse with sections - $newSettings = parse_ini_file($conf, true); - $oldSettings = parse_ini_file("$conf$suffix.bak", true); - } - else { - $newSettings = self::ReadPythonConfig($conf); - $oldSettings = self::ReadPythonConfig("$conf$suffix.bak"); - } - - $settings = array_keys($newSettings); - - foreach($settings as $section) { - if(isset($oldSettings[$section])) { - if(is_array($oldSettings[$section])) { - $sectionKeys = array_keys($newSettings[$section]); - foreach($sectionKeys as $sectionKey) { - // skip airtim_dir as we want to use new value - if($sectionKey != "airtime_dir"){ - if(isset($oldSettings[$section][$sectionKey])) { - self::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); - } - } - } - } - else { - self::UpdateIniValue($conf, $section, $oldSettings[$section]); - } - } - } - } - } - } - - private static function ReadPythonConfig($p_filename) - { - $values = array(); - - $fh = fopen($p_filename, 'r'); - - while(!feof($fh)){ - $line = fgets($fh); - if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ - continue; - }else{ - $info = explode('=', $line, 2); - $values[trim($info[0])] = trim($info[1]); - } - } - - return $values; - } - - /** - * This function updates an INI style config file. - * - * A property and the value the property should be changed to are - * supplied. If the property is not found, then no changes are made. - * - * @param string $p_filename - * The path the to the file. - * @param string $p_property - * The property to look for in order to change its value. - * @param string $p_value - * The value the property should be changed to. - * - */ - private static function UpdateIniValue($p_filename, $p_property, $p_value) - { - $lines = file($p_filename); - $n=count($lines); - foreach ($lines as &$line) { - if ($line[0] != "#"){ - $key_value = explode("=", $line); - $key = trim($key_value[0]); - - if ($key == $p_property){ - $line = "$p_property = $p_value".PHP_EOL; - } - } - } - - $fp=fopen($p_filename, 'w'); - for($i=0; $i<$n; $i++){ - fwrite($fp, $lines[$i]); - } - fclose($fp); - } -} +require_once 'UpgradeCommon.php'; /* All functions other than start() should be marked as * private. diff --git a/install_minimal/upgrades/upgrade-template/UpgradeCommon.php b/install_minimal/upgrades/upgrade-template/UpgradeCommon.php new file mode 100644 index 000000000..57ee794cd --- /dev/null +++ b/install_minimal/upgrades/upgrade-template/UpgradeCommon.php @@ -0,0 +1,206 @@ +GetOne($sql); + if (PEAR::isError($result)) { + return false; + } + return true; + } + + private static function GetAirtimeSrcDir() + { + return __DIR__."/../../../airtime_mvc"; + } + + public static function MigrateTablesToVersion($dir, $version) + { + $appDir = self::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction migrations:migrate $version"; + system($command); + } + + public static function BypassMigrations($dir, $version) + { + $appDir = self::GetAirtimeSrcDir(); + $command = "php $appDir/library/doctrine/migrations/doctrine-migrations.phar ". + "--configuration=$dir/../../DoctrineMigrations/migrations.xml ". + "--db-configuration=$appDir/library/doctrine/migrations/migrations-db.php ". + "--no-interaction --add migrations:version $version"; + system($command); + } + + public static function upgradeConfigFiles(){ + + $configFiles = array(UpgradeCommon::CONF_FILE_AIRTIME, + UpgradeCommon::CONF_FILE_PYPO, + UpgradeCommon::CONF_FILE_RECORDER, + UpgradeCommon::CONF_FILE_LIQUIDSOAP, + UpgradeCommon::CONF_FILE_MEDIAMONITOR, + UpgradeCommon::CONF_FILE_API_CLIENT); + + // Backup the config files + $suffix = date("Ymdhis")."-".VERSION_NUMBER; + foreach ($configFiles as $conf) { + // do not back up monit cfg + if (file_exists($conf)) { + echo "Backing up $conf to $conf$suffix.bak".PHP_EOL; + //copy($conf, $conf.$suffix.".bak"); + exec("cp -p $conf $conf$suffix.bak"); //use cli version to preserve file attributes + } + } + + $default_suffix = "200"; + self::CreateIniFiles($default_suffix); + self::MergeConfigFiles($configFiles, $suffix); + } + + /** + * This function creates the /etc/airtime configuration folder + * and copies the default config files to it. + */ + public static function CreateIniFiles($suffix) + { + if (!file_exists("/etc/airtime/")){ + if (!mkdir("/etc/airtime/", 0755, true)){ + echo "Could not create /etc/airtime/ directory. Exiting."; + exit(1); + } + } + + if (!copy(__DIR__."/airtime.conf.$suffix", self::CONF_FILE_AIRTIME)){ + echo "Could not copy airtime.conf to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/pypo.cfg.$suffix", self::CONF_FILE_PYPO)){ + echo "Could not copy pypo.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/recorder.cfg.$suffix", self::CONF_FILE_RECORDER)){ + echo "Could not copy recorder.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/api_client.cfg.$suffix", self::CONF_FILE_API_CLIENT)){ + echo "Could not copy airtime-monit.cfg to /etc/monit/conf.d/. Exiting."; + exit(1); + } + } + + private static function MergeConfigFiles($configFiles, $suffix) { + foreach ($configFiles as $conf) { + // we want to use new liquidsoap.cfg so don't merge + // also for monit + if( $conf == self::CONF_FILE_LIQUIDSOAP){ + continue; + } + if (file_exists("$conf$suffix.bak")) { + + if($conf === self::CONF_FILE_AIRTIME) { + // Parse with sections + $newSettings = parse_ini_file($conf, true); + $oldSettings = parse_ini_file("$conf$suffix.bak", true); + } + else { + $newSettings = self::ReadPythonConfig($conf); + $oldSettings = self::ReadPythonConfig("$conf$suffix.bak"); + } + + $settings = array_keys($newSettings); + + foreach($settings as $section) { + if(isset($oldSettings[$section])) { + if(is_array($oldSettings[$section])) { + $sectionKeys = array_keys($newSettings[$section]); + foreach($sectionKeys as $sectionKey) { + // skip airtim_dir as we want to use new value + if($sectionKey != "airtime_dir"){ + if(isset($oldSettings[$section][$sectionKey])) { + self::UpdateIniValue($conf, $sectionKey, $oldSettings[$section][$sectionKey]); + } + } + } + } + else { + self::UpdateIniValue($conf, $section, $oldSettings[$section]); + } + } + } + } + } + } + + private static function ReadPythonConfig($p_filename) + { + $values = array(); + + $fh = fopen($p_filename, 'r'); + + while(!feof($fh)){ + $line = fgets($fh); + if(substr(trim($line), 0, 1) == '#' || trim($line) == ""){ + continue; + }else{ + $info = explode('=', $line, 2); + $values[trim($info[0])] = trim($info[1]); + } + } + + return $values; + } + + /** + * This function updates an INI style config file. + * + * A property and the value the property should be changed to are + * supplied. If the property is not found, then no changes are made. + * + * @param string $p_filename + * The path the to the file. + * @param string $p_property + * The property to look for in order to change its value. + * @param string $p_value + * The value the property should be changed to. + * + */ + private static function UpdateIniValue($p_filename, $p_property, $p_value) + { + $lines = file($p_filename); + $n=count($lines); + foreach ($lines as &$line) { + if ($line[0] != "#"){ + $key_value = explode("=", $line); + $key = trim($key_value[0]); + + if ($key == $p_property){ + $line = "$p_property = $p_value".PHP_EOL; + } + } + } + + $fp=fopen($p_filename, 'w'); + for($i=0; $i<$n; $i++){ + fwrite($fp, $lines[$i]); + } + fclose($fp); + } +} diff --git a/install_minimal/upgrades/upgrade-template/airtime-upgrade.php b/install_minimal/upgrades/upgrade-template/airtime-upgrade.php new file mode 100644 index 000000000..42aa0c287 --- /dev/null +++ b/install_minimal/upgrades/upgrade-template/airtime-upgrade.php @@ -0,0 +1,84 @@ + Date: Fri, 30 Sep 2011 12:07:44 -0400 Subject: [PATCH 08/12] CC-2908: Add "Live Stream" title to live stream popup window -done --- .../scripts/dashboard/stream-player.phtml | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/airtime_mvc/application/views/scripts/dashboard/stream-player.phtml b/airtime_mvc/application/views/scripts/dashboard/stream-player.phtml index cc78da874..e070b876f 100644 --- a/airtime_mvc/application/views/scripts/dashboard/stream-player.phtml +++ b/airtime_mvc/application/views/scripts/dashboard/stream-player.phtml @@ -1,4 +1,5 @@