280 lines
7.0 KiB
JavaScript
Executable File
280 lines
7.0 KiB
JavaScript
Executable File
import inquirer from "inquirer";
|
|
import { MongoClient } from "mongodb";
|
|
import QRCode from "qrcode";
|
|
import { writeFileSync, mkdirSync } from "fs";
|
|
import Jimp from "jimp";
|
|
import path from "path";
|
|
import fs from "fs";
|
|
|
|
let url;
|
|
let client;
|
|
let db;
|
|
const dbName = "comfortech";
|
|
|
|
let host = "176.53.196.42";
|
|
let port = "27017";
|
|
let pass = "password";
|
|
let username = "user";
|
|
|
|
await inquirer
|
|
.prompt([
|
|
{
|
|
name: "host",
|
|
message: "Database host",
|
|
default: host,
|
|
},
|
|
{
|
|
name: "port",
|
|
message: "Database port",
|
|
default: "27017",
|
|
},
|
|
{
|
|
type: "list",
|
|
name: "credentials",
|
|
message: "Login as a specific user?",
|
|
choices: ["No", "Yes"],
|
|
},
|
|
])
|
|
.then(async answers => {
|
|
host = answers.host;
|
|
port = answers.port;
|
|
if (answers.credentials == "Yes") {
|
|
await inquirer
|
|
.prompt([
|
|
{
|
|
name: "username",
|
|
message: "Username",
|
|
default: "user",
|
|
},
|
|
{
|
|
name: "pass",
|
|
type: "password",
|
|
message: "Password",
|
|
},
|
|
])
|
|
.then(answers => {
|
|
username = answers.username;
|
|
pass = answers.pass;
|
|
});
|
|
}
|
|
});
|
|
|
|
async function ask_about_all_places(places) {
|
|
const flats_list = places.map(x => {
|
|
return `${x.name} ${x._id.toString()}`;
|
|
});
|
|
return await inquirer
|
|
.prompt([
|
|
{
|
|
name: "all",
|
|
message: "Generate QR codes for all places",
|
|
type: "confirm",
|
|
default: false,
|
|
},
|
|
])
|
|
.then(async answers => {
|
|
if (answers.all) {
|
|
return {
|
|
all: true,
|
|
ids: flats_list,
|
|
};
|
|
} else {
|
|
const place_ids = await inquirer
|
|
.prompt([
|
|
{
|
|
name: "flats",
|
|
message: "Choose flat numbers",
|
|
type: "checkbox",
|
|
choices: flats_list,
|
|
},
|
|
])
|
|
.then(async answers => {
|
|
// return answers.flats.map(num => num.split(" ")[1]);
|
|
return answers.flats;
|
|
});
|
|
return { all: false, ids: place_ids };
|
|
}
|
|
});
|
|
}
|
|
|
|
async function ask_size() {
|
|
return await inquirer.prompt([
|
|
{
|
|
name: "size",
|
|
type: "number",
|
|
message: "Size of a side in px",
|
|
default: "354",
|
|
},
|
|
]);
|
|
}
|
|
|
|
async function ask_to_override_existing(ids) {
|
|
ids = ids.map(item => item.split(" ")[1]);
|
|
console.log("\n\n", ids, "\n\n");
|
|
await db
|
|
.createCollection("qr_code")
|
|
.then(res => {
|
|
console.log("Collection created");
|
|
})
|
|
.catch(err => {
|
|
if (err.code == 48) {
|
|
console.info("Collection exists");
|
|
} else {
|
|
console.error("Error:", err);
|
|
}
|
|
});
|
|
const collection = await db.collection("qr_code");
|
|
|
|
const override = await inquirer
|
|
.prompt([
|
|
{
|
|
name: "override",
|
|
message: "If QR codes exist for chosen places",
|
|
type: "list",
|
|
choices: ["Skip", "Replace"],
|
|
default: "Replace",
|
|
},
|
|
])
|
|
.then(answer => {
|
|
return answer.override == "Skip" ? false : true;
|
|
});
|
|
|
|
if (override) {
|
|
const res = await collection.deleteMany({
|
|
place_id: {
|
|
$in: [...ids],
|
|
},
|
|
});
|
|
} else {
|
|
let res = collection.find({
|
|
place_id: {
|
|
$in: [...ids],
|
|
},
|
|
});
|
|
const existing_qrs = await res.toArray();
|
|
const exclude_places = existing_qrs.map(el => el.place_id);
|
|
console.log(`Skiped ${exclude_places.length}/${ids.length} places (QR code exists)`);
|
|
|
|
exclude_places.forEach(place_id => {
|
|
const index = ids.indexOf(place_id);
|
|
if (index !== -1) {
|
|
ids.splice(index, 1);
|
|
}
|
|
});
|
|
console.log(ids.length, "places left");
|
|
}
|
|
|
|
if (ids.length == 0) return [];
|
|
|
|
let qrcode_ids = [];
|
|
let docs = [];
|
|
|
|
await ids.forEach(async place_id => {
|
|
docs.push({
|
|
place_id,
|
|
one_time: false,
|
|
});
|
|
});
|
|
|
|
const res = await collection
|
|
.insertMany(docs)
|
|
.then(res => {
|
|
return res;
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
});
|
|
|
|
for (const [key, value] of Object.entries(res.insertedIds)) {
|
|
qrcode_ids.push(value.toString());
|
|
}
|
|
|
|
return qrcode_ids;
|
|
}
|
|
|
|
function getAvailableName(fullpath) {
|
|
let dir = path.dirname(fullpath);
|
|
let base = path.basename(fullpath);
|
|
for (let i = 0; fs.existsSync(fullpath); i++) {
|
|
let items = base.split(".");
|
|
fullpath = dir + "/" + items[0] + "_" + i + "." + items[1];
|
|
}
|
|
return fullpath;
|
|
}
|
|
|
|
// Connection URL
|
|
async function main() {
|
|
url = `mongodb://${username ? username + ":" + pass + "@" : ""}${host}:${port}`;
|
|
client = new MongoClient(url);
|
|
|
|
// Use connect method to connect to the server
|
|
await client.connect();
|
|
db = client.db(dbName);
|
|
console.info("Connected successfully");
|
|
const place_col = db.collection("place");
|
|
|
|
const places = place_col.find({ place_type: "flat" });
|
|
console.info(await place_col.countDocuments({ place_type: "flat" }), "places found");
|
|
|
|
const flats = await ask_about_all_places(await places.toArray());
|
|
console.info(`Generate QR codes for ${flats.ids.length} places`);
|
|
console.info(`Places: ${flats.ids} `);
|
|
|
|
const qrcode_ids = await ask_to_override_existing(flats.ids);
|
|
console.log(qrcode_ids.length, "QR codes generated in data base");
|
|
await client.close();
|
|
|
|
const qr_size = parseInt((await ask_size()).size);
|
|
console.log(qr_size, "px");
|
|
|
|
const folder = new Date().valueOf();
|
|
mkdirSync("out/" + folder, { recursive: true });
|
|
qrcode_ids.forEach(async qr => {
|
|
QRCode.toDataURL(qr, {
|
|
errorCorrectionLevel: "H",
|
|
scale: 3,
|
|
margin: 5,
|
|
width: 512,
|
|
color: { light: "#fafafa", dark: "#121212" },
|
|
})
|
|
.then(url => {
|
|
const base64Data = url.replace(/^data:image\/png;base64,/, "");
|
|
const index = qrcode_ids.indexOf(qr);
|
|
let fileName = `./out/${folder}/${flats.ids[index].split(" ")[0]}.png`;
|
|
fileName = getAvailableName(fileName);
|
|
writeFileSync(`${fileName}`, base64Data, "base64");
|
|
|
|
const imageCaption = "KB. " + flats.ids[index].split(" ")[0];
|
|
let loadedImage;
|
|
|
|
Jimp.read(fileName)
|
|
.then(function (image) {
|
|
loadedImage = image;
|
|
var fontpath = path.join(process.cwd(), "opensans/open_sans_32.fnt");
|
|
return Jimp.loadFont(fontpath);
|
|
})
|
|
.then(function (font) {
|
|
loadedImage.print(font, 204, 12, imageCaption).write(fileName);
|
|
const isHorizontal = loadedImage.getWidth() > loadedImage.getHeight();
|
|
|
|
const ratio = isHorizontal
|
|
? loadedImage.getWidth() / loadedImage.getHeight()
|
|
: loadedImage.getHeight() / loadedImage.getWidth();
|
|
const width = qr_size; // set the width you want
|
|
const height = isHorizontal ? width / ratio : width * ratio;
|
|
|
|
return loadedImage.resize(width, height, Jimp.RESIZE_BICUBIC).quality(60).write(fileName);
|
|
})
|
|
.catch(function (err) {
|
|
console.error(err);
|
|
});
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
});
|
|
});
|
|
}
|
|
|
|
await main();
|
|
console.log("Exited");
|