feat: adding dexie

This commit is contained in:
Chubby Granny Chaser
2024-09-22 17:43:05 +01:00
parent ddd6ff7dbe
commit f860439fb5
25 changed files with 311 additions and 345 deletions

View File

@@ -2,6 +2,7 @@ import type { CatalogueEntry } from "@types";
import { registerEvent } from "../register-event";
import { steamGamesWorker } from "@main/workers";
import { steamUrlBuilder } from "@shared";
const getGames = async (
_event: Electron.IpcMainInvokeEvent,
@@ -14,7 +15,12 @@ const getGames = async (
);
return {
results: steamGames,
results: steamGames.map((steamGame) => ({
title: steamGame.name,
shop: "steam",
cover: steamUrlBuilder.library(steamGame.id),
objectID: steamGame.id,
})),
cursor: cursor + steamGames.length,
};
};

View File

@@ -1,39 +0,0 @@
import { registerEvent } from "../register-event";
import { dataSource } from "@main/data-source";
import { DownloadSource } from "@main/entity";
import axios from "axios";
import { downloadSourceSchema } from "../helpers/validators";
import { insertDownloadsFromSource } from "@main/helpers";
const addDownloadSource = async (
_event: Electron.IpcMainInvokeEvent,
url: string
) => {
const response = await axios.get(url);
const source = downloadSourceSchema.parse(response.data);
const downloadSource = await dataSource.transaction(
async (transactionalEntityManager) => {
const downloadSource = await transactionalEntityManager
.getRepository(DownloadSource)
.save({
url,
name: source.name,
downloadCount: source.downloads.length,
});
await insertDownloadsFromSource(
transactionalEntityManager,
downloadSource,
source.downloads
);
return downloadSource;
}
);
return downloadSource;
};
registerEvent("addDownloadSource", addDownloadSource);

View File

@@ -1,10 +0,0 @@
import { downloadSourceRepository } from "@main/repository";
import { registerEvent } from "../register-event";
import { RepacksManager } from "@main/services";
const removeDownloadSource = async (
_event: Electron.IpcMainInvokeEvent,
id: number
) => downloadSourceRepository.delete(id);
registerEvent("removeDownloadSource", removeDownloadSource);

View File

@@ -1,7 +1,13 @@
import { downloadSourcesWorker } from "@main/workers";
import { registerEvent } from "../register-event";
import { fetchDownloadSourcesAndUpdate } from "@main/helpers";
import type { DownloadSource } from "@types";
const syncDownloadSources = async (_event: Electron.IpcMainInvokeEvent) =>
fetchDownloadSourcesAndUpdate();
const syncDownloadSources = async (
_event: Electron.IpcMainInvokeEvent,
downloadSources: DownloadSource[]
) =>
downloadSourcesWorker.run(downloadSources, {
name: "getUpdatedRepacks",
});
registerEvent("syncDownloadSources", syncDownloadSources);

View File

@@ -1,27 +1,12 @@
import { registerEvent } from "../register-event";
import { downloadSourceRepository } from "@main/repository";
import { RepacksManager } from "@main/services";
import { downloadSourceWorker } from "@main/workers";
import { downloadSourcesWorker } from "@main/workers";
const validateDownloadSource = async (
_event: Electron.IpcMainInvokeEvent,
url: string
) => {
const existingSource = await downloadSourceRepository.findOne({
where: { url },
) =>
downloadSourcesWorker.run(url, {
name: "validateDownloadSource",
});
if (existingSource)
throw new Error("Source with the same url already exists");
const repacks = RepacksManager.repacks;
return downloadSourceWorker.run(
{ url, repacks },
{
name: "validateDownloadSource",
}
);
};
registerEvent("validateDownloadSource", validateDownloadSource);

View File

@@ -39,8 +39,6 @@ import "./autoupdater/restart-and-install-update";
import "./user-preferences/authenticate-real-debrid";
import "./download-sources/get-download-sources";
import "./download-sources/validate-download-source";
import "./download-sources/add-download-source";
import "./download-sources/remove-download-source";
import "./download-sources/sync-download-sources";
import "./auth/sign-out";
import "./auth/open-auth-window";

View File

@@ -73,7 +73,6 @@ const getUser = async (
recentGames,
};
} catch (err) {
console.log(err);
return null;
}
};

View File

@@ -1,76 +0,0 @@
import { dataSource } from "@main/data-source";
import { DownloadSource, Repack } from "@main/entity";
import { downloadSourceSchema } from "@main/events/helpers/validators";
import { downloadSourceRepository } from "@main/repository";
import { RepacksManager } from "@main/services";
import { downloadSourceWorker } from "@main/workers";
import { chunk } from "lodash-es";
import type { EntityManager } from "typeorm";
import type { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
import { z } from "zod";
export const insertDownloadsFromSource = async (
trx: EntityManager,
downloadSource: DownloadSource,
downloads: z.infer<typeof downloadSourceSchema>["downloads"]
) => {
const repacks: QueryDeepPartialEntity<Repack>[] = downloads.map(
(download) => ({
title: download.title,
uris: JSON.stringify(download.uris),
magnet: download.uris[0]!,
fileSize: download.fileSize,
repacker: downloadSource.name,
uploadDate: download.uploadDate,
downloadSource: { id: downloadSource.id },
})
);
const downloadsChunks = chunk(repacks, 800);
for (const chunk of downloadsChunks) {
await trx
.getRepository(Repack)
.createQueryBuilder()
.insert()
.values(chunk)
.updateEntity(false)
.orIgnore()
.execute();
}
};
export const fetchDownloadSourcesAndUpdate = async () => {
const downloadSources = await downloadSourceRepository.find({
order: {
id: "desc",
},
});
const results = await downloadSourceWorker.run(downloadSources, {
name: "getUpdatedRepacks",
});
await dataSource.transaction(async (transactionalEntityManager) => {
for (const result of results) {
if (result.etag !== null) {
await transactionalEntityManager.getRepository(DownloadSource).update(
{ id: result.id },
{
etag: result.etag,
status: result.status,
downloadCount: result.downloads.length,
}
);
await insertDownloadsFromSource(
transactionalEntityManager,
result,
result.downloads
);
}
}
await RepacksManager.updateRepacks();
});
};

View File

@@ -36,6 +36,4 @@ export const requestWebPage = async (url: string) => {
};
export const isPortableVersion = () =>
process.env.PORTABLE_EXECUTABLE_FILE != null;
export * from "./download-source";
process.env.PORTABLE_EXECUTABLE_FILE !== null;

View File

@@ -1,14 +1,14 @@
import { DownloadManager, PythonInstance, startMainLoop } from "./services";
import {
downloadQueueRepository,
repackRepository,
// repackRepository,
userPreferencesRepository,
} from "./repository";
import { UserPreferences } from "./entity";
import { RealDebridClient } from "./services/real-debrid";
import { fetchDownloadSourcesAndUpdate } from "./helpers";
import { publishNewRepacksNotifications } from "./services/notifications";
import { MoreThan } from "typeorm";
// import { fetchDownloadSourcesAndUpdate } from "./helpers";
// import { publishNewRepacksNotifications } from "./services/notifications";
// import { MoreThan } from "typeorm";
import { HydraApi } from "./services/hydra-api";
import { uploadGamesBatch } from "./services/library-sync";
@@ -40,17 +40,17 @@ const loadState = async (userPreferences: UserPreferences | null) => {
startMainLoop();
const now = new Date();
// const now = new Date();
fetchDownloadSourcesAndUpdate().then(async () => {
const newRepacksCount = await repackRepository.count({
where: {
createdAt: MoreThan(now),
},
});
// fetchDownloadSourcesAndUpdate().then(async () => {
// const newRepacksCount = await repackRepository.count({
// where: {
// createdAt: MoreThan(now),
// },
// });
if (newRepacksCount > 0) publishNewRepacksNotifications(newRepacksCount);
});
// if (newRepacksCount > 0) publishNewRepacksNotifications(newRepacksCount);
// });
};
userPreferencesRepository

View File

@@ -1,6 +1,6 @@
import { downloadSourceSchema } from "@main/events/helpers/validators";
import { DownloadSourceStatus } from "@shared";
import type { DownloadSource, GameRepack } from "@types";
import type { DownloadSource } from "@types";
import axios, { AxiosError, AxiosHeaders } from "axios";
import { z } from "zod";
@@ -49,23 +49,11 @@ export const getUpdatedRepacks = async (downloadSources: DownloadSource[]) => {
return results;
};
export const validateDownloadSource = async ({
url,
repacks,
}: {
url: string;
repacks: GameRepack[];
}) => {
export const validateDownloadSource = async (url: string) => {
const response = await axios.get(url);
const source = downloadSourceSchema.parse(response.data);
const existingUris = source.downloads
.flatMap((download) => download.uris)
.filter((uri) => repacks.some((repack) => repack.magnet === uri));
return {
name: source.name,
downloadCount: source.downloads.length - existingUris.length,
...downloadSourceSchema.parse(response.data),
etag: response.headers["etag"],
};
};

View File

@@ -1,6 +1,6 @@
import path from "node:path";
import steamGamesWorkerPath from "./steam-games.worker?modulePath";
import downloadSourceWorkerPath from "./download-source.worker?modulePath";
import downloadSourcesWorkerPath from "./download-sources.worker?modulePath";
import Piscina from "piscina";
@@ -14,6 +14,6 @@ export const steamGamesWorker = new Piscina({
maxThreads: 1,
});
export const downloadSourceWorker = new Piscina({
filename: downloadSourceWorkerPath,
export const downloadSourcesWorker = new Piscina({
filename: downloadSourcesWorkerPath,
});