This commit is contained in:
Emmm Monster
2021-05-24 23:48:52 +08:00
parent 407d37c770
commit 3cae9b4cad
9 changed files with 230 additions and 164 deletions

56
src/utils/api.ts Normal file
View File

@@ -0,0 +1,56 @@
import {fromByteArray as Base64Encode} from "base64-js";
export const IXAREA_API_ENDPOINT = "https://stats.ixarea.com/apis"
export interface UpdateInfo {
Found: boolean
HttpsFound: boolean
Version: string
URL: string
Detail: string
}
export async function checkUpdate(version: string): Promise<UpdateInfo> {
const resp = await fetch(IXAREA_API_ENDPOINT + "/music/app-version", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({"Version": version})
});
return await resp.json();
}
export function reportKeyUsage(keyData: Uint8Array, maskData: number[], filename: string, format: string, title: string, artist?: string, album?: string) {
return fetch(IXAREA_API_ENDPOINT + "/qmcmask/usage", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({
Mask: Base64Encode(new Uint8Array(maskData)), Key: Base64Encode(keyData),
Artist: artist, Title: title, Album: album, Filename: filename, Format: format
}),
})
}
interface KeyInfo {
Matrix44: string
}
export async function queryKeyInfo(keyData: Uint8Array, filename: string, format: string): Promise<KeyInfo> {
const resp = await fetch(IXAREA_API_ENDPOINT + "/qmcmask/query", {
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({Format: format, Key: Base64Encode(keyData), Filename: filename, Type: 44}),
});
return await resp.json();
}
export interface CoverInfo {
Id: string
Type: number
}
export async function queryAlbumCover(title: string, artist?: string, album?: string): Promise<CoverInfo> {
const endpoint = IXAREA_API_ENDPOINT + "/music/qq-cover"
const params = new URLSearchParams([["Title", title], ["Artist", artist ?? ""], ["Album", album ?? ""]])
const resp = await fetch(`${endpoint}?${params.toString()}`)
return await resp.json()
}

64
src/utils/utils.ts Normal file
View File

@@ -0,0 +1,64 @@
import {DecryptResult} from "@/decrypt/entity";
export enum FilenamePolicy {
ArtistAndTitle,
TitleOnly,
TitleAndArtist,
SameAsOriginal,
}
export const FilenamePolicies: { key: FilenamePolicy, text: string }[] = [
{key: FilenamePolicy.ArtistAndTitle, text: "歌手-歌曲名"},
{key: FilenamePolicy.TitleOnly, text: "歌曲名"},
{key: FilenamePolicy.TitleAndArtist, text: "歌曲名-歌手"},
{key: FilenamePolicy.SameAsOriginal, text: "同源文件名"},
]
export function DownloadBlobMusic(data: DecryptResult, policy: FilenamePolicy) {
const a = document.createElement('a');
a.href = data.file;
switch (policy) {
default:
case FilenamePolicy.ArtistAndTitle:
a.download = data.artist + " - " + data.title + "." + data.ext;
break;
case FilenamePolicy.TitleOnly:
a.download = data.title + "." + data.ext;
break;
case FilenamePolicy.TitleAndArtist:
a.download = data.title + " - " + data.artist + "." + data.ext;
break;
case FilenamePolicy.SameAsOriginal:
a.download = data.rawFilename + "." + data.ext;
break;
}
document.body.append(a);
a.click();
a.remove();
}
export function RemoveBlobMusic(data: DecryptResult) {
URL.revokeObjectURL(data.file);
if (data.picture?.startsWith("blob:")) {
URL.revokeObjectURL(data.picture);
}
}
export class DecryptQueue {
private readonly pending: (() => Promise<void>)[];
constructor() {
this.pending = []
}
queue(fn: () => Promise<void>) {
this.pending.push(fn)
this.consume()
}
private consume() {
const fn = this.pending.shift()
if (fn) fn().then(() => this.consume).catch(console.error)
}
}

4
src/utils/worker.ts Normal file
View File

@@ -0,0 +1,4 @@
import {expose} from "threads/worker";
import {CommonDecrypt} from "@/decrypt/common";
expose(CommonDecrypt)