diff --git a/public/language/en-GB/admin/extend/plugins.json b/public/language/en-GB/admin/extend/plugins.json index 8532b43f8b..009cc11779 100644 --- a/public/language/en-GB/admin/extend/plugins.json +++ b/public/language/en-GB/admin/extend/plugins.json @@ -1,4 +1,5 @@ { + "trending": "Trending", "installed": "Installed", "active": "Active", "inactive": "Inactive", diff --git a/src/controllers/admin/plugins.js b/src/controllers/admin/plugins.js index 3bf5ce047d..464a844a5a 100644 --- a/src/controllers/admin/plugins.js +++ b/src/controllers/admin/plugins.js @@ -8,15 +8,25 @@ const meta = require('../../meta'); const pluginsController = module.exports; pluginsController.get = async function (req, res) { - const [compatible, all] = await Promise.all([ + const [compatible, all, trending] = await Promise.all([ getCompatiblePlugins(), getAllPlugins(), + plugins.listTrending(), ]); const compatiblePkgNames = compatible.map(pkgData => pkgData.name); const installedPlugins = compatible.filter(plugin => plugin && plugin.installed); const activePlugins = all.filter(plugin => plugin && plugin.installed && plugin.active); + const trendingScores = trending.reduce((memo, cur) => { + memo[cur.label] = cur.value; + return memo; + }, {}); + const trendingPlugins = all.filter(plugin => plugin && Object.keys(trendingScores).includes(plugin.id)).sort((a, b) => trendingScores[b.id] - trendingScores[a.id]).map((plugin) => { + plugin.downloads = trendingScores[plugin.id]; + return plugin; + }); + res.render('admin/extend/plugins', { installed: installedPlugins, installedCount: installedPlugins.length, @@ -34,6 +44,7 @@ pluginsController.get = async function (req, res) { incompatible: all.filter(function (plugin) { return !compatiblePkgNames.includes(plugin.name); }), + trending: trendingPlugins, submitPluginUsage: meta.config.submitPluginUsage, version: nconf.get('version'), }); diff --git a/src/plugins/index.js b/src/plugins/index.js index 0fe7c3b0e5..4d7824b9b1 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -6,7 +6,7 @@ const async = require('async'); const winston = require('winston'); const semver = require('semver'); const nconf = require('nconf'); -const util = require('util'); +const request = require('request-promise-native'); const user = require('../user'); const posts = require('../posts'); @@ -141,24 +141,11 @@ Plugins.reloadRoutes = async function (params) { winston.verbose('[plugins] All plugins reloaded and rerouted'); }; -function request(url, callback) { - require('request')(url, { - json: true, - }, function (err, res, body) { - if (err) { - return callback(err); - } - if (res.statusCode === 404 || !body) { - return callback(null, {}); - } - callback(null, body); - }); -} -const requestAsync = util.promisify(request); - Plugins.get = async function (id) { const url = (nconf.get('registry') || 'https://packages.nodebb.org') + '/api/v1/plugins/' + id; - const body = await requestAsync(url); + const body = await request(url, { + json: true, + }); let normalised = await Plugins.normalise([body ? body.payload : {}]); normalised = normalised.filter(plugin => plugin.id === id); @@ -172,7 +159,9 @@ Plugins.list = async function (matching) { const version = require(path.join(nconf.get('base_dir'), 'package.json')).version; const url = (nconf.get('registry') || 'https://packages.nodebb.org') + '/api/v1/plugins' + (matching !== false ? '?version=' + version : ''); try { - const body = await requestAsync(url); + const body = await request(url, { + json: true, + }); return await Plugins.normalise(body); } catch (err) { winston.error('Error loading ' + url, err); @@ -180,6 +169,13 @@ Plugins.list = async function (matching) { } }; +Plugins.listTrending = async () => { + const url = `${nconf.get('registry') || 'https://packages.nodebb.org'}/api/v1/analytics/top/week`; + return await request(url, { + json: true, + }); +}; + Plugins.normalise = async function (apiReturn) { const themeNamePattern = /^(@.*?\/)?nodebb-theme-.*$/; const pluginMap = {}; diff --git a/src/views/admin/extend/plugins.tpl b/src/views/admin/extend/plugins.tpl index d1df022dd8..12eb193396 100644 --- a/src/views/admin/extend/plugins.tpl +++ b/src/views/admin/extend/plugins.tpl @@ -1,21 +1,37 @@
@@ -58,6 +74,13 @@
+
    diff --git a/src/views/admin/partials/download_plugin_item.tpl b/src/views/admin/partials/download_plugin_item.tpl index 4247b2c445..23e6baaea3 100644 --- a/src/views/admin/partials/download_plugin_item.tpl +++ b/src/views/admin/partials/download_plugin_item.tpl @@ -1,25 +1,25 @@ -
  • +
  • -

    {download.name}

    +

    {../name}

    - -

    {download.description}

    - + +

    {../description}

    + - [[admin/extend/plugins:plugin-item.latest]] {download.latest} + [[admin/extend/plugins:plugin-item.latest]] {../latest}

    - + [[admin/extend/plugins:plugin-item.compatible, {version}]] [[admin/extend/plugins:plugin-item.not-compatible]]

    - -

    [[admin/extend/plugins:plugin-item.more-info]] {download.url}

    - + +

    [[admin/extend/plugins:plugin-item.more-info]] {../url}

    +
  • diff --git a/src/views/admin/partials/installed_plugin_item.tpl b/src/views/admin/partials/installed_plugin_item.tpl index dec83e3ea7..d0855aa8b3 100644 --- a/src/views/admin/partials/installed_plugin_item.tpl +++ b/src/views/admin/partials/installed_plugin_item.tpl @@ -1,56 +1,60 @@ - -
  • + +
  • - - [[admin/extend/plugins:plugin-item.themes]] - - - + {{{ if ../installed }}} + + [[admin/extend/plugins:plugin-item.themes]] + + + - + - - - [[admin/extend/plugins:plugin-item.settings]] - - + + + [[admin/extend/plugins:plugin-item.settings]] + + + {{{ else }}} + + {{{ end }}}
    -

    {installed.name}

    +

    {../name}

    - -

    {installed.description}

    - - - [[admin/extend/plugins:plugin-item.installed]] {installed.version} | [[admin/extend/plugins:plugin-item.latest]] {installed.latest} + +

    {../description}

    + + + [[admin/extend/plugins:plugin-item.installed]] {../version} | [[admin/extend/plugins:plugin-item.latest]] {../latest} - +

    - + [[admin/extend/plugins:plugin-item.compatible, {version}]] [[admin/extend/plugins:plugin-item.not-compatible]]

    - + - -

    [[admin/extend/plugins:plugin-item.more-info]] {installed.url}

    - + +

    [[admin/extend/plugins:plugin-item.more-info]] {../url}

    +
  • - - -
  • + + +
  • -

    {installed.id}

    +

    {../id}

    [[admin/extend/plugins:plugin-item.unknown-explanation]]

  • - +