T
T
TipaUser2019-04-12 19:10:22
Node.js
TipaUser, 2019-04-12 19:10:22

How to convert an application to use multiple configs?

Application - output of time, date and some additional. information using random images for the background.
Approximate view:
5cb0b7e32d111798554970.png
Essence:
How to remake this NodeJS application for the possibility of using several configs (for example, using recursively configs from the ./configs folder) and paths in the url-address (specified in the configs)?
Those.

./configs/config1.js -> address.com/generate1.jpg
./configs/config2.js -> address.com/generate2.jpg
./configs/config3.js -> address.com/generate3.jpg
.. .

Application itself:
const GIFEncoder = require('gifencoder');
    const pngFileStream = require('png-file-stream');
    const Promise = require('bluebird');
    const Jimp = require('jimp');
    const fs = require('fs');
    const gm = require('gm');
    const path = require('path');
    const express = require('express');
    const random = require('d3-random');
    const app = express();
    
    const width = 800;
    const height = 325;
    
    const encoder = new GIFEncoder(width, height);
    const now = () => new Date();
    
    const leadZeros = (value, count) => {
        value = value ? value.toString() : '';
        while (count > value.length) {
            value = '0' + value;
        }
        return value;
    }
    
    const widgets = {
        overlay: (canvas, options) => {
            const file = path.resolve(options.image);
            return canvas.draw([`image Over ${options.x},${options.y} ${options.width},${options.height} ${file}`]);
        },
        time: (canvas, options) => {
            return canvas.font(options.font || './files/16209.ttf', options.fontSize || 30)
                .fill(options.fontColor || '#eee')
                .gravity('Center')
                .drawText(options.x - Math.round(width / 2), options.y - Math.round(height / 2), `${leadZeros(now().getHours(), 2)}:${leadZeros(now().getMinutes(), 2)}`);
        },
        date: (canvas, options) => {
            return canvas.font(options.font || './files/16209.ttf', options.fontSize || 30)
                .fill(options.fontColor || '#eee')
                .gravity('Center')
                .drawText(options.x - Math.round(width / 2), options.y - Math.round(height / 2), `${leadZeros(now().getDate(), 2)}/${leadZeros(now().getMonth() + 1, 2)}`);
        },
        text: (canvas, options) => {
            return canvas.font(options.font || './files/16209.ttf', options.fontSize || 30)
                .fill(options.fontColor || '#eee')
                .gravity('Center')
                .drawText(options.x - Math.round(width / 2), options.y - Math.round(height / 2), options.text);
        },
        quality: (canvas, options) => {
            return canvas
                .quality(options.value);
        }
    };
    
    const config = {
        widgets: [
            { type: 'time', options: { x: 150, y: height - 150 } },
            { type: 'date', options: { x: width - 150, y: height - 150 } },
            { type: 'quality', options: { value: 80 } },
        ]
    };
    
    const preprocess = (dirName, fileName) => {
        const defer = new Promise((resolve, reject) => {
            const inputPath = path.join(dirName, fileName);
    
            let canvas = gm(inputPath);
            for (let i = 0; i < config.widgets.length; i++) {
                const widget = config.widgets[i];
                if (widgets[widget.type]) {
                    canvas = widgets[widget.type](canvas, widget.options);
                }
                else {
                    console.error(`Widget '${widget.type}' is not defined. Check your configuration declaration`);
                }
            }
            canvas.toBuffer('JPG', (err, buffer) => {
                resolve(buffer);
            });
        });
    
        return defer;
    };
    
    const randomizer = random.randomUniform(0, fs.readdirSync('./frames').length);
    const generate = () => {
        const filename = fs.readdirSync('./frames')[Math.floor(randomizer())];
        return preprocess('./frames', filename);
    };
    
    let cache = null;
    let cachedResult = null;
    app.get('/generate', function (req, res) {
        if (!cache || cache < new Date().getTime()) {
            cache = new Date().getTime() + 10000;
            cachedResult = generate();
        }
    
        cachedResult.then(result => {
            res.header('Content-Type', 'image/png');
            res.end(result);
    //		fs.writeFile('img.jpg', result, (err) => {
    //		});
        });
    });
    
    generate().then(() => {
        app.listen(3000, function () {
            console.log(`Img is running on:: 3000!`);
        });
    });

Dependencies:
{
      "dependencies": {
        "bluebird": "^3.5.1",
        "d3-random": "^1.1.0",
        "express": "^4.16.2",
        "gm": "^1.23.0"
      },
      "devDependencies": {
        "@types/bluebird": "^3.5.3",
        "typescript": "^2.3.2"
      }
    }

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
Timur Shemsedinov, 2020-08-01
@MarcusAurelius

1. What do you mean by "use recursively"?
2. Configs can be loaded via require, readFile,
3. Bluebird promises are no longer needed, there are native promises in the node
4. Why is there a typescript in dependencies if the application is based on js?
5. Why is there a library for random numbers in the dependencies, if there is Math.random?
6. Express is a fractal of shit code and should not be used anywhere
7. There are a lot of chord-coded things everywhere in the code, it's terrible
8. Argument values ​​change in functions, this is the closest way to confusion
9. Here is an example of a server with configs: https:// github.com/HowProgrammingWorks/NodejsStarterKit

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question