mirror of
https://github.com/captbaritone/webamp.git
synced 2026-01-23 02:15:01 +00:00
96 lines
2.7 KiB
TypeScript
96 lines
2.7 KiB
TypeScript
import { Int } from "grats";
|
|
import { knex } from "../../../db";
|
|
import SkinModel from "../../../data/SkinModel";
|
|
import ClassicSkinResolver from "./ClassicSkinResolver";
|
|
import ModernSkinResolver from "./ModernSkinResolver";
|
|
import UserContext from "../../../data/UserContext";
|
|
import { ISkin } from "./CommonSkinResolver";
|
|
import { SkinRow } from "../../../types";
|
|
|
|
/**
|
|
* Connection for bulk download skin metadata
|
|
* @gqlType
|
|
*/
|
|
export class BulkDownloadConnection {
|
|
_offset: number;
|
|
_first: number;
|
|
|
|
constructor(first: number, offset: number) {
|
|
this._first = first;
|
|
this._offset = offset;
|
|
}
|
|
|
|
/**
|
|
* Total number of skins available for download
|
|
* @gqlField
|
|
*/
|
|
async totalCount(): Promise<Int> {
|
|
// Get count of both classic and modern skins
|
|
const [classicResult, modernResult] = await Promise.all([
|
|
knex("skins").where({ skin_type: 1 }).count("* as count"),
|
|
knex("skins").where({ skin_type: 2 }).count("* as count"),
|
|
]);
|
|
|
|
const classicCount = Number(classicResult[0].count);
|
|
const modernCount = Number(modernResult[0].count);
|
|
|
|
return classicCount + modernCount;
|
|
}
|
|
|
|
/**
|
|
* Estimated total size in bytes (approximation for progress indication)
|
|
* @gqlField
|
|
*/
|
|
async estimatedSizeBytes(): Promise<string> {
|
|
const totalCount = await this.totalCount();
|
|
// Rough estimate: average skin is ~56KB
|
|
return (totalCount * 56 * 1024).toString();
|
|
}
|
|
|
|
/**
|
|
* List of skin metadata for bulk download
|
|
* @gqlField
|
|
*/
|
|
async nodes(ctx: UserContext): Promise<Array<ISkin>> {
|
|
// Get skins ordered by skin_type (classic first, then modern) and id for consistency
|
|
const skins = await knex<SkinRow>("skins")
|
|
.select(["id", "md5", "skin_type", "emails"])
|
|
.orderBy([{ column: "skins.id", order: "asc" }])
|
|
.where({ skin_type: 1 })
|
|
.orWhere({ skin_type: 2 })
|
|
.where((builder) => {
|
|
builder.where({ skin_type: 1 }).orWhere({ skin_type: 2 });
|
|
})
|
|
.limit(this._first)
|
|
.offset(this._offset);
|
|
|
|
return skins.map((skinRow) => {
|
|
const skinModel = new SkinModel(ctx, skinRow);
|
|
|
|
if (skinRow.skin_type === 1) {
|
|
return new ClassicSkinResolver(skinModel);
|
|
} else if (skinRow.skin_type === 2) {
|
|
return new ModernSkinResolver(skinModel);
|
|
} else {
|
|
throw new Error("Expected classic or modern skin");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get metadata for bulk downloading all skins in the museum
|
|
* @gqlQueryField
|
|
*/
|
|
export function bulkDownload({
|
|
first = 1000,
|
|
offset = 0,
|
|
}: {
|
|
first?: Int;
|
|
offset?: Int;
|
|
}): BulkDownloadConnection {
|
|
if (first > 10000) {
|
|
throw new Error("Maximum limit is 10000 for bulk download");
|
|
}
|
|
return new BulkDownloadConnection(first, offset);
|
|
}
|