Add auto mute plugin
This commit is contained in:
		
							
								
								
									
										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" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
		Reference in New Issue
	
	Block a user