2025-02-21 18:30:13 +08:00
|
|
|
import VersionDao from "../dao/VersionDao";
|
|
|
|
import BaseService from "./BaseService";
|
|
|
|
import GitHubService from "./GitHubService";
|
|
|
|
import FileService from "./FileService";
|
|
|
|
import frpReleasesJson from "../json/frp-releases.json";
|
|
|
|
import { download } from "electron-dl";
|
|
|
|
import { BrowserWindow } from "electron";
|
|
|
|
import GlobalConstant from "../core/GlobalConstant";
|
|
|
|
import path from "path";
|
|
|
|
import fs from "fs";
|
|
|
|
import SecureUtils from "../utils/SecureUtils";
|
|
|
|
import PathUtils from "../utils/PathUtils";
|
2025-02-23 02:11:17 +08:00
|
|
|
import FileUtils from "../utils/FileUtils";
|
2025-02-21 18:30:13 +08:00
|
|
|
|
|
|
|
class VersionService extends BaseService<FrpcVersion> {
|
|
|
|
private readonly _versionDao: VersionDao;
|
|
|
|
private readonly _fileService: FileService;
|
|
|
|
private readonly _gitHubService: GitHubService;
|
|
|
|
private readonly _currFrpArch: Array<string>;
|
|
|
|
private versions: Array<FrpcVersion> = [];
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
versionDao: VersionDao,
|
|
|
|
fileService: FileService,
|
|
|
|
gitHubService: GitHubService
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
this._versionDao = versionDao;
|
|
|
|
this._gitHubService = gitHubService;
|
|
|
|
this._fileService = fileService;
|
|
|
|
const nodeVersion = `${process.platform}_${process.arch}`;
|
2025-02-23 02:11:17 +08:00
|
|
|
this._currFrpArch = GlobalConstant.FRP_ARCH_VERSION_MAPPING[nodeVersion];
|
2025-02-21 18:30:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
downloadFrpVersion(githubReleaseId: number, onProgress: Function) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const version = this.versions.find(
|
|
|
|
f => f.githubReleaseId === githubReleaseId
|
|
|
|
);
|
|
|
|
if (!version) {
|
|
|
|
reject(new Error("version not found"));
|
|
|
|
}
|
|
|
|
const url = version.browserDownloadUrl;
|
|
|
|
const downloadedFilePath = path.join(
|
|
|
|
PathUtils.getDownloadStoragePath(),
|
|
|
|
`${version.assetName}`
|
|
|
|
);
|
|
|
|
|
|
|
|
const versionFilePath = path.join(
|
|
|
|
PathUtils.getVersionStoragePath(),
|
|
|
|
SecureUtils.calculateMD5(version.name)
|
|
|
|
);
|
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
if (fs.existsSync(versionFilePath)) {
|
|
|
|
fs.rmSync(versionFilePath, { recursive: true, force: true });
|
|
|
|
}
|
2025-02-21 18:30:13 +08:00
|
|
|
// const targetPath = path.resolve();
|
|
|
|
download(BrowserWindow.getFocusedWindow(), url, {
|
|
|
|
filename: `${version.assetName}`,
|
|
|
|
directory: PathUtils.getDownloadStoragePath(),
|
|
|
|
onProgress: progress => {
|
|
|
|
onProgress(progress);
|
|
|
|
},
|
|
|
|
onCompleted: () => {
|
|
|
|
const ext = path.extname(version.assetName);
|
|
|
|
if (ext === GlobalConstant.ZIP_EXT) {
|
|
|
|
this._fileService.decompressZipFile(
|
|
|
|
downloadedFilePath,
|
|
|
|
versionFilePath
|
|
|
|
);
|
2025-02-23 02:11:17 +08:00
|
|
|
// todo delete frps and other file.
|
2025-02-21 18:30:13 +08:00
|
|
|
} else if (
|
|
|
|
ext === GlobalConstant.GZ_EXT &&
|
|
|
|
version.assetName.includes(GlobalConstant.TAR_GZ_EXT)
|
|
|
|
) {
|
|
|
|
this._fileService.decompressTarGzFile(
|
|
|
|
downloadedFilePath,
|
2025-02-23 02:11:17 +08:00
|
|
|
versionFilePath,
|
|
|
|
() => {
|
|
|
|
// rename frpc.
|
|
|
|
const frpcFilePath = path.join(versionFilePath, "frpc");
|
|
|
|
if (fs.existsSync(frpcFilePath)) {
|
|
|
|
const newFrpcFilePath = path.join(
|
|
|
|
versionFilePath,
|
|
|
|
PathUtils.getFrpcFilename()
|
|
|
|
);
|
|
|
|
fs.renameSync(frpcFilePath, newFrpcFilePath);
|
|
|
|
}
|
|
|
|
// delete downloaded file.
|
|
|
|
// todo has bug.
|
|
|
|
const downloadedFile = path.join(
|
|
|
|
PathUtils.getDownloadStoragePath(),
|
|
|
|
version.assetName
|
|
|
|
);
|
|
|
|
if (fs.existsSync(downloadedFile)) {
|
|
|
|
fs.rmSync(downloadedFile, { recursive: true, force: true });
|
|
|
|
}
|
|
|
|
}
|
2025-02-21 18:30:13 +08:00
|
|
|
);
|
|
|
|
}
|
2025-02-23 02:11:17 +08:00
|
|
|
|
|
|
|
// todo 2025-02-23 delete downloaded file.
|
2025-02-21 18:30:13 +08:00
|
|
|
version.localPath = versionFilePath;
|
2025-02-23 02:11:17 +08:00
|
|
|
version.downloaded = true;
|
|
|
|
this._versionDao
|
|
|
|
.insert(version)
|
|
|
|
.then(data => {
|
|
|
|
resolve(data);
|
|
|
|
})
|
|
|
|
.catch(err => reject(err));
|
2025-02-21 18:30:13 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
async deleteFrpVersion(githubReleaseId: number) {
|
|
|
|
if (!githubReleaseId) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const version = await this._versionDao.findByGithubReleaseId(
|
|
|
|
githubReleaseId
|
|
|
|
);
|
|
|
|
if (this.frpcVersionExists(version)) {
|
|
|
|
fs.rmSync(version.localPath, { recursive: true, force: true });
|
|
|
|
await this._versionDao.deleteById(version._id);
|
|
|
|
}
|
|
|
|
}
|
2025-02-21 18:30:13 +08:00
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
async getFrpVersionsByGitHub(): Promise<Array<FrpcVersion>> {
|
2025-02-21 18:30:13 +08:00
|
|
|
return new Promise<Array<FrpcVersion>>((resolve, reject) => {
|
|
|
|
this._gitHubService
|
|
|
|
.getGithubRepoAllReleases("fatedier/frp")
|
2025-02-23 02:11:17 +08:00
|
|
|
.then(async (releases: Array<GithubRelease>) => {
|
2025-02-21 18:30:13 +08:00
|
|
|
const versions: Array<FrpcVersion> =
|
2025-02-23 02:11:17 +08:00
|
|
|
await this.githubRelease2FrpcVersion(releases);
|
|
|
|
// const versions: Array<FrpcVersion> = (this.versions = versions);
|
2025-02-21 18:30:13 +08:00
|
|
|
this.versions = versions;
|
|
|
|
resolve(versions);
|
|
|
|
})
|
|
|
|
.catch(err => reject(err));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
async getFrpVersionByLocalJson(): Promise<Array<FrpcVersion>> {
|
|
|
|
return this.githubRelease2FrpcVersion(frpReleasesJson);
|
2025-02-21 18:30:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
getFrpVersion() {}
|
|
|
|
|
|
|
|
private findCurrentArchitectureAsset(assets: Array<GithubAsset>) {
|
|
|
|
return assets.find((af: GithubAsset) => {
|
|
|
|
return this._currFrpArch.every(item => af.name.includes(item));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
private async githubRelease2FrpcVersion(
|
2025-02-21 18:30:13 +08:00
|
|
|
releases: Array<GithubRelease>
|
2025-02-23 02:11:17 +08:00
|
|
|
): Promise<Array<FrpcVersion>> {
|
|
|
|
const allVersions = await this._versionDao.findAll();
|
2025-02-21 18:30:13 +08:00
|
|
|
return releases
|
|
|
|
.filter(release => {
|
|
|
|
return this.findCurrentArchitectureAsset(release.assets);
|
|
|
|
})
|
|
|
|
.map(m => {
|
|
|
|
const asset = this.findCurrentArchitectureAsset(m.assets);
|
|
|
|
const download_count = m.assets.reduce(
|
|
|
|
(sum, item) => sum + item.download_count,
|
|
|
|
0
|
|
|
|
);
|
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
const currVersion = allVersions.find(ff => ff.githubReleaseId === m.id);
|
2025-02-21 18:30:13 +08:00
|
|
|
const v: FrpcVersion = {
|
2025-02-23 02:11:17 +08:00
|
|
|
_id: "",
|
2025-02-21 18:30:13 +08:00
|
|
|
githubReleaseId: m.id,
|
|
|
|
githubAssetId: asset.id,
|
|
|
|
githubCreatedAt: asset.created_at,
|
|
|
|
name: m.name,
|
|
|
|
assetName: asset.name,
|
|
|
|
versionDownloadCount: download_count,
|
|
|
|
assetDownloadCount: asset.download_count,
|
|
|
|
browserDownloadUrl: asset.browser_download_url,
|
2025-02-23 02:11:17 +08:00
|
|
|
downloaded: this.frpcVersionExists(currVersion),
|
|
|
|
localPath: currVersion && currVersion.localPath,
|
2025-02-21 18:30:13 +08:00
|
|
|
size: FileUtils.formatBytes(asset.size)
|
|
|
|
};
|
|
|
|
return v;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
private frpcVersionExists(version: FrpcVersion): boolean {
|
|
|
|
// const version = await this._versionDao.findByGithubReleaseId(
|
|
|
|
// githubReleaseId
|
|
|
|
// );
|
|
|
|
|
|
|
|
if (version) {
|
|
|
|
return fs.existsSync(version.localPath);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2025-02-21 18:30:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export default VersionService;
|