image_crawler/server.cjs

124 lines
4.2 KiB
JavaScript

// server.cjs
const express = require("express");
const fetch = require("node-fetch");
const app = express();
const PORT = 9093;
app.use(express.static("public"));
// Import all search functions
const { searchDigikala, getProductById } = require("./digikala");
const { searchBasalam } = require("./basalam");
const { searchTorob } = require("./torob");
const { searchSnappFood } = require("./snappfood");
const { searchKhanoumi } = require("./khanoumi");
const { searchEmalls } = require("./emalls");
const { searchLionComputer } = require("./lioncomputer");
// Main search API route
app.get("/api/search", async (req, res) => {
const q = req.query.q || "";
if (!q) return res.status(400).json({ error: "Query is required" });
try {
// Execute all searches in parallel
const [basalam, torob, digikala, snappfood, khanoumi, emalls, lioncomputer] = await Promise.allSettled([
searchBasalam(q),
searchTorob(q),
searchDigikala(q),
searchSnappFood(q),
searchKhanoumi(q),
searchEmalls(q),
searchLionComputer(q)
]);
// Handle results - return successful results or empty arrays
const basalamResults = basalam.status === 'fulfilled' ? basalam.value : [];
const torobResults = torob.status === 'fulfilled' ? torob.value : [];
const digikalaResults = digikala.status === 'fulfilled' ? digikala.value : [];
const snappfoodResults = snappfood.status === 'fulfilled' ? snappfood.value : [];
const khanoumiResults = khanoumi.status === 'fulfilled' ? khanoumi.value : [];
const emallsResults = emalls.status === 'fulfilled' ? emalls.value : [];
const lioncomputerResults = lioncomputer.status === 'fulfilled' ? lioncomputer.value : [];
res.json({
basalam: basalamResults,
torob: torobResults,
digikala: digikalaResults,
snappfood: snappfoodResults,
khanoumi: khanoumiResults,
emalls: emallsResults,
lioncomputer: lioncomputerResults
});
} catch (err) {
console.error("Search API error:", err);
res.status(500).json({ error: "Internal server error" });
}
});
// Test endpoint for each service
app.get("/api/test/:service", async (req, res) => {
const service = req.params.service;
const query = "تست";
try {
let results = [];
switch(service) {
case 'basalam':
results = await searchBasalam(query);
break;
case 'torob':
results = await searchTorob(query);
break;
case 'digikala':
results = await searchDigikala(query);
break;
case 'snappfood':
results = await searchSnappFood(query);
break;
case 'khanoumi':
results = await searchKhanoumi(query);
break;
case 'emalls':
results = await searchEmalls(query);
break;
case 'lioncomputer':
results = await searchLionComputer(query);
break;
default:
return res.status(400).json({ error: "Invalid service" });
}
res.json({ service, results });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// ✅ NEW: Get Digikala product by ID (correctly implemented, nothing missing)
app.get("/api/digikala/product/:id", async (req, res) => {
const { id } = req.params;
// Validate that ID is a positive integer string
if (!/^\d+$/.test(id)) {
return res.status(400).json({ error: "Product ID must be a positive integer." });
}
try {
const product = await getProductById(Number(id));
if (!product) {
return res.status(404).json({ error: "Product not found or unavailable." });
}
res.json(product);
} catch (err) {
console.error("Error in /api/digikala/product/:id:", err.message);
res.status(500).json({ error: "Internal server error" });
}
});
// Start server
app.listen(PORT, () => {
console.log(`✓ Server running at http://localhost:${PORT}`);
});