mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-16 01:31:19 +10:00
* First iteration on the new PieChart component * #128 Adds new admin home page * Fixes code after merging conflicts * Removes empty file * Uses real data for admin home page, and improves style * Reverts debugging code * Defines missing variable * Caches user stats data for admin home page * Typo * Styles improvements * Invalidates cache on signup/signin * Implements top 5 biggest games * Improves styling * Improves style * Using generateManifest to get the proper size * Reading data from cache * Removes unnecessary import * Improves caching mechanism for game sizes * Removes lint errors * Replaces piechart tooltip with colors in legend * Fixes caching * Fixes caching and slight improvement on pie chart colours * Fixes a few bugs related to caching * Fixes bug where app signin didn't refresh cache * feat: style improvements * fix: lint --------- Co-authored-by: DecDuck <declanahofmeyr@gmail.com>
This commit is contained in:
@ -15,6 +15,8 @@ import { GameNotFoundError, type LibraryProvider } from "./provider";
|
||||
import { logger } from "../logging";
|
||||
import type { GameModel } from "~/prisma/client/models";
|
||||
import { createHash } from "node:crypto";
|
||||
import type { WorkingLibrarySource } from "~/server/api/v1/admin/library/sources/index.get";
|
||||
import gameSizeManager from "~/server/internal/gamesize";
|
||||
|
||||
export function createGameImportTaskId(libraryId: string, libraryPath: string) {
|
||||
return createHash("md5")
|
||||
@ -39,13 +41,19 @@ class LibraryManager {
|
||||
this.libraries.delete(id);
|
||||
}
|
||||
|
||||
async fetchLibraries() {
|
||||
async fetchLibraries(): Promise<WorkingLibrarySource[]> {
|
||||
const libraries = await prisma.library.findMany({});
|
||||
const libraryWithMetadata = libraries.map((e) => ({
|
||||
...e,
|
||||
working: this.libraries.has(e.id),
|
||||
}));
|
||||
return libraryWithMetadata;
|
||||
|
||||
const libraryWithMetadata = libraries.map(async (library) => {
|
||||
const theLibrary = this.libraries.get(library.id);
|
||||
const working = this.libraries.has(library.id);
|
||||
return {
|
||||
...library,
|
||||
working,
|
||||
fsStats: working ? theLibrary?.fsStats() : undefined,
|
||||
};
|
||||
});
|
||||
return await Promise.all(libraryWithMetadata);
|
||||
}
|
||||
|
||||
async fetchGamesByLibrary() {
|
||||
@ -334,6 +342,8 @@ class LibraryManager {
|
||||
acls: ["system:import:version:read"],
|
||||
});
|
||||
|
||||
await libraryManager.cacheCombinedGameSize(gameId);
|
||||
await libraryManager.cacheGameVersionSize(gameId, versionName);
|
||||
progress(100);
|
||||
},
|
||||
});
|
||||
@ -363,6 +373,68 @@ class LibraryManager {
|
||||
if (!library) return undefined;
|
||||
return await library.readFile(game, version, filename, options);
|
||||
}
|
||||
|
||||
async deleteGameVersion(gameId: string, version: string) {
|
||||
await prisma.gameVersion.delete({
|
||||
where: {
|
||||
gameId_versionName: {
|
||||
gameId: gameId,
|
||||
versionName: version,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await gameSizeManager.deleteGameVersion(gameId, version);
|
||||
}
|
||||
|
||||
async deleteGame(gameId: string) {
|
||||
await prisma.game.delete({
|
||||
where: {
|
||||
id: gameId,
|
||||
},
|
||||
});
|
||||
gameSizeManager.deleteGame(gameId);
|
||||
}
|
||||
|
||||
async getGameVersionSize(
|
||||
gameId: string,
|
||||
versionName?: string,
|
||||
): Promise<number | null> {
|
||||
return gameSizeManager.getGameVersionSize(gameId, versionName);
|
||||
}
|
||||
|
||||
async getBiggestGamesCombinedVersions(top: number) {
|
||||
if (await gameSizeManager.isGameSizesCacheEmpty()) {
|
||||
await gameSizeManager.cacheAllCombinedGames();
|
||||
}
|
||||
return gameSizeManager.getBiggestGamesAllVersions(top);
|
||||
}
|
||||
|
||||
async getBiggestGamesLatestVersions(top: number) {
|
||||
if (await gameSizeManager.isGameVersionsSizesCacheEmpty()) {
|
||||
await gameSizeManager.cacheAllGameVersions();
|
||||
}
|
||||
return gameSizeManager.getBiggestGamesLatestVersion(top);
|
||||
}
|
||||
|
||||
async cacheCombinedGameSize(gameId: string) {
|
||||
const game = await prisma.game.findFirst({ where: { id: gameId } });
|
||||
if (!game) {
|
||||
return;
|
||||
}
|
||||
await gameSizeManager.cacheCombinedGame(game);
|
||||
}
|
||||
|
||||
async cacheGameVersionSize(gameId: string, versionName: string) {
|
||||
const game = await prisma.game.findFirst({
|
||||
where: { id: gameId },
|
||||
include: { versions: true },
|
||||
});
|
||||
if (!game) {
|
||||
return;
|
||||
}
|
||||
await gameSizeManager.cacheGameVersion(game, versionName);
|
||||
}
|
||||
}
|
||||
|
||||
export const libraryManager = new LibraryManager();
|
||||
|
||||
@ -57,6 +57,8 @@ export abstract class LibraryProvider<CFG> {
|
||||
filename: string,
|
||||
options?: { start?: number; end?: number },
|
||||
): Promise<ReadableStream | undefined>;
|
||||
|
||||
abstract fsStats(): { freeSpace: number; totalSpace: number } | undefined;
|
||||
}
|
||||
|
||||
export class GameNotFoundError extends Error {}
|
||||
|
||||
@ -8,6 +8,7 @@ import { LibraryBackend } from "~/prisma/client/enums";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import droplet, { DropletHandler } from "@drop-oss/droplet";
|
||||
import { fsStats } from "~/server/internal/utils/files";
|
||||
|
||||
export const FilesystemProviderConfig = type({
|
||||
baseDir: "string",
|
||||
@ -122,4 +123,8 @@ export class FilesystemProvider
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
fsStats() {
|
||||
return fsStats(this.config.baseDir);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import fs from "fs";
|
||||
import path from "path";
|
||||
import droplet from "@drop-oss/droplet";
|
||||
import { DROPLET_HANDLER } from "./filesystem";
|
||||
import { fsStats } from "~/server/internal/utils/files";
|
||||
|
||||
export const FlatFilesystemProviderConfig = type({
|
||||
baseDir: "string",
|
||||
@ -113,4 +114,8 @@ export class FlatFilesystemProvider
|
||||
|
||||
return stream.getStream();
|
||||
}
|
||||
|
||||
fsStats() {
|
||||
return fsStats(this.config.baseDir);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user