From 96a2861cfa2ee7cff3eba82f66942cf67bb37659 Mon Sep 17 00:00:00 2001 From: Paul Baranowski Date: Mon, 28 Mar 2011 15:38:41 -0400 Subject: [PATCH 1/7] Improved messages during install. --- install/airtime-install.php | 14 +++++++------- install/installInit.php | 18 +++++++++++++++--- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/install/airtime-install.php b/install/airtime-install.php index 7402b5355..aea7ea529 100644 --- a/install/airtime-install.php +++ b/install/airtime-install.php @@ -26,28 +26,28 @@ AirtimeInstall::UpdateIniValue('../build/build.properties', 'project.home', real echo PHP_EOL."*** Database Installation ***".PHP_EOL; -echo "* Creating Airtime Database User".PHP_EOL; +echo "* Creating Airtime database user".PHP_EOL; AirtimeInstall::CreateDatabaseUser(); -echo "* Creating Airtime Database".PHP_EOL; +echo "* Creating Airtime database".PHP_EOL; AirtimeInstall::CreateDatabase(); AirtimeInstall::DbConnect(true); -echo "* Install Postgresql Scripting Language".PHP_EOL; +echo "* Installing Postgresql scripting language".PHP_EOL; AirtimeInstall::InstallPostgresScriptingLanguage(); -echo "* Creating Database Tables".PHP_EOL; +echo "* Creating database tables".PHP_EOL; AirtimeInstall::CreateDatabaseTables(); AirtimeInstall::MigrateTables(__DIR__); -echo "* Storage Directory Setup".PHP_EOL; +echo "* Storage directory setup".PHP_EOL; AirtimeInstall::SetupStorageDirectory($CC_CONFIG); -echo "* Setting Dir Permissions".PHP_EOL; +echo "* Giving Apache permission to access the storage directory".PHP_EOL; AirtimeInstall::ChangeDirOwnerToWebserver($CC_CONFIG["storageDir"]); -echo "* Importing Sample Audio Clips".PHP_EOL; +echo "* Importing sample audio clips".PHP_EOL; system(__DIR__."/../utils/airtime-import --copy ../audio_samples/ > /dev/null"); echo PHP_EOL."*** Pypo Installation ***".PHP_EOL; diff --git a/install/installInit.php b/install/installInit.php index 6723b063a..3f8930e12 100644 --- a/install/installInit.php +++ b/install/installInit.php @@ -144,9 +144,15 @@ class AirtimeInstall { @exec($command, $output, $results); if ($results == 0) { - echo "* User {$CC_CONFIG['dsn']['username']} created.".PHP_EOL; + echo "* Database user '{$CC_CONFIG['dsn']['username']}' created.".PHP_EOL; } else { - echo "* Could not create user {$CC_CONFIG['dsn']['username']}: $output".PHP_EOL; + if (count($output) > 0) { + echo "* Could not create user '{$CC_CONFIG['dsn']['username']}': ".PHP_EOL; + echo implode(PHP_EOL, $output); + } + else { + echo "* Database user '{$CC_CONFIG['dsn']['username']}' already exists.".PHP_EOL; + } } } @@ -159,7 +165,13 @@ class AirtimeInstall { if ($results == 0) { echo "* Database '{$CC_CONFIG['dsn']['database']}' created.".PHP_EOL; } else { - echo "* Could not create database '{$CC_CONFIG['dsn']['database']}': $output".PHP_EOL; + if (count($output) > 0) { + echo "* Could not create database '{$CC_CONFIG['dsn']['database']}': ".PHP_EOL; + echo implode(PHP_EOL, $output); + } + else { + echo "* Database '{$CC_CONFIG['dsn']['database']}' already exists.".PHP_EOL; + } } } From e6e2d70adc35f12f941b55dcc44ce79b12283851 Mon Sep 17 00:00:00 2001 From: Paul Baranowski Date: Mon, 28 Mar 2011 15:42:32 -0400 Subject: [PATCH 2/7] Added credits for 1.7. --- CREDITS | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/CREDITS b/CREDITS index 05fff9198..bb5d3dad4 100644 --- a/CREDITS +++ b/CREDITS @@ -2,11 +2,30 @@ CREDITS ======= +Version 1.7.0 +------------- +Naomi Aro (naomi.aro@sourcefabric.org) + Role: Software Developer + +Martin Konecny (martin.konecny@sourcefabric.org) + Role: Software Developer + +Ofir Gal (ofir.gal@sourcefabric.org) + Role: QA + +Daniel James + Role: Documentor & QA + +Paul Baranowski (paul.baranowski@sourcefabric.org) + Role: Project Manager + + Version 1.6.1 ------------- Version 1.6.1 fixes a problem with playout being interrupted after 48 hours. It also fixes some security issues. + Version 1.6.0 ------------- This version marks a major change to the project, completely replacing the @@ -27,11 +46,14 @@ Naomi Aro (naomi.aro@sourcefabric.org) - Conversion to Propel DB backend Martin Konecny (martin.konecny@sourcefabric.org) - Role:Software Developer + Role: Software Developer Highlights: - New User Interface - Scheduler/Backend +Ofir Gal (ofir.gal@sourcefabric.org) + Role: QA + Daniel James Role: Documentor & QA From f0c47232af5e33cbba9929a3749f57f305d152ea Mon Sep 17 00:00:00 2001 From: Paul Baranowski Date: Mon, 28 Mar 2011 16:12:55 -0400 Subject: [PATCH 3/7] Fixed up INSTALL docs. --- INSTALL | 35 +++++++++++++++++------------------ README | 2 ++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/INSTALL b/INSTALL index 1eea4e8fe..88f7a5807 100644 --- a/INSTALL +++ b/INSTALL @@ -1,23 +1,22 @@ --------------------------------------------------------------------------------- +Airtime is the open radio software for scheduling and remote station management. +Home page: http://airtime.sourcefabric.org/ - Copyright (c) 2010-2011 Sourcefabric O.P.S. +Installation instructions are here: + http://wiki.sourcefabric.org/x/BQBF - This file is part of the Airtime project. - http://airtime.sourcefabric.org/ +Here is the manual: + http://new.flossmanuals.net/airtime/index + +To report bugs, visit our bug tracker at: + http://dev.sourcefabric.org/browse/CC + +Visit our community support forum here: + http://forum.sourcefabric.org/index.php/f/14/ - To report bugs, visit our bug tracker at: - http://dev.sourcefabric.org/browse/CC +For commercial support, see: + http://sourcefabric.org/en/services/about/347/Support.htm + or send an e-mail to contact@sourcefabric.org - Visit our community support forum here: - http://forum.sourcefabric.org/index.php/f/14/ - - For commercial support, see http://sourcefabric.org/en/services/about/347/Support.htm - or send an e-mail to contact@sourcefabric.org +If you are a developer and want to hack on Airtime, go here: + http://wiki.sourcefabric.org/display/CC --------------------------------------------------------------------------------- - -Please see this page for install instructions: -http://wiki.sourcefabric.org/display/CC/Installing+Airtime+%28v1.6%29 - -If you are a developer, see this page: -http://wiki.sourcefabric.org/display/CC diff --git a/README b/README index 111c0e95c..0747ce34a 100644 --- a/README +++ b/README @@ -4,6 +4,8 @@ Airtime is an open source application that provides remote automation of a radio station. +Home page: http://airtime.sourcefabric.org/ + Major features: * Web-based remote station management. Authorized personnel can add program material, create playlists, and schedule programming all via From 4bdd8d425d708e478e2458b26a04004c768a47c4 Mon Sep 17 00:00:00 2001 From: Naomi Date: Tue, 29 Mar 2011 16:32:31 -0400 Subject: [PATCH 4/7] CC-2124 : Rebroadcast: Retry upload to Airtime on failed upload added configurable number of upload retries as well as length between retries. --- python_apps/api_clients/api_client.py | 38 +++++++++++++------ python_apps/show-recorder/config.cfg | 6 +++ python_apps/show-recorder/testrecordscript.py | 6 ++- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/python_apps/api_clients/api_client.py b/python_apps/api_clients/api_client.py index cd2a6e7d7..92f4c0ed8 100644 --- a/python_apps/api_clients/api_client.py +++ b/python_apps/api_clients/api_client.py @@ -288,7 +288,7 @@ class AirTimeApiClient(ApiClientInterface): def get_shows_to_record(self): logger = logging.getLogger() - response = '' + response = None try: url = self.config["base_url"] + self.config["api_base"] + self.config["show_schedule_url"] logger.debug(url) @@ -301,23 +301,37 @@ class AirTimeApiClient(ApiClientInterface): except Exception, e: logger.error("Exception: %s", e) - return response[u'shows'] + return response def upload_recorded_show(self, data, headers): logger = logging.getLogger() response = '' - try: - url = self.config["base_url"] + self.config["api_base"] + self.config["upload_file_url"] - logger.debug(url) - url = url.replace("%%api_key%%", self.config["api_key"]) + retries = int(self.config["upload_retries"]) + retries_wait = int(self.config["upload_wait"]) - request = urllib2.Request(url, data, headers) - response = urllib2.urlopen(request).read().strip() + url = self.config["base_url"] + self.config["api_base"] + self.config["upload_file_url"] + logger.debug(url) + url = url.replace("%%api_key%%", self.config["api_key"]) - logger.info("uploaded show result %s", response) - - except Exception, e: - logger.error("Exception: %s", e) + for i in range(0, retries): + logger.debug("Upload attempt: %s", i+1) + + try: + request = urllib2.Request(url, data, headers) + response = urllib2.urlopen(request).read().strip() + + logger.info("uploaded show result %s", response) + break + + except urllib2.HTTPError, e: + logger.error("Http error code: %s", e.code) + except urllib2.URLError, e: + logger.error("Server is down: %s", e.args) + except Exception, e: + logger.error("Exception: %s", e) + + #wait some time before next retry + time.sleep(retries_wait) return response diff --git a/python_apps/show-recorder/config.cfg b/python_apps/show-recorder/config.cfg index ec812b8cf..823826b31 100644 --- a/python_apps/show-recorder/config.cfg +++ b/python_apps/show-recorder/config.cfg @@ -20,3 +20,9 @@ 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-recorded/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 diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index a352e1f26..ccd2946bc 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -61,7 +61,7 @@ class ShowRecorder(Thread): filename = self.filename.replace(" ", "-") filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) - command = "ecasound -i alsa -o %s -t:%s -ge:3,1,0,-1" % (filepath, length) + command = "ecasound -i alsa -o %s -t:%s -ge:5,1,0,-1" % (filepath, length) args = command.split(" ") print "starting record" @@ -145,6 +145,10 @@ class Record(): def get_shows(self): shows = self.api_client.get_shows_to_record() + if shows is not None: + shows = shows[u'shows'] + else: + shows = [] if len(shows): self.process_shows(shows) From 9ebe7ec1ca485f48d08cba0e8c983a5d312ec7d2 Mon Sep 17 00:00:00 2001 From: Paul Baranowski Date: Tue, 29 Mar 2011 17:31:22 -0400 Subject: [PATCH 5/7] Better error message when timezones dont match up between pypo and airtime. --- python_apps/pypo/pypofetch.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/python_apps/pypo/pypofetch.py b/python_apps/pypo/pypofetch.py index 2958c6bd4..c7b02c589 100644 --- a/python_apps/pypo/pypofetch.py +++ b/python_apps/pypo/pypofetch.py @@ -84,9 +84,12 @@ class PypoFetch(Thread): pypo_timezone = (process.communicate()[0]).strip(' \r\n\t') if server_timezone != pypo_timezone: - logger.error("Server and pypo timezone offsets do not match. Audio playback may not start when expected!") - logger.error("Server timezone offset: %s", server_timezone) - logger.error("Pypo timezone offset: %s", pypo_timezone) + logger.error("ERROR: Airtime server and pypo timezone offsets do not match. Audio playback will not start when expected!!!") + logger.error(" * Server timezone offset: %s", server_timezone) + logger.error(" * Pypo timezone offset: %s", pypo_timezone) + logger.error(" * To fix this, you need to set the 'date.timezone' value in your php.ini file and restart apache.") + logger.error(" * See this page for more info (v1.7): http://wiki.sourcefabric.org/x/BQBF") + logger.error(" * and also the 'FAQ and Support' page underneath it.") """ Process the schedule From 835960d25fa8a9b241376f613ce3cfe5522d790c Mon Sep 17 00:00:00 2001 From: Paul Baranowski Date: Tue, 29 Mar 2011 17:32:03 -0400 Subject: [PATCH 6/7] Added explanation to the user for each of the tools in dev_tools. --- dev_tools/pl.sh | 4 +++- dev_tools/pr.sh | 4 ++++ dev_tools/pypoless.sh | 4 ++++ dev_tools/pypotail.sh | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dev_tools/pl.sh b/dev_tools/pl.sh index 7c6f8b650..4e1c70134 100755 --- a/dev_tools/pl.sh +++ b/dev_tools/pl.sh @@ -1,3 +1,5 @@ #!/bin/sh - +echo +echo "This will tail the pypo-liquidsoap log file." +echo "Type in password for pypo user (default password is 'pypo'):" su -l pypo -c "tail -F /etc/service/pypo-liquidsoap/log/main/current" diff --git a/dev_tools/pr.sh b/dev_tools/pr.sh index f5e741658..aadab42ec 100755 --- a/dev_tools/pr.sh +++ b/dev_tools/pr.sh @@ -1,3 +1,7 @@ #!/bin/sh +echo +echo "This will tail the recorder log file." +echo "Type in password for pypo user (default password is 'pypo'):" + su -l pypo -c "tail -F /etc/service/recorder/log/main/current" diff --git a/dev_tools/pypoless.sh b/dev_tools/pypoless.sh index 542702527..f9db223af 100755 --- a/dev_tools/pypoless.sh +++ b/dev_tools/pypoless.sh @@ -1,3 +1,7 @@ #!/bin/sh +echo +echo "This will output the pypo log file." +echo "Type in password for pypo user (default password is 'pypo'):" + su -l pypo -c "less /etc/service/pypo/log/main/current" diff --git a/dev_tools/pypotail.sh b/dev_tools/pypotail.sh index e91cd3917..0f2168e44 100755 --- a/dev_tools/pypotail.sh +++ b/dev_tools/pypotail.sh @@ -1,3 +1,7 @@ #!/bin/sh +echo +echo "This will tail the pypo log file." +echo "Type in password for pypo user (default password is 'pypo'):" + su -l pypo -c "tail -F /etc/service/pypo/log/main/current" From 4c457ce6bcdf17eb29a1bc93f297cb4e7167c6dd Mon Sep 17 00:00:00 2001 From: Naomi Date: Tue, 29 Mar 2011 18:01:30 -0400 Subject: [PATCH 7/7] set gate to really low level. --- python_apps/show-recorder/testrecordscript.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_apps/show-recorder/testrecordscript.py b/python_apps/show-recorder/testrecordscript.py index ccd2946bc..439f0f07f 100644 --- a/python_apps/show-recorder/testrecordscript.py +++ b/python_apps/show-recorder/testrecordscript.py @@ -61,7 +61,7 @@ class ShowRecorder(Thread): filename = self.filename.replace(" ", "-") filepath = "%s%s.%s" % (config["base_recorded_files"], filename, self.filetype) - command = "ecasound -i alsa -o %s -t:%s -ge:5,1,0,-1" % (filepath, length) + command = "ecasound -i alsa -o %s -t:%s -ge:0.1,0.1,0,-1" % (filepath, length) args = command.split(" ") print "starting record"