Skip to content

Commit

Permalink
Merge pull request #353 from Zagrios/bugfix/prioritise-ipv4-to-avoid-…
Browse files Browse the repository at this point in the history
…ipv6-issues

[bugfix] prioritise ipv4 to avoid ipv6 issues
  • Loading branch information
Zagrios authored Nov 15, 2023
2 parents 1a55072 + 811d7a9 commit 46ee9d3
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 80 deletions.
15 changes: 10 additions & 5 deletions src/main/services/request.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get } from "https";
import { Agent, get } from "https";
import { createWriteStream, unlink } from "fs";
import { Progression } from "main/helpers/fs.helpers";
import { Observable, shareReplay, tap } from "rxjs";
Expand All @@ -17,12 +17,17 @@ export class RequestService {

private constructor() {}

private get ipv4Agent(){
return new Agent({ family: 4 });
}

public async getJSON<T = unknown>(url: RequestInfo, options?: RequestInit): Promise<T> {

try {
const response = await fetch(url, options);
const response = await fetch(url, {...options, agent: this.ipv4Agent});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status} ${response}`);
throw new Error(`HTTP error! status: ${response.status} ${url}`);
}

return await response.json();
Expand All @@ -45,7 +50,7 @@ export class RequestService {
});
file.on("error", err => unlink(dest, () => subscriber.error(err)));

const req = get(url, res => {
const req = get(url, { agent: this.ipv4Agent }, res => {
progress.total = parseInt(res.headers?.["content-length"] || "0", 10);

res.on("data", chunk => {
Expand All @@ -72,7 +77,7 @@ export class RequestService {

const allChunks: Buffer[] = [];

const req = get(url, res => {
const req = get(url, { agent: this.ipv4Agent }, res => {
progress.total = parseInt(res.headers?.["content-length"] || "0", 10);

res.on("data", chunk => {
Expand Down
50 changes: 17 additions & 33 deletions src/main/services/thrid-party/beat-saver/beat-saver-api.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ApiResult } from "renderer/models/api/api.model";
import { BsvMapDetail } from "shared/models/maps";
import { BsvPlaylist, BsvPlaylistPage, MapFilter, SearchParams, SearchResponse } from "shared/models/maps/beat-saver.model";
import fetch from "node-fetch";
import { RequestService } from "../../request.service";

export class BeatSaverApiService {
private static instance: BeatSaverApiService;
Expand All @@ -13,9 +12,13 @@ export class BeatSaverApiService {
return BeatSaverApiService.instance;
}

private readonly request: RequestService;

private readonly bsaverApiUrl = "https://beatsaver.com/api";

private constructor() {}
private constructor() {
this.request = RequestService.getInstance();
}

private mapFilterToUrlParams(filter: MapFilter): URLSearchParams {
if (!filter) {
Expand Down Expand Up @@ -68,57 +71,38 @@ export class BeatSaverApiService {
});
}

public async getMapsDetailsByHashs<T extends string>(hashs: T[]): Promise<ApiResult<Record<Lowercase<T>, BsvMapDetail>>> {
public async getMapsDetailsByHashs<T extends string>(hashs: T[]): Promise<Record<Lowercase<T>, BsvMapDetail>> {
if (hashs.length > 50) {
throw "too musch map hashs";
}

const paramsHashs = hashs.join(",");
const resp = await fetch(`${this.bsaverApiUrl}/maps/hash/${paramsHashs}`);

const data = (await resp.json()) as Record<Lowercase<T>, BsvMapDetail> | BsvMapDetail;
const data = await this.request.getJSON<Record<Lowercase<T>, BsvMapDetail> | BsvMapDetail>(`${this.bsaverApiUrl}/maps/hash/${paramsHashs}`);

if ((data as BsvMapDetail).id) {
const key = (data as BsvMapDetail).versions.at(0).hash.toLowerCase();
const parsedData = {
[key]: data as BsvMapDetail,
} as Record<Lowercase<T>, BsvMapDetail>;

return { status: resp.status, data: parsedData };
return parsedData
}

return { status: resp.status, data: data as Record<Lowercase<T>, BsvMapDetail> };
return data as Record<Lowercase<T>, BsvMapDetail>;
}

public async getMapDetailsById(id: string): Promise<ApiResult<BsvMapDetail>> {
const res = await fetch(`${this.bsaverApiUrl}/maps/id/${id}`);

const data = (await res.json()) as BsvMapDetail;

return { status: res.status, data };
public async getMapDetailsById(id: string): Promise<BsvMapDetail> {
return this.request.getJSON<BsvMapDetail>(`${this.bsaverApiUrl}/maps/id/${id}`);
}

public async searchMaps(search: SearchParams): Promise<ApiResult<SearchResponse>> {
public async searchMaps(search: SearchParams): Promise<SearchResponse> {
const url = new URL(`${this.bsaverApiUrl}/search/text/${search?.page ?? 0}`);

url.search = this.searchParamsToUrlParams(search).toString();

const res = await fetch(url.toString());

if (!res.ok) {
return { status: res.status, data: null };
}

const data = await res.json();

return { status: res.status, data };
return this.request.getJSON<SearchResponse>(url.toString());
}

public async getPlaylistDetails(id: string): Promise<ApiResult<BsvPlaylist>> {
const res = await fetch(`${this.bsaverApiUrl}/playlists/id/${id}/0`);

const data = (await res.json()) as BsvPlaylistPage;

return { status: res.status, data: data.playlist };
public async getPlaylistDetails(id: string): Promise<BsvPlaylist> {
const res = await this.request.getJSON<BsvPlaylistPage>(`${this.bsaverApiUrl}/playlists/id/${id}/0`);
return res.playlist;
}
}
22 changes: 10 additions & 12 deletions src/main/services/thrid-party/beat-saver/beat-saver.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { splitIntoChunk } from "../../../../shared/helpers/array.helpers";
import { BsvMapDetail } from "shared/models/maps";
import { BsvPlaylist, SearchParams } from "shared/models/maps/beat-saver.model";
import { BeatSaverApiService } from "./beat-saver-api.service";
import log from "electron-log";

export class BeatSaverService {
private static instance: BeatSaverService;
Expand Down Expand Up @@ -36,36 +37,33 @@ export class BeatSaverService {
chunkHash.map(async hashs => {
const res = await this.bsaverApi.getMapsDetailsByHashs(hashs);

if (res.status === 200) {
mapDetails.push(...Object.values<BsvMapDetail>(res.data).filter(detail => !!detail));
mapDetails.forEach(detail => {
this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail);
});
}
mapDetails.push(...Object.values<BsvMapDetail>(res).filter(detail => !!detail));
mapDetails.forEach(detail => {
this.cachedMapsDetails.set(detail.versions.at(0).hash.toLowerCase(), detail);
});
})
);

return mapDetails;
}

public async getMapDetailsById(id: string): Promise<BsvMapDetail> {
const res = await this.bsaverApi.getMapDetailsById(id);
return res.data;
return this.bsaverApi.getMapDetailsById(id);
}

public searchMaps(search: SearchParams): Promise<BsvMapDetail[]> {
return this.bsaverApi
.searchMaps(search)
.then(res => {
return res.status === 200 ? res.data.docs : [];
return res.docs;
})
.catch(() => {
.catch(e => {
log.error(e);
return [];
});
}

public async getPlaylistPage(id: string): Promise<BsvPlaylist> {
const res = await this.bsaverApi.getPlaylistDetails(id);
return res.data;
return this.bsaverApi.getPlaylistDetails(id);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import fetch from "node-fetch";
import { ApiResult } from "renderer/models/api/api.model";
import { MSGetQuery, MSGetQueryFilter, MSGetResponse } from "../../../../shared/models/models/model-saber.model";
import { RequestService } from "../../request.service";

export class ModelSaberApiService {

private static instance: ModelSaberApiService;

public static getInstance(): ModelSaberApiService {
Expand All @@ -15,7 +15,11 @@ export class ModelSaberApiService {
private readonly API_URL = "https://modelsaber.com/api/v2/";
private readonly ENDPOINTS = { get: "get.php", types: "types.php" };

private constructor() {}
private readonly request: RequestService;

private constructor() {
this.request = RequestService.getInstance();
}

private parseFilters(filters: MSGetQueryFilter[]): string {
if (!filters) {
Expand Down Expand Up @@ -50,19 +54,10 @@ export class ModelSaberApiService {
return new URLSearchParams(searchParams);
}

public async searchModel(query: MSGetQuery): Promise<ApiResult<MSGetResponse>> {
public async searchModel(query: MSGetQuery): Promise<MSGetResponse> {
const url = new URL(this.ENDPOINTS.get, this.API_URL);

url.search = this.buildUrlQuery(query).toString();

const res = await fetch(url.toString());

if (!res.ok) {
return { data: null, status: res.status };
}

const data = (await res.json()) as MSGetResponse;

return { data, status: res.status };
return this.request.getJSON<MSGetResponse>(url.toString());
}
}
22 changes: 6 additions & 16 deletions src/main/services/thrid-party/model-saber/model-saber.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,11 @@ export class ModelSaberService {
try {
const res = await this.modelSaberApi.searchModel(query);

if (res.status !== 200) {
if (Object.keys(res).length === 0) {
return null;
}

if (Object.keys(res.data).length === 0) {
return null;
}

return res.data[`${id}`];
return res[`${id}`];
} catch (e) {
log.error(e);
return null;
Expand All @@ -63,15 +59,11 @@ export class ModelSaberService {
try {
const res = await this.modelSaberApi.searchModel(query);

if (res.status !== 200) {
if (Object.keys(res).length === 0) {
return null;
}

if (Object.keys(res.data).length === 0) {
return null;
}

const model = Array.from(Object.values(res.data)).at(0);
const model = Array.from(Object.values(res)).at(0);

model.name = striptags(model.name ?? "");
model.author = striptags(model.author ?? "");
Expand All @@ -89,11 +81,9 @@ export class ModelSaberService {
return new Observable<MSModel[]>(observer => {
(async () => {
const res = await this.modelSaberApi.searchModel(query);
if (res.status !== 200) {
observer.error(res.status);
}

observer.next(
Object.values(res.data).map(model => {
Object.values(res).map(model => {
if (!model?.name) {
return null;
}
Expand Down

0 comments on commit 46ee9d3

Please sign in to comment.