From f2035f9660b51f07badd19f0030974168bb9ca37 Mon Sep 17 00:00:00 2001 From: HF Date: Sun, 16 Jan 2022 14:56:46 +0100 Subject: [PATCH] finish canvas link parsing --- ppfun-bridge/deploy.sh | 1 + ppfun-bridge/index.js | 2 +- ppfun-bridge/src/pixelplanet/Palette.js | 2 +- ppfun-bridge/src/pixelplanet/canvases.js | 14 +++---- ppfun-bridge/src/pixelplanet/constants.js | 12 +++--- ppfun-bridge/src/pixelplanet/index.js | 19 +++++---- ppfun-bridge/src/pixelplanet/loadChunk.js | 9 ++-- ppfun-bridge/src/pixelplanet/renderCanvas.js | 20 ++++++--- ppfun-bridge/src/ppfunMatrixBridge.js | 44 +++++++++++++++++--- ppfun-bridge/src/ppfunsocket.js | 6 +-- 10 files changed, 87 insertions(+), 42 deletions(-) diff --git a/ppfun-bridge/deploy.sh b/ppfun-bridge/deploy.sh index c72613f..d50f35a 100755 --- a/ppfun-bridge/deploy.sh +++ b/ppfun-bridge/deploy.sh @@ -1,4 +1,5 @@ #!/bin/bash scp -r ./src/* pixelplanet:~/ppfun-bridge/src/ scp ./*.js pixelplanet:~/ppfun-bridge/ +scp ./*.json pixelplanet:~/ppfun-bridge/ ssh pixelplanet 'pm2 stop ppfun-bridge; cd ~/ppfun-bridge; pm2 start ecosystem.yml' diff --git a/ppfun-bridge/index.js b/ppfun-bridge/index.js index 552c836..18567ab 100644 --- a/ppfun-bridge/index.js +++ b/ppfun-bridge/index.js @@ -3,7 +3,7 @@ // node index.js -r -u "http://localhost:9000" # remember to add the registration! // node index.js -p 9000 -const PPfunMatrixBridge = require('./src/ppfunMatrixBridge'); +import PPfunMatrixBridge from './src/ppfunMatrixBridge.js'; const PORT = parseInt(process.env.PORT, 10) || 8009; const APISOCKET_KEY = process.env.APISOCKET_KEY || ''; diff --git a/ppfun-bridge/src/pixelplanet/Palette.js b/ppfun-bridge/src/pixelplanet/Palette.js index d3fa3f7..9a288b3 100644 --- a/ppfun-bridge/src/pixelplanet/Palette.js +++ b/ppfun-bridge/src/pixelplanet/Palette.js @@ -124,4 +124,4 @@ class Palette { } } -module.exports = Palette; +export default Palette; diff --git a/ppfun-bridge/src/pixelplanet/canvases.js b/ppfun-bridge/src/pixelplanet/canvases.js index 02b092f..ee914ca 100644 --- a/ppfun-bridge/src/pixelplanet/canvases.js +++ b/ppfun-bridge/src/pixelplanet/canvases.js @@ -1,12 +1,13 @@ -const Palette = require('./Palette'); -const { +import Palette from './Palette.js'; +import fetch from 'node-fetch'; +import { TILE_SIZE, TILE_ZOOM_LEVEL, -} = require('./constants'); +} from './constants.js'; let canvases = new Map(); -function fetchCanvasData() { +async function fetchCanvasData() { try { const response = await fetch('https://pixelplanet.fun/api/me'); if (response.status >= 300) { @@ -21,9 +22,8 @@ function fetchCanvasData() { canvas.id = id; canvas.palette = new Palette(canvas.colors); canvas.maxTiledZoom = Math.log2(canvas.size / TILE_SIZE) / TILE_ZOOM_LEVEL * 2; - canvasMap.set(canvas.ident, canvas); + canvases.set(canvas.ident, canvas); } - canvases = canvasMap; console.log('Successfully fetched canvas data from pixelplanet'); } catch (e) { console.log('Couldn\'t connect to pixelplanet, trying to connect again in 60s'); @@ -33,4 +33,4 @@ function fetchCanvasData() { } fetchCanvasData(); -module.exports = canvases; +export default canvases; diff --git a/ppfun-bridge/src/pixelplanet/constants.js b/ppfun-bridge/src/pixelplanet/constants.js index 2408335..4f2c787 100644 --- a/ppfun-bridge/src/pixelplanet/constants.js +++ b/ppfun-bridge/src/pixelplanet/constants.js @@ -1,7 +1,5 @@ -module.exports = { - WIDTH: 1024; - HEIGHT: 768; - MAX_SCALE: 40; // 52 in log2 - TILE_SIZE: 256; - TILE_ZOOM_LEVEL: 4; -} +export const WIDTH = 1024; +export const HEIGHT = 768; +export const MAX_SCALE = 40; // 52 in log2 +export const TILE_SIZE = 256; +export const TILE_ZOOM_LEVEL = 4; diff --git a/ppfun-bridge/src/pixelplanet/index.js b/ppfun-bridge/src/pixelplanet/index.js index 373ecbe..bb9b335 100644 --- a/ppfun-bridge/src/pixelplanet/index.js +++ b/ppfun-bridge/src/pixelplanet/index.js @@ -1,11 +1,12 @@ import fetch from 'node-fetch'; -const canvases = require('./canvases'); -const renderCanvas = require('./renderCanvas'); +import canvases from './canvases.js'; +import renderCanvas from './renderCanvas.js'; const linkRegExp = /(#[a-z]*,-?[0-9]*,-?[0-9]*(,-?[0-9]+)?)/gi; const linkRegExpFilter = (val, ind) => ((ind % 3) !== 2); let lastCoords = []; +let lastParse = Date.now(); function compArray(arr1, arr2) { for (let i = 0; i <= arr1.length; i += 1) { @@ -16,7 +17,7 @@ function compArray(arr1, arr2) { return true; } -async function parseCanvasLinks(text) { +export async function parseCanvasLinks(text) { if (!text || !canvases) { return null; @@ -28,9 +29,13 @@ async function parseCanvasLinks(text) { } const coordsParts = msgArray[1].substr(1).split(','); - if (compArray(coordsParts, lastCoords)) { + const curTime = Date.now(); + if (compArray(coordsParts, lastCoords) + || curTime - 4000 < lastParse + ) { return null; } + lastParse = curTime; lastCoords = coordsParts; const [ canvasIdent, x, y, z ] = coordsParts; @@ -40,9 +45,7 @@ async function parseCanvasLinks(text) { } console.log(`Fetch canvas ${canvas.title} on ${x}/${y} with zoom ${z}`); - const image = await renderCanvas(canvas, x, y, z); + const imageData = await renderCanvas(canvas, x, y, z); - return image; + return imageData; } - -exports.parseCanvasLinks = parseCanvasLinks; diff --git a/ppfun-bridge/src/pixelplanet/loadChunk.js b/ppfun-bridge/src/pixelplanet/loadChunk.js index 3d6bb77..ba4ffaa 100644 --- a/ppfun-bridge/src/pixelplanet/loadChunk.js +++ b/ppfun-bridge/src/pixelplanet/loadChunk.js @@ -1,14 +1,15 @@ import fetch from 'node-fetch'; +import nodeCanvas from 'canvas'; const { createCanvas, loadImage, createImageData, -} = require('canvas'); +} = nodeCanvas; -const { +import { TILE_SIZE, -} = require('./constants'); +} from './constants.js'; async function fetchBaseChunk( canvasId, @@ -44,7 +45,7 @@ async function fetchTile(canvasId, zoom, cx, cy, tile) { ctx.drawImage(image, 0, 0); } -module.exports = function ( +export default async function ( canvas, zoom, cx, diff --git a/ppfun-bridge/src/pixelplanet/renderCanvas.js b/ppfun-bridge/src/pixelplanet/renderCanvas.js index fe63d6f..76889a6 100644 --- a/ppfun-bridge/src/pixelplanet/renderCanvas.js +++ b/ppfun-bridge/src/pixelplanet/renderCanvas.js @@ -1,14 +1,15 @@ -const { createCanvas } = require('canvas'); +import nodeCanvas from 'canvas'; +const { createCanvas } = nodeCanvas; -const getChunk = require('./loadChunk'); +import getChunk from './loadChunk.js'; -const { +import { WIDTH, HEIGHT, MAX_SCALE, TILE_SIZE, TILE_ZOOM_LEVEL, -} = require('./constants'); +} from './constants.js'; function coordToChunk(z, canvasSize, tiledScale) { return Math.floor((z + canvasSize / 2) / TILE_SIZE * tiledScale); @@ -89,5 +90,14 @@ export default async function renderCanvas( } await Promise.all(promises); - return can.toBuffer('image/png'); + const memetype = 'image/png'; + const imageBuffer = can.toBuffer(memetype); + return { + image: imageBuffer, + name: `ppfun-snap-${canvas.title}_${x}_${y}_${z}.png`, + type: memetype, + w: can.width, + h: can.height, + size: imageBuffer.size, + } } diff --git a/ppfun-bridge/src/ppfunMatrixBridge.js b/ppfun-bridge/src/ppfunMatrixBridge.js index ab72e9d..ec8914b 100644 --- a/ppfun-bridge/src/ppfunMatrixBridge.js +++ b/ppfun-bridge/src/ppfunMatrixBridge.js @@ -1,9 +1,9 @@ "use strict"; -const MatrixBridge = require("matrix-appservice-bridge").Bridge; +import { Bridge } from 'matrix-appservice-bridge'; -const PPfunSocket = require('./ppfunsocket'); -//const parseCanvasLinks = require('./pixelplanet') +import PPfunSocket from './ppfunsocket.js'; +import { parseCanvasLinks } from './pixelplanet/index.js'; class PPfunMatrixBridge { constructor(opts) { @@ -28,7 +28,7 @@ class PPfunMatrixBridge { apiSocketUrl, apiSocketKey, ); - this.matrixBridge = new MatrixBridge({ + this.matrixBridge = new Bridge({ homeserverUrl, domain, registration, @@ -79,6 +79,37 @@ class PPfunMatrixBridge { ); } + async sendCanvasSnapshotIfNeccessary(roomId, msg) { + // post image if canvas link got posted + try { + const imageData = await parseCanvasLinks(msg); + if (imageData) { + const { image, name, type, h, w, size } = imageData; + const intent = this.matrixBridge.getIntent(); + let mxcUrl; + mxcUrl = await intent.uploadContent(image, { + name, + type, + }); + if (mxcUrl) { + intent.sendMessage(roomId, { + body: name, + msgtype: 'm.image', + url: mxcUrl, + info: { + h, + w, + mimetype: type, + size, + }, + }); + } + } + } catch (e) { + console.error(`Error when parsing pixelplanet url ${e}`); + } + } + async recMatrix(request, context) { const event = request.getData(); if (event.type === "m.room.message" @@ -89,6 +120,8 @@ class PPfunMatrixBridge { if (!cid) { return; } + const msg = event.content.body; + this.sendCanvasSnapshotIfNeccessary(event.room_id, msg); const userId = event.sender; const uid = (userId.startsWith(`@${this.prefix}_`) && userId.endsWith(this.domain)) @@ -102,7 +135,6 @@ class PPfunMatrixBridge { this.idToNameMap.set(userId, userId.substring(1)); name = await this.getDisplayName(userId); } - const msg = event.content.body; console.log(`MATRIX ${name}: ${msg}`); this.sendPPfun(name, parseInt(uid, 10), msg, cid); return; @@ -222,4 +254,4 @@ class PPfunMatrixBridge { } } -module.exports = PPfunMatrixBridge; +export default PPfunMatrixBridge; diff --git a/ppfun-bridge/src/ppfunsocket.js b/ppfun-bridge/src/ppfunsocket.js index ff388e2..3a147a8 100644 --- a/ppfun-bridge/src/ppfunsocket.js +++ b/ppfun-bridge/src/ppfunsocket.js @@ -1,7 +1,7 @@ "use strict"; -const EventEmitter = require('events'); -const WebSocket = require('ws') +import EventEmitter from 'events'; +import WebSocket from 'ws'; class PPfunSocket extends EventEmitter { constructor(url, apisocketkey) { @@ -136,4 +136,4 @@ class PPfunSocket extends EventEmitter { } } -module.exports = PPfunSocket; +export default PPfunSocket;