added qr_tool and db_tool
This commit is contained in:
commit
166bee898e
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Comfortech ulitls
|
||||
Tools for routine operations acceleration
|
||||
___
|
||||
|
||||
|
||||
### DB Tool
|
||||
|
||||
- Dump Database
|
||||
- Restore Database
|
||||
|
||||
### QR Tool
|
||||
|
||||
- Create/Update QR codes for userplaces
|
||||
- Download just created QR code images
|
||||
|
3
db_tool/.gitignore
vendored
Normal file
3
db_tool/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/dist
|
||||
/node_modules
|
||||
/dumps
|
14
db_tool/README.md
Normal file
14
db_tool/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Mongo buckup tool
|
||||
|
||||
- create backup of database
|
||||
- restore from local folder
|
||||
|
||||
**Backups goes to `dump` folder**
|
||||
|
||||
## Setup
|
||||
|
||||
`npm i`
|
||||
|
||||
## Usage
|
||||
|
||||
`npm run start`
|
163
db_tool/main.js
Normal file
163
db_tool/main.js
Normal file
@ -0,0 +1,163 @@
|
||||
import { exec, spawn } from "child_process";
|
||||
import { readdir } from "fs/promises";
|
||||
import inquirer from "inquirer";
|
||||
import moment from "moment";
|
||||
import { MongoClient } from "mongodb";
|
||||
|
||||
const prompt = inquirer.createPromptModule();
|
||||
|
||||
const getDirectories = async source =>
|
||||
(await readdir(source, { withFileTypes: true }))
|
||||
.filter(dirent => dirent.isDirectory())
|
||||
.map(dirent => dirent.name);
|
||||
|
||||
async function performBackup(databaseName) {
|
||||
try {
|
||||
const timestamp = moment().format("DD.MM.YYYY_HHmmss");
|
||||
const { backupFolder } = await prompt([
|
||||
{
|
||||
type: "input",
|
||||
name: "backupFolder",
|
||||
message: "Enter the backup folder path (leave empty for default):",
|
||||
default: `${databaseName}_${timestamp}`,
|
||||
},
|
||||
]);
|
||||
|
||||
const folderName = "dumps/" + backupFolder;
|
||||
const backupCommand = `mongodump --db ${databaseName} --out ${folderName}`;
|
||||
|
||||
console.log(`Creating backup of database ${databaseName}...`);
|
||||
await exec(backupCommand);
|
||||
|
||||
console.log(`Backup created successfully in folder ${folderName}.`);
|
||||
} catch (error) {
|
||||
console.error("An error occurred during the backup process:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function performRestore(restoreFolder, uri) {
|
||||
try {
|
||||
console.log(`Restoring database from folder ${restoreFolder}...`);
|
||||
let ls = spawn("mongorestore", ["--uri", uri, "--drop", restoreFolder]);
|
||||
|
||||
ls.stdout.on("data", function (data) {
|
||||
console.log(data.toString());
|
||||
});
|
||||
|
||||
ls.stderr.on("data", function (data) {
|
||||
console.log(data.toString());
|
||||
});
|
||||
|
||||
ls.on("exit", function (code) {
|
||||
console.log("child process exited with code " + code.toString());
|
||||
});
|
||||
|
||||
console.log("Database restored successfully.");
|
||||
} catch (error) {
|
||||
console.error("An error occurred during the restore process:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function generateConnectionString({ username, password, host, port }) {
|
||||
let credentials = "";
|
||||
|
||||
if (username && password) {
|
||||
credentials = `${username}:${password}@`;
|
||||
}
|
||||
|
||||
const uri = `mongodb://${credentials}${host}:${port}`;
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
const credentials = await prompt([
|
||||
{
|
||||
type: "input",
|
||||
name: "username",
|
||||
message: "Enter your MongoDB username:",
|
||||
},
|
||||
{
|
||||
type: "password",
|
||||
name: "password",
|
||||
message: "Enter your MongoDB password:",
|
||||
},
|
||||
{
|
||||
type: "input",
|
||||
name: "host",
|
||||
message: "Enter the MongoDB host:",
|
||||
default: "localhost",
|
||||
},
|
||||
{
|
||||
type: "input",
|
||||
name: "port",
|
||||
message: "Enter the MongoDB port:",
|
||||
default: "27017",
|
||||
},
|
||||
]);
|
||||
|
||||
const uri = generateConnectionString(credentials);
|
||||
|
||||
const client = new MongoClient(uri);
|
||||
|
||||
await client.connect();
|
||||
console.log("Connected to MongoDB successfully.");
|
||||
|
||||
const { action } = await prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "action",
|
||||
message: "Choose an action:",
|
||||
choices: ["Backup", "Restore"],
|
||||
},
|
||||
]);
|
||||
|
||||
if (action === "Backup") {
|
||||
const { databaseName } = await prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "databaseName",
|
||||
message: "Choose a database to backup:",
|
||||
choices: await client
|
||||
.db()
|
||||
.admin()
|
||||
.listDatabases()
|
||||
.then(({ databases }) => databases.map(({ name }) => name)),
|
||||
},
|
||||
]);
|
||||
|
||||
await performBackup(databaseName);
|
||||
} else if (action === "Restore") {
|
||||
try {
|
||||
const dirs = await getDirectories("./dumps");
|
||||
const { restoreFolder } = await prompt([
|
||||
{
|
||||
type: "list",
|
||||
name: "restoreFolder",
|
||||
message: "Choose the folder to restore from:",
|
||||
choices: dirs,
|
||||
},
|
||||
]);
|
||||
|
||||
await performRestore("./dumps/" + restoreFolder, uri);
|
||||
} catch (err) {
|
||||
if (err.errno === -2) {
|
||||
console.log("No 'dumps' dir found");
|
||||
} else {
|
||||
throw new Error(err);
|
||||
}
|
||||
console.log("Disconnected from MongoDB.");
|
||||
await client.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await client.close();
|
||||
console.log("Disconnected from MongoDB.");
|
||||
} catch (error) {
|
||||
console.error("An error occurred:", error);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
1928
db_tool/package-lock.json
generated
Normal file
1928
db_tool/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
db_tool/package.json
Normal file
18
db_tool/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "backup_mongo",
|
||||
"version": "1.0.0",
|
||||
"description": "backup and restore mongo collections",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "node main",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Cawa",
|
||||
"license": "ISC",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"inquirer": "^9.2.6",
|
||||
"moment": "^2.29.4",
|
||||
"mongodb": "^5.5.0"
|
||||
}
|
||||
}
|
3
qr_tool/.gitignore
vendored
Normal file
3
qr_tool/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/dist
|
||||
/node_modules
|
||||
/out
|
25
qr_tool/README.md
Normal file
25
qr_tool/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# QR codes generator
|
||||
|
||||
### Usage
|
||||
|
||||
```shell
|
||||
npm i
|
||||
node index.js
|
||||
```
|
||||
|
||||
To create qrs you need enter
|
||||
|
||||
- Database IP address
|
||||
- Database external port
|
||||
- Username
|
||||
- Password
|
||||
|
||||
After that
|
||||
|
||||
- Choose **places** to generate QR codes
|
||||
- Choose **skip** existing qrcodes for selected places or **replace** with new
|
||||
- Choose **size of image** to save
|
||||
|
||||
### Result
|
||||
|
||||
Folder `./out` will contain folders with png files.
|
279
qr_tool/index.js
Executable file
279
qr_tool/index.js
Executable file
@ -0,0 +1,279 @@
|
||||
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");
|
BIN
qr_tool/opensans/open-sans-32.png
Normal file
BIN
qr_tool/opensans/open-sans-32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
99
qr_tool/opensans/open_sans_32.fnt
Normal file
99
qr_tool/opensans/open_sans_32.fnt
Normal file
@ -0,0 +1,99 @@
|
||||
info face="Open Sans" size=-32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=0 aa=1 padding=0,0,0,0 spacing=0,0 outline=0
|
||||
common lineHeight=44 base=35 scaleW=256 scaleH=128 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
|
||||
page id=0 file="open-sans-32.png"
|
||||
chars count=95
|
||||
char id=32 x=0 y=0 width=0 height=0 xoffset=0 yoffset=0 xadvance=8 page=0 chnl=15
|
||||
char id=33 x=248 y=29 width=4 height=24 xoffset=2 yoffset=11 xadvance=8 page=0 chnl=15
|
||||
char id=34 x=59 y=72 width=9 height=9 xoffset=2 yoffset=11 xadvance=13 page=0 chnl=15
|
||||
char id=35 x=46 y=24 width=19 height=24 xoffset=1 yoffset=11 xadvance=21 page=0 chnl=15
|
||||
char id=36 x=100 y=74 width=15 height=27 xoffset=2 yoffset=10 xadvance=19 page=0 chnl=15
|
||||
char id=37 x=0 y=81 width=24 height=24 xoffset=2 yoffset=11 xadvance=27 page=0 chnl=15
|
||||
char id=38 x=24 y=81 width=22 height=24 xoffset=2 yoffset=11 xadvance=24 page=0 chnl=15
|
||||
char id=39 x=73 y=72 width=3 height=9 xoffset=2 yoffset=11 xadvance=7 page=0 chnl=15
|
||||
char id=40 x=228 y=0 width=8 height=29 xoffset=1 yoffset=11 xadvance=9 page=0 chnl=15
|
||||
char id=41 x=236 y=0 width=8 height=29 xoffset=1 yoffset=11 xadvance=10 page=0 chnl=15
|
||||
char id=42 x=212 y=15 width=16 height=15 xoffset=1 yoffset=10 xadvance=18 page=0 chnl=15
|
||||
char id=43 x=211 y=35 width=15 height=16 xoffset=2 yoffset=15 xadvance=19 page=0 chnl=15
|
||||
char id=44 x=68 y=72 width=5 height=8 xoffset=1 yoffset=31 xadvance=8 page=0 chnl=15
|
||||
char id=45 x=28 y=75 width=8 height=3 xoffset=1 yoffset=24 xadvance=10 page=0 chnl=15
|
||||
char id=46 x=36 y=75 width=4 height=4 xoffset=2 yoffset=31 xadvance=8 page=0 chnl=15
|
||||
char id=47 x=176 y=24 width=12 height=24 xoffset=0 yoffset=11 xadvance=12 page=0 chnl=15
|
||||
char id=48 x=123 y=0 width=15 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=49 x=229 y=48 width=9 height=24 xoffset=3 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=50 x=132 y=48 width=15 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=51 x=133 y=24 width=15 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=52 x=83 y=76 width=17 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=53 x=138 y=0 width=15 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=54 x=130 y=97 width=15 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=55 x=145 y=72 width=15 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=56 x=147 y=48 width=15 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=57 x=148 y=24 width=15 height=24 xoffset=2 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=58 x=217 y=89 width=4 height=18 xoffset=2 yoffset=17 xadvance=8 page=0 chnl=15
|
||||
char id=59 x=223 y=69 width=6 height=22 xoffset=0 yoffset=17 xadvance=8 page=0 chnl=15
|
||||
char id=60 x=195 y=72 width=15 height=17 xoffset=2 yoffset=15 xadvance=19 page=0 chnl=15
|
||||
char id=61 x=44 y=72 width=15 height=9 xoffset=2 yoffset=19 xadvance=19 page=0 chnl=15
|
||||
char id=62 x=197 y=18 width=15 height=17 xoffset=2 yoffset=15 xadvance=19 page=0 chnl=15
|
||||
char id=63 x=162 y=48 width=13 height=24 xoffset=0 yoffset=11 xadvance=14 page=0 chnl=15
|
||||
char id=64 x=0 y=24 width=25 height=27 xoffset=2 yoffset=11 xadvance=29 page=0 chnl=15
|
||||
char id=65 x=25 y=24 width=21 height=24 xoffset=0 yoffset=11 xadvance=20 page=0 chnl=15
|
||||
char id=66 x=116 y=48 width=16 height=24 xoffset=3 yoffset=11 xadvance=20 page=0 chnl=15
|
||||
char id=67 x=65 y=24 width=18 height=24 xoffset=2 yoffset=11 xadvance=20 page=0 chnl=15
|
||||
char id=68 x=70 y=0 width=18 height=24 xoffset=3 yoffset=11 xadvance=23 page=0 chnl=15
|
||||
char id=69 x=163 y=24 width=13 height=24 xoffset=3 yoffset=11 xadvance=17 page=0 chnl=15
|
||||
char id=70 x=168 y=0 width=13 height=24 xoffset=3 yoffset=11 xadvance=16 page=0 chnl=15
|
||||
char id=71 x=51 y=0 width=19 height=24 xoffset=2 yoffset=11 xadvance=23 page=0 chnl=15
|
||||
char id=72 x=99 y=50 width=17 height=24 xoffset=3 yoffset=11 xadvance=23 page=0 chnl=15
|
||||
char id=73 x=248 y=53 width=3 height=24 xoffset=3 yoffset=11 xadvance=9 page=0 chnl=15
|
||||
char id=74 x=188 y=24 width=9 height=30 xoffset=-3 yoffset=11 xadvance=9 page=0 chnl=15
|
||||
char id=75 x=100 y=24 width=17 height=24 xoffset=3 yoffset=11 xadvance=20 page=0 chnl=15
|
||||
char id=76 x=175 y=48 width=13 height=24 xoffset=3 yoffset=11 xadvance=17 page=0 chnl=15
|
||||
char id=77 x=21 y=51 width=23 height=24 xoffset=3 yoffset=11 xadvance=29 page=0 chnl=15
|
||||
char id=78 x=65 y=81 width=18 height=24 xoffset=3 yoffset=11 xadvance=24 page=0 chnl=15
|
||||
char id=79 x=30 y=0 width=21 height=24 xoffset=2 yoffset=11 xadvance=25 page=0 chnl=15
|
||||
char id=80 x=153 y=0 width=15 height=24 xoffset=3 yoffset=11 xadvance=19 page=0 chnl=15
|
||||
char id=81 x=0 y=51 width=21 height=30 xoffset=2 yoffset=11 xadvance=25 page=0 chnl=15
|
||||
char id=82 x=106 y=0 width=17 height=24 xoffset=3 yoffset=11 xadvance=20 page=0 chnl=15
|
||||
char id=83 x=145 y=96 width=15 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=84 x=83 y=100 width=17 height=24 xoffset=1 yoffset=11 xadvance=19 page=0 chnl=15
|
||||
char id=85 x=88 y=0 width=18 height=24 xoffset=3 yoffset=11 xadvance=24 page=0 chnl=15
|
||||
char id=86 x=44 y=48 width=20 height=24 xoffset=0 yoffset=11 xadvance=19 page=0 chnl=15
|
||||
char id=87 x=0 y=0 width=30 height=24 xoffset=0 yoffset=11 xadvance=30 page=0 chnl=15
|
||||
char id=88 x=46 y=81 width=19 height=24 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=89 x=64 y=48 width=19 height=24 xoffset=0 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=90 x=117 y=24 width=16 height=24 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=91 x=210 y=89 width=7 height=29 xoffset=3 yoffset=11 xadvance=11 page=0 chnl=15
|
||||
char id=92 x=181 y=0 width=12 height=24 xoffset=0 yoffset=11 xadvance=12 page=0 chnl=15
|
||||
char id=93 x=244 y=0 width=8 height=29 xoffset=0 yoffset=11 xadvance=10 page=0 chnl=15
|
||||
char id=94 x=208 y=0 width=17 height=15 xoffset=1 yoffset=11 xadvance=18 page=0 chnl=15
|
||||
char id=95 x=15 y=123 width=14 height=3 xoffset=0 yoffset=37 xadvance=14 page=0 chnl=15
|
||||
char id=96 x=21 y=75 width=7 height=6 xoffset=1 yoffset=9 xadvance=9 page=0 chnl=15
|
||||
char id=97 x=197 y=35 width=14 height=18 xoffset=1 yoffset=17 xadvance=17 page=0 chnl=15
|
||||
char id=98 x=115 y=100 width=15 height=25 xoffset=3 yoffset=10 xadvance=20 page=0 chnl=15
|
||||
char id=99 x=210 y=71 width=13 height=18 xoffset=2 yoffset=17 xadvance=15 page=0 chnl=15
|
||||
char id=100 x=130 y=72 width=15 height=25 xoffset=2 yoffset=10 xadvance=20 page=0 chnl=15
|
||||
char id=101 x=188 y=54 width=15 height=18 xoffset=2 yoffset=17 xadvance=18 page=0 chnl=15
|
||||
char id=102 x=174 y=101 width=12 height=26 xoffset=1 yoffset=9 xadvance=12 page=0 chnl=15
|
||||
char id=103 x=83 y=50 width=16 height=26 xoffset=1 yoffset=17 xadvance=18 page=0 chnl=15
|
||||
char id=104 x=160 y=72 width=14 height=25 xoffset=3 yoffset=10 xadvance=20 page=0 chnl=15
|
||||
char id=105 x=251 y=58 width=3 height=24 xoffset=3 yoffset=11 xadvance=8 page=0 chnl=15
|
||||
char id=106 x=202 y=89 width=8 height=32 xoffset=-2 yoffset=11 xadvance=8 page=0 chnl=15
|
||||
char id=107 x=160 y=97 width=14 height=25 xoffset=3 yoffset=10 xadvance=17 page=0 chnl=15
|
||||
char id=108 x=252 y=33 width=3 height=25 xoffset=3 yoffset=10 xadvance=8 page=0 chnl=15
|
||||
char id=109 x=0 y=105 width=25 height=18 xoffset=3 yoffset=17 xadvance=30 page=0 chnl=15
|
||||
char id=110 x=203 y=53 width=14 height=18 xoffset=3 yoffset=17 xadvance=20 page=0 chnl=15
|
||||
char id=111 x=67 y=105 width=16 height=18 xoffset=2 yoffset=17 xadvance=19 page=0 chnl=15
|
||||
char id=112 x=100 y=101 width=15 height=26 xoffset=3 yoffset=17 xadvance=20 page=0 chnl=15
|
||||
char id=113 x=115 y=74 width=15 height=26 xoffset=2 yoffset=17 xadvance=20 page=0 chnl=15
|
||||
char id=114 x=238 y=51 width=10 height=18 xoffset=3 yoffset=17 xadvance=13 page=0 chnl=15
|
||||
char id=115 x=217 y=51 width=12 height=18 xoffset=2 yoffset=17 xadvance=15 page=0 chnl=15
|
||||
char id=116 x=238 y=29 width=10 height=22 xoffset=1 yoffset=13 xadvance=12 page=0 chnl=15
|
||||
char id=117 x=193 y=0 width=15 height=18 xoffset=3 yoffset=17 xadvance=20 page=0 chnl=15
|
||||
char id=118 x=186 y=101 width=16 height=18 xoffset=0 yoffset=17 xadvance=16 page=0 chnl=15
|
||||
char id=119 x=25 y=105 width=25 height=18 xoffset=0 yoffset=17 xadvance=25 page=0 chnl=15
|
||||
char id=120 x=50 y=105 width=17 height=18 xoffset=0 yoffset=17 xadvance=17 page=0 chnl=15
|
||||
char id=121 x=83 y=24 width=17 height=26 xoffset=-1 yoffset=17 xadvance=16 page=0 chnl=15
|
||||
char id=122 x=226 y=30 width=12 height=18 xoffset=1 yoffset=17 xadvance=14 page=0 chnl=15
|
||||
char id=123 x=185 y=72 width=10 height=29 xoffset=1 yoffset=11 xadvance=12 page=0 chnl=15
|
||||
char id=124 x=252 y=0 width=3 height=33 xoffset=8 yoffset=10 xadvance=18 page=0 chnl=15
|
||||
char id=125 x=174 y=72 width=11 height=29 xoffset=1 yoffset=11 xadvance=12 page=0 chnl=15
|
||||
char id=126 x=0 y=123 width=15 height=5 xoffset=2 yoffset=20 xadvance=19 page=0 chnl=15
|
6064
qr_tool/package-lock.json
generated
Executable file
6064
qr_tool/package-lock.json
generated
Executable file
File diff suppressed because it is too large
Load Diff
22
qr_tool/package.json
Executable file
22
qr_tool/package.json
Executable file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "qr_code_generator",
|
||||
"version": "1.0.0",
|
||||
"description": "Genetares QR codes for places",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node --experimental-modules index.js",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"type": "module",
|
||||
"author": "Alexander Evsikov",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"easyqrcodejs": "^4.4.13",
|
||||
"inquirer": "^9.1.4",
|
||||
"jimp": "^0.16.2",
|
||||
"jsdom": "^20.0.3",
|
||||
"mongodb": "^4.12.1",
|
||||
"qr-image": "^3.2.0",
|
||||
"qrcode": "^1.5.1"
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user