plerobuddies/src/buddies/mobygames/collector.js

86 lines
3.0 KiB
JavaScript

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
}