s3si.ts/src/exporters/mongodb.ts

90 lines
2.5 KiB
TypeScript
Raw Normal View History

import { MongoDB } from "../../deps.ts";
2023-02-28 11:34:07 -05:00
import { AGENT_VERSION, NSOAPP_VERSION, S3SI_VERSION } from "../constant.ts";
import { CoopHistoryDetail, ExportResult, Game, GameExporter, VsHistoryDetail } from "../types.ts";
import { parseHistoryDetailId } from "../utils.ts";
2023-02-28 11:34:07 -05:00
import { FileExporterTypeCommon } from "./file.ts";
export class MongoDBExporter implements GameExporter {
name = "mongodb";
mongoDbClient: MongoDB.MongoClient;
mongoDb: MongoDB.Db;
battlesCollection: MongoDB.Collection;
jobsCollection: MongoDB.Collection;
constructor(private mongoDbUri: string) {
this.mongoDbClient = new MongoDB.MongoClient(mongoDbUri);
this.mongoDb = this.mongoDbClient.db("splashcat");
this.battlesCollection = this.mongoDb.collection("battles");
this.jobsCollection = this.mongoDb.collection("jobs");
}
getGameId(id: string) { // very similar to the file exporter
const { uid, timestamp } = parseHistoryDetailId(id);
return `${uid}_${timestamp}Z`;
}
async notExported({ type, list }: { type: Game["type"], list: string[] }): Promise<string[]> {
const out: string[] = [];
const collection = type === "CoopInfo" ? this.jobsCollection : this.battlesCollection;
for (const id of list) {
// countOldStorage can be removed later eventually when all old documents
// are gone from SplatNet 3
const countOldStorage = await collection.countDocuments({
splatNetData: {
id: id,
}
});
const uniqueId = this.getGameId(id);
const countNewStorage = await collection.countDocuments({
gameId: uniqueId,
});
if (countOldStorage === 0 && countNewStorage === 0) {
out.push(id);
}
}
return out;
}
2023-02-28 11:34:07 -05:00
async exportGame(game: Game): Promise<ExportResult> {
const uniqueId = this.getGameId(game.detail.id);
const common = {
// this seems like useful data to store...
// loosely modeled after FileExporterTypeCommon
nsoVersion: NSOAPP_VERSION,
agentVersion: AGENT_VERSION,
s3siVersion: S3SI_VERSION,
exportTime: new Date(),
};
const body:
{
data: Game,
splatNetData: VsHistoryDetail | CoopHistoryDetail,
gameId: string,
} & typeof common = {
...common,
data: game,
splatNetData: game.detail,
gameId: uniqueId,
};
const isJob = game.type === "CoopInfo";
const collection = isJob ? this.jobsCollection : this.battlesCollection;
const result = await collection.insertOne(body);
const objectId = result.insertedId;
return {
status: "success",
url: `https://new.splatoon.catgirlin.space/battle/${objectId.toString()}`,
};
}
}