From cb0593370a34550b51c8a3e93147f7b713669d07 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Sat, 4 Jul 2015 00:38:53 -0400 Subject: [PATCH 01/16] Quick fix --- airtime_mvc/application/Bootstrap.php | 8 ++--- airtime_mvc/application/models/Preference.php | 36 +++++++++++++++---- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index 0c1911d55..2519b303c 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -144,10 +144,10 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $baseUrl = Application_Common_OsPath::getBaseDir(); - $view->headLink(array('rel' => 'icon', - 'href' => $baseUrl . 'favicon.ico?' . $CC_CONFIG['airtime_version'], - 'type' => 'image/x-icon'), 'PREPEND') - ->appendStylesheet($baseUrl . 'css/bootstrap.css?' . $CC_CONFIG['airtime_version']) + /* + * array('rel' => 'icon', 'href' => $baseUrl . 'favicon.ico?' . $CC_CONFIG['airtime_version'], 'type' => 'image/x-icon'), 'PREPEND' + */ + $view->headLink()->appendStylesheet($baseUrl . 'css/bootstrap.css?' . $CC_CONFIG['airtime_version']) ->appendStylesheet($baseUrl . 'css/redmond/jquery-ui-1.8.8.custom.css?' . $CC_CONFIG['airtime_version']) ->appendStylesheet($baseUrl . 'css/pro_dropdown_3.css?' . $CC_CONFIG['airtime_version']) ->appendStylesheet($baseUrl . 'css/qtip/jquery.qtip.min.css?' . $CC_CONFIG['airtime_version']) diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index e8d116246..ec8b49a3c 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -27,17 +27,17 @@ class Application_Model_Preference private static function setValue($key, $value, $isUserValue = false) { $cache = new Cache(); - - try { - - $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME); - $con->beginTransaction(); + $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME); + $con->beginTransaction(); + try { + static::_lock($con); $userId = self::getUserId(); - if ($isUserValue && is_null($userId)) + if ($isUserValue && is_null($userId)) { throw new Exception("User id can't be null for a user preference {$key}."); - + } + //Check if key already exists $sql = "SELECT COUNT(*) FROM cc_pref" ." WHERE keystr = :key"; @@ -113,6 +113,28 @@ class Application_Model_Preference $cache->store($key, $value, $isUserValue, $userId); } + /** + * Given a PDO connection, lock the cc_pref table for the current transaction + * + * Creates a table level lock, which defaults to ACCESS EXCLUSIVE mode; + * see http://www.postgresql.org/docs/9.1/static/explicit-locking.html + * + * @param PDO $con + */ + private static function _lock($con) { + // If we're not in a transaction, a lock is pointless + if (!$con->inTransaction()) { + return; + } + // Don't specify NOWAIT here; we should block on obtaining this lock + // in case we're handling simultaneous requests. + // Locks only last until the end of the transaction, so we shouldn't have to + // worry about this causing any noticeable difference in request processing speed + $sql = "LOCK TABLE cc_pref"; + $st = $con->prepare($sql); + $st->execute(); + } + private static function getValue($key, $isUserValue = false) { $cache = new Cache(); From db7e4086ba0db45cd338096c33e417288b4524be Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Sat, 4 Jul 2015 01:16:58 -0400 Subject: [PATCH 02/16] Re-add favicon headlink --- airtime_mvc/application/Bootstrap.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index 2519b303c..919b365bd 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -144,10 +144,8 @@ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap $baseUrl = Application_Common_OsPath::getBaseDir(); - /* - * array('rel' => 'icon', 'href' => $baseUrl . 'favicon.ico?' . $CC_CONFIG['airtime_version'], 'type' => 'image/x-icon'), 'PREPEND' - */ - $view->headLink()->appendStylesheet($baseUrl . 'css/bootstrap.css?' . $CC_CONFIG['airtime_version']) + $view->headLink(array('rel' => 'icon', 'href' => $baseUrl . 'favicon.ico?' . $CC_CONFIG['airtime_version'], 'type' => 'image/x-icon'), 'PREPEND') + ->appendStylesheet($baseUrl . 'css/bootstrap.css?' . $CC_CONFIG['airtime_version']) ->appendStylesheet($baseUrl . 'css/redmond/jquery-ui-1.8.8.custom.css?' . $CC_CONFIG['airtime_version']) ->appendStylesheet($baseUrl . 'css/pro_dropdown_3.css?' . $CC_CONFIG['airtime_version']) ->appendStylesheet($baseUrl . 'css/qtip/jquery.qtip.min.css?' . $CC_CONFIG['airtime_version']) From e69eb9c2b1a01bfd654dc5cc891f9c10d83f2c26 Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 6 Jul 2015 09:33:04 -0400 Subject: [PATCH 03/16] SAAS-916: Localize schedule widget dates --- airtime_mvc/application/common/WidgetHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/common/WidgetHelper.php b/airtime_mvc/application/common/WidgetHelper.php index a60969d3b..c715ed5e5 100644 --- a/airtime_mvc/application/common/WidgetHelper.php +++ b/airtime_mvc/application/common/WidgetHelper.php @@ -98,7 +98,7 @@ class WidgetHelper // javascript date formats so it's easier to sort the shows by day. $result["weekDays"][$weekStartDateTime->format("Y-n-j")] = array(); $result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfMonth"] = $dateParse["day"]; - $result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfWeek"] = strtoupper(date("D", $weekStartDateTime->getTimestamp())); + $result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfWeek"] = _(strtoupper(date("D", $weekStartDateTime->getTimestamp()))); // Shows scheduled for this day will get added to this array when // we convert the show times to the client's local timezone in weekly-program.phtml From 6914e161653409163faa5c49e97cc9cc1c0991ca Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 6 Jul 2015 10:21:27 -0400 Subject: [PATCH 04/16] SAAS-916: Localize schedule widget dates Forgot to commit msg strings for this --- airtime_mvc/application/controllers/LocaleController.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/airtime_mvc/application/controllers/LocaleController.php b/airtime_mvc/application/controllers/LocaleController.php index 7d83a165e..444bc058e 100644 --- a/airtime_mvc/application/controllers/LocaleController.php +++ b/airtime_mvc/application/controllers/LocaleController.php @@ -251,6 +251,13 @@ class LocaleController extends Zend_Controller_Action "Thu" => _("Thu"), "Fri" => _("Fri"), "Sat" => _("Sat"), + "SUN" => _("SUN"), + "MON" => _("MON"), + "TUE" => _("TUE"), + "WED" => _("WED"), + "THU" => _("THU"), + "FRI" => _("FRI"), + "SAT" => _("SAT"), "Shows longer than their scheduled time will be cut off by a following show." => _("Shows longer than their scheduled time will be cut off by a following show."), "Cancel Current Show?" => _("Cancel Current Show?"), "Stop recording current show?" => _("Stop recording current show?"), From 71b2a4e94694337ac09253f3faac51f6e0814a69 Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 6 Jul 2015 10:29:02 -0400 Subject: [PATCH 05/16] Removing duplicate locale strings --- airtime_mvc/application/controllers/LocaleController.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/airtime_mvc/application/controllers/LocaleController.php b/airtime_mvc/application/controllers/LocaleController.php index 444bc058e..7d83a165e 100644 --- a/airtime_mvc/application/controllers/LocaleController.php +++ b/airtime_mvc/application/controllers/LocaleController.php @@ -251,13 +251,6 @@ class LocaleController extends Zend_Controller_Action "Thu" => _("Thu"), "Fri" => _("Fri"), "Sat" => _("Sat"), - "SUN" => _("SUN"), - "MON" => _("MON"), - "TUE" => _("TUE"), - "WED" => _("WED"), - "THU" => _("THU"), - "FRI" => _("FRI"), - "SAT" => _("SAT"), "Shows longer than their scheduled time will be cut off by a following show." => _("Shows longer than their scheduled time will be cut off by a following show."), "Cancel Current Show?" => _("Cancel Current Show?"), "Stop recording current show?" => _("Stop recording current show?"), From f86c50a834a90db9057eb552e3febf5ad23e4ed9 Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 6 Jul 2015 10:30:16 -0400 Subject: [PATCH 06/16] SAAS-916: Localize schedule widget dates Fix to use existing locale strings --- airtime_mvc/application/common/WidgetHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/common/WidgetHelper.php b/airtime_mvc/application/common/WidgetHelper.php index c715ed5e5..d22727ad9 100644 --- a/airtime_mvc/application/common/WidgetHelper.php +++ b/airtime_mvc/application/common/WidgetHelper.php @@ -98,7 +98,7 @@ class WidgetHelper // javascript date formats so it's easier to sort the shows by day. $result["weekDays"][$weekStartDateTime->format("Y-n-j")] = array(); $result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfMonth"] = $dateParse["day"]; - $result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfWeek"] = _(strtoupper(date("D", $weekStartDateTime->getTimestamp()))); + $result["weekDays"][$weekStartDateTime->format("Y-n-j")]["dayOfWeek"] = strtoupper(_(date("D", $weekStartDateTime->getTimestamp()))); // Shows scheduled for this day will get added to this array when // we convert the show times to the client's local timezone in weekly-program.phtml From ec0fbd2d6140be09e37fe8e2c6a01b6b1f77de3b Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 6 Jul 2015 10:47:04 -0400 Subject: [PATCH 07/16] Fix for schedule widget weekdays going out of order --- .../application/views/scripts/embed/weekly-program.phtml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/views/scripts/embed/weekly-program.phtml b/airtime_mvc/application/views/scripts/embed/weekly-program.phtml index 0b4cdb0a5..872afc849 100644 --- a/airtime_mvc/application/views/scripts/embed/weekly-program.phtml +++ b/airtime_mvc/application/views/scripts/embed/weekly-program.phtml @@ -59,7 +59,11 @@ }); } }); - $scope.weekDays = $window.schedule_data["weekDays"]; + // Convert the object into an array to maintain the same order when we + // iterate over each weekday + $scope.weekDays = $.map($window.schedule_data["weekDays"], function(value, index) { + return [value]; + }); $scope.isEmpty = function(obj) { return obj.length == 0; From 31ce52b8575361593275de7530d6c216fb38cad3 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Mon, 6 Jul 2015 11:52:04 -0400 Subject: [PATCH 08/16] CC-6062 - Fix stretching last column after adding show in calendar view --- airtime_mvc/public/js/airtime/schedule/add-show.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/airtime_mvc/public/js/airtime/schedule/add-show.js b/airtime_mvc/public/js/airtime/schedule/add-show.js index df862e971..a5804dbc5 100644 --- a/airtime_mvc/public/js/airtime/schedule/add-show.js +++ b/airtime_mvc/public/js/airtime/schedule/add-show.js @@ -786,6 +786,11 @@ function setAddShowEvents(form) { scheduleRefetchEvents(json); $addShowForm.hide(); } + + /* CC-6062: Resize the window to avoid stretching the last column */ + windowResize(); + makeAddShowButton(); + } }); }); From a5a91c25e01a5dcceabddaaaa473587159aae7a0 Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 6 Jul 2015 12:53:15 -0400 Subject: [PATCH 09/16] SAAS-929: Shows don't show up on schedule widget on Firefox --- airtime_mvc/application/common/WidgetHelper.php | 10 ++++++++++ .../views/scripts/embed/weekly-program.phtml | 6 ++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/common/WidgetHelper.php b/airtime_mvc/application/common/WidgetHelper.php index d22727ad9..8be23e200 100644 --- a/airtime_mvc/application/common/WidgetHelper.php +++ b/airtime_mvc/application/common/WidgetHelper.php @@ -127,6 +127,16 @@ class WidgetHelper "ALL", $showQueryDateRangeEnd->format("Y-m-d H:i:s")); + // Convert each start and end time string to DateTime objects + // so we can get a real timestamp. The timestamps will be used + // to convert into javascript Date objects. + foreach($shows as &$show) { + $dtStarts = new DateTime($show["starts"], new DateTimeZone("UTC")); + $show["starts_timestamp"] = $dtStarts->getTimestamp(); + + $dtEnds = new DateTime($show["ends"], new DateTimeZone("UTC")); + $show["ends_timestamp"] = $dtEnds->getTimestamp(); + } $result["shows"] = $shows; // XSS exploit prevention diff --git a/airtime_mvc/application/views/scripts/embed/weekly-program.phtml b/airtime_mvc/application/views/scripts/embed/weekly-program.phtml index 872afc849..911cd4b87 100644 --- a/airtime_mvc/application/views/scripts/embed/weekly-program.phtml +++ b/airtime_mvc/application/views/scripts/embed/weekly-program.phtml @@ -40,8 +40,10 @@ // First we have to create a Date object out of the show time in UTC. // Then we can format the string in the client's local timezone. - var start_date = new Date(value.starts + " UTC"); - var end_date = new Date(value.ends + " UTC"); + // NOTE: we have to multiply the timestamp by 1000 because in PHP + // the timestamps are in seconds and are in milliseconds in javascript. + var start_date = new Date(value.starts_timestamp*1000); + var end_date = new Date(value.ends_timestamp*1000); // This variable is used to identify which schedule_data object (which day of the week) // we should assign the show to. From 5cb396e512ef3caefde48a4ff8805091312bd5e3 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Mon, 6 Jul 2015 18:03:44 -0400 Subject: [PATCH 10/16] SAAS-923 - 2.5.14 schema upgrade to add partial unique index on cc_pref's keystr column (when subjid is null) --- airtime_mvc/application/configs/constants.php | 3 ++- .../upgrade_sql/airtime_2.5.14/upgrade.sql | 4 ++++ airtime_mvc/application/models/Preference.php | 3 ++- airtime_mvc/application/upgrade/Upgrades.php | 18 ++++++++++++++++++ airtime_mvc/build/sql/defaultdata.sql | 8 ++++++++ 5 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 airtime_mvc/application/controllers/upgrade_sql/airtime_2.5.14/upgrade.sql diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index 4360cd9e7..aaed5d901 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -24,7 +24,8 @@ define('LICENSE_URL' , 'http://www.gnu.org/licenses/agpl-3.0-standalone.h define('AIRTIME_COPYRIGHT_DATE' , '2010-2015'); define('AIRTIME_REST_VERSION' , '1.1'); define('AIRTIME_API_VERSION' , '1.1'); -define('AIRTIME_CODE_VERSION' , '2.5.13'); +// XXX: it's important that we upgrade this every time we add an upgrade! +define('AIRTIME_CODE_VERSION' , '2.5.14'); // Defaults define('DEFAULT_LOGO_PLACEHOLDER', 1); diff --git a/airtime_mvc/application/controllers/upgrade_sql/airtime_2.5.14/upgrade.sql b/airtime_mvc/application/controllers/upgrade_sql/airtime_2.5.14/upgrade.sql new file mode 100644 index 000000000..3a5362ca1 --- /dev/null +++ b/airtime_mvc/application/controllers/upgrade_sql/airtime_2.5.14/upgrade.sql @@ -0,0 +1,4 @@ +ALTER TABLE cc_pref ALTER COLUMN subjid SET NULL; +ALTER TABLE cc_pref ALTER COLUMN subjid SET DEFAULT NULL; +CREATE UNIQUE INDEX cc_pref_key_idx ON cc_pref (keystr) WHERE subjid IS NULL; +ANALYZE cc_pref; \ No newline at end of file diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index ec8b49a3c..736dbef98 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -31,7 +31,8 @@ class Application_Model_Preference $con->beginTransaction(); try { - static::_lock($con); + /* Comment this out while we reevaluate it in favor of a unique constraint + static::_lock($con); */ $userId = self::getUserId(); if ($isUserValue && is_null($userId)) { diff --git a/airtime_mvc/application/upgrade/Upgrades.php b/airtime_mvc/application/upgrade/Upgrades.php index aa012eca6..bcd9c5093 100644 --- a/airtime_mvc/application/upgrade/Upgrades.php +++ b/airtime_mvc/application/upgrade/Upgrades.php @@ -455,3 +455,21 @@ class AirtimeUpgrader2513 extends AirtimeUpgrader return '2.5.13'; } } + +/** + * Class AirtimeUpgrader2514 + * + * SAAS-923 - Add a partial constraint to cc_pref so that keystrings must be unique + */ +class AirtimeUpgrader2514 extends AirtimeUpgrader +{ + protected function getSupportedSchemaVersions() { + return array ( + '2.5.13' + ); + } + + public function getNewVersion() { + return '2.5.14'; + } +} diff --git a/airtime_mvc/build/sql/defaultdata.sql b/airtime_mvc/build/sql/defaultdata.sql index 49bf3ff29..30fd8d765 100644 --- a/airtime_mvc/build/sql/defaultdata.sql +++ b/airtime_mvc/build/sql/defaultdata.sql @@ -376,3 +376,11 @@ INSERT INTO cc_stream_setting ("keyname", "value", "type") VALUES ('s4_descripti INSERT INTO cc_stream_setting ("keyname", "value", "type") VALUES ('s4_genre', '', 'string'); INSERT INTO cc_stream_setting (keyname, value, type) VALUES ('s4_channels', 'stereo', 'string'); +-- added in 2.5.14 - this can't be set up in Propel's XML schema, so we need to do it here -- Duncan + +ALTER TABLE cc_pref ALTER COLUMN subjid SET NULL; +ALTER TABLE cc_pref ALTER COLUMN subjid SET DEFAULT NULL; +CREATE UNIQUE INDEX cc_pref_key_idx ON cc_pref (keystr) WHERE subjid IS NULL; +ANALYZE cc_pref; -- this validates the new partial index + +--end added in 2.5.14 From b200a29f437556e7df9ee0d66b4cb82226a97a8c Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 7 Jul 2015 09:21:44 -0400 Subject: [PATCH 11/16] SAAS-928: Time strings on Radio Page are not localized --- .../views/scripts/embed/weekly-program.phtml | 4 ++-- .../embed/weekly-schedule-widget-basic.css | 20 +++++++++---------- .../css/embed/weekly-schedule-widget.css | 20 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/airtime_mvc/application/views/scripts/embed/weekly-program.phtml b/airtime_mvc/application/views/scripts/embed/weekly-program.phtml index 911cd4b87..a7bb24e69 100644 --- a/airtime_mvc/application/views/scripts/embed/weekly-program.phtml +++ b/airtime_mvc/application/views/scripts/embed/weekly-program.phtml @@ -55,8 +55,8 @@ if ($window.schedule_data["weekDays"][format_start_date] !== undefined) { $window.schedule_data["weekDays"][format_start_date]["shows"].push( { - "show_start_hour": start_date.getHours().toString().paddingLeft("00")+":"+ start_date.getMinutes().toString().paddingLeft("00"), - "show_end_hour": end_date.getHours().toString().paddingLeft("00")+":"+ end_date.getMinutes().toString().paddingLeft("00"), + "show_start_hour": start_date.toLocaleTimeString([], { hour: 'numeric', minute : 'numeric' }), + "show_end_hour": end_date.toLocaleTimeString([], { hour: 'numeric', minute : 'numeric' }), "name": value.name }); } diff --git a/airtime_mvc/public/css/embed/weekly-schedule-widget-basic.css b/airtime_mvc/public/css/embed/weekly-schedule-widget-basic.css index e8bc86c01..a74d276a7 100644 --- a/airtime_mvc/public/css/embed/weekly-schedule-widget-basic.css +++ b/airtime_mvc/public/css/embed/weekly-schedule-widget-basic.css @@ -123,7 +123,7 @@ background: rgba(53, 53, 53, 1.0); .schedule_item div.time_grid { /*padding-right: 10px;*/ - width: 20%; + width: 30%; font-weight: 300; color: #AAAAAA; display: inline-block; @@ -133,7 +133,7 @@ background: rgba(53, 53, 53, 1.0); overflow: hidden; text-overflow: ellipsis; padding-left: 10px; - width: 77%; + width: 67%; display:inline-block; vertical-align: middle; } @@ -182,11 +182,11 @@ background: rgba(53, 53, 53, 1.0); @media (max-width: 630px) { .schedule_item div.time_grid { - width: 25%; + width: 37%; } .schedule_item div.name_grid { - width: 70%; + width: 58%; } } @@ -197,31 +197,31 @@ background: rgba(53, 53, 53, 1.0); } .schedule_item div.time_grid { - width: 30%; + width: 35%; } .schedule_item div.name_grid { - width: 67%; + width: 60%; } } @media (max-width: 500px) { .schedule_item div.time_grid { - width: 35%; + width: 40%; } .schedule_item div.name_grid { - width: 62%; + width: 55%; } } @media (max-width: 400px) { .schedule_item div.time_grid { - width: 40%; + width: 90%; } .schedule_item div.name_grid { - width: 50%; + width: 90%; } } diff --git a/airtime_mvc/public/css/embed/weekly-schedule-widget.css b/airtime_mvc/public/css/embed/weekly-schedule-widget.css index 2f731c7aa..59c460860 100644 --- a/airtime_mvc/public/css/embed/weekly-schedule-widget.css +++ b/airtime_mvc/public/css/embed/weekly-schedule-widget.css @@ -97,7 +97,7 @@ body { .schedule_item div.time_grid { /*padding-right: 10px;*/ - width: 20%; + width: 30%; font-weight: 300; color: #AAAAAA; display: inline-block; @@ -107,7 +107,7 @@ body { overflow: hidden; text-overflow: ellipsis; padding-left: 10px; - width: 77%; + width: 67%; display:inline-block; vertical-align: middle; } @@ -132,11 +132,11 @@ body { @media (max-width: 630px) { .schedule_item div.time_grid { - width: 25%; + width: 37%; } .schedule_item div.name_grid { - width: 72%; + width: 58%; } } @@ -147,31 +147,31 @@ body { } .schedule_item div.time_grid { - width: 30%; + width: 35%; } .schedule_item div.name_grid { - width: 67%; + width: 60%; } } @media (max-width: 500px) { .schedule_item div.time_grid { - width: 35%; + width: 40%; } .schedule_item div.name_grid { - width: 62%; + width: 55%; } } @media (max-width: 400px) { .schedule_item div.time_grid { - width: 40%; + width: 90%; } .schedule_item div.name_grid { - width: 50%; + width: 90%; } } From 92c9fd30b5b23775840e919e520114fed60c1b93 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Tue, 7 Jul 2015 13:54:19 -0400 Subject: [PATCH 12/16] SAAS-922 - expose mime-based file extensions from /rest/media --- .../application/common/FileDataHelper.php | 27 +++++++++++ airtime_mvc/application/common/HTTPHelper.php | 9 +--- airtime_mvc/application/models/Preference.php | 4 +- airtime_mvc/application/models/StoredFile.php | 45 +------------------ .../application/models/airtime/CcFiles.php | 34 +++++++------- 5 files changed, 51 insertions(+), 68 deletions(-) diff --git a/airtime_mvc/application/common/FileDataHelper.php b/airtime_mvc/application/common/FileDataHelper.php index 5a600e419..0d2c243c0 100644 --- a/airtime_mvc/application/common/FileDataHelper.php +++ b/airtime_mvc/application/common/FileDataHelper.php @@ -24,4 +24,31 @@ class FileDataHelper { $data["bpm"] = intval($data["bpm"]); } } + + /** + * Return a suitable extension for the given file + * + * @param string $mime + * + * @return string file extension with(!) a dot + * + * @throws Exception + */ + public static function getFileExtensionFromMime($mime) + { + if ($mime == "audio/ogg" || $mime == "application/ogg" || $mime == "audio/vorbis") { + return ".ogg"; + } elseif ($mime == "audio/mp3" || $mime == "audio/mpeg" || $mime == "audio/mpeg3") { + return ".mp3"; + } elseif ($mime == "audio/x-flac") { + return ".flac"; + } elseif ($mime == "audio/mp4") { + return ".mp4"; + } elseif ($mime == "audio/wav" || $mime == "audio/x-wav") { + return ".wav"; + } else { + throw new Exception("Unknown $mime"); + } + } + } \ No newline at end of file diff --git a/airtime_mvc/application/common/HTTPHelper.php b/airtime_mvc/application/common/HTTPHelper.php index 04a9e9cc5..c702da480 100644 --- a/airtime_mvc/application/common/HTTPHelper.php +++ b/airtime_mvc/application/common/HTTPHelper.php @@ -45,8 +45,6 @@ class Application_Common_HTTPHelper class ZendActionHttpException extends Exception { - private $_action; - /** * @param Zend_Controller_Action $action * @param int $statusCode @@ -58,8 +56,7 @@ class ZendActionHttpException extends Exception { */ public function __construct(Zend_Controller_Action $action, $statusCode, $message, $code = 0, Exception $previous = null) { - $this->_action = $action; - Logging::info("Error in action " . $action->getRequest()->getActionName() + Logging::error("Error in action " . $action->getRequest()->getActionName() . " with status code $statusCode: $message"); $action->getResponse() ->setHttpResponseCode($statusCode) @@ -67,8 +64,4 @@ class ZendActionHttpException extends Exception { parent::__construct($message, $code, $previous); } - public function getAction() { - return $this->_action; - } - } \ No newline at end of file diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 736dbef98..5c1e7c889 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -163,9 +163,9 @@ class Application_Model_Preference $sql .= " AND subjid = :id"; $paramMap[':id'] = $userId; } - + $result = Application_Common_Database::prepareAndExecute($sql, $paramMap, Application_Common_Database::COLUMN); - + //return an empty string if the result doesn't exist. if ($result == 0) { $res = ""; diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index 58fe8a703..ebc2ab2b0 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -17,6 +17,7 @@ class Application_Model_StoredFile { /** * @holds propel database object + * @var CcFiles */ private $_file; @@ -467,48 +468,6 @@ SQL; $this->_file->save(); } - - public function getRealFileExtension() { - $path = $this->_file->getDbFilepath(); - $path_elements = explode('.', $path); - if (count($path_elements) < 2) { - return ""; - } else { - return $path_elements[count($path_elements) - 1]; - } - } - - /** - * Return suitable extension. - * - * @return string - * file extension without a dot - */ - public function getFileExtension() - { - $possible_ext = $this->getRealFileExtension(); - if ($possible_ext !== "") { - return $possible_ext; - } - - // We fallback to guessing the extension from the mimetype if we - // cannot extract it from the file name - - $mime = $this->_file->getDbMime(); - - if ($mime == "audio/ogg" || $mime == "application/ogg" || $mime == "audio/vorbis") { - return "ogg"; - } elseif ($mime == "audio/mp3" || $mime == "audio/mpeg") { - return "mp3"; - } elseif ($mime == "audio/x-flac") { - return "flac"; - } elseif ($mime == "audio/mp4") { - return "mp4"; - } else { - throw new Exception("Unknown $mime"); - } - } - /** * Get the absolute filepath * @@ -568,7 +527,7 @@ SQL; */ public function getRelativeFileUrl($baseUrl) { - return $baseUrl."api/get-media/file/".$this->getId().".".$this->getFileExtension(); + return $baseUrl."api/get-media/file/".$this->getId().FileDataHelper::getFileExtensionFromMime($this->_file->getDbMime()); } public function getResourceId() diff --git a/airtime_mvc/application/models/airtime/CcFiles.php b/airtime_mvc/application/models/airtime/CcFiles.php index 16fb99c67..c574c9d7c 100644 --- a/airtime_mvc/application/models/airtime/CcFiles.php +++ b/airtime_mvc/application/models/airtime/CcFiles.php @@ -205,11 +205,6 @@ class CcFiles extends BaseCcFiles { $cloudFile->save(); Application_Model_Preference::updateDiskUsage($fileSizeBytes); - - $now = new DateTime("now", new DateTimeZone("UTC")); - $file->setDbMtime($now); - $file->save(); - } else if ($file) { // Since we check for this value when deleting files, set it first @@ -238,14 +233,13 @@ class CcFiles extends BaseCcFiles { $file->setDbFilepath($filePathRelativeToStor); } } - - $now = new DateTime("now", new DateTimeZone("UTC")); - $file->setDbMtime($now); - $file->save(); - } else { throw new FileNotFoundException(); } + + $now = new DateTime("now", new DateTimeZone("UTC")); + $file->setDbMtime($now); + $file->save(); } catch (FileNotFoundException $e) { @@ -356,17 +350,27 @@ class CcFiles extends BaseCcFiles { /** * * Strips out the private fields we do not want to send back in API responses - * @param $file string a CcFiles object + * + * @param CcFiles $file a CcFiles object + * + * @return array */ //TODO: rename this function? - public static function sanitizeResponse($file) - { + public static function sanitizeResponse($file) { $response = $file->toArray(BasePeer::TYPE_FIELDNAME); - + foreach (self::$privateFields as $key) { unset($response[$key]); } - + + $mime = $file->getDbMime(); + if (!empty($mime)) { + // Get an extension based on the file's mime type and change the path to use this extension + $path = pathinfo($file->getDbFilepath()); + $ext = FileDataHelper::getFileExtensionFromMime($mime); + $response["filepath"] = ($path["dirname"] . '/' . $path["filename"] . $ext); + } + return $response; } From e246771af0bc9f10b38cf38d9fa4c8fd4e600830 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Tue, 7 Jul 2015 15:09:06 -0400 Subject: [PATCH 13/16] SAAS-922 - additional mime-type coverage --- airtime_mvc/application/common/FileDataHelper.php | 4 ++++ airtime_mvc/application/models/StoredFile.php | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/common/FileDataHelper.php b/airtime_mvc/application/common/FileDataHelper.php index 0d2c243c0..316d6359f 100644 --- a/airtime_mvc/application/common/FileDataHelper.php +++ b/airtime_mvc/application/common/FileDataHelper.php @@ -40,6 +40,10 @@ class FileDataHelper { return ".ogg"; } elseif ($mime == "audio/mp3" || $mime == "audio/mpeg" || $mime == "audio/mpeg3") { return ".mp3"; + } elseif ($mime == "audio/mp2") { + return ".mp2"; + } elseif ($mime == "audio/mp1") { + return ".mp1"; } elseif ($mime == "audio/x-flac") { return ".flac"; } elseif ($mime == "audio/mp4") { diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index ebc2ab2b0..e975ccd8c 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -527,7 +527,7 @@ SQL; */ public function getRelativeFileUrl($baseUrl) { - return $baseUrl."api/get-media/file/".$this->getId().FileDataHelper::getFileExtensionFromMime($this->_file->getDbMime()); + return $baseUrl."api/get-media/file/".$this->getId(); } public function getResourceId() From 776596d5b6bc898ddefdd254d0537333148ac1a1 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Tue, 7 Jul 2015 15:48:22 -0400 Subject: [PATCH 14/16] SAAS-922 - replace large conditionals with single public mime-type map --- .../application/common/FileDataHelper.php | 42 +++++++++++-------- .../controllers/AudiopreviewController.php | 41 ++++-------------- 2 files changed, 33 insertions(+), 50 deletions(-) diff --git a/airtime_mvc/application/common/FileDataHelper.php b/airtime_mvc/application/common/FileDataHelper.php index 316d6359f..0aff43523 100644 --- a/airtime_mvc/application/common/FileDataHelper.php +++ b/airtime_mvc/application/common/FileDataHelper.php @@ -2,6 +2,25 @@ class FileDataHelper { + public static function getAudioMimeTypeArray() { + return array( + "audio/ogg" => "ogg", + "application/ogg" => "ogg", + "audio/vorbis" => "ogg", + "audio/mp3" => "mp3", + "audio/mpeg" => "mp3", + "audio/mpeg3" => "mp3", + "audio/mp4" => "mp4", + "audio/x-flac" => "flac", + "audio/wav" => "wav", + "audio/x-wav" => "wav", + "audio/mp2" => "mp2", + "audio/mp1" => "mp1", + "audio/x-ms-wma" => "wma", + "audio/basic" => "au", + ); + } + /** * We want to throw out invalid data and process the upload successfully * at all costs, so check the data and sanitize it if necessary @@ -30,28 +49,17 @@ class FileDataHelper { * * @param string $mime * - * @return string file extension with(!) a dot + * @return string file extension with(!) a dot (for convenience) * * @throws Exception */ public static function getFileExtensionFromMime($mime) { - if ($mime == "audio/ogg" || $mime == "application/ogg" || $mime == "audio/vorbis") { - return ".ogg"; - } elseif ($mime == "audio/mp3" || $mime == "audio/mpeg" || $mime == "audio/mpeg3") { - return ".mp3"; - } elseif ($mime == "audio/mp2") { - return ".mp2"; - } elseif ($mime == "audio/mp1") { - return ".mp1"; - } elseif ($mime == "audio/x-flac") { - return ".flac"; - } elseif ($mime == "audio/mp4") { - return ".mp4"; - } elseif ($mime == "audio/wav" || $mime == "audio/x-wav") { - return ".wav"; - } else { - throw new Exception("Unknown $mime"); + $mime = trim(strtolower($mime)); + try { + return ('.' . static::getAudioMimeTypeArray()[$mime]); + } catch (Exception $e) { + throw new Exception("Unknown file type: $mime"); } } diff --git a/airtime_mvc/application/controllers/AudiopreviewController.php b/airtime_mvc/application/controllers/AudiopreviewController.php index c5ad22a58..bff30e929 100644 --- a/airtime_mvc/application/controllers/AudiopreviewController.php +++ b/airtime_mvc/application/controllers/AudiopreviewController.php @@ -198,23 +198,10 @@ class AudiopreviewController extends Zend_Controller_Action $elementMap['type'] = $track['type']; if ($track['type'] == 0) { - $mime = $track['mime']; - //type is file - if (strtolower($mime) === 'audio/mp3') { - $elementMap['element_mp3'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/ogg') { - $elementMap['element_oga'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/vorbis') { - $elementMap['element_oga'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/mp4') { - $elementMap['element_m4a'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/wav') { - $elementMap['element_wav'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/x-wav') { - $elementMap['element_wav'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/x-flac') { - $elementMap['element_flac'] = $track['item_id']; - } else { + $mime = trim(strtolower($track['mime'])); + try { + $elementMap['element_' . FileDataHelper::getAudioMimeTypeArray()[$mime]] = $track['item_id']; + } catch (Exception $e) { throw new Exception("Unknown file type: $mime"); } @@ -288,22 +275,10 @@ class AudiopreviewController extends Zend_Controller_Action $elementMap['type'] = $track['type']; if ($track['type'] == 0) { - $mime = $track['mime']; - if (strtolower($mime) === 'audio/mp3') { - $elementMap['element_mp3'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/ogg') { - $elementMap['element_oga'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/vorbis') { - $elementMap['element_oga'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/mp4') { - $elementMap['element_m4a'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/wav') { - $elementMap['element_wav'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/x-wav') { - $elementMap['element_wav'] = $track['item_id']; - } elseif (strtolower($mime) === 'audio/x-flac') { - $elementMap['element_flac'] = $track['item_id']; - } else { + $mime = trim(strtolower($track['mime'])); + try { + $elementMap['element_' . FileDataHelper::getAudioMimeTypeArray()[$mime]] = $track['item_id']; + } catch (Exception $e) { throw new Exception("Unknown file type: $mime"); } From e12494ef5f8406cde7dfb6e5583f8da1d957f7c1 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Tue, 7 Jul 2015 15:55:35 -0400 Subject: [PATCH 15/16] Fix show source mount error --- airtime_mvc/application/forms/LiveStreamingPreferences.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/airtime_mvc/application/forms/LiveStreamingPreferences.php b/airtime_mvc/application/forms/LiveStreamingPreferences.php index f22ed0054..6701902f7 100644 --- a/airtime_mvc/application/forms/LiveStreamingPreferences.php +++ b/airtime_mvc/application/forms/LiveStreamingPreferences.php @@ -99,7 +99,7 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm $showSourceMount = new Zend_Form_Element_Text('show_source_mount'); $showSourceMount->setAttrib('readonly', true) ->setLabel(_('Mount:')) - ->setValue(isset($showSourceParams["mount"])?$showSourceParams["mount"]:""); + ->setValue(isset($showSourceParams["path"])?$showSourceParams["path"]:""); $this->addElement($showSourceMount); // demo only code @@ -128,10 +128,10 @@ class Application_Form_LiveStreamingPreferences extends Zend_Form_SubForm 'viewScript' => 'form/preferences_livestream.phtml', 'master_source_host' => isset($masterSourceParams["host"])?$masterSourceParams["host"]:"", 'master_source_port' => isset($masterSourceParams["port"])?$masterSourceParams["port"]:"", - 'master_source_mount' => isset($masterSourceParams["mount"])?$masterSourceParams["mount"]:"", + 'master_source_mount' => isset($masterSourceParams["path"])?$masterSourceParams["path"]:"", 'show_source_host' => isset($showSourceParams["host"])?$showSourceParams["host"]:"", 'show_source_port' => isset($showSourceParams["port"])?$showSourceParams["port"]:"", - 'show_source_mount' => isset($showSourceParams["mount"])?$showSourceParams["mount"]:"", + 'show_source_mount' => isset($showSourceParams["path"])?$showSourceParams["path"]:"", 'isDemo' => $isDemo, ) ) From 3cebbaf29a566158312bf9cf042ace9172e09942 Mon Sep 17 00:00:00 2001 From: Duncan Sommerville Date: Tue, 7 Jul 2015 16:15:35 -0400 Subject: [PATCH 16/16] Add aac mime-types into audio mime map --- airtime_mvc/application/common/FileDataHelper.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/airtime_mvc/application/common/FileDataHelper.php b/airtime_mvc/application/common/FileDataHelper.php index 0aff43523..2c5648f9f 100644 --- a/airtime_mvc/application/common/FileDataHelper.php +++ b/airtime_mvc/application/common/FileDataHelper.php @@ -10,6 +10,8 @@ class FileDataHelper { "audio/mp3" => "mp3", "audio/mpeg" => "mp3", "audio/mpeg3" => "mp3", + "audio/aac" => "aac", + "audio/aacp" => "aac", "audio/mp4" => "mp4", "audio/x-flac" => "flac", "audio/wav" => "wav",