const axios = require('axios') const fsp = require('fs').promises const { existsSync, createWriteStream } = require('fs') const endpoint = "https://api.mobygames.com/v1" const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) // TODO move AC code to axios, move this to utilities.js async function download(url, filename) { console.log(` -- mobygames: downloading file ${url}...`) const result = await axios({ url, method: 'GET', responseType: 'stream' }) await result.data.pipe(createWriteStream(filename)) } /** game example from cache: { "game_id": 138, "moby_url": "http://www.mobygames.com/game/pac-man", "title": "Pac-Man" } */ async function collectScreenshotsFor(game, buddyConfig) { const { platform, mobyGamesToken } = buddyConfig const id = game['game_id'] const ext = url => url.split(".").pop() const screenshots = (await axios.get(`${endpoint}/games/${id}/platforms/${platform}/screenshots?api_key=${mobyGamesToken}`)).data.screenshots const titleshots = screenshots.filter(s => s.caption?.toLowerCase()?.indexOf("title screen") >= 0) const titleshot = titleshots.length == 0 ? screenshots[0].image : titleshots[0].image const titleshotfile = `data/mobygames/title_${id}_1.${ext(titleshot)}` // not sure if this is ok, we now take the SECOND LAST screenshot that doesn't contain 'title screen' // however, the screenshot could be a dull one, but taking something random isn't great either const gameshots = screenshots.filter(s => s.caption?.toLowerCase()?.indexOf("title screen") == -1) const gameshot = gameshots[gameshots.length < 2 ? 0 : gameshots.length - 2].image const gameshotfile = `data/mobygames/title_${id}_2.${ext(gameshot)}` await download(titleshot, titleshotfile) await download(gameshot, gameshotfile) return [ titleshotfile, gameshotfile ] } // for the gameboy: 10, 688 - see https://www.mobygames.com/browse/games/gameboy/list-games/ async function collect(buddyConfig) { const { platform, totalAmountOfGamesForPlatform, mobyGamesToken } = buddyConfig const overviewFile = `data/mobygames/games_${platform}.json` if(existsSync(overviewFile)) { console.log(' -- mobygames: retrieving list from cache...') const fileData = await fsp.readFile(overviewFile) return JSON.parse(fileData) } console.log(' -- mobygames: no overview json file found for platform, fetching...') const allGames = [] for(let offset = 0; offset < totalAmountOfGamesForPlatform; offset += 100) { console.log(` -- mobygames: fetching platform ${platform} offset ${offset}...`) const result = await axios.get(`${endpoint}/games?platform=${platform}&api_key=${mobyGamesToken}&offset=${offset}`) allGames.push(result.data.games) // there's a rate limit of 1 request per second. await delay(1200) } const games = allGames.flat() await fsp.writeFile(overviewFile, JSON.stringify({ games }, null, 2)) console.log(` -- mobygames: done collecting, result in games_${platform}.json!`) return { games } } module.exports = { collect, collectScreenshotsFor }