Improve zip download

* Remove jszip for zip.js which is better maintained
* Pictures keep their creation date
This commit is contained in:
Antoine Bartuccio 2024-07-30 11:11:31 +02:00
parent 3304f32ef0
commit ffa3936878
7 changed files with 78 additions and 49 deletions

View File

@ -1 +0,0 @@
!function(e){"object"==typeof exports?module.exports=e():"function"==typeof define&&define.amd?define(e):"undefined"!=typeof window?window.JSZipUtils=e():"undefined"!=typeof global?global.JSZipUtils=e():"undefined"!=typeof self&&(self.JSZipUtils=e())}(function(){return function o(i,f,u){function s(n,e){if(!f[n]){if(!i[n]){var t="function"==typeof require&&require;if(!e&&t)return t(n,!0);if(a)return a(n,!0);throw new Error("Cannot find module '"+n+"'")}var r=f[n]={exports:{}};i[n][0].call(r.exports,function(e){var t=i[n][1][e];return s(t||e)},r,r.exports,o,i,f,u)}return f[n].exports}for(var a="function"==typeof require&&require,e=0;e<u.length;e++)s(u[e]);return s}({1:[function(e,t,n){"use strict";var u={};function r(){try{return new window.XMLHttpRequest}catch(e){}}u._getBinaryFromXHR=function(e){return e.response||e.responseText};var s="undefined"!=typeof window&&window.ActiveXObject?function(){return r()||function(){try{return new window.ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}()}:r;u.getBinaryContent=function(t,n){var e,r,o,i;"function"==typeof(n=n||{})?(i=n,n={}):"function"==typeof n.callback&&(i=n.callback),i||"undefined"==typeof Promise?(r=function(e){i(null,e)},o=function(e){i(e,null)}):e=new Promise(function(e,t){r=e,o=t});try{var f=s();f.open("GET",t,!0),"responseType"in f&&(f.responseType="arraybuffer"),f.overrideMimeType&&f.overrideMimeType("text/plain; charset=x-user-defined"),f.onreadystatechange=function(e){if(4===f.readyState)if(200===f.status||0===f.status)try{r(u._getBinaryFromXHR(f))}catch(e){o(new Error(e))}else o(new Error("Ajax error for "+t+" : "+this.status+" "+this.statusText))},n.progress&&(f.onprogress=function(e){n.progress({path:t,originalEvent:e,percent:e.loaded/e.total*100,loaded:e.loaded,total:e.total})}),f.send()}catch(e){o(new Error(e),null)}return e},t.exports=u},{}]},{},[1])(1)});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,28 @@
BSD 3-Clause License
Copyright (c) 2023, Gildas Lormeau
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,28 @@
# Built scripts of zip.js
**Warning**: These files are not compatible with ES modules, i.e. they cannot be imported with `import`. Instead, import `index.js` in the root folder of the project or one of the files prefixed with `zip-` in the [`/lib`](../lib) folder (e.g. `/lib/zip-no-worker-inflate.js`).
- for production (minified):
| | [`ZipReader`](https://gildas-lormeau.github.io/zip.js/api/classes/ZipReader.html) API | [`ZipWriter`](https://gildas-lormeau.github.io/zip.js/api/classes/ZipWriter.html) API | [`zip.fs`](https://gildas-lormeau.github.io/zip.js/api/classes/FS.html) API | Web Workers | No Web Workers | Usage |
|--------------------------------|-----------------|-----------------|--------------|-------------|----------------|-------------------------------------------------------|
| `zip.min.js` | x | x | | x | | compression/decompression with web workers |
| `zip-no-worker.min.js` | x | x | | | x | compression/decompression without web workers |
| `zip-no-worker-inflate.min.js` | x | | | | x | decompression without web workers |
| `zip-no-worker-deflate.min.js` | | x | | | x | compression without web workers |
| `zip-full.min.js` | x | x | | x | x | compression/decompression with or without web workers |
| `zip-fs.min.js` | x | x | x | x | | compression/decompression with web workers |
| `zip-fs-full.min.js` | x | x | x | x | x | compression/decompression with or without web workers |
- for development/debugging:
| | `zip` API | [`zip.fs`](https://gildas-lormeau.github.io/zip.js/api/classes/FS.html) API | Web Workers | No Web Workers |
|-----------------------|-----------|--------------|-------------|----------------|
| `zip.js` | x | | x | |
| `zip-full.js` | x | | x | x |
| `zip-fs.js` | x | x | x | |
| `zip-fs-full.js` | x | x | x | x |
- `z-worker.js` can be used as a web worker script if the [Content Security Policy](https://developer.mozilla.org/docs/Web/HTTP/CSP) blocks scripts loaded with a `blob:` scheme
- `z-worker-fflate.js` is the web worker script for using [fflate](https://gildas-lormeau.github.io/zip.js/core-api.html#alternative-codec-fflate)
- `z-worker-pako.js` is the web worker script for using [pako](https://gildas-lormeau.github.io/zip.js/core-api.html#alternative-codec-pako)

File diff suppressed because one or more lines are too long

View File

@ -5,12 +5,11 @@
{%- endblock -%} {%- endblock -%}
{% block additional_js %} {% block additional_js %}
<script defer src="{{ static('core/js/jszip/jszip.min.js') }}"></script>
<script defer src="{{ static('core/js/jszip/jszip-utils.min.js') }}"></script>
<script defer type="module"> <script defer type="module">
import { showSaveFilePicker } from "{{ static('core/js/native-file-system-adapter/mod.js') }}"; import { showSaveFilePicker } from "{{ static('core/js/native-file-system-adapter/mod.js') }}";
window.showSaveFilePicker = showSaveFilePicker; /* Export function to normal javascript */ window.showSaveFilePicker = showSaveFilePicker; /* Export function to normal javascript */
</script> </script>
<script defer type="text/javascript" src="{{ static('core/js/zipjs/zip-fs-full.min.js') }}"></script>
{% endblock %} {% endblock %}
{% block title %} {% block title %}
@ -54,38 +53,20 @@
{% endfor %} {% endfor %}
<script> <script>
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
/* Enable button once everything is loaded and if JSZip is supported */ document.getElementById("download").disabled = false;
document.getElementById("download").disabled = !JSZip.support.blob;
}); });
async function download(url) { async function download(url) {
let zip = new JSZip();
let pictures = await (await fetch(url)).json(); let pictures = await (await fetch(url)).json();
let progressBar = document.getElementById("download_progress"); let progressBar = document.getElementById("download_progress");
let picturesDownloaded = 0;
let button = document.getElementById("download"); let button = document.getElementById("download");
let picturesDownloaded = 0;
button.disabled = true; button.disabled = true;
progressBar.value = picturesDownloaded; progressBar.value = picturesDownloaded;
progressBar.hidden = false; progressBar.hidden = false;
pictures.forEach(async (picture) => {
zip.file(
"IMG_" + picture.date.replaceAll(":", "_").replaceAll("-", "_") + picture.name.slice(picture.name.lastIndexOf(".")),
new Promise(function (resolve, reject) {
JSZipUtils.getBinaryContent(picture.full_size_url, (err, data) => {
progressBar.value = picturesDownloaded++ * 100 / (pictures.length - 1);
if (err) {
reject(err);
return;
}
resolve(data);
})
}),
{ binary: true }
);
});
let fileHandle = await window.showSaveFilePicker({ let fileHandle = await window.showSaveFilePicker({
_preferPolyfill: false, _preferPolyfill: false,
suggestedName: "{%- trans -%} pictures {%- endtrans -%}.zip", suggestedName: "{%- trans -%} pictures {%- endtrans -%}.zip",
@ -94,16 +75,22 @@
}) })
let writeStream = await fileHandle.createWritable(); let writeStream = await fileHandle.createWritable();
await zip.generateInternalStream({ let zipWriter = new zip.ZipWriter(writeStream);
type: "uint8array",
streamFiles: true, async function progress() {
compression: "DEFLATE", progressBar.value = picturesDownloaded++ * 100 / (pictures.length - 1);
compressionOptions: { level: 9 } }
})
.on("data", (data) => writeStream.write(data)) await Promise.all(pictures.map(picture =>
.on("error", (err) => console.error(err)) zipWriter.add(
.on("end", () => writeStream.close()) "IMG_" + picture.date.replaceAll(":", "_").replaceAll("-", "_") + picture.name.slice(picture.name.lastIndexOf(".")),
.resume(); new zip.HttpReader(picture.full_size_url),
{ level: 9, lastModDate: new Date(picture.date), onstart: progress }
)
)
)
await zipWriter.close();
button.disabled = false; button.disabled = false;
progressBar.hidden = true; progressBar.hidden = true;

View File

@ -724,8 +724,7 @@ if SENTRY_DSN:
) )
SITH_FRONT_DEP_VERSIONS = { SITH_FRONT_DEP_VERSIONS = {
"https://github.com/Stuk/jszip-utils": "0.1.0", "https://github.com/gildas-lormeau/zip.js": "2.7.47",
"https://github.com/Stuk/jszip": "3.10.1",
"https://github.com/jimmywarting/native-file-system-adapter": "3.0.1", "https://github.com/jimmywarting/native-file-system-adapter": "3.0.1",
"https://github.com/chartjs/Chart.js/": "2.6.0", "https://github.com/chartjs/Chart.js/": "2.6.0",
"https://github.com/Ionaru/easy-markdown-editor/": "2.18.0", "https://github.com/Ionaru/easy-markdown-editor/": "2.18.0",