finish canvas link parsing

This commit is contained in:
HF 2022-01-16 14:56:46 +01:00
parent a6fd5b7962
commit f2035f9660
10 changed files with 87 additions and 42 deletions

View File

@ -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'

View File

@ -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 || '';

View File

@ -124,4 +124,4 @@ class Palette {
}
}
module.exports = Palette;
export default Palette;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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,
}
}

View File

@ -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;

View File

@ -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;