From c940a21ea65df641611d2bd94d1cc15bb03954f3 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Thu, 18 Aug 2016 14:11:06 -0400 Subject: [PATCH] roadmap v1 --- controller/Controller.class.php | 4 +- controller/action/ContentActions.class.php | 8 +- controller/action/DownloadActions.class.php | 84 ++----------------- {data => lib}/cache/Apc.class.php | 0 lib/tools/Curl.class.php | 2 +- lib/tools/Os.class.php | 29 +++++++ lib/{mailchimp => vendor}/MCAPI.class.php | 0 model/CreditApi.class.php | 34 -------- {data => model}/api/Asana.class.php | 33 +++++--- model/api/Github.class.php | 71 ++++++++++++++++ .../api}/Mailchimp.class.php | 0 {data => model}/api/Prefinery.class.php | 0 view/template/content/roadmap.php | 82 ++++++++++++++---- view/template/download/_unavailable.php | 4 +- web/scss/_badge.scss | 4 + web/scss/_blog.scss | 4 + web/scss/_global.scss | 1 + 17 files changed, 213 insertions(+), 147 deletions(-) rename {data => lib}/cache/Apc.class.php (100%) create mode 100644 lib/tools/Os.class.php rename lib/{mailchimp => vendor}/MCAPI.class.php (100%) delete mode 100644 model/CreditApi.class.php rename {data => model}/api/Asana.class.php (75%) create mode 100644 model/api/Github.class.php rename {lib/mailchimp => model/api}/Mailchimp.class.php (100%) rename {data => model}/api/Prefinery.class.php (100%) diff --git a/controller/Controller.class.php b/controller/Controller.class.php index f569b908..efb61068 100644 --- a/controller/Controller.class.php +++ b/controller/Controller.class.php @@ -86,9 +86,9 @@ class Controller case '/dl/lbry_setup.sh': return static::redirect('/get', 301); case '/get/lbry.dmg': - return static::redirect(DownloadActions::getDownloadUrl(DownloadActions::OS_OSX) ?: '/get'); + return static::redirect(Github::getDownloadUrl(Os::OS_OSX) ?: '/get'); case '/get/lbry.deb': - return static::redirect(DownloadActions::getDownloadUrl(DownloadActions::OS_LINUX) ?: '/get'); + return static::redirect(Github::getDownloadUrl(Os::OS_LINUX) ?: '/get'); case '/art': return static::redirect('/what', 301); case '/why': diff --git a/controller/action/ContentActions.class.php b/controller/action/ContentActions.class.php index 972d5705..bcc9f0cc 100644 --- a/controller/action/ContentActions.class.php +++ b/controller/action/ContentActions.class.php @@ -15,10 +15,7 @@ class ContentActions extends Actions public static function executeHome() { - return ['page/home', [ - 'totalUSD' => CreditApi::getTotalDollarSales(), - 'totalPeople' => CreditApi::getTotalPeople() - ]]; + return ['page/home']; } public static function executeFaq() @@ -114,7 +111,8 @@ class ContentActions extends Actions public static function executeRoadmap() { return ['content/roadmap', [ - 'tasks' => Asana::listRoadmapTasks() + 'tasks' => Asana::listRoadmapTasks(), + 'changesets' => Github::listRoadmapChangesets() ]]; } diff --git a/controller/action/DownloadActions.class.php b/controller/action/DownloadActions.class.php index 33be7180..b7120d20 100644 --- a/controller/action/DownloadActions.class.php +++ b/controller/action/DownloadActions.class.php @@ -2,23 +2,6 @@ class DownloadActions extends Actions { - const OS_ANDROID = 'android', - OS_IOS = 'ios', - OS_LINUX = 'linux', - OS_OSX = 'osx', - OS_WINDOWS = 'windows'; - - public static function getOses() - { - return [ - static::OS_WINDOWS => ['/windows', 'Windows', 'icon-windows', '_windows'], - static::OS_OSX => ['/osx', 'OS X', 'icon-apple', '_osx'], - static::OS_LINUX => ['/linux', 'Linux', 'icon-linux', '_linux'], - static::OS_ANDROID => ['/android', 'Android', 'icon-android', '_android'], - static::OS_IOS => ['/ios', 'iOS', 'icon-mobile', '_ios'] - ]; - } - public static function executeGet() { $email = static::param('e'); @@ -52,7 +35,7 @@ class DownloadActions extends Actions return ['download/get', ['os' => static::guessOs()]]; } - $osChoices = static::getOses(); + $osChoices = Os::getAll(); $os = static::guessOs(); if ($os && isset($osChoices[$os])) @@ -64,7 +47,7 @@ class DownloadActions extends Actions 'osIcon' => $osIcon, 'prefineryUser' => $user ?: [], 'downloadHtml' => View::exists('download/' . $partial) ? - View::render('download/' . $partial, ['downloadUrl' => static::getDownloadUrl($os)]) : + View::render('download/' . $partial, ['downloadUrl' => Github::getDownloadUrl($os)]) : false ]]; } @@ -123,8 +106,8 @@ class DownloadActions extends Actions public static function prepareListPartial(array $vars) { return $vars + ['osChoices' => isset($vars['excludeOs']) ? - array_diff_key(static::getOses(), [$vars['excludeOs'] => null]) : - static::getOses() + array_diff_key(Os::getAll(), [$vars['excludeOs'] => null]) : + Os::getAll() ]; } @@ -165,7 +148,7 @@ class DownloadActions extends Actions { //if exact OS is requested, use that $uri = strtok($_SERVER['REQUEST_URI'], '?'); - foreach (static::getOses() as $os => $osChoice) + foreach (Os::getAll() as $os => $osChoice) { if ($osChoice[0] == $uri) { @@ -182,67 +165,16 @@ class DownloadActions extends Actions $ua = $_SERVER['HTTP_USER_AGENT']; if (stripos($ua, 'OS X') !== false) { - return strpos($ua, 'iPhone') !== false || stripos($ua, 'iPad') !== false ? static::OS_IOS : static::OS_OSX; + return strpos($ua, 'iPhone') !== false || stripos($ua, 'iPad') !== false ? Os::OS_IOS : Os::OS_OSX; } if (stripos($ua, 'Linux') !== false || strpos($ua, 'X11') !== false) { - return strpos($ua, 'Android') !== false ? static::OS_ANDROID : static::OS_LINUX; + return strpos($ua, 'Android') !== false ? Os::OS_ANDROID : Os::OS_LINUX; } if (stripos($ua, 'Windows') !== false) { - return static::OS_WINDOWS; + return Os::OS_WINDOWS; } return null; } - - public static function getDownloadUrl($os, $useCache = true) - { - if (!in_array($os, array_keys(static::getOses()))) - { - throw new DomainException('Unknown OS'); - } - - $apc = $useCache && extension_loaded('apc') && ini_get('apc.enabled'); - $key = 'lbry_release_data2'; - $releaseData = null; - - if ($apc) - { - $releaseData = apc_fetch($key); - } - - if (!$releaseData) - { - try - { - $releaseData = - json_decode(Curl::get('https://api.github.com/repos/lbryio/lbry/releases/latest', [], ['user_agent' => 'LBRY']), true); - if ($apc) - { - apc_store($key, $releaseData, 600); // cache for 10 min - } - } - catch (Exception $e) - { - } - } - - if (!$releaseData) - { - return null; - } - - foreach ($releaseData['assets'] as $asset) - { - if ( - ($os == static::OS_LINUX && in_array($asset['content_type'], ['application/x-debian-package', 'application/x-deb'])) || - ($os == static::OS_OSX && in_array($asset['content_type'], ['application/x-diskcopy', 'application/x-apple-diskimage'])) - ) - { - return $asset['browser_download_url']; - } - } - - return null; - } } diff --git a/data/cache/Apc.class.php b/lib/cache/Apc.class.php similarity index 100% rename from data/cache/Apc.class.php rename to lib/cache/Apc.class.php diff --git a/lib/tools/Curl.class.php b/lib/tools/Curl.class.php index 25676ad6..30b496c3 100644 --- a/lib/tools/Curl.class.php +++ b/lib/tools/Curl.class.php @@ -31,7 +31,7 @@ class Curl 'cache' => false, 'headers' => [], 'verify' => true, - 'timeout' => 5, + 'timeout' => 10, //5 was timing out on /roadmap for Asana API 'follow_redirects' => true, 'user_agent' => null, 'proxy' => null, diff --git a/lib/tools/Os.class.php b/lib/tools/Os.class.php new file mode 100644 index 00000000..22e9d81c --- /dev/null +++ b/lib/tools/Os.class.php @@ -0,0 +1,29 @@ + ['/windows', 'Windows', 'icon-windows', '_windows'], + Os::OS_OSX => ['/osx', 'OS X', 'icon-apple', '_osx'], + Os::OS_LINUX => ['/linux', 'Linux', 'icon-linux', '_linux'], + Os::OS_ANDROID => ['/android', 'Android', 'icon-android', '_android'], + Os::OS_IOS => ['/ios', 'iOS', 'icon-mobile', '_ios'] + ]; + } +} \ No newline at end of file diff --git a/lib/mailchimp/MCAPI.class.php b/lib/vendor/MCAPI.class.php similarity index 100% rename from lib/mailchimp/MCAPI.class.php rename to lib/vendor/MCAPI.class.php diff --git a/model/CreditApi.class.php b/model/CreditApi.class.php deleted file mode 100644 index b9f43994..00000000 --- a/model/CreditApi.class.php +++ /dev/null @@ -1,34 +0,0 @@ - 'LBRY Browser', - 158602294500137 => 'LBRYnet', - 161514803479899 => 'Blockchain and Wallets', - 158829550589337 => 'Reporting and Analytics', - 136290697597644 => 'Integration and Building', - 158602294500249 => 'Documentation', - 158602294500214 => 'Other' + 158602294500138 => ['LBRY Browser', 'https://github.com/lbryio/lbry-web-ui'], + 158602294500137 => ['LBRYnet', 'https://github.com/lbryio/lbry'], + 161514803479899 => ['Blockchain and Wallets', 'https://github.com/lbryio/lbrycrd'], + 158829550589337 => ['Reporting and Analytics', null], + 136290697597644 => ['Integration and Building', null], + 158602294500249 => ['Documentation', null], + 158602294500214 => ['Other', null] ]; $tasks = [ @@ -68,8 +68,9 @@ class Asana ]; $categories = array_keys($tasks); - foreach($projects as $projectId => $projectName) + foreach($projects as $projectId => $projectTuple) { + list($projectName, $projectUrl) = $projectTuple; $projectTasks = static::get('/tasks?' . http_build_query(['completed_since' => 'now', 'project' => $projectId])); $key = null; foreach ($projectTasks as $task) @@ -85,20 +86,30 @@ class Asana $fullTask = static::get('/tasks/' . $task['id']); $tasks[$key][] = array_intersect_key($fullTask, ['name' => null, 'due_on' => null]) + [ 'project' => $projectName, + 'url' => $projectUrl, 'assignee' => $fullTask['assignee'] ? ucwords($fullTask['assignee']['name']) : '' ]; } } } + foreach($tasks as &$taskSet) + { + usort($taskSet, function($tA, $tB) { + if ($tA['due_on'] xor $tB['due_on']) + { + return $tA['due_on'] ? -1 : 1; + } + return $tA['due_on'] < $tB['due_on'] ? -1 : 1; + }); + } + return $tasks; } protected static function get($endpoint, array $data = []) { - $apiKey = '0/c85cfce3591c2a3e214408cfba7cc44c'; -// $apiKey = Config::get('prefinery_key'); -// curl -H "Authorization: Bearer ACCESS_TOKEN" https://app.asana.com/api/1.0/users/me + $apiKey = Config::get('asana_key'); $options = static::$curlOptions + [ 'headers' => ['Authorization: Bearer ' . $apiKey] diff --git a/model/api/Github.class.php b/model/api/Github.class.php new file mode 100644 index 00000000..7398f354 --- /dev/null +++ b/model/api/Github.class.php @@ -0,0 +1,71 @@ + 'LBRY', 'json_response' => true, 'cache' => false]); + } + + public static function listRoadmapChangesets() + { + $sets = []; + + $page = 1; + $allReleases = []; + + do + { + $releases = static::get('/repos/lbryio/lbry/releases?page=' . $page); + $page++; + $allReleases = array_merge($allReleases, $releases); + } while (count($releases) >= 30); + + usort($allReleases, function($rA, $rB) { + if ($rA['prerelease'] xor $rB['prerelease']) + { + return $rA['prerelease'] ? -1 : 1; + } + return $rA['tag_name'] < $rB['tag_name']; + }); + + foreach($allReleases as $release) + { +// static::get('/repos/lbryio/lbry/releases') + $sets[$release['tag_name']] = array_intersect_key($release, ['prerelease' => null]) + [ + 'published_at' => date('Y-m-d', strtotime($release['published_at'])), + 'body' => ParsedownExtra::instance()->text($release['body']) + ]; + } + + return $sets; + } +} \ No newline at end of file diff --git a/lib/mailchimp/Mailchimp.class.php b/model/api/Mailchimp.class.php similarity index 100% rename from lib/mailchimp/Mailchimp.class.php rename to model/api/Mailchimp.class.php diff --git a/data/api/Prefinery.class.php b/model/api/Prefinery.class.php similarity index 100% rename from data/api/Prefinery.class.php rename to model/api/Prefinery.class.php diff --git a/view/template/content/roadmap.php b/view/template/content/roadmap.php index df15aaf8..8803ce9f 100644 --- a/view/template/content/roadmap.php +++ b/view/template/content/roadmap.php @@ -3,27 +3,77 @@ false]) ?>
-
+

{{roadmap.title}}

-
- The LBRY roadmap pulls in information dynamically from our internal project management system and public - GitHub page. +
+ Recent, ongoing and upcoming changes to LBRY.
-

Scheduled Changes

- $categoryTasks): ?> -
-

- - - - - - - +
+

Recent Changes

+
+ + + + + + + $changeset): ?> + 5 ? 'style="display: none"' : '' ?>> + + + + + + + + + + +
ReleaseDateNotes
+ + + prerelease + +
v0.1-v0.2.2These releases were not tagged and noted properly. We were too busy creating awesome!
+ show all changes + + $('#show-all-changesets').click(function() { + $(this).hide(); + $('#changeset-table').find('tr').show(); + }); + +
+ $categoryTasks): ?> +
+

Changes

+ + + + + + + + + + + + + + +
ItemDateComponentOwner
+ + + + + + + unassigned' ?> +
-
\ No newline at end of file + + \ No newline at end of file diff --git a/view/template/download/_unavailable.php b/view/template/download/_unavailable.php index 58ca2427..07bbf829 100644 --- a/view/template/download/_unavailable.php +++ b/view/template/download/_unavailable.php @@ -1,8 +1,8 @@

{{download.unavailable}}

- +

{{download.osx}}

- +

{{download.windows}}

\ No newline at end of file diff --git a/web/scss/_badge.scss b/web/scss/_badge.scss index fd6059c8..197e8d76 100644 --- a/web/scss/_badge.scss +++ b/web/scss/_badge.scss @@ -18,4 +18,8 @@ $badge-height: $spacing-vertical * 3/4; { background-color: $color-primary; } + &.badge-info + { + background-color: $color-info-bg; + } } \ No newline at end of file diff --git a/web/scss/_blog.scss b/web/scss/_blog.scss index 943f0702..5b59db02 100644 --- a/web/scss/_blog.scss +++ b/web/scss/_blog.scss @@ -138,6 +138,10 @@ vertical-align: text-bottom; } } + td.center + { + vertical-align: middle; + } tr.thead:not(:first-child) th { border-top: 1px solid #e2e2e2; diff --git a/web/scss/_global.scss b/web/scss/_global.scss index a49ec16f..53fe73ab 100644 --- a/web/scss/_global.scss +++ b/web/scss/_global.scss @@ -7,6 +7,7 @@ $color-light-alt: hsl(hue($color-primary), 15, 85); $color-text-dark: #000; $color-money: #216C2A; $color-meta-light: #505050; +$color-info-bg: #3a779d; $font-size: 16px;