Added testing service
This commit is contained in:
parent
68e9d52ae5
commit
61e2da7163
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 90,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": false,
|
||||||
|
"endOfLine": "auto"
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"editor.bracketPairColorization.enabled": true,
|
||||||
|
"editor.guides.bracketPairs": true,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "images",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Image download scheduler as microservice",
|
||||||
|
"main": "server.js",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "node --watch src/server.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "r"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"images"
|
||||||
|
],
|
||||||
|
"author": "Verdnatura",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.3.4",
|
||||||
|
"gm": "^1.25.0",
|
||||||
|
"mariadb": "^3.1.0",
|
||||||
|
"pino": "^8.11.0",
|
||||||
|
"pino-pretty": "^10.0.0",
|
||||||
|
"uuid": "^9.0.0"
|
||||||
|
},
|
||||||
|
"imports": {
|
||||||
|
"#config/*": "./src/config/*.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier": "^2.8.4"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
import pino from 'pino'
|
||||||
|
|
||||||
|
export default pino({
|
||||||
|
transport: {
|
||||||
|
target: 'pino-pretty',
|
||||||
|
options: {
|
||||||
|
colorize: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,19 @@
|
||||||
|
import mariadb from 'mariadb'
|
||||||
|
import logger from '#config/logger'
|
||||||
|
|
||||||
|
const pool = mariadb.createPool({
|
||||||
|
host: 'localhost',
|
||||||
|
user: 'root',
|
||||||
|
password: 'root',
|
||||||
|
database: 'vn',
|
||||||
|
})
|
||||||
|
|
||||||
|
pool.on('error', (error) => {
|
||||||
|
if (error && error.message) logger.error(error.message)
|
||||||
|
})
|
||||||
|
|
||||||
|
pool.on('connection', () => {
|
||||||
|
logger.info('Database pool connection stablished')
|
||||||
|
})
|
||||||
|
|
||||||
|
export default pool
|
|
@ -0,0 +1,119 @@
|
||||||
|
import logger from '#config/logger'
|
||||||
|
import db from '#config/mariadb'
|
||||||
|
|
||||||
|
import { EventEmitter } from 'events'
|
||||||
|
import fs from 'fs/promises'
|
||||||
|
import { createWriteStream } from 'fs'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { v4 as uuid } from 'uuid'
|
||||||
|
|
||||||
|
import gm from 'gm'
|
||||||
|
|
||||||
|
const eventEmitter = new EventEmitter()
|
||||||
|
|
||||||
|
eventEmitter.on('queued', function () {
|
||||||
|
console.log('Queued')
|
||||||
|
})
|
||||||
|
|
||||||
|
eventEmitter.on('start', function () {
|
||||||
|
console.log('Job started')
|
||||||
|
})
|
||||||
|
|
||||||
|
eventEmitter.on('finish', function () {
|
||||||
|
logger.info('Job done')
|
||||||
|
setTimeout(queue, 5000)
|
||||||
|
})
|
||||||
|
|
||||||
|
// eventEmitter.emit('queued')
|
||||||
|
|
||||||
|
// const api = 'https://api.floriday.io/images/4f22b704-3192-432b-845c-206871ffb29d.jpg'
|
||||||
|
// const api = 'https://api.floriday.io/images/b1d9ee26-e68f-31b0-8f5d-749eee90499b.jpg'
|
||||||
|
// const api = 'https://api.floriday.io/images/9f5628f1-47dc-375b-af2a-fb5c57125ec9.jpg'
|
||||||
|
async function queue() {
|
||||||
|
eventEmitter.emit('start')
|
||||||
|
|
||||||
|
const transaction = await db.getConnection()
|
||||||
|
try {
|
||||||
|
await transaction.query('START TRANSACTION')
|
||||||
|
const [image] = await transaction.query(`
|
||||||
|
SELECT
|
||||||
|
itemFk,
|
||||||
|
url
|
||||||
|
FROM itemImageQueue
|
||||||
|
WHERE url IS NOT NULL
|
||||||
|
AND attempts < 3
|
||||||
|
ORDER BY priority, attempts, updated
|
||||||
|
LIMIT 1
|
||||||
|
`)
|
||||||
|
await transaction.query(
|
||||||
|
`
|
||||||
|
UPDATE itemImageQueue
|
||||||
|
SET error = "OK"
|
||||||
|
WHERE itemFk = ?
|
||||||
|
`,
|
||||||
|
[image.itemFk]
|
||||||
|
)
|
||||||
|
|
||||||
|
const sizes = await transaction.query(`
|
||||||
|
SELECT
|
||||||
|
size.width,
|
||||||
|
size.height,
|
||||||
|
size.crop,
|
||||||
|
collection.maxWidth,
|
||||||
|
collection.maxHeight,
|
||||||
|
collection.model,
|
||||||
|
collection.property
|
||||||
|
FROM hedera.imageCollection AS collection
|
||||||
|
JOIN hedera.imageCollectionSize AS size
|
||||||
|
ON size.collectionFk = collection.id
|
||||||
|
WHERE collection.name = 'catalog'
|
||||||
|
`)
|
||||||
|
|
||||||
|
const response = await axios.get(image.url, {
|
||||||
|
responseType: 'stream',
|
||||||
|
})
|
||||||
|
|
||||||
|
const fileName = `${uuid()}.jpeg`
|
||||||
|
|
||||||
|
const writeStream = createWriteStream(`./images/${fileName}`)
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
writeStream.on('open', () => response.data.pipe(writeStream))
|
||||||
|
writeStream.on('finish', () => resolve())
|
||||||
|
writeStream.on('error', (error) => reject(error))
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.info('Resizing...')
|
||||||
|
|
||||||
|
for (const size of sizes) {
|
||||||
|
const { width, height } = size
|
||||||
|
|
||||||
|
const path = `./images/${width}x${height}`
|
||||||
|
await fs.mkdir(path, { recursive: true })
|
||||||
|
|
||||||
|
const toPath = `${path}/${fileName}`
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
gm(`./images/${fileName}`)
|
||||||
|
.resize(width, height)
|
||||||
|
.setFormat('png')
|
||||||
|
.write(toPath, function (err) {
|
||||||
|
if (err) reject(err)
|
||||||
|
if (!err) resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
await transaction.query('COMMIT')
|
||||||
|
await transaction.release()
|
||||||
|
|
||||||
|
logger.info('Done')
|
||||||
|
|
||||||
|
eventEmitter.emit('finish')
|
||||||
|
} catch (error) {
|
||||||
|
logger.error(error)
|
||||||
|
await transaction.query('ROLLBACK')
|
||||||
|
await transaction.release()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue()
|
Reference in New Issue