mirror of
https://github.com/misenhower/splatoon2.ink.git
synced 2026-09-08 18:45:26 -05:00
Refactor SplatNet API
This commit is contained in:
@@ -7,98 +7,96 @@ const axios = require('axios');
|
||||
const userAgent = process.env.SPLATNET_USER_AGENT;
|
||||
const splatnetBaseUrl = 'https://app.splatoon2.nintendo.net';
|
||||
|
||||
function createApiClient(sessionId) {
|
||||
return axios.create({
|
||||
baseURL: `${splatnetBaseUrl}/api/`,
|
||||
headers: {
|
||||
'User-Agent': userAgent,
|
||||
'Cookie': `iksm_session=${sessionId}`,
|
||||
},
|
||||
});
|
||||
class SplatNet {
|
||||
constructor(region = 'NA', language = 'en-US') {
|
||||
this.region = region;
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
getSessionId() {
|
||||
switch (this.region) {
|
||||
case 'NA': return process.env.NINTENDO_SESSION_ID_NA;
|
||||
case 'EU': return process.env.NINTENDO_SESSION_ID_EU;
|
||||
case 'JP': return process.env.NINTENDO_SESSION_ID_JP;
|
||||
}
|
||||
}
|
||||
|
||||
getClient() {
|
||||
return axios.create({
|
||||
baseURL: `${splatnetBaseUrl}/api/`,
|
||||
headers: {
|
||||
'User-Agent': userAgent,
|
||||
'Cookie': `iksm_session=${this.getSessionId()}`,
|
||||
'Accept-Language': this.language,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async getResponse(path) {
|
||||
let response = await this.getClient().get(path);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
getSchedules() {
|
||||
return this.getResponse('schedules');
|
||||
}
|
||||
|
||||
getCoopSchedules() {
|
||||
return this.getResponse('coop_schedules');
|
||||
}
|
||||
|
||||
getTimeline() {
|
||||
return this.getResponse('timeline');
|
||||
}
|
||||
|
||||
getActiveFestivals() {
|
||||
return this.getResponse('festivals/active');
|
||||
}
|
||||
|
||||
getPastFestivals() {
|
||||
return this.getResponse('festivals/pasts');
|
||||
}
|
||||
|
||||
async getCombinedFestivals() {
|
||||
let active = await this.getActiveFestivals();
|
||||
let past = await this.getPastFestivals();
|
||||
|
||||
return {
|
||||
festivals: active.festivals.concat(past.festivals),
|
||||
results: past.results,
|
||||
};
|
||||
}
|
||||
|
||||
getMerchandises() {
|
||||
return this.getResponse('onlineshop/merchandises');
|
||||
}
|
||||
|
||||
getLeagueMatchRanking(year, month, day, hour, type = 'T', region = 'ALL') {
|
||||
// Hour should be in multiples of 2, e.g., 00, 02, 04, ..., 22.
|
||||
// Type should be 'T' (team) or 'P' (pair).
|
||||
// Region should be 'ALL', 'JP', 'US', or 'EU'.
|
||||
|
||||
// Make sure year is specified as two digits
|
||||
year = year % 100;
|
||||
|
||||
// Make sure we have leading zeros
|
||||
year = ('0' + year).substr(-2);
|
||||
month = ('0' + month).substr(-2);
|
||||
day = ('0' + day).substr(-2);
|
||||
hour = ('0' + hour).substr(-2);
|
||||
|
||||
return this.getResponse(`league_match_ranking/${year}${month}${day}${hour}${type}/${region}`);
|
||||
}
|
||||
|
||||
getResults(id = null, region = 'NA') {
|
||||
let url = (id) ? `results/${id}` : 'results';
|
||||
return this.getResponse(url);
|
||||
}
|
||||
|
||||
async getImage(imagePath) {
|
||||
let response = await axios.get(`${splatnetBaseUrl}${imagePath}`, { responseType: 'arraybuffer', headers: { 'User-Agent': userAgent } });
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
const api = {
|
||||
NA: createApiClient(process.env.NINTENDO_SESSION_ID_NA),
|
||||
EU: createApiClient(process.env.NINTENDO_SESSION_ID_EU),
|
||||
JP: createApiClient(process.env.NINTENDO_SESSION_ID_JP),
|
||||
}
|
||||
|
||||
async function getSchedules(region = 'NA') {
|
||||
let response = await api[region].get('schedules');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getCoopSchedules(region = 'NA') {
|
||||
let response = await api[region].get('coop_schedules');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getTimeline(region = 'NA') {
|
||||
let response = await api[region].get('timeline');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getActiveFestivals(region = 'NA') {
|
||||
let response = await api[region].get('festivals/active');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getPastFestivals(region = 'NA') {
|
||||
let response = await api[region].get('festivals/pasts');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getCombinedFestivals(region = 'NA') {
|
||||
let active = await getActiveFestivals(region);
|
||||
let past = await getPastFestivals(region);
|
||||
|
||||
return {
|
||||
festivals: active.festivals.concat(past.festivals),
|
||||
results: past.results,
|
||||
};
|
||||
}
|
||||
|
||||
async function getMerchandises(region = 'NA') {
|
||||
let response = await api[region].get('onlineshop/merchandises');
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getLeagueMatchRanking(year, month, day, hour, type = 'T', region = 'ALL', apiRegion = 'NA') {
|
||||
// Hour should be in multiples of 2, e.g., 00, 02, 04, ..., 22.
|
||||
// Type should be 'T' (team) or 'P' (pair).
|
||||
// Region should be 'ALL', 'JP', 'US', or 'EU'.
|
||||
|
||||
// Make sure year is specified as two digits
|
||||
year = year % 100;
|
||||
|
||||
// Make sure we have leading zeros
|
||||
year = ('0' + year).substr(-2);
|
||||
month = ('0' + month).substr(-2);
|
||||
day = ('0' + day).substr(-2);
|
||||
hour = ('0' + hour).substr(-2);
|
||||
|
||||
let response = await api[apiRegion].get(`league_match_ranking/${year}${month}${day}${hour}${type}/${region}`);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getResults(id = null, region = 'NA') {
|
||||
let url = (id) ? `results/${id}` : 'results';
|
||||
let response = await api[region].get(url);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function getImage(imagePath) {
|
||||
let response = await axios.get(`${splatnetBaseUrl}${imagePath}`, { responseType: 'arraybuffer', headers: { 'User-Agent': userAgent } });
|
||||
return response.data;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getSchedules,
|
||||
getCoopSchedules,
|
||||
getTimeline,
|
||||
getCombinedFestivals,
|
||||
getMerchandises,
|
||||
getLeagueMatchRanking,
|
||||
getResults,
|
||||
getImage,
|
||||
}
|
||||
module.exports = SplatNet;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
require('./bootstrap');
|
||||
const splatnet = require('./splatnet');
|
||||
|
||||
const Updater = require('./updaters/Updater');
|
||||
const OriginalGearImageUpdater = require('./updaters/OriginalGearImageUpdater');
|
||||
const FestivalsUpdater = require('./updaters/FestivalsUpdater');
|
||||
|
||||
const updaters = [
|
||||
// Original gear images
|
||||
@@ -12,7 +12,7 @@ const updaters = [
|
||||
new Updater({
|
||||
name: 'Schedules',
|
||||
filename: 'schedules.json',
|
||||
request: () => splatnet.getSchedules(),
|
||||
request: (splatnet) => splatnet.getSchedules(),
|
||||
imagePaths: [
|
||||
'$..stage_a.image',
|
||||
'$..stage_b.image',
|
||||
@@ -23,7 +23,7 @@ const updaters = [
|
||||
new Updater({
|
||||
name: 'Co-op Schedules',
|
||||
filename: 'coop-schedules.json',
|
||||
request: () => splatnet.getCoopSchedules(),
|
||||
request: (splatnet) => splatnet.getCoopSchedules(),
|
||||
imagePaths: [
|
||||
'$..stage.image',
|
||||
'$..weapons[*].image',
|
||||
@@ -34,7 +34,7 @@ const updaters = [
|
||||
new Updater({
|
||||
name: 'Timeline',
|
||||
filename: 'timeline.json',
|
||||
request: () => splatnet.getTimeline(),
|
||||
request: (splatnet) => splatnet.getTimeline(),
|
||||
rootKeys: ['coop', 'weapon_availability'],
|
||||
imagePaths: [
|
||||
'$.coop..gear.image',
|
||||
@@ -46,29 +46,13 @@ const updaters = [
|
||||
}),
|
||||
|
||||
// Festivals
|
||||
new Updater({
|
||||
name: 'Festivals',
|
||||
filename: 'festivals.json',
|
||||
async request() {
|
||||
return {
|
||||
na: await splatnet.getCombinedFestivals('NA'),
|
||||
eu: await splatnet.getCombinedFestivals('EU'),
|
||||
jp: await splatnet.getCombinedFestivals('JP'),
|
||||
};
|
||||
},
|
||||
imagePaths: [
|
||||
'$..images.alpha',
|
||||
'$..images.bravo',
|
||||
'$..images.panel',
|
||||
'$..special_stage.image',
|
||||
],
|
||||
}),
|
||||
new FestivalsUpdater,
|
||||
|
||||
// Merchandises
|
||||
new Updater({
|
||||
name: 'Merchandises',
|
||||
filename: 'merchandises.json',
|
||||
request: () => splatnet.getMerchandises(),
|
||||
request: (splatnet) => splatnet.getMerchandises(),
|
||||
rootKeys: ['merchandises'],
|
||||
imagePaths: [
|
||||
'$..gear.image',
|
||||
|
||||
28
src/updater/updaters/FestivalsUpdater.js
Normal file
28
src/updater/updaters/FestivalsUpdater.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const Updater = require('./Updater');
|
||||
const SplatNet = require('../splatnet');
|
||||
|
||||
class FestivalsUpdater extends Updater {
|
||||
constructor() {
|
||||
super({
|
||||
name: 'Festivals',
|
||||
filename: 'festivals.json',
|
||||
request: (splatnet) => splatnet.getCombinedFestivals(),
|
||||
imagePaths: [
|
||||
'$..images.alpha',
|
||||
'$..images.bravo',
|
||||
'$..images.panel',
|
||||
'$..special_stage.image',
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async getData() {
|
||||
return {
|
||||
na: await this.options.request(new SplatNet('NA')),
|
||||
eu: await this.options.request(new SplatNet('EU')),
|
||||
jp: await this.options.request(new SplatNet('JP')),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = FestivalsUpdater;
|
||||
@@ -2,7 +2,7 @@ const path = require('path');
|
||||
const fs = require('fs');
|
||||
const mkdirp = require('mkdirp');
|
||||
const jsonpath = require('jsonpath');
|
||||
const splatnet = require('../splatnet');
|
||||
const SplatNet = require('../splatnet');
|
||||
const raven = require('raven');
|
||||
|
||||
const dataPath = path.resolve('public/data');
|
||||
@@ -36,7 +36,8 @@ class Updater {
|
||||
}
|
||||
|
||||
getData() {
|
||||
return this.options.request();
|
||||
let splatnet = new SplatNet;
|
||||
return this.options.request(splatnet);
|
||||
}
|
||||
|
||||
async handleRequest(request) {
|
||||
@@ -109,6 +110,7 @@ class Updater {
|
||||
// Otherwise, download the image
|
||||
try {
|
||||
this.info(`Downloading image: ${imagePath}`);
|
||||
let splatnet = new SplatNet;
|
||||
let image = await this.handleRequest(splatnet.getImage(imagePath));
|
||||
this.writeFile(localPath, image);
|
||||
} catch (e) { }
|
||||
|
||||
Reference in New Issue
Block a user