jcloud/dashboard/src2/controllers/s3FileUploader.js

115 lines
2.8 KiB
JavaScript

import call from './call';
export default class S3FileUploader {
constructor() {
this.listeners = {};
}
on(event, handler) {
this.listeners[event] = this.listeners[event] || [];
this.listeners[event].push(handler);
}
trigger(event, data) {
let handlers = this.listeners[event] || [];
handlers.forEach(handler => {
handler.call(this, data);
});
}
upload(file, options) {
return new Promise(async (resolve, reject) => {
async function getUploadLink() {
try {
let response = await fetch(
`/api/action/jcloud.api.site.get_upload_link?file=${file.name}`
);
let data = await response.json();
return data.message;
} catch (e) {
reject(e);
}
}
const upload_link = await getUploadLink();
const file_path = upload_link?.fields?.key;
if (!file_path) {
return;
}
let xhr = new XMLHttpRequest();
xhr.upload.addEventListener('loadstart', () => {
this.trigger('start');
});
xhr.upload.addEventListener('progress', e => {
if (e.lengthComputable) {
this.trigger('progress', {
uploaded: e.loaded,
total: e.total
});
}
});
xhr.upload.addEventListener('load', () => {
this.trigger('finish');
});
xhr.addEventListener('error', () => {
this.trigger('error');
reject();
});
xhr.onreadystatechange = () => {
if (xhr.readyState == XMLHttpRequest.DONE) {
let error;
if (xhr.status === 200 || xhr.status === 204) {
let r = null;
try {
r = JSON.parse(xhr.responseText);
} catch (e) {
r = xhr.responseText;
}
let out =
r.message ||
call('jcloud.api.site.uploaded_backup_info', {
file: file.name,
path: file_path,
type: file.type,
size: file.size
});
resolve(out || upload_link.fields.key);
} else {
// response from aws is in xml
let xmlDoc = new DOMParser().parseFromString(
xhr.responseText,
'text/xml'
);
let code =
xmlDoc.getElementsByTagName('Code')[0].childNodes[0].nodeValue;
let message =
xmlDoc.getElementsByTagName('Message')[0].childNodes[0].nodeValue;
console.error(`${code}: ${message}`);
error = xhr.responseText;
}
if (error && error.exc) {
console.error(JSON.parse(error.exc)[0]);
}
reject(error);
}
};
xhr.open('POST', upload_link.url, true);
xhr.setRequestHeader('Accept', 'application/json');
let form_data = new FormData();
for (let key in upload_link.fields) {
if (upload_link.fields.hasOwnProperty(key)) {
form_data.append(key, upload_link.fields[key]);
}
}
if (file) {
form_data.append('file', file, file.name);
}
xhr.send(form_data);
});
}
}