Spaces:
Sleeping
Sleeping
File size: 6,079 Bytes
21011e9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | 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();
|