teleAuctionBot / import_characters.js
amanfor18's picture
Upload 15 files
21011e9 verified
Raw
History Blame Contribute Delete
6.08 kB
require("dotenv").config();
const fs = require("fs");
const path = require("path");
const { MongoClient } = require("mongodb");
const DB_FILE = path.join(__dirname, "db.json");
const CSV_FILE = path.join(__dirname, "characters.csv");
// Helper to parse a CSV line, respecting double quotes
function parseCSVLine(line) {
const result = [];
let current = "";
let inQuotes = false;
for (let i = 0; i < line.length; i++) {
const char = line[i];
if (char === '"') {
inQuotes = !inQuotes;
} else if (char === "," && !inQuotes) {
result.push(current.trim());
current = "";
} else {
current += char;
}
}
result.push(current.trim());
return result;
}
// Generate template if CSV does not exist
if (!fs.existsSync(CSV_FILE)) {
const templateContent = `Name,Base price,features,Image URL 1,Caption 1,Image URL 2,Caption 2,Image URL 3,CAption 3,Category
Goku,100,"Series: Dragon Ball; Rarity: SSR",AgACAg...,Goku Super Saiyan,AgACAg...,Goku Base Form,,,Anime
Naruto,80,"Series: Naruto; Rarity: SR",AgACAg...,Naruto Sage Mode,,,,,,Anime
Luffy,90,"Series: One Piece; Rarity: UR",AgACAg...,Luffy Gear 5,,,,,,Anime
`;
fs.writeFileSync(CSV_FILE, templateContent, "utf8");
console.log("๐Ÿ“ No 'characters.csv' file was found.");
console.log("โœ… Created a sample 'characters.csv' with the requested columns!");
console.log("โ„น๏ธ Open 'characters.csv' in Excel/Google Sheets, add your characters, and run this script again.");
process.exit(0);
}
const fileContent = fs.readFileSync(CSV_FILE, "utf8");
const lines = fileContent.split(/\r?\n/).filter((line) => line.trim() !== "");
if (lines.length <= 1) {
console.log("โš ๏ธ The 'characters.csv' file is empty or only contains the header row.");
process.exit(0);
}
// Skip header
const header = lines[0];
const dataLines = lines.slice(1);
let successCount = 0;
let failCount = 0;
const errors = [];
const importedChars = [];
dataLines.forEach((line, index) => {
const lineNum = index + 2; // 1-indexed plus header line offset
const parts = parseCSVLine(line);
// We expect at least the first 3 columns
if (parts.length < 3) {
failCount++;
errors.push(`Line ${lineNum}: Missing core columns (Expected Name, Base price, features)`);
return;
}
const name = parts[0];
const basePriceVal = parts[1];
const featuresRaw = parts[2];
const img1 = parts[3];
const cap1 = parts[4];
const img2 = parts[5];
const cap2 = parts[6];
const img3 = parts[7];
const cap3 = parts[8];
const category = parts[9];
if (!name) {
failCount++;
errors.push(`Line ${lineNum}: Character Name is required.`);
return;
}
const base_price = parseInt(basePriceVal, 10);
if (isNaN(base_price) || base_price < 0) {
failCount++;
errors.push(`Line ${lineNum}: Invalid Base Price '${basePriceVal}'. Must be a non-negative number.`);
return;
}
// Parse features (separated by ;)
const features = featuresRaw
? featuresRaw
.split(";")
.map((f) => f.trim())
.filter((f) => f.length > 0)
: [];
// Build image_url list
const image_url = [];
if (img1) {
if (cap1) {
image_url.push({ file_id: img1, caption: cap1 });
} else {
image_url.push(img1);
}
}
if (img2) {
if (cap2) {
image_url.push({ file_id: img2, caption: cap2 });
} else {
image_url.push(img2);
}
}
if (img3) {
if (cap3) {
image_url.push({ file_id: img3, caption: cap3 });
} else {
image_url.push(img3);
}
}
// Generate unique character ID
const id = `custom_${Date.now()}_${Math.floor(1000 + Math.random() * 9000)}`;
importedChars.push({
id,
name,
image_url,
base_price,
features,
category: category || "",
addedBy: "bulk_import"
});
successCount++;
});
async function saveImportedData() {
if (successCount === 0) {
console.log(`\nโŒ Bulk Import Failed.`);
return;
}
const mongoUri = process.env.MONGODB_URI;
if (mongoUri) {
console.log("\n๐Ÿ”Œ Connecting to MongoDB for import...");
let client;
try {
client = new MongoClient(mongoUri);
await client.connect();
const db = client.db();
const collection = db.collection("bot_state");
const record = await collection.findOne({ _id: "state" });
let currentDB = record ? record.data : { customCharacters: [] };
currentDB.customCharacters = currentDB.customCharacters || [];
currentDB.customCharacters.push(...importedChars);
await collection.updateOne(
{ _id: "state" },
{ $set: { data: currentDB } },
{ upsert: true }
);
console.log(`\n๐ŸŽ‰ Bulk Import Complete (MongoDB Atlas)!`);
console.log(`โœ… Successfully imported *${successCount}* characters.`);
} catch (err) {
console.error("โŒ Failed to save changes to MongoDB:", err.message || err);
process.exit(1);
} finally {
if (client) await client.close();
}
} else {
// Fallback to local db.json
console.log("\n๐Ÿ’พ Saving to local db.json...");
let localDB = { customCharacters: [] };
if (fs.existsSync(DB_FILE)) {
try {
localDB = JSON.parse(fs.readFileSync(DB_FILE, "utf8"));
} catch (err) {
console.error("โŒ Failed to parse local db.json:", err);
process.exit(1);
}
}
localDB.customCharacters = localDB.customCharacters || [];
localDB.customCharacters.push(...importedChars);
try {
fs.writeFileSync(DB_FILE, JSON.stringify(localDB, null, 2), "utf8");
console.log(`\n๐ŸŽ‰ Bulk Import Complete (local file)!`);
console.log(`โœ… Successfully imported *${successCount}* characters.`);
} catch (err) {
console.error("โŒ Failed to save changes to db.json:", err);
process.exit(1);
}
}
if (failCount > 0) {
console.log(`โš ๏ธ Failed to import *${failCount}* rows due to formatting/validation errors:`);
errors.forEach((err) => console.log(` - ${err}`));
}
}
saveImportedData();