From 8e46df1868a95de978a17a77a0df72a57894c724 Mon Sep 17 00:00:00 2001 From: spacemeowx2 Date: Sat, 26 Nov 2022 23:15:40 +0800 Subject: [PATCH] refactor: add uid to file summary export --- scripts/export-file-to-stat-ink.ts | 4 +- src/exporters/file.ts | 65 ++++++++++++++++++++++++++---- src/splatnet3.ts | 16 ++++++++ src/types.ts | 1 + 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/scripts/export-file-to-stat-ink.ts b/scripts/export-file-to-stat-ink.ts index b406428..d3279e6 100644 --- a/scripts/export-file-to-stat-ink.ts +++ b/scripts/export-file-to-stat-ink.ts @@ -39,8 +39,8 @@ async function exportType( const detail = await getContent(); let resultUrl: string | undefined; try { - const { url } = await statInkExporter.exportGame(detail); - resultUrl = url; + const result = await statInkExporter.exportGame(detail); + resultUrl = result.status === "success" ? result.url : undefined; } catch (e) { console.log("Failed to export game", e); // try to re-export using cached data diff --git a/src/exporters/file.ts b/src/exporters/file.ts index 67250be..bc8cf79 100644 --- a/src/exporters/file.ts +++ b/src/exporters/file.ts @@ -3,20 +3,32 @@ import { ExportResult, Game, GameExporter, + Summary, VsInfo, } from "../types.ts"; import { path } from "../../deps.ts"; import { NSOAPP_VERSION, S3SI_VERSION } from "../constant.ts"; import { parseHistoryDetailId, urlSimplify } from "../utils.ts"; -export type FileExporterType = { - type: "VS" | "COOP"; +export type FileExporterTypeCommon = { nsoVersion: string; s3siVersion: string; exportTime: string; - data: VsInfo | CoopInfo; }; +export type FileExporterType = + & ({ + type: "VS"; + data: VsInfo; + } | { + type: "COOP"; + data: CoopInfo; + } | { + type: "SUMMARY"; + data: Summary; + }) + & FileExporterTypeCommon; + /** * Don't save url in exported file */ @@ -62,6 +74,9 @@ export class FileExporter implements GameExporter { const content = await Deno.readTextFile(filepath); const body = JSON.parse(content) as FileExporterType; + if (body.type === "SUMMARY") { + continue; + } if (body.type === "VS" && type === "VsInfo") { out.push({ id: body.data.detail.id, @@ -85,22 +100,58 @@ export class FileExporter implements GameExporter { const content = await Deno.readTextFile(filepath); const body = JSON.parse(content) as FileExporterType; - return body.data; + // summary is excluded + return body.data as Game; }, })); } + async exportSummary(summary: Summary): Promise { + const filename = `${summary.uid}_summary.json`; + const filepath = path.join(this.exportPath, filename); + + const body: FileExporterType = { + type: "SUMMARY", + nsoVersion: NSOAPP_VERSION, + s3siVersion: S3SI_VERSION, + exportTime: new Date().toISOString(), + data: summary, + }; + + await Deno.writeTextFile( + filepath, + JSON.stringify({ + body, + }), + ); + + return { + status: "success", + url: filepath, + }; + } async exportGame(info: Game): Promise { await Deno.mkdir(this.exportPath, { recursive: true }); const filename = this.getFilenameById(info.detail.id); const filepath = path.join(this.exportPath, filename); - const body: FileExporterType = { - type: info.type === "VsInfo" ? "VS" : "COOP", + const common: FileExporterTypeCommon = { nsoVersion: NSOAPP_VERSION, s3siVersion: S3SI_VERSION, exportTime: new Date().toISOString(), - data: info, + }; + const dataType = info.type === "VsInfo" + ? { + type: "VS" as const, + data: info, + } + : { + type: "COOP" as const, + data: info, + }; + const body: FileExporterType = { + ...common, + ...dataType, }; await Deno.writeTextFile( diff --git a/src/splatnet3.ts b/src/splatnet3.ts index 643508d..14be585 100644 --- a/src/splatnet3.ts +++ b/src/splatnet3.ts @@ -15,6 +15,7 @@ import { } from "./types.ts"; import { DEFAULT_ENV, Env } from "./env.ts"; import { getBulletToken, getGToken } from "./iksm.ts"; +import { parseHistoryDetailId } from "./utils.ts"; export class Splatnet3 { protected profile: Profile; @@ -231,7 +232,22 @@ export class Splatnet3 { ); const HistoryRecordQuery = await this.request(Queries.HistoryRecordQuery); const CoopHistoryQuery = await this.request(Queries.CoopHistoryQuery); + const getFirstBattleId = async () => { + const latest = await this.request(Queries.LatestBattleHistoriesQuery); + const id = latest?.latestBattleHistories?.historyGroups?.nodes?.[0] + ?.historyDetails?.nodes?.[0]?.id; + return id; + }; + + const id = CoopHistoryQuery?.coopResult?.historyGroups?.nodes?.[0] + ?.historyDetails?.nodes?.[0]?.id ?? await getFirstBattleId(); + if (!id) { + throw new Error("No battle id found"); + } + const { uid } = parseHistoryDetailId(id); + return { + uid, ConfigureAnalyticsQuery, HistoryRecordQuery, CoopHistoryQuery, diff --git a/src/types.ts b/src/types.ts index 3d28af3..4c6393c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -311,6 +311,7 @@ export type SummaryFetcher = { }; export type Summary = { + uid: string; ConfigureAnalyticsQuery: RespMap[Queries.ConfigureAnalyticsQuery]; HistoryRecordQuery: RespMap[Queries.HistoryRecordQuery]; CoopHistoryQuery: RespMap[Queries.CoopHistoryQuery];