Add auto block videos plugin
This commit is contained in:
parent
83c91c18e0
commit
71499383b9
60
peertube-plugin-auto-block-videos/README.md
Normal file
60
peertube-plugin-auto-block-videos/README.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Auto block videos plugin for PeerTube
|
||||
|
||||
Auto block videos based on public blocklists.
|
||||
|
||||
## Block lists
|
||||
|
||||
**Add your public list here**
|
||||
|
||||
## Blocklist URL format
|
||||
|
||||
This plugin expects the following JSON format from public blocklists:
|
||||
|
||||
```
|
||||
{
|
||||
data: {
|
||||
value: string
|
||||
action?: 'add' | 'remove' // Default is 'add'
|
||||
updatedAt?: string // ISO 8601
|
||||
}[]
|
||||
}
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
{
|
||||
data: [
|
||||
{
|
||||
value: 'https://framatube.org/videos/watch/37938234-ddf2-46d7-8967-8ac84820d5cd'
|
||||
},
|
||||
{
|
||||
value: 'https://peertube.cpy.re/videos/watch/f78a97f8-a142-4ce1-a5bd-154bf9386504',
|
||||
updatedAt: '2020-05-07T14:42:48.954Z'
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This plugin does not apply a diff, so if you want to remove an entity from the blocklist, add `action: 'remove'` to the object.
|
||||
|
||||
For example, to revert `https://peertube.cpy.re/videos/watch/f78a97f8-a142-4ce1-a5bd-154bf9386504` from the blocklist, update the JSON:
|
||||
|
||||
```
|
||||
{
|
||||
data: [
|
||||
{
|
||||
value: 'https://peertube.cpy.re/videos/watch/f78a97f8-a142-4ce1-a5bd-154bf9386504',
|
||||
action: 'remove'
|
||||
},
|
||||
{
|
||||
value: 'https://framatube.org/videos/watch/37938234-ddf2-46d7-8967-8ac84820d5cd'
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The purpose of the `updatedAt` field is to not override admin blocks/unblocks:
|
||||
* Plugin auto block video A with an `updatedAt: '2020-05-07T14:42:48.954Z'`
|
||||
* Admin thinks this video is fine so it unblocks video A
|
||||
* On another check, the plugin won't re-block the account A because the `updatedAt` is before the last check
|
181
peertube-plugin-auto-block-videos/main.js
Normal file
181
peertube-plugin-auto-block-videos/main.js
Normal file
@ -0,0 +1,181 @@
|
||||
const simpleGet = require('simple-get')
|
||||
|
||||
const store = {
|
||||
urls: [],
|
||||
checkIntervalSeconds: null,
|
||||
alreadyAdded: new Set(),
|
||||
alreadyRemoved: new Set(),
|
||||
timeout: null
|
||||
}
|
||||
|
||||
async function register ({
|
||||
settingsManager,
|
||||
storageManager,
|
||||
peertubeHelpers,
|
||||
registerSetting
|
||||
}) {
|
||||
const { logger } = peertubeHelpers
|
||||
|
||||
registerSetting({
|
||||
name: 'blocklist-urls',
|
||||
label: 'Blocklist URLs (one per line)',
|
||||
type: 'input-textarea',
|
||||
private: true
|
||||
})
|
||||
|
||||
registerSetting({
|
||||
name: 'check-seconds-interval',
|
||||
label: 'Blocklist check frequency (seconds)',
|
||||
type: 'input',
|
||||
private: true,
|
||||
default: 3600 // 1 Hour
|
||||
})
|
||||
|
||||
const settings = await settingsManager.getSettings([ 'check-seconds-interval', 'blocklist-urls' ])
|
||||
|
||||
await load(peertubeHelpers, storageManager, settings['blocklist-urls'], settings['check-seconds-interval'])
|
||||
|
||||
settingsManager.onSettingsChange(settings => {
|
||||
load(peertubeHelpers, storageManager, settings['blocklist-urls'], settings['check-seconds-interval'])
|
||||
.catch(err => logger.error('Cannot load auto block videos plugin.', { err }))
|
||||
})
|
||||
}
|
||||
|
||||
async function unregister () {
|
||||
return
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
register,
|
||||
unregister
|
||||
}
|
||||
|
||||
// ############################################################################
|
||||
|
||||
async function load (peertubeHelpers, storageManager, blocklistUrls, checkIntervalSeconds) {
|
||||
const { logger } = peertubeHelpers
|
||||
|
||||
if (store.timeout) clearTimeout(store.timeout)
|
||||
|
||||
store.checkIntervalSeconds = checkIntervalSeconds
|
||||
|
||||
store.urls = (blocklistUrls || '').split('\n')
|
||||
.filter(url => !!url)
|
||||
|
||||
if (store.urls.length === 0) {
|
||||
logger.info('Do not load auto block videos plugin because of empty blocklist URLs.')
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Loaded %d blocklist URLs for auto block videos plugin.', store.urls.length, { urls: store.urls })
|
||||
|
||||
runLater(peertubeHelpers, storageManager)
|
||||
}
|
||||
|
||||
async function runCheck (peertubeHelpers, storageManager) {
|
||||
const { logger } = peertubeHelpers
|
||||
|
||||
if (store.urls.length === 0) return runLater(peertubeHelpers, storageManager)
|
||||
|
||||
let lastChecks = await storageManager.getData('last-checks')
|
||||
if (!lastChecks) lastChecks = {}
|
||||
|
||||
const newLastCheck = {}
|
||||
|
||||
for (const url of store.urls) {
|
||||
try {
|
||||
const { data } = await get(url)
|
||||
newLastCheck[url] = new Date().toISOString()
|
||||
|
||||
const lastCheckTime = lastChecks[url]
|
||||
? new Date(lastChecks[url]).getTime()
|
||||
: 0
|
||||
|
||||
if (Array.isArray(data.data) === false) {
|
||||
logger.error('JSON response is not valid from %s.', { data })
|
||||
continue
|
||||
}
|
||||
|
||||
for (const entity of data.data) {
|
||||
if (!entity.value) {
|
||||
logger.error('JSON entity is not valid.', { entity })
|
||||
continue
|
||||
}
|
||||
|
||||
// We already checked this entity?
|
||||
if (entity.updatedAt) {
|
||||
const updatedAtTime = new Date(entity.updatedAt).getTime()
|
||||
|
||||
if (updatedAtTime < lastCheckTime) continue
|
||||
}
|
||||
|
||||
if (entity.action === 'remove') await removeEntity(peertubeHelpers, entity.value)
|
||||
else await addEntity(peertubeHelpers, entity.value)
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn('Cannot auto block videos from %s.', url, { err })
|
||||
}
|
||||
}
|
||||
|
||||
await storageManager.storeData('last-checks', newLastCheck)
|
||||
|
||||
runLater(peertubeHelpers, storageManager)
|
||||
}
|
||||
|
||||
function runLater (peertubeHelpers, storageManager) {
|
||||
const { logger } = peertubeHelpers
|
||||
|
||||
logger.debug('Will run auto videos block check in %d seconds.', store.checkIntervalSeconds)
|
||||
|
||||
store.timeout = setTimeout(() => {
|
||||
runCheck(peertubeHelpers, storageManager)
|
||||
}, store.checkIntervalSeconds * 1000)
|
||||
}
|
||||
|
||||
function get (url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
simpleGet.concat({ url, method: 'GET', json: true }, function (err, res, data) {
|
||||
if (err) return reject(err)
|
||||
|
||||
return resolve({ res, data })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async function addEntity (peertubeHelpers, value) {
|
||||
const { moderation, videos, logger } = peertubeHelpers
|
||||
|
||||
if (store.alreadyAdded.has(value)) return
|
||||
|
||||
store.alreadyRemoved.delete(value)
|
||||
store.alreadyAdded.add(value)
|
||||
|
||||
const video = await videos.loadByUrl(value)
|
||||
if (!video) return
|
||||
|
||||
if (video.remote !== true) {
|
||||
logger.info('Do not auto block our own video %s.', value)
|
||||
return
|
||||
}
|
||||
|
||||
logger.info('Auto block video %s from blocklist.', value)
|
||||
|
||||
const reason = 'Automatically blocked from auto block plugin.'
|
||||
return moderation.blacklistVideo({ videoIdOrUUID: video.id, createOptions: { reason } })
|
||||
}
|
||||
|
||||
async function removeEntity (peertubeHelpers, value) {
|
||||
const { moderation, logger, videos } = peertubeHelpers
|
||||
|
||||
if (store.alreadyRemoved.has(value)) return
|
||||
|
||||
store.alreadyAdded.delete(value)
|
||||
store.alreadyRemoved.add(value)
|
||||
|
||||
const video = await videos.loadByUrl(value)
|
||||
if (!video) return
|
||||
|
||||
logger.info('Auto removing video %s from blocklist.', value)
|
||||
|
||||
return moderation.unblacklistVideo({ videoIdOrUUID: video.id })
|
||||
}
|
49
peertube-plugin-auto-block-videos/package-lock.json
generated
Normal file
49
peertube-plugin-auto-block-videos/package-lock.json
generated
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "peertube-plugin-auto-block-videos",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"decompress-response": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
|
||||
"integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
|
||||
"requires": {
|
||||
"mimic-response": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
|
||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
|
||||
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
|
||||
"integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
|
||||
"requires": {
|
||||
"decompress-response": "^4.2.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
}
|
||||
}
|
||||
}
|
23
peertube-plugin-auto-block-videos/package.json
Normal file
23
peertube-plugin-auto-block-videos/package.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "peertube-plugin-auto-block-videos",
|
||||
"version": "0.0.1",
|
||||
"description": "Auto block videos plugin for PeerTube",
|
||||
"engine": {
|
||||
"peertube": ">=2.2.0"
|
||||
},
|
||||
"keywords": [
|
||||
"peertube",
|
||||
"plugin"
|
||||
],
|
||||
"homepage": "https://framagit.org/framasoft/peertube/official-plugins/tree/master/peertube-plugin-auto-block-videos",
|
||||
"author": "Chocobozzz",
|
||||
"bugs": "https://framagit.org/framasoft/peertube/official-plugins/issues",
|
||||
"library": "./main.js",
|
||||
"staticDirs": {},
|
||||
"css": [],
|
||||
"clientScripts": [],
|
||||
"translations": {},
|
||||
"dependencies": {
|
||||
"simple-get": "^3.1.0"
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"value": "peertube.cpy.re"
|
||||
},
|
||||
{
|
||||
"value": "peertube3.cpy.re"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user