const got = require('got') const { JSDOM } = require("jsdom") const md5 = require('md5') const fsp = require('fs').promises const { createWriteStream, existsSync } = require("fs") const stream = require("stream") const { promisify } = require("util") const pipeline = promisify(stream.pipeline) async function discoverAnimals() { const list = await got('https://animalcrossing.fandom.com/wiki/Villager_list_(New_Horizons)') const dom = new JSDOM(list.body) const rows = [...dom.window.document.querySelectorAll('table.roundy')[1].querySelectorAll('tr')].slice(3) return rows.map(row => { const attrs = [...row.querySelectorAll('td')] const link = attrs[0].querySelector('a') const img = attrs[1].querySelector('a').href const birthday = attrs[4].innerHTML return { href: link.href, name: link.innerHTML, birthday, img } }) } async function discoverQuotes(animal) { const detail = await got(`https://animalcrossing.fandom.com${animal.href}`) const dom = new JSDOM(detail.body) const text = dom.window.document.querySelector('.mw-parser-output').innerHTML.match(/“<\/b><\/span>(.*?)<\/i>/g) if(!text) return [] return text.map(itm => { return itm .replace("", "") .replace(/(.*)<\/a>/g, "$1") .replace("“<\/b><\/span>", "") }) } async function collect() { const animals = await discoverAnimals() const shouldIDownloadQuotes = existsSync('data/ac/animals.json') for await(animal of animals) { const fileName = `data/ac/${md5(animal.img)}.png` if(!existsSync(fileName)) { await pipeline(got.stream(animal.img), createWriteStream(fileName)) console.log(`${animal.name} avatar downloaded.`) } if(!shouldIDownloadQuotes) { const quotes = await discoverQuotes(animal) animal.quotes = quotes console.log(`${animal.name} quotes downloaded (${quotes}).`) } } if(!shouldIDownloadQuotes) { await fsp.writeFile('data/ac/animals.json', JSON.stringify({ animals }, null, 2)) console.log('Okay, animals.json written!') } return animals } module.exports = { collect }