From 25d379937305b288d906240692a318fce76776fb Mon Sep 17 00:00:00 2001 From: DJ Stomp <85457381+DJStompZone@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:21:00 -0700 Subject: [PATCH 1/4] Download Progress Add optional progress indicator for backup downloads Add option to specify filename for output file --- src/structures/Download.js | 99 ++++++++++++++++++++++++++------------ 1 file changed, 67 insertions(+), 32 deletions(-) diff --git a/src/structures/Download.js b/src/structures/Download.js index 0a4f63e..2c4c3b9 100644 --- a/src/structures/Download.js +++ b/src/structures/Download.js @@ -1,37 +1,72 @@ const fs = require('fs').promises const fetch = require('node-fetch') +const { Writable } = require('stream'); module.exports = class Download { - #api - constructor (api, data) { - this.#api = api - this.downloadUrl = data.downloadLink ?? data.downloadUrl - if (this.#api.platform === 'bedrock') { - this.token = data.token - this.size = data.size - this.fileExtension = '.mcworld' - } else { - this.resourcePackUrl = data.resourcePackUrl - this.resourcePackHash = data.resourcePackHash - this.fileExtension = '.tar.gz' - } - } - - async writeToDirectory (directory) { - return this.#downloadWorld().then(buffer => fs.writeFile(`${directory}/world${this.fileExtension}`, buffer)) - } - - async getBuffer () { - return this.#downloadWorld() - } - - async #downloadWorld () { - const res = await fetch(this.downloadUrl, { - headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} - }) - - if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`) - - return await res.buffer() - } + #api + constructor(api, data) { + this.#api = api + this.downloadUrl = data.downloadLink ?? data.downloadUrl + if (this.#api.platform === 'bedrock') { + this.token = data.token + this.size = data.size + this.fileExtension = '.mcworld' + } else { + this.resourcePackUrl = data.resourcePackUrl + this.resourcePackHash = data.resourcePackHash + this.fileExtension = '.tar.gz' + } + } + + async writeToDirectory(directory, showProgress = false, filename = 'world') { + return (showProgress ? this.#downloadWorldWithProgress() : this.#downloadWorld()) + .then(buffer => fs.writeFile(`${directory}/${filename}${this.fileExtension}`, buffer)) + } + + async getBuffer() { + return this.#downloadWorld() + } + + async #downloadWorld() { + const res = await fetch(this.downloadUrl, { + headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} + }) + + if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`) + + return await res.buffer() + } + + async #downloadWorldWithProgress() { + const res = await fetch(this.downloadUrl, { + headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} + }); + + if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`); + + const totalSize = parseInt(res.headers.get('content-length'), 10); + let downloadedSize = 0; + + const progressBar = (size) => { + downloadedSize += size; + const percentage = ((downloadedSize / totalSize) * 100).toFixed(2); + process.stdout.clearLine(); + process.stdout.cursorTo(0); + process.stdout.write(`Progress: [${'#'.repeat((percentage / 10).toFixed(0))}] ${percentage}%`); + }; + + return new Promise((resolve, reject) => { + const fileChunks = []; + res.body + .on('data', (chunk) => { + fileChunks.push(chunk); + progressBar(chunk.length); + }) + .on('end', () => { + process.stdout.write('\n'); + resolve(Buffer.concat(fileChunks)); + }) + .on('error', reject); + }); + } } From 7c6fb55badadf1b12428115a8d551d48acbbd056 Mon Sep 17 00:00:00 2001 From: DJ Stomp <85457381+DJStompZone@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:24:29 -0700 Subject: [PATCH 2/4] Tabs -> Spaces --- src/structures/Download.js | 112 ++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/src/structures/Download.js b/src/structures/Download.js index 2c4c3b9..8194902 100644 --- a/src/structures/Download.js +++ b/src/structures/Download.js @@ -3,70 +3,70 @@ const fetch = require('node-fetch') const { Writable } = require('stream'); module.exports = class Download { - #api - constructor(api, data) { - this.#api = api - this.downloadUrl = data.downloadLink ?? data.downloadUrl - if (this.#api.platform === 'bedrock') { - this.token = data.token - this.size = data.size - this.fileExtension = '.mcworld' - } else { - this.resourcePackUrl = data.resourcePackUrl - this.resourcePackHash = data.resourcePackHash - this.fileExtension = '.tar.gz' - } - } + #api + constructor(api, data) { + this.#api = api + this.downloadUrl = data.downloadLink ?? data.downloadUrl + if (this.#api.platform === 'bedrock') { + this.token = data.token + this.size = data.size + this.fileExtension = '.mcworld' + } else { + this.resourcePackUrl = data.resourcePackUrl + this.resourcePackHash = data.resourcePackHash + this.fileExtension = '.tar.gz' + } + } - async writeToDirectory(directory, showProgress = false, filename = 'world') { - return (showProgress ? this.#downloadWorldWithProgress() : this.#downloadWorld()) - .then(buffer => fs.writeFile(`${directory}/${filename}${this.fileExtension}`, buffer)) - } + async writeToDirectory(directory, showProgress = false, filename = 'world') { + return (showProgress ? this.#downloadWorldWithProgress() : this.#downloadWorld()) + .then(buffer => fs.writeFile(`${directory}/${filename}${this.fileExtension}`, buffer)) + } - async getBuffer() { - return this.#downloadWorld() - } + async getBuffer() { + return this.#downloadWorld() + } - async #downloadWorld() { - const res = await fetch(this.downloadUrl, { - headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} - }) + async #downloadWorld() { + const res = await fetch(this.downloadUrl, { + headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} + }) - if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`) + if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`) - return await res.buffer() - } + return await res.buffer() + } - async #downloadWorldWithProgress() { - const res = await fetch(this.downloadUrl, { - headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} - }); + async #downloadWorldWithProgress() { + const res = await fetch(this.downloadUrl, { + headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} + }); - if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`); + if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`); - const totalSize = parseInt(res.headers.get('content-length'), 10); - let downloadedSize = 0; + const totalSize = parseInt(res.headers.get('content-length'), 10); + let downloadedSize = 0; - const progressBar = (size) => { - downloadedSize += size; - const percentage = ((downloadedSize / totalSize) * 100).toFixed(2); - process.stdout.clearLine(); - process.stdout.cursorTo(0); - process.stdout.write(`Progress: [${'#'.repeat((percentage / 10).toFixed(0))}] ${percentage}%`); - }; + const progressBar = (size) => { + downloadedSize += size; + const percentage = ((downloadedSize / totalSize) * 100).toFixed(2); + process.stdout.clearLine(); + process.stdout.cursorTo(0); + process.stdout.write(`Progress: [${'#'.repeat((percentage / 10).toFixed(0))}] ${percentage}%`); + }; - return new Promise((resolve, reject) => { - const fileChunks = []; - res.body - .on('data', (chunk) => { - fileChunks.push(chunk); - progressBar(chunk.length); - }) - .on('end', () => { - process.stdout.write('\n'); - resolve(Buffer.concat(fileChunks)); - }) - .on('error', reject); - }); - } + return new Promise((resolve, reject) => { + const fileChunks = []; + res.body + .on('data', (chunk) => { + fileChunks.push(chunk); + progressBar(chunk.length); + }) + .on('end', () => { + process.stdout.write('\n'); + resolve(Buffer.concat(fileChunks)); + }) + .on('error', reject); + }); + } } From e5c73b64f33d637b580be967d4d4c4d49b5ddcd1 Mon Sep 17 00:00:00 2001 From: DJ Stomp <85457381+DJStompZone@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:40:10 -0700 Subject: [PATCH 3/4] Spaces -_- Eslint is busting my balls today --- src/structures/Download.js | 110 ++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/src/structures/Download.js b/src/structures/Download.js index 8194902..ef879d0 100644 --- a/src/structures/Download.js +++ b/src/structures/Download.js @@ -3,70 +3,70 @@ const fetch = require('node-fetch') const { Writable } = require('stream'); module.exports = class Download { - #api - constructor(api, data) { - this.#api = api - this.downloadUrl = data.downloadLink ?? data.downloadUrl - if (this.#api.platform === 'bedrock') { - this.token = data.token - this.size = data.size - this.fileExtension = '.mcworld' - } else { - this.resourcePackUrl = data.resourcePackUrl - this.resourcePackHash = data.resourcePackHash - this.fileExtension = '.tar.gz' - } + #api + constructor(api, data) { + this.#api = api + this.downloadUrl = data.downloadLink ?? data.downloadUrl + if (this.#api.platform === 'bedrock') { + this.token = data.token + this.size = data.size + this.fileExtension = '.mcworld' + } else { + this.resourcePackUrl = data.resourcePackUrl + this.resourcePackHash = data.resourcePackHash + this.fileExtension = '.tar.gz' } + } - async writeToDirectory(directory, showProgress = false, filename = 'world') { - return (showProgress ? this.#downloadWorldWithProgress() : this.#downloadWorld()) - .then(buffer => fs.writeFile(`${directory}/${filename}${this.fileExtension}`, buffer)) - } + async writeToDirectory(directory, showProgress = false, filename = 'world') { + return (showProgress ? this.#downloadWorldWithProgress() : this.#downloadWorld()) + .then(buffer => fs.writeFile(`${directory}/${filename}${this.fileExtension}`, buffer)) + } - async getBuffer() { - return this.#downloadWorld() - } + async getBuffer() { + return this.#downloadWorld() + } - async #downloadWorld() { - const res = await fetch(this.downloadUrl, { - headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} - }) + async #downloadWorld() { + const res = await fetch(this.downloadUrl, { + headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} + }) - if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`) + if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`) - return await res.buffer() - } + return await res.buffer() + } - async #downloadWorldWithProgress() { - const res = await fetch(this.downloadUrl, { - headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} - }); + async #downloadWorldWithProgress() { + const res = await fetch(this.downloadUrl, { + headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} + }); - if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`); + if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`); - const totalSize = parseInt(res.headers.get('content-length'), 10); - let downloadedSize = 0; + const totalSize = parseInt(res.headers.get('content-length'), 10); + let downloadedSize = 0; - const progressBar = (size) => { - downloadedSize += size; - const percentage = ((downloadedSize / totalSize) * 100).toFixed(2); - process.stdout.clearLine(); - process.stdout.cursorTo(0); - process.stdout.write(`Progress: [${'#'.repeat((percentage / 10).toFixed(0))}] ${percentage}%`); - }; + const progressBar = (size) => { + downloadedSize += size; + const percentage = ((downloadedSize / totalSize) * 100).toFixed(2); + process.stdout.clearLine(); + process.stdout.cursorTo(0); + process.stdout.write(`Progress: [${'#'.repeat((percentage / 10).toFixed(0))}] ${percentage}%`); + }; - return new Promise((resolve, reject) => { - const fileChunks = []; - res.body - .on('data', (chunk) => { - fileChunks.push(chunk); - progressBar(chunk.length); - }) - .on('end', () => { - process.stdout.write('\n'); - resolve(Buffer.concat(fileChunks)); - }) - .on('error', reject); - }); - } + return new Promise((resolve, reject) => { + const fileChunks = []; + res.body + .on('data', (chunk) => { + fileChunks.push(chunk); + progressBar(chunk.length); + }) + .on('end', () => { + process.stdout.write('\n'); + resolve(Buffer.concat(fileChunks)); + }) + .on('error', reject); + }); + } } From 09fb574c9b01cafc276a0edbc4935cc5b3f3dec0 Mon Sep 17 00:00:00 2001 From: DJ Stomp <85457381+DJStompZone@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:44:59 -0700 Subject: [PATCH 4/4] Update Download.js --- src/structures/Download.js | 45 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/structures/Download.js b/src/structures/Download.js index ef879d0..89ccd4d 100644 --- a/src/structures/Download.js +++ b/src/structures/Download.js @@ -1,10 +1,9 @@ const fs = require('fs').promises const fetch = require('node-fetch') -const { Writable } = require('stream'); module.exports = class Download { #api - constructor(api, data) { + constructor (api, data) { this.#api = api this.downloadUrl = data.downloadLink ?? data.downloadUrl if (this.#api.platform === 'bedrock') { @@ -18,16 +17,16 @@ module.exports = class Download { } } - async writeToDirectory(directory, showProgress = false, filename = 'world') { + async writeToDirectory (directory, showProgress = false, filename = 'world') { return (showProgress ? this.#downloadWorldWithProgress() : this.#downloadWorld()) .then(buffer => fs.writeFile(`${directory}/${filename}${this.fileExtension}`, buffer)) } - async getBuffer() { + async getBuffer () { return this.#downloadWorld() } - async #downloadWorld() { + async #downloadWorld () { const res = await fetch(this.downloadUrl, { headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} }) @@ -37,36 +36,36 @@ module.exports = class Download { return await res.buffer() } - async #downloadWorldWithProgress() { + async #downloadWorldWithProgress () { const res = await fetch(this.downloadUrl, { headers: (this.token) ? { Authorization: `Bearer ${this.token}` } : {} - }); + }) - if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`); + if (!res.ok) throw new Error(`Failed to download world: ${res.status} ${res.statusText}`) - const totalSize = parseInt(res.headers.get('content-length'), 10); - let downloadedSize = 0; + const totalSize = parseInt(res.headers.get('content-length'), 10) + let downloadedSize = 0 const progressBar = (size) => { - downloadedSize += size; - const percentage = ((downloadedSize / totalSize) * 100).toFixed(2); - process.stdout.clearLine(); - process.stdout.cursorTo(0); - process.stdout.write(`Progress: [${'#'.repeat((percentage / 10).toFixed(0))}] ${percentage}%`); - }; + downloadedSize += size + const percentage = ((downloadedSize / totalSize) * 100).toFixed(2) + process.stdout.clearLine() + process.stdout.cursorTo(0) + process.stdout.write(`Progress: [${'#'.repeat((percentage / 10).toFixed(0))}] ${percentage}%`) + } return new Promise((resolve, reject) => { - const fileChunks = []; + const fileChunks = [] res.body .on('data', (chunk) => { - fileChunks.push(chunk); - progressBar(chunk.length); + fileChunks.push(chunk) + progressBar(chunk.length) }) .on('end', () => { - process.stdout.write('\n'); - resolve(Buffer.concat(fileChunks)); + process.stdout.write('\n') + resolve(Buffer.concat(fileChunks)) }) - .on('error', reject); - }); + .on('error', reject) + }) } }