@samitouri / QOSami-HFS / commits / 831ab246

automatic stop blacklisted plugins

Massimo Melina committed Oct 16, 2024 at 23:09 UTC 831ab2468554f4716898740dc05ab0de1f0a619b
1 file changed +16 -7
src/github.ts
+16 -7
@@ -3,7 +3,7 @@
3 import events from './events'
4 import { DAY, httpString, httpStream, unzip, AsapStream, debounceAsync, asyncGeneratorToArray, wait, popKey } from './misc'
5 import {
6 - DISABLING_SUFFIX, findPluginByRepo, getAvailablePlugins, getPluginInfo, isPluginEnabled, mapPlugins,
6 + DISABLING_SUFFIX, enablePlugin, findPluginByRepo, getAvailablePlugins, getPluginInfo, isPluginEnabled, mapPlugins,
7 parsePluginSource, PATH as PLUGINS_PATH, Repo, startPlugin, stopPlugin, STORAGE_FOLDER
8 } from './plugins'
9 import { ApiError } from './apiMiddleware'
@@ -47,9 +47,9 @@ export async function downloadPlugin(repo: Repo, { branch='', overwrite=false }=
47 repo = repo.main
48 if (downloading[repo])
49 throw new ApiError(HTTP_CONFLICT, "already downloading")
50 - const projectInfo = await getProjectInfo()
51 - if (projectInfo?.plugins_blacklist?.includes(repo))
52 - throw new ApiError(HTTP_FORBIDDEN, "blacklisted")
50 + const msg = await isPluginBlacklisted(repo)
51 + if (msg)
52 + throw new ApiError(HTTP_FORBIDDEN, "blacklisted: " + msg)
53 console.log('downloading plugin', repo)
54 downloadProgress(repo, true)
55 try {
@@ -205,14 +205,17 @@ async function *apiGithubPaginated<T=any>(uri: string) {
205 }
206 }
207
208 +async function isPluginBlacklisted(repo: string) {
209 + return getProjectInfo().then(x => x?.repo_blacklist?.[repo]?.message as string || '', () => undefined)
210 +}
211 +
212 export async function searchPlugins(text='', { skipRepos=[''] }={}) {
209 - const projectInfo = await getProjectInfo()
213 const searches = [encodeURI(text), ...text.split(' ').filter(Boolean).slice(0, 2).map(x => 'user:' + encodeURI(x))] // first 2 words can be the author
214 const list = await Promise.all(searches.map(x => asyncGeneratorToArray(apiGithubPaginated(`search/repositories?q=topic:hfs-plugin+${x}`))))
215 .then(all => all.flat()) // make it a single array
216 return new AsapStream(list.map(async it => { // using AsapStream we parallelize these promises and produce each result as it's ready
217 const repo = it.full_name as string
215 - if (projectInfo?.plugins_blacklist?.includes(repo) || skipRepos.includes(repo)) return
218 + if (skipRepos.includes(repo) || await isPluginBlacklisted(repo)) return
219 const pl = await readOnlineCompatiblePlugin(repo, it.default_branch).catch(() => undefined)
220 if (!pl) return
221 Object.assign(pl, { // inject some extra useful fields
@@ -227,11 +230,12 @@ export const alerts = storedMap.singleSync<string[]>('alerts', [])
230 // centralized hosted information, to be used as little as possible
231 const FN = 'central.json'
232 let builtIn = JSON.parse(readFileSync(join(__dirname, '..', FN), 'utf8'))
233 +let lastResult: any
234 export const getProjectInfo = debounceAsync(
235 () => readGithubFile(`${HFS_REPO}/${HFS_REPO_BRANCH}/${FN}`)
236 .then(JSON.parse, () => null)
237 .then(o => {
234 - o = Object.assign({ ...builtIn }, o) // fall back to built-in
238 + o = lastResult = Object.assign({ ...builtIn, ...lastResult }, o) // fall back to built-in
239 // merge byVersions info in the main object, but collect alerts separately, to preserve multiple instances
240 const allAlerts: string[] = [o.alert]
241 for (const [ver, more] of Object.entries(popKey(o, 'byVersion') || {}))
@@ -246,6 +250,11 @@ export const getProjectInfo = debounceAsync(
250 console.log("ALERT:", a)
251 return allAlerts
252 })
253 + for (const k of Object.keys(o.repo_blacklist || {})) {
254 + const p = findPluginByRepo(k)
255 + if (p)
256 + enablePlugin(p.id, false)
257 + }
258 return o
259 }),
260 { retain: DAY, retainFailure: 60_000 })
\ No newline at end of file