diff --git a/Dockerfile b/Dockerfile index ce40035..dfd81c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,9 @@ RUN mkdir -p /data WORKDIR /data COPY . . RUN rm -f .env +RUN apt-get update -qqy +RUN apt-get install -qqy imagemagick graphicsmagick +RUN apt-get clean RUN npm install EXPOSE ${NODE_PORT} CMD ["npm", "run", "dbrun"] \ No newline at end of file diff --git a/config/index.js b/config/index.js index 477b073..81842ba 100644 --- a/config/index.js +++ b/config/index.js @@ -1,6 +1,7 @@ module.exports = { port: process.env.NODE_PORT || 10230, url: process.env.HOST_URL || '', + image_root: process.env.IMAGE_ROOT || '/image', line: { secret: process.env.LINE_SECRET || '', access: process.env.LINE_ACCESS || '' diff --git a/libs/api-action/line.js b/libs/api-action/line.js index a6f31a6..16f4883 100644 --- a/libs/api-action/line.js +++ b/libs/api-action/line.js @@ -77,6 +77,8 @@ const replyMessage = async (replyToken, message) => { default: obj = textObject(message) } + } else { + obj = textObject(message) } if (obj !== null) { diff --git a/libs/line-message/commands/index.js b/libs/line-message/commands/index.js index f5e1fe3..820f28d 100644 --- a/libs/line-message/commands/index.js +++ b/libs/line-message/commands/index.js @@ -7,7 +7,8 @@ const parseCMD = async (text = '', source = {}) => { let txt = text.trim() let arr = txt.split(' ').map(t => t.trim()) if (arr.length === 0) return null - if (arr[0][0] !== '!') return null + let cmdMsg = false + if (arr[0][0] === '!') cmdMsg = true let cmd = arr[0].replace(/^!/, '') cmd = cmd.toLowerCase() @@ -16,56 +17,70 @@ const parseCMD = async (text = '', source = {}) => { try { // query normal command - let result = await db.query({ - text: `select "message", "group" from "public"."commands" where "cmd" = $1 and ("group" = '' or "group" = $2)`, - values: [cmd, source.groupId] - }) - if (result.rowCount > 0) { - let obj = result.rows.filter(t => t.group === source.groupId) - if (obj.length === 0) obj = result.rows[0] - else obj = obj[0] - let content = obj.message - let m = content.match(/{{(.+?)}}/g) - if (m !== null && m.length > 0) { - for (let i = 0; i < m.length; i++) { - let c = m[i].replace(/^{{/, '').replace(/}}$/, '') - let carr = c.split('=') - if (carr.length > 1) c = carr - let res = await actions(c, arr.slice(1).join(' '), source) - content = content.replace(m[i], res || '') + if (cmdMsg) { + let result = await db.query({ + text: `select "message", "group" from "public"."commands" where "cmd" = $1 and ("group" = '' or "group" = $2)`, + values: [cmd, source.groupId] + }) + if (result.rowCount > 0) { + let obj = result.rows.filter(t => t.group === source.groupId) + if (obj.length === 0) obj = result.rows[0] + else obj = obj[0] + let content = obj.message + let m = content.match(/{{(.+?)}}/g) + if (m !== null && m.length > 0) { + for (let i = 0; i < m.length; i++) { + let c = m[i].replace(/^{{/, '').replace(/}}$/, '') + let carr = c.split('=') + if (carr.length > 1) c = carr + let res = await actions(c, arr.slice(1).join(' '), source) + content = content.replace(m[i], res || '') + } } - } - if (content.trim().length > 0) { - reply = { - reply: content + if (content.trim().length > 0) { + reply = { + reply: content + } } } } if (reply === null) { + console.log('enter key command') // query keyword commands let keyCMD = await db.query({ - text: `select "message", "group", "cmd" from "public"."key_commands" where ("group" = '' or "group" = $1)`, + text: `select "message", "group", "key" from "public"."key_commands" where ("group" = '' or "group" = $1)`, values: [source.groupId] }) + console.log(keyCMD.rows) if (keyCMD.rowCount > 0) { let obj = keyCMD.rows.filter(t => t.group === '') let obj2 = keyCMD.rows.filter(t => t.group === source.groupId) obj = obj.map(t => { for (let i of obj2) { - if (i.cmd === t.cmd && i.group !== '') return i + if (i.key === t.key && i.group !== '') return i } return t }) + let tmp = obj2.filter(t => { + for (let i of obj) { + if (i.key === t.key) return false + } + return true + }) + obj = [...obj, ...tmp] let regex = null let txt = '' + console.log('obj ::: ', obj) for (let i of obj) { - txt += (txt.length > 0 ? '|' : '') + i.cmd + txt += (txt.length > 0 ? '|' : '') + i.key } regex = new RegExp(`(${txt})`) - let m = arr.slice(1).join(' ').match(regex) + console.log(regex) + let m = text.match(regex) + console.log('match :::: ', m) if (m !== null && m.length > 0) { - let key = obj.filter(t => t.cmd === m[0]) + let key = obj.filter(t => t.key === m[0]) if (key.length > 0) { let content = key[0].message let m = content.match(/{{(.+?)}}/g) @@ -74,7 +89,7 @@ const parseCMD = async (text = '', source = {}) => { let c = m[i].replace(/^{{/, '').replace(/}}$/, '') let carr = c.split('=') if (carr.length > 1) c = carr - let res = await actions(c, arr.slice(1).join(' '), source) + let res = await actions(c, text, source) content = content.replace(m[i], res || '') } } diff --git a/package.json b/package.json index 6ddabaa..e2c7bad 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "cheerio": "^1.0.0-rc.2", "cron": "^1.3.0", "dotenv": "^6.0.0", + "gm": "^1.23.1", "koa": "^2.5.1", "koa-body": "^4.0.3", "koa-logger": "^3.2.0", diff --git a/route/index.js b/route/index.js index 930270b..4be1dc0 100644 --- a/route/index.js +++ b/route/index.js @@ -1,5 +1,103 @@ const Router = require('koa-router') const r = new Router() +const gm = require('gm') +const config = require('@config/index') +const fs = require('fs') +const path = require('path') + +const getImageToRes = async (c, n) => { + let filepath = path.resolve(config.image_root, c.state.file) + console.log(filepath) + try { + fs.accessSync(filepath) + } catch (err) { + c.throw(404, 'image not found') + } + + let buf = null + + let imgSize = await getImageSize(filepath) + if (imgSize === null) c.throw(500) + if (c.state.ori === true) { + // max 1024x1024 + if (imgSize.width > 1024 || imgSize.height > 1024) { + buf = await resizeImage(filepath, 1024) + if (buf === null) c.throw(500) + } + } else { + // max 240x240 + if (imgSize.width > 240 || imgSize.height > 240) { + buf = await resizeImage(filepath, 240) + if (buf === null) c.throw(500) + } + } + + if (buf === null) { + let format = await getImageFormat(filepath) + if (format === null) c.throw(500) + if (format !== 'JPEG') { + buf = await convertToJPEG(filepath) + if (buf === null) c.throw(500) + } else { + buf = fs.readFileSync(filepath) + } + } + + c.type = 'image/jpeg' + c.body = buf +} + +const convertToJPEG = async (file = null) => { + let buf = await new Promise((resolve) => { + gm(file).toBuffer('JPEG', (err, buf) => { + resolve(err ? null : buf) + }) + }) + return buf +} + +const getImageFormat = async (file = null) => { + let format = await new Promise((resolve) => { + gm(file).format((err, format) => { + resolve(err ? null : format) + }) + }) + return format +} + +const getImageSize = async (file = null) => { + let size = await new Promise((resolve) => { + gm(file).size((err, val) => { + resolve(err ? null : val) + }) + }) + return size +} + +const resizeImage = async (file = null, size = 1024) => { + let buf = await new Promise((resolve) => { + gm(file).resize(size, size).toBuffer('JPEG', (err, buf) => { + resolve(err ? null : buf) + }) + }) + return buf +} + +r.get('/image/origin/:name', async (c, n) => { + c.state.ori = true + let name = c.params.name || '' + if (typeof name !== 'string' || name.trim().length === 0) c.throw('image name not valid', 400) + c.state.file = name + return n() +}, getImageToRes) + +r.get('/image/thumbnail/:name', async (c, n) => { + c.state.ori = false + let name = c.params.name || '' + if (typeof name !== 'string' || name.trim().length === 0) c.throw('image name not valid', 400) + c.state.file = name + return n() +}, getImageToRes) r.use('/line', require('./line').routes()) r.use('/google', require('./google').routes())