Loading src/components/JamaUploadView.vue +3 −5 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ </div> <v-container v-else> <h3> Envoi en cours | {{ done }}/{{ titleInfos }} Envoi en cours | {{ done + 1 }}/{{ titleInfos }} </h3> <v-row> <v-col cols="4"> Loading Loading @@ -137,6 +137,8 @@ export default { }, endUploadEvent() { this.isUploading = false; this.$forceUpdate(); this.done = 0; }, startFileUploadEvent(e) { Loading @@ -157,14 +159,10 @@ export default { message: e.detail.message, visible: true }) console.log(Object.keys(this.uncompletedUploads).length); if(e.detail.status === 'available') { delete this.uncompletedUploads[e.detail.hash]; localStorage.setItem(JAMA_LSTORAGE_INCOMPLETED_KEY, JSON.stringify(this.uncompletedUploads)); } console.log(Object.keys(this.uncompletedUploads).length); console.log(Object.values(this.uncompletedUploads).map((u)=>console.log(u.name))); this.progressValue = 0; this.progressMessage=""; this.$forceUpdate(); Loading src/components/VueJama.vue +54 −31 Original line number Diff line number Diff line Loading @@ -586,7 +586,14 @@ export default { this.$store.commit('setShowHiddenCollections', this.options.showHiddenCollections == null ? true : this.options.showHiddenCollections); this.$store.commit('setAcceptedFormats', this.options.acceptedFormats || []); this.$store.commit('setMultiSelectActionAddons', this.options.multiSelectActionAddons || []) this.fetchPermissions().then(() => this.fetchUserPermissions().then(() => this.initJamaPermissions())); this.fetchPermissions().then((r) => { if(r) { this.fetchUserPermissions().then(() => this.initJamaPermissions()) } else{ alert('Une erreur est survenue. Service indisponible.') } }) if (!this.currentProjectId) { await this.fetchProjects(); } else { Loading Loading @@ -660,6 +667,7 @@ export default { }, async loadCollection(collection) { try { this.loading = true; if (!this.trashMode) { EventBus.$emit('set-mode', RESOURCES_MODE); Loading Loading @@ -689,12 +697,15 @@ export default { ).then(() => { this.loading = false }); } catch(e){ alert("Une erreur est survenue. Service indisponible.") } }, loadCollectionById(id) { this.fetchCollection(id).then(() => { console.log("will load collection", this.currentCollection); this.loadCollection(this.currentCollection); }) }, Loading Loading @@ -754,7 +765,6 @@ export default { }, reloadCurrentCollection() { console.log("reload current collection", this.currentCollection); this.loadCollectionById(this.currentCollection.id); }, Loading @@ -775,10 +785,23 @@ export default { resourceRemoved() { this.$store.commit('setCurrentResource', null); this.alertInfo("Ressource supprimée"); }, alertError(message){ EventBus.$emit('JAMA_NOTIFICATION', { type: 'error', timeout: 2000, message: message, visible: true }) }, alertInfo(message){ EventBus.$emit('JAMA_NOTIFICATION', { type: 'info', timeout: 2000, message: "Ressource supprimée", message: message, visible: true }) }, Loading src/store/JamaStore.js +8 −6 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ export default new Vuex.Store({ async fetchPermissions({commit}) { let permissions = await JamaRPClient.listPermissions(); commit('setPermissions', permissions); return permissions }, async fetchUserPermissions({commit}) { Loading Loading @@ -318,7 +319,6 @@ export default new Vuex.Store({ async fetchCollection({commit}, id) { let collection = await JamaRPClient.collection(id); console.log("collection fetched", collection) commit('setCurrentCollection', collection); }, Loading Loading @@ -457,11 +457,13 @@ export default new Vuex.Store({ * @param context * @param files * @param path * @returns {Promise<*[]>} * @returns {boolean} */ async manageFilesUpload(context, {files, path, projectId}) { let uploadResults = await JamaRPClient.uploadFiles(files, projectId, path, context.getters.acceptedFormats); let errorMessages = []; if(!uploadResults[0]) return false; //let errorMessages = []; for (let i = 0; i < uploadResults.length; i++) { if (uploadResults[i].already_uploaded) { try { Loading @@ -470,11 +472,11 @@ export default new Vuex.Store({ console.log(e); console.log('cannot add ' + uploadResults[i].id) } } else { }/* else { if (uploadResults[i].chunk_errors || uploadResults[i].status === 'bad_format') { errorMessages.push(uploadResults[i].message); } } }*/ } let onError = uploadResults.filter((ur) => !ur.ok); if(onError.length > 0 ) Loading @@ -493,7 +495,7 @@ export default new Vuex.Store({ visible: true }) return uploadResults; return true; }, /** Loading src/utils/JamaClient.js +76 −44 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ import ChecksumService from '../utils/ChecksumService'; const CHUNK_SIZE = 1024 * 1024; const CHUNK_MAX_RETRY = 3; const CHUNK_RETRY_WAIT = 2000; class ChunksUploader { Loading Loading @@ -106,7 +108,11 @@ class JamaClient extends JamacRpcClient { async uploadChunk(chunkNum, path, projectId) { sleep(ms){ return new Promise(resolve => setTimeout(resolve, ms)); } async uploadChunk(chunkNum, path, projectId, attempts = 0) { try { let response = await this.fileChunksUploader.uploadChunk(chunkNum, path, projectId); this.dispatchEvent(new CustomEvent(upload_events.chunk_uploaded_event, { Loading @@ -119,16 +125,32 @@ class JamaClient extends JamacRpcClient { }) ); if (!response.ok) { if(attempts < CHUNK_MAX_RETRY){ console.info("chunk NOT OK (RETRY): " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); await this.sleep(CHUNK_RETRY_WAIT); return this.uploadChunk(chunkNum, path, projectId, attempts+1) } else { console.info("chunk NOT OK : " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); return {ok: false, hash: this.fileChunksUploader.getChecksum(), status: 'incomplete'} return { ok: false, hash: this.fileChunksUploader.getChecksum(), status: 'incomplete' } } } else { console.info("chunk ok : " + (chunkNum+ 1) + "/" + this.fileChunksUploader.getNbChunks()); return response; } } catch (err) { if(attempts < CHUNK_MAX_RETRY){ console.info("chunk NOT OK (RETRY): " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); await this.sleep(CHUNK_RETRY_WAIT); return this.uploadChunk(chunkNum, path, projectId, attempts+1) } else { console.error("chunk NOT OK : " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); return {ok: false, hash: this.fileChunksUploader.getChecksum(), status: 'incomplete'} } } } Loading Loading @@ -167,12 +189,16 @@ class JamaClient extends JamacRpcClient { let alreadyUploaded = statusInfos.status === 'available'; //then upload not yet already uploaded chunks if (!alreadyUploaded) { const nbChunks = !uploadInfos ? this.fileChunksUploader.getNbChunks() : uploadInfos.nb_chunks; const nbChunks = this.fileChunksUploader.getNbChunks(); for (let i = 0; i < nbChunks; i++) { if (!uploadInfos || uploadInfos.available_chunks.indexOf('202-' + lpad(i + 1, 3) + '.part') < 0) { console.log(nbChunks + '-' + lpad(i + 1, this.fileChunksUploader.getNbChunks().toString().length) + '.part'); if (!statusInfos.available_chunks || statusInfos.available_chunks.indexOf( //if nb chunks = 42 then first chunk = '42-01.part', if nb chunks = 142 then first chunk = '142-001.part' nbChunks + '-' + lpad(i + 1, nbChunks.toString().length) + '.part') < 0) { let response = await this.uploadChunk(i, path, projectId); if (!response.ok) return {ok: false, hash: hash, status: 'incomplete'} Loading Loading @@ -200,52 +226,56 @@ class JamaClient extends JamacRpcClient { let path = (files[i]).webkitRelativePath.replace((files[i]).name, '') if (collectionPath) path = collectionPath + '/' + path; console.log("- upload du fichier : " + i, 'path =' + path); let uploadResult = await this.uploadOrResumeFile(files[i], path, projectId); let result = await this.uploadOrResumeFile(files[i], path, projectId); let uploadResult = this.mangeUploadFileResult(files[i], result); uploadResults.push(uploadResult); } else { uploadResults.push( { ok: false, status: 'bad_format', message: files[i].name + ' : mauvais format de fichier. Formats acceptés : ' + acceptedFormat.join(', '), resource: files[i].name, } ) } } this.dispatchEvent(new CustomEvent(upload_events.end_upload_event, {detail: uploadResults})) return uploadResults; } mangeUploadFileResult(file, uploadResult){ let result = null; if (uploadResult.ok) { console.log("- fichier uploadé : " + i, 'path =' + path); console.log("- fichier uploadé : " + file.name); let result = { ok: true, already_uploaded : uploadResult.already_uploaded, status: uploadResult.status, name: files[i].name, name: file.name, id: uploadResult.id, hash: uploadResult.hash, message: "Fichier versé avec succès" } uploadResults.push(result); this.dispatchEvent(new CustomEvent(upload_events.end_file_upload_event, { 'detail': result }) ); } else { let errorMessage = "Une erreur est survenue lors du versement du fichier " + files[i].name; let errorMessage = "Une erreur est survenue lors du versement du fichier " + file.name; let result = { ok: false, status: 'error', message: errorMessage, name: files[i].name, name: file.name, hash: uploadResult.hash } uploadResults.push(result); this.dispatchEvent(new CustomEvent(upload_events.end_file_upload_event, { 'detail': result }) ); } } else { uploadResults.push( { ok: false, status: 'bad_format', message: files[i].name + ' : mauvais format de fichier. Formats acceptés : ' + acceptedFormat.join(', '), resource: files[i].name, } ) } } this.dispatchEvent(new CustomEvent(upload_events.end_upload_event, {detail: uploadResults})) return uploadResults; return result; } checkExtension(file, acceptedFormats) { Loading @@ -270,7 +300,9 @@ class JamaClient extends JamacRpcClient { * } */ async resumeUpload(file, uploadInfos) { await this.uploadOrResumeFile(file, uploadInfos.path, uploadInfos.project, uploadInfos); let result = await this.uploadOrResumeFile(file, uploadInfos.path, uploadInfos.project, uploadInfos); let uploadResult = this.mangeUploadFileResult(file, result); this.dispatchEvent(new CustomEvent(upload_events.end_upload_event, {detail: [uploadResult]})) } addListener(listener) { Loading Loading
src/components/JamaUploadView.vue +3 −5 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ </div> <v-container v-else> <h3> Envoi en cours | {{ done }}/{{ titleInfos }} Envoi en cours | {{ done + 1 }}/{{ titleInfos }} </h3> <v-row> <v-col cols="4"> Loading Loading @@ -137,6 +137,8 @@ export default { }, endUploadEvent() { this.isUploading = false; this.$forceUpdate(); this.done = 0; }, startFileUploadEvent(e) { Loading @@ -157,14 +159,10 @@ export default { message: e.detail.message, visible: true }) console.log(Object.keys(this.uncompletedUploads).length); if(e.detail.status === 'available') { delete this.uncompletedUploads[e.detail.hash]; localStorage.setItem(JAMA_LSTORAGE_INCOMPLETED_KEY, JSON.stringify(this.uncompletedUploads)); } console.log(Object.keys(this.uncompletedUploads).length); console.log(Object.values(this.uncompletedUploads).map((u)=>console.log(u.name))); this.progressValue = 0; this.progressMessage=""; this.$forceUpdate(); Loading
src/components/VueJama.vue +54 −31 Original line number Diff line number Diff line Loading @@ -586,7 +586,14 @@ export default { this.$store.commit('setShowHiddenCollections', this.options.showHiddenCollections == null ? true : this.options.showHiddenCollections); this.$store.commit('setAcceptedFormats', this.options.acceptedFormats || []); this.$store.commit('setMultiSelectActionAddons', this.options.multiSelectActionAddons || []) this.fetchPermissions().then(() => this.fetchUserPermissions().then(() => this.initJamaPermissions())); this.fetchPermissions().then((r) => { if(r) { this.fetchUserPermissions().then(() => this.initJamaPermissions()) } else{ alert('Une erreur est survenue. Service indisponible.') } }) if (!this.currentProjectId) { await this.fetchProjects(); } else { Loading Loading @@ -660,6 +667,7 @@ export default { }, async loadCollection(collection) { try { this.loading = true; if (!this.trashMode) { EventBus.$emit('set-mode', RESOURCES_MODE); Loading Loading @@ -689,12 +697,15 @@ export default { ).then(() => { this.loading = false }); } catch(e){ alert("Une erreur est survenue. Service indisponible.") } }, loadCollectionById(id) { this.fetchCollection(id).then(() => { console.log("will load collection", this.currentCollection); this.loadCollection(this.currentCollection); }) }, Loading Loading @@ -754,7 +765,6 @@ export default { }, reloadCurrentCollection() { console.log("reload current collection", this.currentCollection); this.loadCollectionById(this.currentCollection.id); }, Loading @@ -775,10 +785,23 @@ export default { resourceRemoved() { this.$store.commit('setCurrentResource', null); this.alertInfo("Ressource supprimée"); }, alertError(message){ EventBus.$emit('JAMA_NOTIFICATION', { type: 'error', timeout: 2000, message: message, visible: true }) }, alertInfo(message){ EventBus.$emit('JAMA_NOTIFICATION', { type: 'info', timeout: 2000, message: "Ressource supprimée", message: message, visible: true }) }, Loading
src/store/JamaStore.js +8 −6 Original line number Diff line number Diff line Loading @@ -245,6 +245,7 @@ export default new Vuex.Store({ async fetchPermissions({commit}) { let permissions = await JamaRPClient.listPermissions(); commit('setPermissions', permissions); return permissions }, async fetchUserPermissions({commit}) { Loading Loading @@ -318,7 +319,6 @@ export default new Vuex.Store({ async fetchCollection({commit}, id) { let collection = await JamaRPClient.collection(id); console.log("collection fetched", collection) commit('setCurrentCollection', collection); }, Loading Loading @@ -457,11 +457,13 @@ export default new Vuex.Store({ * @param context * @param files * @param path * @returns {Promise<*[]>} * @returns {boolean} */ async manageFilesUpload(context, {files, path, projectId}) { let uploadResults = await JamaRPClient.uploadFiles(files, projectId, path, context.getters.acceptedFormats); let errorMessages = []; if(!uploadResults[0]) return false; //let errorMessages = []; for (let i = 0; i < uploadResults.length; i++) { if (uploadResults[i].already_uploaded) { try { Loading @@ -470,11 +472,11 @@ export default new Vuex.Store({ console.log(e); console.log('cannot add ' + uploadResults[i].id) } } else { }/* else { if (uploadResults[i].chunk_errors || uploadResults[i].status === 'bad_format') { errorMessages.push(uploadResults[i].message); } } }*/ } let onError = uploadResults.filter((ur) => !ur.ok); if(onError.length > 0 ) Loading @@ -493,7 +495,7 @@ export default new Vuex.Store({ visible: true }) return uploadResults; return true; }, /** Loading
src/utils/JamaClient.js +76 −44 Original line number Diff line number Diff line Loading @@ -3,6 +3,8 @@ import ChecksumService from '../utils/ChecksumService'; const CHUNK_SIZE = 1024 * 1024; const CHUNK_MAX_RETRY = 3; const CHUNK_RETRY_WAIT = 2000; class ChunksUploader { Loading Loading @@ -106,7 +108,11 @@ class JamaClient extends JamacRpcClient { async uploadChunk(chunkNum, path, projectId) { sleep(ms){ return new Promise(resolve => setTimeout(resolve, ms)); } async uploadChunk(chunkNum, path, projectId, attempts = 0) { try { let response = await this.fileChunksUploader.uploadChunk(chunkNum, path, projectId); this.dispatchEvent(new CustomEvent(upload_events.chunk_uploaded_event, { Loading @@ -119,16 +125,32 @@ class JamaClient extends JamacRpcClient { }) ); if (!response.ok) { if(attempts < CHUNK_MAX_RETRY){ console.info("chunk NOT OK (RETRY): " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); await this.sleep(CHUNK_RETRY_WAIT); return this.uploadChunk(chunkNum, path, projectId, attempts+1) } else { console.info("chunk NOT OK : " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); return {ok: false, hash: this.fileChunksUploader.getChecksum(), status: 'incomplete'} return { ok: false, hash: this.fileChunksUploader.getChecksum(), status: 'incomplete' } } } else { console.info("chunk ok : " + (chunkNum+ 1) + "/" + this.fileChunksUploader.getNbChunks()); return response; } } catch (err) { if(attempts < CHUNK_MAX_RETRY){ console.info("chunk NOT OK (RETRY): " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); await this.sleep(CHUNK_RETRY_WAIT); return this.uploadChunk(chunkNum, path, projectId, attempts+1) } else { console.error("chunk NOT OK : " + (chunkNum + 1) + "/" + this.fileChunksUploader.getNbChunks()); return {ok: false, hash: this.fileChunksUploader.getChecksum(), status: 'incomplete'} } } } Loading Loading @@ -167,12 +189,16 @@ class JamaClient extends JamacRpcClient { let alreadyUploaded = statusInfos.status === 'available'; //then upload not yet already uploaded chunks if (!alreadyUploaded) { const nbChunks = !uploadInfos ? this.fileChunksUploader.getNbChunks() : uploadInfos.nb_chunks; const nbChunks = this.fileChunksUploader.getNbChunks(); for (let i = 0; i < nbChunks; i++) { if (!uploadInfos || uploadInfos.available_chunks.indexOf('202-' + lpad(i + 1, 3) + '.part') < 0) { console.log(nbChunks + '-' + lpad(i + 1, this.fileChunksUploader.getNbChunks().toString().length) + '.part'); if (!statusInfos.available_chunks || statusInfos.available_chunks.indexOf( //if nb chunks = 42 then first chunk = '42-01.part', if nb chunks = 142 then first chunk = '142-001.part' nbChunks + '-' + lpad(i + 1, nbChunks.toString().length) + '.part') < 0) { let response = await this.uploadChunk(i, path, projectId); if (!response.ok) return {ok: false, hash: hash, status: 'incomplete'} Loading Loading @@ -200,52 +226,56 @@ class JamaClient extends JamacRpcClient { let path = (files[i]).webkitRelativePath.replace((files[i]).name, '') if (collectionPath) path = collectionPath + '/' + path; console.log("- upload du fichier : " + i, 'path =' + path); let uploadResult = await this.uploadOrResumeFile(files[i], path, projectId); let result = await this.uploadOrResumeFile(files[i], path, projectId); let uploadResult = this.mangeUploadFileResult(files[i], result); uploadResults.push(uploadResult); } else { uploadResults.push( { ok: false, status: 'bad_format', message: files[i].name + ' : mauvais format de fichier. Formats acceptés : ' + acceptedFormat.join(', '), resource: files[i].name, } ) } } this.dispatchEvent(new CustomEvent(upload_events.end_upload_event, {detail: uploadResults})) return uploadResults; } mangeUploadFileResult(file, uploadResult){ let result = null; if (uploadResult.ok) { console.log("- fichier uploadé : " + i, 'path =' + path); console.log("- fichier uploadé : " + file.name); let result = { ok: true, already_uploaded : uploadResult.already_uploaded, status: uploadResult.status, name: files[i].name, name: file.name, id: uploadResult.id, hash: uploadResult.hash, message: "Fichier versé avec succès" } uploadResults.push(result); this.dispatchEvent(new CustomEvent(upload_events.end_file_upload_event, { 'detail': result }) ); } else { let errorMessage = "Une erreur est survenue lors du versement du fichier " + files[i].name; let errorMessage = "Une erreur est survenue lors du versement du fichier " + file.name; let result = { ok: false, status: 'error', message: errorMessage, name: files[i].name, name: file.name, hash: uploadResult.hash } uploadResults.push(result); this.dispatchEvent(new CustomEvent(upload_events.end_file_upload_event, { 'detail': result }) ); } } else { uploadResults.push( { ok: false, status: 'bad_format', message: files[i].name + ' : mauvais format de fichier. Formats acceptés : ' + acceptedFormat.join(', '), resource: files[i].name, } ) } } this.dispatchEvent(new CustomEvent(upload_events.end_upload_event, {detail: uploadResults})) return uploadResults; return result; } checkExtension(file, acceptedFormats) { Loading @@ -270,7 +300,9 @@ class JamaClient extends JamacRpcClient { * } */ async resumeUpload(file, uploadInfos) { await this.uploadOrResumeFile(file, uploadInfos.path, uploadInfos.project, uploadInfos); let result = await this.uploadOrResumeFile(file, uploadInfos.path, uploadInfos.project, uploadInfos); let uploadResult = this.mangeUploadFileResult(file, result); this.dispatchEvent(new CustomEvent(upload_events.end_upload_event, {detail: [uploadResult]})) } addListener(listener) { Loading