Merge pull request #423 from hydralauncher/hotfix/repack-uploadDate

Hotfix/repack upload date
This commit is contained in:
Zamitto 2024-05-17 19:33:22 -03:00 committed by GitHub
commit 01c3ddf167
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 6586 additions and 62 deletions

BIN
hydra.db

Binary file not shown.

View File

@ -29,7 +29,8 @@
"build:win": "electron-vite build && electron-builder --win",
"build:mac": "electron-vite build && electron-builder --mac",
"build:linux": "electron-vite build && electron-builder --linux",
"prepare": "husky"
"prepare": "husky",
"typeorm:migration-create": "yarn typeorm migration:create"
},
"dependencies": {
"@electron-toolkit/preload": "^3.0.0",

View File

@ -9,6 +9,7 @@ import {
import type { SqliteConnectionOptions } from "typeorm/driver/sqlite/SqliteConnectionOptions";
import { databasePath } from "./constants";
import migrations from "./migrations";
export const createDataSource = (options: Partial<SqliteConnectionOptions>) =>
new DataSource({
@ -19,4 +20,6 @@ export const createDataSource = (options: Partial<SqliteConnectionOptions>) =>
...options,
});
export const dataSource = createDataSource({});
export const dataSource = createDataSource({
migrations: migrations,
});

View File

@ -53,6 +53,8 @@ app.whenReady().then(() => {
);
dataSource.initialize().then(async () => {
await dataSource.runMigrations();
await resolveDatabaseUpdates();
await import("./main");

View File

@ -0,0 +1,78 @@
import { createDataSource } from "@main/data-source";
import { Repack } from "@main/entity";
import { app } from "electron";
import { chunk } from "lodash-es";
import path from "path";
import { In, MigrationInterface, QueryRunner, Table } from "typeorm";
export class FixRepackUploadDate1715900413313 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.createTable(
new Table({
name: "repack_temp",
columns: [
{ name: "title", type: "varchar" },
{ name: "old_id", type: "int" },
],
}),
true
);
await queryRunner.query(
`INSERT INTO repack_temp (title, old_id) SELECT title, id FROM repack WHERE repacker IN ('onlinefix', 'Xatab');`
);
await queryRunner.query(
`DELETE FROM repack WHERE repacker IN ('onlinefix', 'Xatab');`
);
const updateDataSource = createDataSource({
database: app.isPackaged
? path.join(process.resourcesPath, "hydra.db")
: path.join(__dirname, "..", "..", "hydra.db"),
});
await updateDataSource.initialize();
const updateRepackRepository = updateDataSource.getRepository(Repack);
const updatedRepacks = await updateRepackRepository.find({
where: {
repacker: In(["onlinefix", "Xatab"]),
},
});
const chunks = chunk(
updatedRepacks.map((repack) => {
const { id: _, ...rest } = repack;
return rest;
}),
500
);
for (const chunk of chunks) {
await queryRunner.manager
.createQueryBuilder(Repack, "repack")
.insert()
.values(chunk)
.orIgnore()
.execute();
}
await queryRunner.query(
`UPDATE game
SET repackId = (
SELECT id
from repack LEFT JOIN repack_temp ON repack_temp.title = repack.title
WHERE repack_temp.old_id = game.repackId
)
WHERE EXISTS (select old_id from repack_temp WHERE old_id = game.repackId)`
);
await queryRunner.dropTable("repack_temp");
}
public async down(_: QueryRunner): Promise<void> {
return;
}
}

View File

@ -0,0 +1,3 @@
import { FixRepackUploadDate1715900413313 } from "./1715900413313-fix_repack_uploadDate";
export default [FixRepackUploadDate1715900413313];

View File

@ -3,21 +3,19 @@ import { decodeNonUtf8Response, savePage } from "./helpers";
import { logger } from "../logger";
import { JSDOM } from "jsdom";
import { format, parse, sub } from "date-fns";
import { ru } from "date-fns/locale";
import createWorker from "@main/workers/torrent-parser.worker?nodeWorker";
import { toMagnetURI } from "parse-torrent";
const worker = createWorker({});
import { onlinefixFormatter } from "@main/helpers";
import makeFetchCookie from "fetch-cookie";
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
import { formatBytes } from "@shared";
const ONLINE_FIX_URL = "https://online-fix.me/";
let totalPages = 1;
export const getNewRepacksFromOnlineFix = async (
existingRepacks: Repack[] = [],
page = 1,
@ -74,18 +72,16 @@ export const getNewRepacksFromOnlineFix = async (
const repacks: QueryDeepPartialEntity<Repack>[] = [];
const articles = Array.from(document.querySelectorAll(".news"));
const totalPages = Number(
document.querySelector("nav > a:nth-child(13)")?.textContent
);
if (page == 1) {
totalPages = Number(
document.querySelector("nav > a:nth-child(13)")?.textContent
);
}
try {
await Promise.all(
articles.map(async (article) => {
const gameText = article.querySelector("h2.title")?.textContent?.trim();
if (!gameText) return;
const gameName = onlinefixFormatter(gameText);
const gameLink = article.querySelector("a")?.getAttribute("href");
if (!gameLink) return;
@ -94,32 +90,6 @@ export const getNewRepacksFromOnlineFix = async (
);
const gameDocument = new JSDOM(gamePage).window.document;
const uploadDateText = gameDocument.querySelector("time")?.textContent;
if (!uploadDateText) return;
let decodedDateText = uploadDateText;
// "Вчера" means yesterday.
if (decodedDateText.includes("Вчера")) {
const yesterday = sub(new Date(), { days: 1 });
const formattedYesterday = format(yesterday, "d LLLL yyyy", {
locale: ru,
});
decodedDateText = decodedDateText.replace(
"Вчера", // "Change yesterday to the default expected date format"
formattedYesterday
);
}
const uploadDate = parse(
decodedDateText,
"d LLLL yyyy, HH:mm",
new Date(),
{
locale: ru,
}
);
const torrentButtons = Array.from(
gameDocument.querySelectorAll("a")
).filter((a) => a.textContent?.includes("Torrent"));
@ -148,13 +118,15 @@ export const getNewRepacksFromOnlineFix = async (
worker.once("message", (torrent) => {
if (!torrent) return;
const { name, created } = torrent;
repacks.push({
fileSize: formatBytes(torrent.length ?? 0),
magnet: toMagnetURI(torrent),
page: 1,
repacker: "onlinefix",
title: gameName,
uploadDate: uploadDate,
title: name,
uploadDate: created,
});
});

View File

@ -12,6 +12,9 @@ import { formatBytes } from "@shared";
import { getFileBuffer } from "@main/helpers";
const worker = createWorker({});
worker.setMaxListeners(11);
let totalPages = 1;
const formatXatabDate = (str: string) => {
const date = new Date();
@ -69,27 +72,37 @@ export const getNewRepacksFromXatab = async (
const repacks: QueryDeepPartialEntity<Repack>[] = [];
for (const $a of Array.from(
window.document.querySelectorAll(".entry__title a")
)) {
try {
const repack = await getXatabRepack(($a as HTMLAnchorElement).href);
if (repack) {
repacks.push({
title: $a.textContent!,
repacker: "Xatab",
...repack,
page,
});
}
} catch (err: unknown) {
logger.error((err as Error).message, {
method: "getNewRepacksFromXatab",
});
}
if (page === 1) {
totalPages = Number(
window.document.querySelector(
"#bottom-nav > div.pagination > a:nth-child(12)"
)?.textContent
);
}
const repacksFromPage = Array.from(
window.document.querySelectorAll(".entry__title a")
).map(($a) => {
return getXatabRepack(($a as HTMLAnchorElement).href)
.then((repack) => {
if (repack) {
repacks.push({
title: $a.textContent!,
repacker: "Xatab",
...repack,
page,
});
}
})
.catch((err: unknown) => {
logger.error((err as Error).message, {
method: "getNewRepacksFromXatab",
});
});
});
await Promise.all(repacksFromPage);
const newRepacks = repacks.filter(
(repack) =>
!existingRepacks.some(
@ -98,6 +111,7 @@ export const getNewRepacksFromXatab = async (
);
if (!newRepacks.length) return;
if (page === totalPages) return;
await savePage(newRepacks);

View File

@ -42,7 +42,7 @@ export function Modal({
}, [onClose]);
const isTopMostModal = () => {
const openModals = document.querySelectorAll("[role=modal]");
const openModals = document.querySelectorAll("[role=dialog]");
return (
openModals.length &&

6451
yarn.lock Normal file

File diff suppressed because it is too large Load Diff