diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index e321f5a9c..e9b278230 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -25,6 +25,7 @@ define('AIRTIME_TRANSIFEX_URL' , 'http://libretime.org/translating/'); define('SUPPORT_TICKET_URL' , 'https://github.com/LibreTime/libretime/issues'); define('UI_REVAMP_EMBED_URL' , 'https://www.youtube.com/embed/nqpNnCKGluY'); define('LIBRETIME_WHATS_NEW_URL' , 'https://github.com/LibreTime/libretime/releases'); +define('LIBRETIME_UPDATE_FEED' , 'https://github.com/LibreTime/libretime/releases.atom'); define('LIBRETIME_EMAIL_FROM' , 'noreply@libretime.org'); define('LICENSE_VERSION' , 'GNU AGPL v.3'); diff --git a/airtime_mvc/application/controllers/LocaleController.php b/airtime_mvc/application/controllers/LocaleController.php index 99ac81f9b..482e3ec35 100644 --- a/airtime_mvc/application/controllers/LocaleController.php +++ b/airtime_mvc/application/controllers/LocaleController.php @@ -39,9 +39,11 @@ class LocaleController extends Zend_Controller_Action //dashboard/versiontooltip.js "You are running the latest version" => _("You are running the latest version"), "New version available: " => _("New version available: "), - "This version will soon be obsolete." => _("This version will soon be obsolete."), - "This version is no longer supported." => _("This version is no longer supported."), - "Please upgrade to " => _("Please upgrade to "), + "You have a pre-release version of LibreTime intalled." => _("You have a pre-release version of LibreTime intalled."), + "A patch update for your LibreTime installation is available." => _("A patch update for your LibreTime installation is available."), + "A feature update for your LibreTime installation is available." => _("A feature update for your LibreTime installation is available."), + "A major update for your LibreTime installation is available." => _("A major update for your LibreTime installation is available."), + "Multiple major updates for LibreTime installation are available. Please upgrade as soon as possible." => _("Multiple major updates for LibreTime installation are available. Please upgrade as soon as possible."), //library/events/library_playlistbuilder.js "Add to current playlist" => _("Add to current playlist"), "Add to current smart block" => _("Add to current smart block"), diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index 00b78ddcd..296915956 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -879,8 +879,27 @@ class Application_Model_Preference public static function GetLatestVersion() { $config = Config::getConfig(); - $latest = self::getValue("latest_version"); - if ($latest == null || strlen($latest) == 0) { + + $latest = json_decode(self::getValue('latest_version')); + $nextCheck = self::getValue('latest_version_nextcheck'); + if ($latest && $nextCheck > time()) { + return $latest; + } + + $rss = new SimplePie(); + $rss->set_feed_url(array(LIBRETIME_UPDATE_FEED)); + $rss->enable_cache(false); + $rss->init(); + $rss->handle_content_type(); + // get all available versions ut to default github api limit + $versions = array(); + foreach ($rss->get_items() as $item) { + $versions[] = $item->get_title(); + } + $latest = $versions; + self::setValue('latest_version', json_encode($latest)); + self::setValue('latest_version_nextcheck', strtotime('+1 week')); + if (empty($latest)) { return $config['airtime_version']; } else { return $latest; @@ -899,7 +918,7 @@ class Application_Model_Preference { $link = self::getValue("latest_link"); if ($link == null || strlen($link) == 0) { - return 'http://airtime.sourcefabric.org'; + return LIBRETIME_WHATS_NEW_URL; } else { return $link; } diff --git a/airtime_mvc/application/views/helpers/VersionNotify.php b/airtime_mvc/application/views/helpers/VersionNotify.php index bc940b31a..7e6c873c2 100644 --- a/airtime_mvc/application/views/helpers/VersionNotify.php +++ b/airtime_mvc/application/views/helpers/VersionNotify.php @@ -1,5 +1,8 @@ =%1$s', $currentParts[0] + 1)); + $minorCandidates = SemVer::satisfiedBy($latest, sprintf('~%1$s.%2$s', $currentParts[0], $currentParts[1] + 1)); + $patchCandidates = SemVer::satisfiedBy($latest, sprintf('>=%1$s.%2$s.%3$s <%1$s.%3$s', $currentParts[0], $currentParts[1], $currentParts[2] + 1, $currentParts[1] + 1)); + $hasMajor = !empty($majorCandidates); + $hasMinor = !empty($minorCandidates); + $hasPatch = !empty($patchCandidates); + $isPreRelease = $isGitRelease || array_key_exists(4, $currentParts); + $hasMultiMajor = count($majorCandidates) > 1; + + if ($isPreRelease) { + // orange "warning" if you are on unreleased code + $class = 'update2'; + } else if ($hasPatch || $hasMultiMajor) { + // current patch or more than 1 major behind + $class = 'outdated'; + } else if ($hasMinor) { + // green warning for feature update + $class = 'update'; + } else if ($hasMajor) { + // orange warning for 1 major beind + $class = 'update2'; + } else { + $class = 'uptodate'; + } + $latest = SemVer::rsort($latest); + $highestVersion = $latest[0]; + + $data = (object) array( + 'link' => $link, + 'latest' => $highestVersion, + 'current' => $current, + 'hasPatch' => $hasPatch, + 'hasMinor' => $hasMinor, + 'hasMajor' => $hasMajor, + 'isPreRelease' => $isPreRelease, + 'hasMultiMajor' => $hasMultiMajor, + ); + + $result = sprintf('', json_encode($data)) + . "
"; + return $result; } } diff --git a/airtime_mvc/public/css/styles.css b/airtime_mvc/public/css/styles.css index 6a587a2d9..ead2b90cf 100644 --- a/airtime_mvc/public/css/styles.css +++ b/airtime_mvc/public/css/styles.css @@ -101,8 +101,8 @@ select { /* Version Notification Starts*/ #version-icon { position:absolute; - right:96px; - top:104px; + top:68px; + right: 196px; height:35px; width:35px; z-index:1000; diff --git a/airtime_mvc/public/js/airtime/dashboard/versiontooltip.js b/airtime_mvc/public/js/airtime/dashboard/versiontooltip.js index 4b6675591..a5e75a37c 100644 --- a/airtime_mvc/public/js/airtime/dashboard/versiontooltip.js +++ b/airtime_mvc/public/js/airtime/dashboard/versiontooltip.js @@ -2,43 +2,91 @@ * Get the tooltip message to be displayed */ function getContent() { - var diff = getVersionDiff(); var link = getLatestLink(); - + var hasPatch = getHasPatch(); + var hasMinor = getHasMinor(); + var hasMajor = getHasMajor(); + var hasMultiMajor = getHasMultiMajor(); + var isPreRelease = getIsPreRelease(); + var msg = ""; // See file airtime_mvc/application/views/helpers/VersionNotify.php for more info if(isUpToDate()) { msg = $.i18n._("You are running the latest version"); - } else if (diff < 20) { - msg = $.i18n._("New version available: ") + link; - } else if (diff < 30) { - msg = $.i18n._("This version will soon be obsolete.")+"
"+$.i18n._("Please upgrade to ") + link; } else { - msg = $.i18n._("This version is no longer supported.")+"
"+$.i18n._("Please upgrade to ") + link; + msg = $.i18n._("New version available: ") + link + ''; } return msg; } /** - * Get major version difference b/w current and latest version, in int + * Get if patch is available */ -function getVersionDiff() { - return parseInt($("#version-diff").html()); +function getHasPatch() { + return versionNotifyInfo.hasPatch; + } +/** + * Get if minor update is available + */ +function getHasMinor() { + return versionNotifyInfo.hasMinor; +} + +/** + * Get if major update is available + */ +function getHasMajor() { + return versionNotifyInfo.hasMajor; +} + +/** + * Get if multiple major updates are available + */ +function getHasMultiMajor() { + return versionNotifyInfo.hasMultiMajor; +} + +/** + * Get if pre-release was installed + */ +function getIsPreRelease() { + return versionNotifyInfo.isPreRelease; +} + + + + /** * Get the current version */ function getCurrentVersion() { - return $("#version-current").html(); + return versionNotifyInfo.current; } /** * Get the latest version */ function getLatestVersion() { - return $("#version-latest").html(); + return versionNotifyInfo.latest; } /** @@ -52,18 +100,14 @@ function getLatestLink() { * Returns true if current version is up to date */ function isUpToDate() { - var diff = getVersionDiff(); - var current = getCurrentVersion(); - var latest = getLatestVersion(); - var temp = (diff == 0 && current == latest) || diff < 0; - return (diff == 0 && current == latest) || diff < 0; + return !getHasPatch() && !getHasMinor() && !getHasMajor(); } /** * Opens the link in a new window */ function openLatestLink() { - window.open($("#version-link").html()); + window.open(versionNotifyInfo.link); } /** @@ -103,4 +147,4 @@ $(document).ready(function() { if($('#version-icon').length > 0) { setupVersionQtip(); } -}); \ No newline at end of file +}); diff --git a/composer.json b/composer.json index 41080c092..97a1bddf2 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "ise/php-soundcloud": "3.0.1", "massivescale/celery-php": "2.0.*@dev", "simplepie/simplepie": "dev-master", - "zendframework/zendframework1": "^1.12" + "zendframework/zendframework1": "^1.12", + "composer/semver": "^1.4" }, "require-dev": { "phpunit/phpunit": "^4.3", diff --git a/composer.lock b/composer.lock index d302bacf1..cc0730007 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "33cfdc655be243bdcabe59ca6f3ca434", + "content-hash": "2770ac91638846655f6d1cfc549df150", "packages": [ { "name": "aws/aws-sdk-php", @@ -73,6 +73,68 @@ ], "time": "2014-12-08T21:56:46+00:00" }, + { + "name": "composer/semver", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2016-08-30T16:08:34+00:00" + }, { "name": "guzzle/guzzle", "version": "v3.9.3", @@ -268,7 +330,7 @@ "queue", "task" ], - "time": "2015-04-17T10:58:54+00:00" + "time": "2015-04-17 10:58:54" }, { "name": "phing/phing", @@ -536,16 +598,22 @@ "source": { "type": "git", "url": "https://github.com/simplepie/simplepie.git", - "reference": "6102a15d768c7d81fe48f7e2f1d8cf9e71e5959f" + "reference": "eb6dd2d578dd62a1eec68b60cdda8c4a38a8de49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplepie/simplepie/zipball/6102a15d768c7d81fe48f7e2f1d8cf9e71e5959f", - "reference": "6102a15d768c7d81fe48f7e2f1d8cf9e71e5959f", + "url": "https://api.github.com/repos/simplepie/simplepie/zipball/eb6dd2d578dd62a1eec68b60cdda8c4a38a8de49", + "reference": "eb6dd2d578dd62a1eec68b60cdda8c4a38a8de49", "shasum": "" }, "require": { - "php": ">=5.2.0" + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4 || ~5" + }, + "suggest": { + "mf2/mf2": "Microformat module that allows for parsing HTML for microformats" }, "type": "library", "autoload": { @@ -582,7 +650,7 @@ "feeds", "rss" ], - "time": "2015-09-02T01:14:05+00:00" + "time": "2017-02-28 01:12:12" }, { "name": "symfony/event-dispatcher",