Skip to content
Snippets Groups Projects
Commit 349a871a authored by Bekerle, Patrizio's avatar Bekerle, Patrizio :fire: Committed by Reiter, Christoph
Browse files

Add decompress-zip support (VPU/Apps/Signature#11)

parent 833bd284
No related branches found
No related tags found
No related merge requests found
......@@ -2,6 +2,8 @@
[GitLab Repository](https://gitlab.tugraz.at/VPU/WebComponents/FileUpload)
Files will be uploaded sequentially (not parallel) to prevent overburdening the destination server.
## Usage
```html
......@@ -19,13 +21,15 @@
- `deferred` (optional): if set files will not be uploaded immediately but only queued
- use method `uploadFile` or `uploadOneQueuedFile` to really upload the queued file
- example `<vpu-fileupload deferred></vpu-fileupload>`
- `allowed-mime-types` (optional): if set accept only files matching mime types
- `allowed-mime-types` (optional): if set accepts only files matching mime types
- example `<vpu-fileupload allowed-mime-types='application/pdf'></vpu-fileupload>` ... PDFs only
- example `<vpu-fileupload allowed-mime-types='image/*'></vpu-fileupload>` ... images (of all sub types) only
- example `<vpu-fileupload allowed-mime-types='image/png,text/plain'></vpu-fileupload>` ... PNGs or TXTs only
- example `<vpu-fileupload allowed-mime-types='*/*'></vpu-fileupload>` ... all file types (default)
- `disabled` (optional): disable input control
- example `<vpu-fileupload disabled>`
- `decompress-zip` (optional): decompress zip file and queue the contained files
- example `<vpu-fileupload decompress-zip>`
## Local development
......
......@@ -45,6 +45,7 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) {
this.queuedFiles = [];
this.queuedFilesCount = 0;
this.disabled = false;
this.decompressZip = false;
this._queueKey = 0;
}
......@@ -64,13 +65,14 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) {
url: { type: String },
allowedMimeTypes: { type: String, attribute: 'allowed-mime-types' },
text: { type: String },
buttonLabel: { type: String, attribute: 'button-label'},
uploadInProgress: { type: Boolean, attribute: false},
multipleUploadInProgress: { type: Boolean, attribute: false},
alwaysSendFile: { type: Boolean, attribute: 'always-send-file'},
isDeferred: { type: Boolean, attribute: 'deferred'},
buttonLabel: { type: String, attribute: 'button-label' },
uploadInProgress: { type: Boolean, attribute: false },
multipleUploadInProgress: { type: Boolean, attribute: false },
alwaysSendFile: { type: Boolean, attribute: 'always-send-file' },
isDeferred: { type: Boolean, attribute: 'deferred' },
queuedFilesCount: { type: Number, attribute: false },
disabled: { type: Boolean },
decompressZip: { type: Boolean, attribute: 'decompress-zip' },
};
}
......@@ -174,19 +176,15 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) {
console.log('file \'' + file.name + '\' has size=0 and is denied!')
return;
}
if (this.allowedMimeTypes) {
// check if file is allowed
const [fileMainType, fileSubType] = file.type.split('/');
const mimeTypes = this.allowedMimeTypes.split(',');
let deny = true;
mimeTypes.forEach((str) => {
const [mainType, subType] = str.split('/');
deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType));
});
if (deny) {
console.log(`mime type ${file.type} of file '${file.name}' is not compatible with ${this.allowedMimeTypes}`);
return;
}
// check if we want to decompress the zip and queue the contained files
if (this.decompressZip && file.type === "application/zip") {
// add decompressed files to tempFilesToHandle
tempFilesToHandle = tempFilesToHandle.concat(await this.decompressZIP(file));
return;
} else if (this.allowedMimeTypes && !this.checkFileType(file)) {
return;
}
tempFilesToHandle.push(file);
......@@ -206,6 +204,66 @@ export class FileUpload extends ScopedElementsMixin(VPULitElement) {
}, 100);
}
checkFileType(file) {
// check if file is allowed
const [fileMainType, fileSubType] = file.type.split('/');
const mimeTypes = this.allowedMimeTypes.split(',');
let deny = true;
mimeTypes.forEach((str) => {
const [mainType, subType] = str.split('/');
deny = deny && ((mainType !== '*' && mainType !== fileMainType) || (subType !== '*' && subType !== fileSubType));
});
if (deny) {
console.log(`mime type ${file.type} of file '${file.name}' is not compatible with ${this.allowedMimeTypes}`);
return false;
}
return true;
}
/**
* Decompress files synchronously
*
* @param file
* @returns {Promise<[]>}
*/
async decompressZIP(file) {
// see: https://stuk.github.io/jszip/
let JSZip = (await import('jszip/dist/jszip.js')).default;
let filesToHandle = [];
// load zip file
await JSZip.loadAsync(file)
.then(async (zip) => {
// we are not using zip.forEach because we need to handle those files synchronously which
// isn't supported by JSZip (see https://github.com/Stuk/jszip/issues/281)
// using zip.files directly works great!
await commonUtils.asyncObjectForEach(zip.files, async (zipEntry) => {
// TODO: find way to check mime type, see https://github.com/Stuk/jszip/issues/626
// if (!this.checkFileType(zipEntry)) {
// return;
// }
await zipEntry.async("blob")
.then((blob) => {
blob.name = zipEntry.name;
filesToHandle.push(blob);
}, (e) => {
// handle the error
console.error("Decompressing of file in " + file.name + " failed:" + e.message);
});
});
}, function (e) {
// handle the error
console.error("Loading of " + file.name + " failed:" + e.message);
});
return filesToHandle;
}
async sendFinishedEvent(response, file, sendFile = false) {
if (response === undefined) {
return;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment