161 lines
4.4 KiB
JavaScript
161 lines
4.4 KiB
JavaScript
import config from '../../config/config.js';
|
|
import fs from "fs";
|
|
import db from "../../config/database.js";
|
|
import archiver from "archiver";
|
|
import decompress from "decompress";
|
|
import bot from "../../context/bot.js";
|
|
import userStates from "../../context/userStates.js";
|
|
|
|
export default class AdminDumpHandler {
|
|
static isAdmin(userId) {
|
|
return config.ADMIN_IDS.includes(userId.toString());
|
|
}
|
|
|
|
static async handleDump(msg) {
|
|
const chatId = msg.chat.id;
|
|
|
|
if (!this.isAdmin(msg.from.id)) {
|
|
await bot.sendMessage(chatId, 'Unauthorized access.');
|
|
return;
|
|
}
|
|
|
|
const keyboard = {
|
|
inline_keyboard: [
|
|
[
|
|
{text: '📥 Import dump', callback_data: 'import_database'},
|
|
{text: '📤 Export dump', callback_data: 'export_database'},
|
|
],
|
|
[{text: '« Back', callback_data: 'admin_menu'}]
|
|
]
|
|
}
|
|
|
|
await bot.sendMessage(chatId, 'Choose an option', {reply_markup: keyboard});
|
|
}
|
|
|
|
static async handleExportDatabase(callbackQuery) {
|
|
if (!this.isAdmin(callbackQuery.from.id)) {
|
|
return;
|
|
}
|
|
|
|
const chatId = callbackQuery.message.chat.id;
|
|
|
|
const tables = [
|
|
"categories",
|
|
"crypto_wallets",
|
|
"locations",
|
|
"products",
|
|
"purchases",
|
|
"transactions",
|
|
"users"
|
|
]
|
|
|
|
const dumpPath = "./dump"
|
|
|
|
try {
|
|
fs.rmdirSync(dumpPath, {recursive: true, force: true});
|
|
fs.rmSync(`${dumpPath}/dump.zip`);
|
|
} catch (e) {
|
|
|
|
}
|
|
|
|
fs.mkdirSync(dumpPath);
|
|
|
|
for (const table of tables) {
|
|
const result = await db.allAsync(`SELECT * FROM ${table}`);
|
|
const tableData = JSON.stringify(result);
|
|
fs.writeFileSync(`${dumpPath}/${table}.json`, tableData);
|
|
}
|
|
|
|
const archive = archiver('zip', {zlib: { level: 9 } });
|
|
archive.directory(dumpPath, false);
|
|
|
|
const output = fs.createWriteStream('./dump.zip');
|
|
archive.pipe(output);
|
|
|
|
await archive.finalize();
|
|
|
|
output.on('close', () => {
|
|
bot.sendDocument(chatId, './dump.zip', {caption: 'Database dump'});
|
|
});
|
|
}
|
|
|
|
static async handleImportDatabase(callbackQuery) {
|
|
if (!this.isAdmin(callbackQuery.from.id)) {
|
|
return;
|
|
}
|
|
|
|
const chatId = callbackQuery.message.chat.id;
|
|
|
|
userStates.set(chatId, { action: 'upload_database_dump' });
|
|
|
|
await bot.editMessageText(
|
|
'Please upload database dump',
|
|
{
|
|
chat_id: chatId,
|
|
message_id: callbackQuery.message.message_id,
|
|
}
|
|
);
|
|
}
|
|
|
|
static async getDumpStatistic() {
|
|
const tables = [
|
|
"categories",
|
|
"crypto_wallets",
|
|
"locations",
|
|
"products",
|
|
"purchases",
|
|
"transactions",
|
|
"users"
|
|
]
|
|
|
|
const stat = {}
|
|
|
|
for (const table of tables) {
|
|
const jsonContent = await fs.readFileSync(`./dump/${table}.json`, 'utf8');
|
|
const data = JSON.parse(jsonContent);
|
|
stat[table] = data.length
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
static async handleDumpImport(msg) {
|
|
const chatId = msg.chat.id;
|
|
|
|
const state = userStates.get(chatId);
|
|
|
|
if (!state || state.action !== 'upload_database_dump') {
|
|
return false;
|
|
}
|
|
|
|
if (!this.isAdmin(msg.from.id)) {
|
|
await bot.sendMessage(chatId, 'Unauthorized access.');
|
|
return;
|
|
}
|
|
|
|
if (msg.document) {
|
|
if (!msg.document.file_name.endsWith('.zip')) {
|
|
await bot.sendMessage(chatId, 'Please upload a .zip file.');
|
|
return true;
|
|
}
|
|
|
|
const file = await bot.getFile(msg.document.file_id);
|
|
const fileContent = await bot.downloadFile(file.file_id, '.');
|
|
|
|
await decompress(fileContent, './dump');
|
|
|
|
const statistics = await this.getDumpStatistic();
|
|
await bot.sendMessage(chatId, JSON.stringify(statistics, null, 2));
|
|
userStates.delete(chatId);
|
|
} else {
|
|
await bot.sendMessage(chatId, 'Please upload a valid .zip file.');
|
|
return true;
|
|
}
|
|
}
|
|
|
|
static async confirmImport(callbackQuery) {
|
|
if (!this.isAdmin(callbackQuery.from.id)) {
|
|
return;
|
|
}
|
|
}
|
|
} |