feat: show top 5 trending plugins in new tab in Extend > Plugins

v1.18.x
Julian Lam 5 years ago
parent 07af621381
commit b12e8d6312

@ -1,4 +1,5 @@
{
"trending": "Trending",
"installed": "Installed",
"active": "Active",
"inactive": "Inactive",

@ -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'),
});

@ -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 = {};

@ -1,21 +1,37 @@
<ul class="nav nav-pills">
<li class="active"><a href="#installed" data-toggle="tab">
[[admin/extend/plugins:installed]]
<span class="badge">{installedCount}</span>
</a></li>
<li><a href="#active" data-toggle="tab">
[[admin/extend/plugins:active]]
<span class="badge">{activeCount}</span>
</a></li>
<li><a href="#deactive" data-toggle="tab">
[[admin/extend/plugins:inactive]]
<span class="badge">{inactiveCount}</span>
</a></li>
<li><a href="#upgrade" data-toggle="tab">
[[admin/extend/plugins:out-of-date]]
<span class="badge">{upgradeCount}</span>
</a></li>
<li><a href="#download" data-toggle="tab">[[admin/extend/plugins:find-plugins]]</a></li>
<li>
<a href="#trending" data-toggle="tab">
[[admin/extend/plugins:trending]]
<i class="fa fa-star"></i>
</a>
</li>
<li class="active">
<a href="#installed" data-toggle="tab">
[[admin/extend/plugins:installed]]
<span class="badge">{installedCount}</span>
</a>
</li>
<li>
<a href="#active" data-toggle="tab">
[[admin/extend/plugins:active]]
<span class="badge">{activeCount}</span>
</a>
</li>
<li>
<a href="#deactive" data-toggle="tab">
[[admin/extend/plugins:inactive]]
<span class="badge">{inactiveCount}</span>
</a>
</li>
<li>
<a href="#upgrade" data-toggle="tab">
[[admin/extend/plugins:out-of-date]]
<span class="badge">{upgradeCount}</span>
</a>
</li>
<li>
<a href="#download" data-toggle="tab">[[admin/extend/plugins:find-plugins]]</a>
</li>
</ul>
<br />
@ -58,6 +74,13 @@
<div class="col-lg-9 col-lg-pull-3">
<div class="tab-content">
<div class="tab-pane fade" id="trending">
<ul class="trending">
{{{ each trending }}}
<!-- IMPORT admin/partials/installed_plugin_item.tpl -->
{{{ end }}}
</ul>
</div>
<div class="tab-pane fade active in" id="installed">
<ul class="installed">
<!-- BEGIN installed -->

@ -1,25 +1,25 @@
<li id="{download.id}" data-plugin-id="{download.id}" class="clearfix">
<li id="{../id}" data-plugin-id="{../id}" class="clearfix">
<div class="pull-right">
<button data-action="toggleActive" class="btn btn-success hidden"><i class="fa fa-power-off"></i> [[admin/extend/plugins:plugin-item.activate]]</button>
<button data-action="toggleInstall" data-installed="0" class="btn btn-success"><i class="fa fa-download"></i> [[admin/extend/plugins:plugin-item.install]]</button>
</div>
<h2><strong>{download.name}</strong></h2>
<h2><strong>{../name}</strong></h2>
<!-- IF download.description -->
<p>{download.description}</p>
<!-- ENDIF download.description -->
<!-- IF ../description -->
<p>{../description}</p>
<!-- ENDIF ../description -->
<small>[[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{download.latest}</strong></small>
<small>[[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{../latest}</strong></small>
<p>
<!-- IF download.isCompatible -->
<!-- IF ../isCompatible -->
<i class="fa fa-check text-success"></i> [[admin/extend/plugins:plugin-item.compatible, {version}]]
<!-- ELSE -->
<i class="fa fa-question text-warning"></i> [[admin/extend/plugins:plugin-item.not-compatible]]
<!-- ENDIF -->
</p>
<!-- IF download.url -->
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{download.url}">{download.url}</a></p>
<!-- ENDIF download.url -->
<!-- IF ../url -->
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{../url}">{../url}</a></p>
<!-- ENDIF ../url -->
</li>

@ -1,56 +1,60 @@
<!-- IF !installed.error -->
<li id="{installed.id}" data-plugin-index="@index" data-plugin-id="{installed.id}" data-version="{installed.version}" class="clearfix <!-- IF installed.active -->active<!-- ENDIF installed.active -->">
<!-- IF !../error -->
<li id="{../id}" data-plugin-index="@index" data-plugin-id="{../id}" data-version="{../version}" class="clearfix <!-- IF ../active -->active<!-- ENDIF ../active -->">
<div class="pull-right controls">
<!-- IF installed.isTheme -->
<a href="{config.relative_path}/admin/appearance/themes" class="btn btn-info">[[admin/extend/plugins:plugin-item.themes]]</a>
<!-- ELSE -->
<button data-action="toggleActive" class="btn <!-- IF installed.active --> btn-warning<!-- ELSE --> btn-success<!-- ENDIF installed.active -->">
<i class="fa fa-power-off"></i> <!-- IF installed.active -->[[admin/extend/plugins:plugin-item.deactivate]]<!-- ELSE -->[[admin/extend/plugins:plugin-item.activate]]<!-- ENDIF installed.active --></button>
<!-- ENDIF installed.isTheme -->
{{{ if ../installed }}}
<!-- IF ../isTheme -->
<a href="{config.relative_path}/admin/appearance/themes" class="btn btn-info">[[admin/extend/plugins:plugin-item.themes]]</a>
<!-- ELSE -->
<button data-action="toggleActive" class="btn <!-- IF ../active --> btn-warning<!-- ELSE --> btn-success<!-- ENDIF ../active -->">
<i class="fa fa-power-off"></i> <!-- IF ../active -->[[admin/extend/plugins:plugin-item.deactivate]]<!-- ELSE -->[[admin/extend/plugins:plugin-item.activate]]<!-- ENDIF ../active --></button>
<!-- ENDIF ../isTheme -->
<button data-action="toggleInstall" data-installed="1" class="btn btn-danger"><i class="fa fa-trash-o"></i> [[admin/extend/plugins:plugin-item.uninstall]]</button>
<button data-action="toggleInstall" data-installed="1" class="btn btn-danger"><i class="fa fa-trash-o"></i> [[admin/extend/plugins:plugin-item.uninstall]]</button>
<!-- IF installed.active -->
<!-- IF installed.settingsRoute -->
<a href="{config.relative_path}{installed.settingsRoute}" class="btn btn-primary"><i class="fa fa-wrench"></i> [[admin/extend/plugins:plugin-item.settings]]</a>
<!-- ENDIF installed.settingsRoute -->
<!-- ENDIF installed.active -->
<!-- IF ../active -->
<!-- IF ../settingsRoute -->
<a href="{config.relative_path}{../settingsRoute}" class="btn btn-primary"><i class="fa fa-wrench"></i> [[admin/extend/plugins:plugin-item.settings]]</a>
<!-- ENDIF ../settingsRoute -->
<!-- ENDIF ../active -->
{{{ else }}}
<button data-action="toggleInstall" data-installed="0" class="btn btn-success"><i class="fa fa-download"></i> [[admin/extend/plugins:plugin-item.install]]</button>
{{{ end }}}
</div>
<h2><strong>{installed.name}</strong></h2>
<h2><strong>{../name}</strong></h2>
<!-- IF installed.description -->
<p>{installed.description}</p>
<!-- ENDIF installed.description -->
<!-- IF installed.outdated --><i class="fa fa-exclamation-triangle text-danger"></i> <!-- ENDIF installed.outdated -->
<small>[[admin/extend/plugins:plugin-item.installed]] <strong class="currentVersion">{installed.version}</strong> | [[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{installed.latest}</strong></small>
<!-- IF ../description -->
<p>{../description}</p>
<!-- ENDIF ../description -->
<!-- IF ../outdated --><i class="fa fa-exclamation-triangle text-danger"></i> <!-- ENDIF ../outdated -->
<small>[[admin/extend/plugins:plugin-item.installed]] <strong class="currentVersion">{../version}</strong> | [[admin/extend/plugins:plugin-item.latest]] <strong class="latestVersion">{../latest}</strong></small>
<!-- IF installed.outdated -->
<!-- IF ../outdated -->
<button data-action="upgrade" class="btn btn-success btn-xs"><i class="fa fa-download"></i> [[admin/extend/plugins:plugin-item.upgrade]]</button>
<p>
<!-- IF installed.isCompatible -->
<!-- IF ../isCompatible -->
<i class="fa fa-check text-success"></i> [[admin/extend/plugins:plugin-item.compatible, {version}]]
<!-- ELSE -->
<i class="fa fa-question text-warning"></i> [[admin/extend/plugins:plugin-item.not-compatible]]
<!-- ENDIF -->
</p>
<!-- ENDIF installed.outdated -->
<!-- ENDIF ../outdated -->
<!-- IF installed.url -->
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{installed.url}">{installed.url}</a></p>
<!-- ENDIF installed.url -->
<!-- IF ../url -->
<p>[[admin/extend/plugins:plugin-item.more-info]] <a target="_blank" href="{../url}">{../url}</a></p>
<!-- ENDIF ../url -->
</li>
<!-- ENDIF !installed.error -->
<!-- IF installed.error -->
<li data-plugin-id="{installed.id}" class="clearfix">
<!-- ENDIF !../error -->
<!-- IF ../error -->
<li data-plugin-id="{../id}" class="clearfix">
<div class="pull-right">
<button class="btn btn-default disabled"><i class="fa fa-exclamation-triangle"></i> [[admin/extend/plugins:plugin-item.unknown]]</button>
<button data-action="toggleInstall" data-installed="1" class="btn btn-danger"><i class="fa fa-trash-o"></i> [[admin/extend/plugins:plugin-item.uninstall]]</button>
</div>
<h2><strong>{installed.id}</strong></h2>
<h2><strong>{../id}</strong></h2>
<p>
[[admin/extend/plugins:plugin-item.unknown-explanation]]
</p>
</li>
<!-- ENDIF installed.error -->
<!-- ENDIF ../error -->

Loading…
Cancel
Save