diff --git a/squeebot.repo.json b/squeebot.repo.json index fe3430d..4c9eea0 100644 --- a/squeebot.repo.json +++ b/squeebot.repo.json @@ -33,6 +33,10 @@ "name": "url-fediverse", "version": "1.0.0" }, + { + "name": "url-peertube", + "version": "1.0.0" + }, { "name": "url-twitter", "version": "1.0.0" diff --git a/url-peertube/plugin.json b/url-peertube/plugin.json new file mode 100644 index 0000000..d77c9f7 --- /dev/null +++ b/url-peertube/plugin.json @@ -0,0 +1,9 @@ +{ + "main": "plugin.js", + "name": "url-peertube", + "description": "URLReply PeerTube", + "version": "1.0.0", + "tags": ["urlreply"], + "dependencies": ["urlreply"], + "npmDependencies": [] +} diff --git a/url-peertube/plugin.ts b/url-peertube/plugin.ts new file mode 100644 index 0000000..bebbe44 --- /dev/null +++ b/url-peertube/plugin.ts @@ -0,0 +1,72 @@ +import { httpGET, sanitizeEscapedText, toHHMMSS } from '@squeebot/core/lib/common'; +import { + Plugin, + EventListener, + DependencyLoad +} from '@squeebot/core/lib/plugin'; + +import { IMessage } from '@squeebot/core/lib/types'; + +async function peertubeResponse(url: URL, msg: IMessage): Promise { + const url2go = `${url.origin}/api/v1/videos/${url.pathname.split('/')[3]}`; + let data; + + try { + data = await httpGET(url2go); + if (!data) { + throw new Error('No API response, probably not peertube after all.'); + } + data = JSON.parse(data); + } catch (e) { + return false; + } + + if (!data.id || !data.uuid || data.errors) { + return false; + } + + const keys = []; + if (data.isLive) { + keys.push(['field', '[LIVE]', {color: 'red'}]); + } + + keys.push(['field', 'PeerTube', { color: 'white', type: 'title' }]); + keys.push(['field', data.name, {type: 'description'}]); + + keys.push(['field', data.views.toString(), { type: 'metric', label: 'Views' }]); + + if (!data.isLive) { + keys.push(['field', toHHMMSS(data.duration.toString()), { label: 'Duration' }]); + } + + if (data.likes != null) { + const likeCount = data.likes.toString(); + const dislikeCount = data.dislikes.toString(); + + keys.push(['field', likeCount, { color: 'limegreen', label: ['▲', 'Likes'], type: 'metric' }]); + keys.push(['field', dislikeCount, { color: 'red', label: ['▼', 'Dislikes'], type: 'metric' }]); + } + + keys.push(['field', data.channel.displayName || data.channel.name, { label: ['By'] }]); + + msg.resolve(keys); + return true; +} + +class FediResponsePlugin extends Plugin { + @EventListener('pluginUnload') + public unloadEventHandler(plugin: string | Plugin): void { + if (plugin === this.name || plugin === this) { + this.emit('pluginUnloaded', this); + } + } + + @DependencyLoad('urlreply') + addUrlReply(urlreply: any): void { + urlreply.registerHandler(this.name, '/videos/watch/', async (url: URL, msg: IMessage) => { + return peertubeResponse(url, msg); + }); + } +} + +module.exports = FediResponsePlugin;