Add auto mute plugin
This commit is contained in:
parent
f4e6b00c7b
commit
20a188733d
44
peertube-plugin-auto-mute/README.md
Normal file
44
peertube-plugin-auto-mute/README.md
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
# Auto mute plugin for PeerTube
|
||||||
|
|
||||||
|
Auto mute accounts or instances based on public blocklists.
|
||||||
|
|
||||||
|
## Format
|
||||||
|
|
||||||
|
This plugins expect the following JSON format from public blocklists:
|
||||||
|
|
||||||
|
```
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
value: string
|
||||||
|
action?: 'add' | 'remove' // Default is 'add'
|
||||||
|
}[]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
{
|
||||||
|
value: 'peertube.cpy.re'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'root@peertube.cpy.re'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
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 `peertube.cpy.re` from the blocklist, update the JSON:
|
||||||
|
|
||||||
|
```
|
||||||
|
[
|
||||||
|
{
|
||||||
|
value: 'peertube.cpy.re',
|
||||||
|
action: 'remove'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'root@peertube.cpy.re'
|
||||||
|
}
|
||||||
|
]
|
148
peertube-plugin-auto-mute/main.js
Normal file
148
peertube-plugin-auto-mute/main.js
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
const simpleGet = require('simple-get')
|
||||||
|
|
||||||
|
const store = {
|
||||||
|
urls: [],
|
||||||
|
checkIntervalSeconds: null,
|
||||||
|
alreadyAdded: new Set(),
|
||||||
|
alreadyRemoved: new Set(),
|
||||||
|
serverAccountId: null
|
||||||
|
}
|
||||||
|
|
||||||
|
async function register ({
|
||||||
|
settingsManager,
|
||||||
|
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-textarea',
|
||||||
|
private: true,
|
||||||
|
default: 3600 // 1 Hour
|
||||||
|
})
|
||||||
|
|
||||||
|
const serverActor = await peertubeHelpers.server.getServerActor()
|
||||||
|
store.serverAccountId = serverActor.Account.id
|
||||||
|
|
||||||
|
const settings = await settingsManager.getSettings([ 'check-seconds-interval', 'blocklist-urls' ])
|
||||||
|
|
||||||
|
await load(peertubeHelpers, settings['blocklist-urls'], settings['check-seconds-interval'])
|
||||||
|
|
||||||
|
settingsManager.onSettingsChange(settings => {
|
||||||
|
load(peertubeHelpers, settings['blocklist-urls'], settings['check-seconds-interval'])
|
||||||
|
.catch(err => logger.error('Cannot load auto mute plugin.', { err }))
|
||||||
|
})
|
||||||
|
|
||||||
|
runCheckForever(peertubeHelpers)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function unregister () {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
register,
|
||||||
|
unregister
|
||||||
|
}
|
||||||
|
|
||||||
|
// ############################################################################
|
||||||
|
|
||||||
|
async function load (peertubeHelpers, blocklistUrls, checkIntervalSeconds) {
|
||||||
|
const { logger } = peertubeHelpers
|
||||||
|
|
||||||
|
store.checkIntervalSeconds = checkIntervalSeconds
|
||||||
|
|
||||||
|
store.urls = (blocklistUrls || '').split('\n')
|
||||||
|
.filter(url => !!url)
|
||||||
|
|
||||||
|
if (store.urls.length === 0) {
|
||||||
|
logger.info('Do not load auto mute plugin because of empty blocklist URLs.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info('Loaded %d blocklist URLs for auto mute plugin.', store.urls.length, { urls: store.urls })
|
||||||
|
}
|
||||||
|
|
||||||
|
async function runCheckForever (peertubeHelpers) {
|
||||||
|
const { logger } = peertubeHelpers
|
||||||
|
|
||||||
|
if (store.urls.length === 0) return runLater()
|
||||||
|
|
||||||
|
for (const url of store.urls) {
|
||||||
|
try {
|
||||||
|
const { data } = await get(url)
|
||||||
|
|
||||||
|
if (Array.isArray(data.data) === false) {
|
||||||
|
throw new Error('JSON response is not valid.')
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entity of data.data) {
|
||||||
|
if (!entity.value) throw new Error('JSON entity is not valid.')
|
||||||
|
|
||||||
|
if (entity.action === 'remove') await removeEntity(peertubeHelpers, entity.value)
|
||||||
|
else await addEntity(peertubeHelpers, entity.value)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
logger.warn('Cannot get mute blocklist from %s.', url, { err })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
runLater()
|
||||||
|
}
|
||||||
|
|
||||||
|
function runLater () {
|
||||||
|
setTimeout(runCheckForever, store.checkIntervalSeconds * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
function get (url) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
simpleGet({ url, json: true }, function (err, res, data) {
|
||||||
|
if (err) return reject(err)
|
||||||
|
|
||||||
|
return resolve({ res, data })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function addEntity (peertubeHelpers, value) {
|
||||||
|
const moderation = { peertubeHelpers }
|
||||||
|
|
||||||
|
if (store.alreadyAdded.has(value)) return
|
||||||
|
|
||||||
|
store.alreadyRemoved.delete(value)
|
||||||
|
store.alreadyAdded.add(value)
|
||||||
|
|
||||||
|
// Account
|
||||||
|
if (value.includes('@')) {
|
||||||
|
return moderation.blockAccount({ byAccountId: store.serverAccountId, handleToBlock: value })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server
|
||||||
|
return moderation.blockServer({ byAccountId: store.serverAccountId, hostToBlock: value })
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeEntity (peertubeHelpers, value) {
|
||||||
|
const moderation = { peertubeHelpers }
|
||||||
|
|
||||||
|
if (store.alreadyRemoved.has(value)) return
|
||||||
|
|
||||||
|
store.alreadyAdded.delete(value)
|
||||||
|
store.alreadyRemoved.add(value)
|
||||||
|
|
||||||
|
// Account
|
||||||
|
if (value.includes('@')) {
|
||||||
|
return moderation.blockAccount({ byAccountId: store.serverAccountId, handleToUnblock: value })
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server
|
||||||
|
return moderation.blockAccount({ byAccountId: store.serverAccountId, hostToUnblock: value })
|
||||||
|
}
|
49
peertube-plugin-auto-mute/package-lock.json
generated
Normal file
49
peertube-plugin-auto-mute/package-lock.json
generated
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "peertube-plugin-auto-mute",
|
||||||
|
"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-mute/package.json
Normal file
23
peertube-plugin-auto-mute/package.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "peertube-plugin-auto-mute",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "Auto mute plugin for PeerTube",
|
||||||
|
"engine": {
|
||||||
|
"peertube": ">=2.2.0"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"peertube",
|
||||||
|
"plugin"
|
||||||
|
],
|
||||||
|
"homepage": "https://framagit.org/framasoft/peertube/official-plugins/tree/master/peertube-plugin-auto-mute",
|
||||||
|
"author": "Chocobozzz",
|
||||||
|
"bugs": "https://framagit.org/framasoft/peertube/official-plugins/issues",
|
||||||
|
"library": "./main.js",
|
||||||
|
"staticDirs": {},
|
||||||
|
"css": [],
|
||||||
|
"clientScripts": [],
|
||||||
|
"translations": {},
|
||||||
|
"dependencies": {
|
||||||
|
"simple-get": "^3.1.0"
|
||||||
|
}
|
||||||
|
}
|
10
peertube-plugin-auto-mute/tests/blocklist-sample.json
Normal file
10
peertube-plugin-auto-mute/tests/blocklist-sample.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"value": "peertube.cpy.re"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"value": "peertube3.cpy.re"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -32,6 +32,10 @@
|
|||||||
{
|
{
|
||||||
"script": "client/search-client-plugin.js",
|
"script": "client/search-client-plugin.js",
|
||||||
"scopes": [ "search" ]
|
"scopes": [ "search" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"script": "client/login-client-plugin.js",
|
||||||
|
"scopes": [ "login" ]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"translations": {
|
"translations": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user