diff --git a/src/index.js b/src/index.js index 5d00dd8..fff10ef 100755 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ const { QMainWindow, FlexLayout, QWidget, QLabel, QFileDialog, QPushButton, FileMode, QIcon, QLineEdit } = require("@nodegui/nodegui"); -const downloadCollection = require("./modules/downloadCollection.js"); +const osuCollectorClient = require("./struct/osuCollectorClient.js"); +const osuCollector = new osuCollectorClient(); const win = new QMainWindow(); win.setWindowTitle("osu!collector"); @@ -127,29 +128,29 @@ rootView.setStyleSheet(rootStyleSheet); // Handle directory select button let directory = ""; directorySelectButton.addEventListener('clicked', (checked) => { - const fileDialog = new QFileDialog(); - fileDialog.setFileMode(FileMode.Directory); - fileDialog.exec(); + const fileDialog = new QFileDialog(); + fileDialog.setFileMode(FileMode.Directory); + fileDialog.exec(); - const directorys = fileDialog.selectedFiles(); - directory = directorys[0]; - directoryLabel.setText(directory); + const directorys = fileDialog.selectedFiles(); + directory = directorys[0]; + directoryLabel.setText(directory); }) downloadButton.addEventListener('clicked', (checked) => { - if (directory == "") { - downloadStatus.setText("Directory not selected.") - return - } - - const collectionId = collectionIdInput.text() - console.log(collectionId) - if (collectionId == "") { - downloadStatus.setText("Collection Id not selected.") - return - } - - downloadCollection(directory, collectionId); + if (directory == "") { + downloadStatus.setText("Directory not selected.") + return + } + + const collectionId = collectionIdInput.text() + console.log(collectionId) + if (collectionId == "") { + downloadStatus.setText("Collection Id not selected.") + return + } + + osuCollector.downloadColleciton(directory, collectionId); }) win.show(); diff --git a/src/modules/downloadCollection.js b/src/modules/downloadCollection.js deleted file mode 100644 index f141d04..0000000 --- a/src/modules/downloadCollection.js +++ /dev/null @@ -1,63 +0,0 @@ -const { OsuCollectorNode } = require("osu-collector-node") -const { DownloaderHelper } = require("node-downloader-helper"); -const fs = require('fs'); - -const mirrors = { - chimu: "https://api.chimu.moe/v1/download/", - kitsu: "https://kitsu.moe/api/d/", -}; - -const osuCollector = new OsuCollectorNode() - -async function downloadCollection(Directory, CollectionId) { - const Collection = await osuCollector.getCollection({ id: CollectionId }).catch(console.log); - const downloadDirectory = `${Directory}/${Collection.name}`; - - if (!Collection) return; - if (!downloadDirectory) return; - - // Make directory to download beatmaps to. - if (!fs.existsSync(downloadDirectory)) { - fs.mkdir(downloadDirectory, (error) => { - if (error) console.log(error); - if (!error) console.log("New Directory created successfully"); - }); - } - - // Attempt to download all beatmapsets - for (beatmapset of Collection.beatmapsets) { - const beatmapId = beatmapset.id; - const filename = `${beatmapId}.osz` - const beatmapDirectory = `${downloadDirectory}/${filename}` - - function AttemptDownload(api) { - const Download = new DownloaderHelper(`${mirrors[api]}${beatmapId}`, downloadDirectory, { fileName: filename }); - - Download.start().catch(async (err) => { });; - console.log(`[${beatmapId}] Beatmap downloading (${api})`); - - Download.on("end", () => { - console.log(`[${beatmapId}] Beatmap download completed successfully (${api})`); - }); - - Download.on('error', (err) => { - console.warn(`[${beatmapId}] Beatmap download failed`); - - if (fs.existsSync(beatmapDirectory)) { - fs.unlinkSync(beatmapDirectory); - } - - if (api == "kitsu") return; - - console.warn(`[${beatmapId}] Reattempting download`); - AttemptDownload("kitsu"); - }) - } - - if (!fs.existsSync(beatmapDirectory)) { - AttemptDownload("chimu"); - } - }; -} - -module.exports = downloadCollection; \ No newline at end of file diff --git a/src/struct/osuCollectorClient.js b/src/struct/osuCollectorClient.js new file mode 100644 index 0000000..2606ae2 --- /dev/null +++ b/src/struct/osuCollectorClient.js @@ -0,0 +1,89 @@ +const { OsuCollectorNode } = require("osu-collector-node") +const { DownloaderHelper } = require("node-downloader-helper"); +const Constants = require("../util/Constants.js"); +const fs = require('fs'); +const path = require("path"); + +class Client { + /** + * Creates a new client object + */ + constructor() { + this.osuCollector = new OsuCollectorNode(); + } + + /** + * Download a collection to a directory + * @param {String} Directory Directory to download to + * @param {number} collectionId Collection Id + */ + async downloadColleciton(Directory, collectionId) { + const Collection = await this.osuCollector.getCollection({ id: collectionId }).catch(console.log); + const downloadDirectory = `${Directory}/${(Collection.name).replace(/[/\\?%*:|"<>]/g, '-')}`; // Remove illegal characters + + if (!Collection) return; + if (!downloadDirectory) return; + + // Make directory to download beatmaps to. + if (!fs.existsSync(downloadDirectory)) { + fs.mkdir(downloadDirectory, (error) => { + if (error) console.log(error); + if (!error) console.log("New Directory created successfully"); + }); + } + console.log(Collection.beatmapsets) + for (let beatmapset of Collection.beatmapsets) { + this._attemptBeatmapsetDownload(beatmapset.id, downloadDirectory, 0, true); + } + } + + /** + * Makes an api call + * @param {number} beatmapId Beatmap Id + * @param {path} downloadDirectory Beatmap Id + * @param {number} api + * @param {boolean} reattempt Resursive searching + */ + async _attemptBeatmapsetDownload(beatmapId, downloadDirectory, api, reattempt) { + const mirrorApi = Constants.mirror[api]; + const filename = `${beatmapId}.osz` + const beatmapDirectory = `${downloadDirectory}/${filename}` + + // If file is already downloaded break + if (fs.existsSync(beatmapDirectory)) return; + + // Create download process + console.log(api) + console.log(`${mirrorApi.url}${beatmapId}`) + const downloadProcess = new DownloaderHelper(`${mirrorApi.url}${beatmapId}`, downloadDirectory, { fileName: filename }); + + // Begin Download + downloadProcess.start().catch(async (err) => { });; + console.log(`[${beatmapId}] Beatmap downloading (${mirrorApi.name})`); + + // Successfull Download + downloadProcess.on("end", () => { + console.log(`[${beatmapId}] Beatmap download completed successfully (${mirrorApi.name})`); + }); + + // Error Download + downloadProcess.on('error', (err) => { + console.warn(`[${beatmapId}] Beatmap download failed`); + + // Delete beatmapset file if it exists + if (fs.existsSync(beatmapDirectory)) { + fs.unlinkSync(beatmapDirectory); + } + + // Reattempt download with another api + const next = (api + 1); + if (!reattempt) return // If set to not reattempt search break recursion + if (!Constants.mirror[next]) return; // If there are no more apis to download from break recursion + + console.warn(`[${beatmapId}] Reattempting download...`); + this._attemptBeatmapsetDownload(beatmapId, downloadDirectory, next, true); + }) + } +} + +module.exports = Client; diff --git a/src/util/Constants.js b/src/util/Constants.js new file mode 100644 index 0000000..7800eb3 --- /dev/null +++ b/src/util/Constants.js @@ -0,0 +1,19 @@ +module.exports = { + /** + * Mirror apis + */ + mirror: { + 0: { + name: "chimu", + url: "https://api.chimu.moe/v1/download/" + }, + 1: { + name: "kitsu", + url: "https://kitsu.moe/api/d/" + }, + 2: { + name: "nerinyan", + url: "https://api.nerinyan.moe/d/" + }, + } +} \ No newline at end of file