diff --git a/install_minimal/upgrades/airtime-2.1.0/ConfFileUpgrade.php b/install_minimal/upgrades/airtime-2.1.0/ConfFileUpgrade.php new file mode 100644 index 000000000..f7aea03c3 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.1.0/ConfFileUpgrade.php @@ -0,0 +1,15 @@ +getMessage().PHP_EOL; + echo $CC_DBC->getUserInfo().PHP_EOL; + echo "Database connection problem.".PHP_EOL; + echo "Check if database '{$CC_CONFIG['dsn']['database']}' exists". + " with corresponding permissions.".PHP_EOL; + if ($p_exitOnError) { + exit(1); + } + } else { + $CC_DBC->setFetchMode(DB_FETCHMODE_ASSOC); + } + } + + + 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) + { + echo "Upgrading database, may take several minutes, please wait".PHP_EOL; + + $appDir = self::GetAirtimeSrcDir(); + $command = "php --php-ini $dir/../../airtime-php.ini ". + "$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 --php-ini $dir/../../airtime-php.ini ". + "$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_LIQUIDSOAP, + UpgradeCommon::CONF_FILE_MEDIAMONITOR, + UpgradeCommon::CONF_FILE_API_CLIENT); + + // Backup the config files + $suffix = date("Ymdhis")."-".UpgradeCommon::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 + } + } + + self::CreateIniFiles(UpgradeCommon::CONF_BACKUP_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__."/media-monitor.cfg.$suffix", self::CONF_FILE_MEDIAMONITOR)){ + echo "Could not copy meadia-monitor.cfg to /etc/airtime/. Exiting."; + exit(1); + } + if (!copy(__DIR__."/api_client.cfg.$suffix", self::CONF_FILE_API_CLIENT)){ + echo "Could not copy api_client.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); + } + + public static function queryDb($p_sql){ + global $CC_DBC; + + $result = $CC_DBC->getRow($p_sql, $fetchmode=DB_FETCHMODE_ASSOC); + if (PEAR::isError($result)) { + echo "Error executing $sql. Exiting."; + exit(1); + } + + return $result; + } +} diff --git a/install_minimal/upgrades/airtime-2.1.0/etc/airtime.conf.210 b/install_minimal/upgrades/airtime-2.1.0/etc/airtime.conf.210 new file mode 100644 index 000000000..578c50828 --- /dev/null +++ b/install_minimal/upgrades/airtime-2.1.0/etc/airtime.conf.210 @@ -0,0 +1,27 @@ +[database] +host = localhost +dbname = airtime +dbuser = airtime +dbpass = airtime + +[rabbitmq] +host = 127.0.0.1 +port = 5672 +user = guest +password = guest +vhost = / + +[general] +api_key = AAA +web_server_user = www-data +airtime_dir = x +base_url = localhost +base_port = 80 + +;How many hours ahead of time should Airtime playout engine (PYPO) +;cache scheduled media files. +cache_ahead_hours = 1 + +[soundcloud] +connection_retries = 3 +time_between_retries = 60 diff --git a/install_minimal/upgrades/airtime-2.1.0/etc/api_client.cfg.210 b/install_minimal/upgrades/airtime-2.1.0/etc/api_client.cfg.210 new file mode 100644 index 000000000..2ff113b9c --- /dev/null +++ b/install_minimal/upgrades/airtime-2.1.0/etc/api_client.cfg.210 @@ -0,0 +1,111 @@ +bin_dir = "/usr/lib/airtime/api_clients" + +############################# +## Common +############################# + +# Value needed to access the API +api_key = 'AAA' + +# Path to the base of the API +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 + +############################# +## Config for Media Monitor +############################# + +# URL to setup the media monitor +media_setup_url = 'media-monitor-setup/format/json/api_key/%%api_key%%' + +# Tell Airtime the file id associated with a show instance. +upload_recorded = 'upload-recorded/format/json/api_key/%%api_key%%/fileid/%%fileid%%/showinstanceid/%%showinstanceid%%' + +# URL to tell Airtime to update file's meta data +update_media_url = 'reload-metadata/format/json/api_key/%%api_key%%/mode/%%mode%%' + +# URL to tell Airtime we want a listing of all files it knows about +list_all_db_files = 'list-all-files/format/json/api_key/%%api_key%%/dir_id/%%dir_id%%' + +# URL to tell Airtime we want a listing of all dirs its watching (including the stor dir) +list_all_watched_dirs = 'list-all-watched-dirs/format/json/api_key/%%api_key%%' + +# URL to tell Airtime we want to add watched directory +add_watched_dir = 'add-watched-dir/format/json/api_key/%%api_key%%/path/%%path%%' + +# URL to tell Airtime we want to add watched directory +remove_watched_dir = 'remove-watched-dir/format/json/api_key/%%api_key%%/path/%%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 about file system mount change +update_fs_mount = 'update-file-system-mount/format/json/api_key/%%api_key%%' + +# URL to tell Airtime about file system mount change +handle_watched_dir_missing = 'handle-watched-dir-missing/format/json/api_key/%%api_key%%/dir/%%dir%%' + +############################# +## Config for Recorder +############################# + +# URL to get the schedule of shows set to record +show_schedule_url = 'recorded-shows/format/json/api_key/%%api_key%%' + +# URL to upload the recorded show's file to Airtime +upload_file_url = 'upload-file/format/json/api_key/%%api_key%%' + +#number of retries to upload file if connection problem +upload_retries = 3 + +#time to wait between attempts to upload file if connection problem (in seconds) +upload_wait = 60 + +################################################################################ +# Uncomment *one of the sets* of values from the API clients below, and comment +# out all the others. +################################################################################ + +############################# +## Config for Pypo +############################# + +# Schedule export path. +# %%from%% - starting date/time in the form YYYY-MM-DD-hh-mm +# %%to%% - starting date/time in the form YYYY-MM-DD-hh-mm +export_url = 'schedule/api_key/%%api_key%%' + +get_media_url = 'get-media/file/%%file%%/api_key/%%api_key%%' + +# Update whether a schedule group has begun playing. +update_item_url = 'notify-schedule-group-play/api_key/%%api_key%%/schedule_id/%%schedule_id%%' + +# Update whether an audio clip is currently playing. +update_start_playing_url = 'notify-media-item-start-play/api_key/%%api_key%%/media_id/%%media_id%%/schedule_id/%%schedule_id%%' + +# ??? +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%%/' + +#URL to update liquidsoap status +update_liquidsoap_status = 'update-liquidsoap-status/format/json/api_key/%%api_key%%/msg/%%msg%%/stream_id/%%stream_id%%/boot_time/%%boot_time%%' + +#URL to check live stream auth +check_live_stream_auth = 'check-live-stream-auth/format/json/api_key/%%api_key%%/username/%%username%%/password/%%password%%/djtype/%%djtype%%' + +#URL to update source status +update_source_status = 'update-source-status/format/json/api_key/%%api_key%%/sourcename/%%sourcename%%/status/%%status%%' + +get_bootstrap_info = 'get-bootstrap-info/format/json/api_key/%%api_key%%' + diff --git a/install_minimal/upgrades/airtime-2.1.0/etc/liquidsoap.cfg.210 b/install_minimal/upgrades/airtime-2.1.0/etc/liquidsoap.cfg.210 new file mode 100644 index 000000000..d76e3af3d --- /dev/null +++ b/install_minimal/upgrades/airtime-2.1.0/etc/liquidsoap.cfg.210 @@ -0,0 +1,69 @@ +########################################### +# Liquidsoap config file # +########################################### + +########################################### +# Output settings # +########################################### +output_sound_device = false +output_sound_device_type = "ALSA" +s1_output = "icecast" +s2_output = "icecast" +s3_output = "icecast" + +s1_enable = true +s2_enable = false +s3_enable = false + +s1_type = "ogg" +s2_type = "ogg" +s3_type = "mp3" + +s1_bitrate = 128 +s2_bitrate = 128 +s3_bitrate = 160 + +########################################### +# Logging settings # +########################################### +log_file = "/var/log/airtime/pypo-liquidsoap/