From 8782c89d71613f3552976e7d0ba60fb6138e580d Mon Sep 17 00:00:00 2001 From: Stefan Dej Date: Wed, 1 Feb 2023 20:27:08 +0100 Subject: [PATCH] refactor: use moonraker zip function (#1245) --- package-lock.json | 186 ++---------------- package.json | 2 - src/components/panels/GcodefilesPanel.vue | 54 ++--- .../panels/Machine/ConfigFilesPanel.vue | 51 ++--- .../panels/Timelapse/TimelapseFilesPanel.vue | 64 +++--- src/store/files/actions.ts | 6 + 6 files changed, 69 insertions(+), 294 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8850c17c6..b3535a004 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,9 +26,7 @@ "core-js": "^3.16.0", "echarts": "^5.2.2", "echarts-gl": "^2.0.8", - "file-saver": "^2.0.5", "js-sha256": "^0.9.0", - "jszip": "^3.10.1", "lodash.kebabcase": "^4.1.1", "lodash.throttle": "^4.1.1", "overlayscrollbars": "^1.13.1", @@ -4167,7 +4165,8 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true }, "node_modules/crelt": { "version": "1.0.5", @@ -5778,11 +5777,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/file-saver": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", - "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" - }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -6322,11 +6316,6 @@ "node": ">= 4" } }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" - }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -6374,7 +6363,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/ini": { "version": "2.0.0", @@ -6722,11 +6712,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -6990,17 +6975,6 @@ "verror": "1.10.0" } }, - "node_modules/jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, "node_modules/lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", @@ -7032,14 +7006,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dependencies": { - "immediate": "~3.0.5" - } - }, "node_modules/listr2": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", @@ -7530,11 +7496,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7723,11 +7684,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "node_modules/proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", @@ -7828,25 +7784,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -8211,11 +8148,6 @@ "randombytes": "^2.1.0" } }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8447,19 +8379,6 @@ "duplexer": "~0.1.1" } }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -9037,7 +8956,8 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "node_modules/uuid": { "version": "9.0.0", @@ -13083,7 +13003,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true }, "crelt": { "version": "1.0.5", @@ -14209,11 +14130,6 @@ "flat-cache": "^3.0.4" } }, - "file-saver": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", - "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" - }, "filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -14593,11 +14509,6 @@ "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" - }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -14633,7 +14544,8 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "ini": { "version": "2.0.0", @@ -14864,11 +14776,6 @@ "call-bind": "^1.0.2" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -15077,17 +14984,6 @@ "verror": "1.10.0" } }, - "jszip": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "setimmediate": "^1.0.5" - } - }, "lazy-ass": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", @@ -15110,14 +15006,6 @@ "type-check": "~0.4.0" } }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "requires": { - "immediate": "~3.0.5" - } - }, "listr2": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", @@ -15482,11 +15370,6 @@ "aggregate-error": "^3.0.0" } }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -15613,11 +15496,6 @@ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "proxy-from-env": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", @@ -15688,27 +15566,6 @@ "safe-buffer": "^5.1.0" } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -15971,11 +15828,6 @@ "randombytes": "^2.1.0" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -16146,21 +15998,6 @@ "duplexer": "~0.1.1" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -16584,7 +16421,8 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true }, "uuid": { "version": "9.0.0", diff --git a/package.json b/package.json index 1bfc89f48..41738da43 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,7 @@ "core-js": "^3.16.0", "echarts": "^5.2.2", "echarts-gl": "^2.0.8", - "file-saver": "^2.0.5", "js-sha256": "^0.9.0", - "jszip": "^3.10.1", "lodash.kebabcase": "^4.1.1", "lodash.throttle": "^4.1.1", "overlayscrollbars": "^1.13.1", diff --git a/src/components/panels/GcodefilesPanel.vue b/src/components/panels/GcodefilesPanel.vue index f7e5a72cb..a8daa17f3 100644 --- a/src/components/panels/GcodefilesPanel.vue +++ b/src/components/panels/GcodefilesPanel.vue @@ -23,6 +23,7 @@ :title="$t('Files.Download')" color="primary" class="px-2 minwidth-0 ml-3" + :loading="loadings.includes('gcodeDownloadZip')" @click="downloadSelectedFiles"> {{ mdiCloudDownload }} @@ -532,9 +533,6 @@ import { } from '@mdi/js' import StartPrintDialog from '@/components/dialogs/StartPrintDialog.vue' import ControlMixin from '@/components/mixins/control' -import JSZip from 'jszip' -import axios from 'axios' -import { saveAs } from 'file-saver' interface contextMenu { shown: boolean @@ -1141,53 +1139,31 @@ export default class GcodefilesPanel extends Mixins(BaseMixin, ControlMixin) { } async downloadSelectedFiles() { - const zip = new JSZip() + let items: string[] = [] - const addDirectoryToZip = async (zip: JSZip, directory: FileStateFile[], absoluteUrl: string) => { + const addElementToItems = async (absolutPath: string, directory: FileStateFile[]) => { for (const file of directory) { + const filePath = `${absolutPath}/${file.filename}` + if (file.isDirectory && file.childrens) { - const url = `${absoluteUrl}${encodeURI(file.filename + '/')}` - await addDirectoryToZip(zip.folder(file.filename) as JSZip, file.childrens, url) + await addElementToItems(filePath, file.childrens) continue } - const CancelToken = axios.CancelToken - const source = CancelToken.source() - this.$store.commit('editor/updateCancelTokenSource', source) - this.$store.commit('editor/updateLoaderState', true) - - this.$store.commit('editor/setFilename', file.filename) - - await axios - .get(absoluteUrl + encodeURI(file.filename), { - cancelToken: source.token, - onDownloadProgress: (progressEvent) => - this.$store.dispatch('editor/downloadProgress', { - progressEvent, - direction: 'downloading', - filesize: file.size, - }), - responseType: 'blob', - }) - .then((r) => { - if (r.status === 200) return r.data - return Promise.reject(new Error(r.statusText)) - }) - .then((blob) => zip?.file(file.filename, blob)) + items.push(filePath) } } - const url = `${this.apiUrl}/server/files/gcodes${encodeURI(this.currentPath + '/')}` - await addDirectoryToZip(zip, this.selectedFiles, url) - - setTimeout(() => { - this.$store.dispatch('editor/clearLoader') - }, 100) + await addElementToItems('gcodes/' + this.currentPath, this.selectedFiles) + const date = new Date() + const timestamp = `${date.getFullYear()}${date.getMonth()}${date.getDay()}-${date.getHours()}${date.getMinutes()}${date.getSeconds()}` - zip.generateAsync({ type: 'blob' }).then(async (blob) => { - saveAs(blob, 'archive.zip') - }) + this.$socket.emit( + 'server.files.zip', + { items, dest: `gcodes/collection-${timestamp}.zip` }, + { action: 'files/downloadZip', loading: 'gcodeDownloadZip' } + ) this.selectedFiles = [] } diff --git a/src/components/panels/Machine/ConfigFilesPanel.vue b/src/components/panels/Machine/ConfigFilesPanel.vue index dfd0f393c..9cad5f4a5 100644 --- a/src/components/panels/Machine/ConfigFilesPanel.vue +++ b/src/components/panels/Machine/ConfigFilesPanel.vue @@ -485,8 +485,6 @@ import { mdiCloseThick, mdiLockOutline, } from '@mdi/js' -import JSZip from 'jszip' -import { saveAs } from 'file-saver' interface contextMenu { shown: boolean @@ -672,7 +670,7 @@ export default class ConfigFilesPanel extends Mixins(BaseMixin) { text: this.$t('Machine.ConfigFilesPanel.Download'), color: 'primary', icon: mdiCloudDownload, - loadingName: null, + loadingName: 'configDownloadZip', onlyWriteable: false, condition: this.selectedFiles.length > 0, click: () => { @@ -866,6 +864,8 @@ export default class ConfigFilesPanel extends Mixins(BaseMixin) { } set currentPath(newVal) { + this.selectedFiles = [] + this.$store.dispatch('gui/saveSettingWithoutUpload', { name: 'view.configfiles.currentPath', value: newVal }) } @@ -945,53 +945,24 @@ export default class ConfigFilesPanel extends Mixins(BaseMixin) { } async downloadSelectedFiles() { - const zip = new JSZip() + let items: string[] = [] - const addDirectoryToZip = async (zip: JSZip, directory: FileStateFile[], absoluteUrl: string) => { + const addElementToItems = async (absolutPath: string, directory: FileStateFile[]) => { for (const file of directory) { + const filePath = `${absolutPath}/${file.filename}` + if (file.isDirectory && file.childrens) { - const url = `${absoluteUrl}${encodeURI(file.filename + '/')}` - await addDirectoryToZip(zip.folder(file.filename) as JSZip, file.childrens, url) + await addElementToItems(filePath, file.childrens) continue } - const CancelToken = axios.CancelToken - const source = CancelToken.source() - this.$store.commit('editor/updateCancelTokenSource', source) - this.$store.commit('editor/updateLoaderState', true) - - this.$store.commit('editor/setFilename', file.filename) - - await axios - .get(absoluteUrl + encodeURI(file.filename), { - cancelToken: source.token, - onDownloadProgress: (progressEvent) => - this.$store.dispatch('editor/downloadProgress', { - progressEvent, - direction: 'downloading', - filesize: file.size, - }), - responseType: 'blob', - }) - .then((r) => { - if (r.status === 200) return r.data - return Promise.reject(new Error(r.statusText)) - }) - .then((blob) => zip?.file(file.filename, blob)) + items.push(filePath) } } - const url = `${this.apiUrl}/server/files${encodeURI(this.absolutePath + '/')}` - await addDirectoryToZip(zip, this.selectedFiles, url) - - setTimeout(() => { - this.$store.dispatch('editor/clearLoader') - }, 100) - - zip.generateAsync({ type: 'blob' }).then(async (blob) => { - saveAs(blob, 'archive.zip') - }) + await addElementToItems(this.absolutePath, this.selectedFiles) + this.$socket.emit('server.files.zip', { items }, { action: 'files/downloadZip', loading: 'configDownloadZip' }) this.selectedFiles = [] } diff --git a/src/components/panels/Timelapse/TimelapseFilesPanel.vue b/src/components/panels/Timelapse/TimelapseFilesPanel.vue index bec51c505..aa7d028bc 100644 --- a/src/components/panels/Timelapse/TimelapseFilesPanel.vue +++ b/src/components/panels/Timelapse/TimelapseFilesPanel.vue @@ -37,6 +37,7 @@ :title="$t('Timelapse.Download')" color="primary" class="px-2 minwidth-0 ml-3" + :loading="loadings.includes('timelapseDownloadZip')" @click="downloadSelectedFiles"> {{ mdiCloudDownload }} @@ -422,9 +423,6 @@ import { mdiRenameBox, mdiDelete, } from '@mdi/js' -import JSZip from 'jszip' -import axios from 'axios' -import { saveAs } from 'file-saver' interface dialogRenameObject { show: boolean @@ -704,53 +702,41 @@ export default class TimelapseFilesPanel extends Mixins(BaseMixin) { } async downloadSelectedFiles() { - const zip = new JSZip() + let items: string[] = [] - const addDirectoryToZip = async (zip: JSZip, directory: FileStateFile[], absoluteUrl: string) => { + const addElementToItems = async (absolutPath: string, directory: FileStateFile[]) => { for (const file of directory) { + const filePath = `${absolutPath}/${file.filename}` + if (file.isDirectory && file.childrens) { - const url = `${absoluteUrl}${encodeURI(file.filename + '/')}` - await addDirectoryToZip(zip.folder(file.filename) as JSZip, file.childrens, url) + await addElementToItems(filePath, file.childrens) continue } - const CancelToken = axios.CancelToken - const source = CancelToken.source() - this.$store.commit('editor/updateCancelTokenSource', source) - this.$store.commit('editor/updateLoaderState', true) - - this.$store.commit('editor/setFilename', file.filename) - - await axios - .get(absoluteUrl + encodeURI(file.filename), { - cancelToken: source.token, - onDownloadProgress: (progressEvent) => - this.$store.dispatch('editor/downloadProgress', { - progressEvent, - direction: 'downloading', - filesize: file.size, - }), - responseType: 'blob', - }) - .then((r) => { - if (r.status === 200) return r.data - return Promise.reject(new Error(r.statusText)) - }) - .then((blob) => zip?.file(file.filename, blob)) + items.push(filePath) + + if (file.filename.endsWith('.mp4')) { + const indexLastPoint = file.filename.lastIndexOf('.') + const filenameWithoutExtension = file.filename.slice(0, indexLastPoint) + const filenamePng = `${filenameWithoutExtension}.jpg` + + if (this.files.indexOf((file: FileStateFile) => file.filename === filenamePng) !== -1) { + items.push(`${absolutPath}/${filenamePng}`) + } + } } } - const url = `${this.apiUrl}/server/files/${encodeURI(this.currentPath + '/')}` - await addDirectoryToZip(zip, this.selectedFiles, url) + await addElementToItems(this.currentPath, this.selectedFiles) + const date = new Date() + const timestamp = `${date.getFullYear()}${date.getMonth()}${date.getDay()}-${date.getHours()}${date.getMinutes()}${date.getSeconds()}` - setTimeout(() => { - this.$store.dispatch('editor/clearLoader') - }, 100) - - zip.generateAsync({ type: 'blob' }).then(async (blob) => { - saveAs(blob, 'archive.zip') - }) + this.$socket.emit( + 'server.files.zip', + { items, dest: `timelapse/collection-${timestamp}.zip` }, + { action: 'files/downloadZip', loading: 'timelapseDownloadZip' } + ) this.selectedFiles = [] } diff --git a/src/store/files/actions.ts b/src/store/files/actions.ts index 041800e55..8de05b111 100644 --- a/src/store/files/actions.ts +++ b/src/store/files/actions.ts @@ -335,6 +335,12 @@ export const actions: ActionTree = { commit('uploadSetMaxNumber', payload) }, + downloadZip({ rootGetters }, payload) { + const apiUrl = rootGetters['socket/getUrl'] + const url = `${apiUrl}/server/files/${payload.destination.root}/${encodeURI(payload.destination.path)}` + window.open(url) + }, + rolloverLog(_, payload) { payload.rolled_over.forEach((name: string) => { Vue.$toast.success(i18n.t('Machine.LogfilesPanel.RolloverToastSuccessful', { name }))