diff options
author | Chocobozzz <me@florianbigard.com> | 2019-07-16 11:33:22 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-07-24 10:58:16 +0200 |
commit | 6702a1b2ccd666285dee9c72b5bace641d2fce8b (patch) | |
tree | 78b7125d664b6f6b6c993c4e8483e1bdd24a0a30 /server/lib | |
parent | 503c6f440abc8f5924c38c4bd63591cb6cefacec (diff) | |
download | PeerTube-6702a1b2ccd666285dee9c72b5bace641d2fce8b.tar.gz PeerTube-6702a1b2ccd666285dee9c72b5bace641d2fce8b.tar.zst PeerTube-6702a1b2ccd666285dee9c72b5bace641d2fce8b.zip |
Add ability to search available plugins
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/plugins/plugin-index.ts | 64 | ||||
-rw-r--r-- | server/lib/plugins/plugin-manager.ts | 4 | ||||
-rw-r--r-- | server/lib/schedulers/plugins-check-scheduler.ts | 60 |
3 files changed, 128 insertions, 0 deletions
diff --git a/server/lib/plugins/plugin-index.ts b/server/lib/plugins/plugin-index.ts new file mode 100644 index 000000000..4a8a90ec8 --- /dev/null +++ b/server/lib/plugins/plugin-index.ts | |||
@@ -0,0 +1,64 @@ | |||
1 | import { doRequest } from '../../helpers/requests' | ||
2 | import { CONFIG } from '../../initializers/config' | ||
3 | import { | ||
4 | PeertubePluginLatestVersionRequest, | ||
5 | PeertubePluginLatestVersionResponse | ||
6 | } from '../../../shared/models/plugins/peertube-plugin-latest-version.model' | ||
7 | import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model' | ||
8 | import { ResultList } from '../../../shared/models' | ||
9 | import { PeerTubePluginIndex } from '../../../shared/models/plugins/peertube-plugin-index.model' | ||
10 | import { PluginModel } from '../../models/server/plugin' | ||
11 | import { PluginManager } from './plugin-manager' | ||
12 | import { logger } from '../../helpers/logger' | ||
13 | |||
14 | const packageJSON = require('../../../../package.json') | ||
15 | |||
16 | async function listAvailablePluginsFromIndex (options: PeertubePluginIndexList) { | ||
17 | const { start = 0, count = 20, search, sort = 'npmName', pluginType } = options | ||
18 | |||
19 | const qs: PeertubePluginIndexList = { | ||
20 | start, | ||
21 | count, | ||
22 | sort, | ||
23 | pluginType, | ||
24 | search, | ||
25 | currentPeerTubeEngine: packageJSON.version | ||
26 | } | ||
27 | |||
28 | const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins' | ||
29 | |||
30 | const { body } = await doRequest({ uri, qs, json: true }) | ||
31 | |||
32 | logger.debug('Got result from PeerTube index.', { body }) | ||
33 | |||
34 | await addInstanceInformation(body) | ||
35 | |||
36 | return body as ResultList<PeerTubePluginIndex> | ||
37 | } | ||
38 | |||
39 | async function addInstanceInformation (result: ResultList<PeerTubePluginIndex>) { | ||
40 | for (const d of result.data) { | ||
41 | d.installed = PluginManager.Instance.isRegistered(d.npmName) | ||
42 | d.name = PluginModel.normalizePluginName(d.npmName) | ||
43 | } | ||
44 | |||
45 | return result | ||
46 | } | ||
47 | |||
48 | async function getLatestPluginsVersion (npmNames: string[]): Promise<PeertubePluginLatestVersionResponse> { | ||
49 | const bodyRequest: PeertubePluginLatestVersionRequest = { | ||
50 | npmNames, | ||
51 | currentPeerTubeEngine: packageJSON.version | ||
52 | } | ||
53 | |||
54 | const uri = CONFIG.PLUGINS.INDEX.URL + '/api/v1/plugins/latest-version' | ||
55 | |||
56 | const { body } = await doRequest({ uri, body: bodyRequest }) | ||
57 | |||
58 | return body | ||
59 | } | ||
60 | |||
61 | export { | ||
62 | listAvailablePluginsFromIndex, | ||
63 | getLatestPluginsVersion | ||
64 | } | ||
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts index 7576b284c..9e4ec5adf 100644 --- a/server/lib/plugins/plugin-manager.ts +++ b/server/lib/plugins/plugin-manager.ts | |||
@@ -55,6 +55,10 @@ export class PluginManager { | |||
55 | 55 | ||
56 | // ###################### Getters ###################### | 56 | // ###################### Getters ###################### |
57 | 57 | ||
58 | isRegistered (npmName: string) { | ||
59 | return !!this.getRegisteredPluginOrTheme(npmName) | ||
60 | } | ||
61 | |||
58 | getRegisteredPluginOrTheme (npmName: string) { | 62 | getRegisteredPluginOrTheme (npmName: string) { |
59 | return this.registeredPlugins[npmName] | 63 | return this.registeredPlugins[npmName] |
60 | } | 64 | } |
diff --git a/server/lib/schedulers/plugins-check-scheduler.ts b/server/lib/schedulers/plugins-check-scheduler.ts new file mode 100644 index 000000000..9c60dbcd4 --- /dev/null +++ b/server/lib/schedulers/plugins-check-scheduler.ts | |||
@@ -0,0 +1,60 @@ | |||
1 | import { logger } from '../../helpers/logger' | ||
2 | import { AbstractScheduler } from './abstract-scheduler' | ||
3 | import { retryTransactionWrapper } from '../../helpers/database-utils' | ||
4 | import { SCHEDULER_INTERVALS_MS } from '../../initializers/constants' | ||
5 | import { CONFIG } from '../../initializers/config' | ||
6 | import { PluginModel } from '../../models/server/plugin' | ||
7 | import { chunk } from 'lodash' | ||
8 | import { getLatestPluginsVersion } from '../plugins/plugin-index' | ||
9 | import { compareSemVer } from '../../../shared/core-utils/miscs/miscs' | ||
10 | |||
11 | export class PluginsCheckScheduler extends AbstractScheduler { | ||
12 | |||
13 | private static instance: AbstractScheduler | ||
14 | |||
15 | protected schedulerIntervalMs = SCHEDULER_INTERVALS_MS.checkPlugins | ||
16 | |||
17 | private constructor () { | ||
18 | super() | ||
19 | } | ||
20 | |||
21 | protected async internalExecute () { | ||
22 | return retryTransactionWrapper(this.checkLatestPluginsVersion.bind(this)) | ||
23 | } | ||
24 | |||
25 | private async checkLatestPluginsVersion () { | ||
26 | if (CONFIG.PLUGINS.INDEX.ENABLED === false) return | ||
27 | |||
28 | logger.info('Checkin latest plugins version.') | ||
29 | |||
30 | const plugins = await PluginModel.listInstalled() | ||
31 | |||
32 | // Process 10 plugins in 1 HTTP request | ||
33 | const chunks = chunk(plugins, 10) | ||
34 | for (const chunk of chunks) { | ||
35 | // Find plugins according to their npm name | ||
36 | const pluginIndex: { [npmName: string]: PluginModel} = {} | ||
37 | for (const plugin of chunk) { | ||
38 | pluginIndex[PluginModel.buildNpmName(plugin.name, plugin.type)] = plugin | ||
39 | } | ||
40 | |||
41 | const npmNames = Object.keys(pluginIndex) | ||
42 | const results = await getLatestPluginsVersion(npmNames) | ||
43 | |||
44 | for (const result of results) { | ||
45 | const plugin = pluginIndex[result.npmName] | ||
46 | if (!result.latestVersion) continue | ||
47 | |||
48 | if (plugin.latestVersion !== result.latestVersion && compareSemVer(plugin.latestVersion, result.latestVersion) < 0) { | ||
49 | plugin.latestVersion = result.latestVersion | ||
50 | await plugin.save() | ||
51 | } | ||
52 | } | ||
53 | } | ||
54 | |||
55 | } | ||
56 | |||
57 | static get Instance () { | ||
58 | return this.instance || (this.instance = new this()) | ||
59 | } | ||
60 | } | ||