UNPKG

whattocode-cli

Version:

CLI tool to get random project ideas from what-to-code.com

186 lines (157 loc) 6.1 kB
const puppeteer = require('puppeteer-core'); const fs = require('fs'); const path = require('path'); const os = require('os'); const DATA_DIR = path.join(os.homedir(), '.whattocode'); const IDEAS_FILE = path.join(DATA_DIR, 'ideas.json'); function wordWrap(text, maxWidth) { const words = text.split(' '); const lines = []; let currentLine = ''; words.forEach(word => { if (currentLine.length + word.length + 1 <= maxWidth) { currentLine = currentLine ? `${currentLine} ${word}` : word; } else { lines.push(currentLine); currentLine = word; } }); if (currentLine) { lines.push(currentLine); } return lines; } async function scrapeIdeas() { console.log("Launching browser..."); const browser = await puppeteer.launch({ headless: "new" }); const page = await browser.newPage(); const ideas = []; try { console.log("Navigating to what-to-code.com..."); await page.goto("https://what-to-code.com", { waitUntil: 'networkidle0' }); console.log("Waiting for ideas to load..."); await page.waitForSelector(".Idea_idea__8CbUI"); console.log("Scrolling to load all ideas..."); let lastHeight = await page.evaluate('document.body.scrollHeight'); while (true) { await page.evaluate('window.scrollTo(0, document.body.scrollHeight)'); await page.waitForTimeout(2000); let newHeight = await page.evaluate('document.body.scrollHeight'); if (newHeight === lastHeight) { break; } lastHeight = newHeight; } const cards = await page.$$(".Idea_idea__8CbUI"); console.log(`Found ${cards.length} ideas`); for (let i = 0; i < cards.length; i++) { try { const title = await cards[i].$eval(".has-text-weight-bold", el => el.textContent); const description = await cards[i].$eval(".subtitle", el => el.textContent); const likes = await cards[i].$eval(".card-footer-item", el => el.textContent); const idea = { title: title.trim(), description: description.trim(), likes: parseInt(likes.split(" ")[0]) }; ideas.push(idea); console.log(`Processed idea ${i + 1}/${cards.length}: ${title.trim()}`); } catch (err) { console.log(`Error processing card ${i + 1}:`, err.message); } } } catch (err) { console.error("Error during scraping:", err.message); } finally { await browser.close(); } return ideas; } function loadIdeas() { try { if (fs.existsSync(IDEAS_FILE)) { return JSON.parse(fs.readFileSync(IDEAS_FILE, 'utf8')); } } catch (err) { console.error("Error loading ideas:", err.message); } return null; } function saveIdeas(ideas) { try { fs.mkdirSync(DATA_DIR, { recursive: true }); fs.writeFileSync(IDEAS_FILE, JSON.stringify(ideas, null, 2)); return true; } catch (err) { console.error("Error saving ideas:", err.message); return false; } } function getRandomIdea() { const ideas = loadIdeas(); if (!ideas || ideas.length === 0) { console.log("No ideas found. Please run 'whattocode update' first."); return null; } return ideas[Math.floor(Math.random() * ideas.length)]; } function printHelp() { console.log(` Usage: whattocode <command> Commands: random Get a random project idea update Update the local database of ideas help Show this help message `); } async function main() { const command = process.argv[2]; if (!command || command === 'help' || command === '-h' || command === '--help') { printHelp(); return; } switch (command) { case 'random': const idea = getRandomIdea(); if (idea) { const width = 70; console.log("\n" + "=".repeat(width)); console.log(" Random Project Idea ".padStart((width + " Random Project Idea ".length) / 2, "=").padEnd(width, "=")); console.log("=".repeat(width) + "\n"); // box title console.log("+" + "-".repeat(width - 2) + "+"); const titleLines = wordWrap(idea.title, width - 4); titleLines.forEach(line => { console.log(`| ${line.padEnd(width - 4)} |`); }); console.log("+" + "-".repeat(width - 2) + "+\n"); // show description console.log("Description:"); console.log("-".repeat(width)); const descLines = wordWrap(idea.description, width); descLines.forEach(line => console.log(line)); // show amt. of likes console.log("\n" + "-".repeat(width)); console.log(`[${idea.likes} likes]`.padStart(width)); console.log(); } break; case 'update': console.log("Updating ideas database..."); const ideas = await scrapeIdeas(); if (ideas && ideas.length > 0) { if (saveIdeas(ideas)) { console.log(`Successfully saved ${ideas.length} ideas to ${IDEAS_FILE}`); } } break; default: console.log(`Unknown command: ${command}`); printHelp(); process.exit(1); } } main().catch(err => { console.error("Error:", err.message); process.exit(1); });