diff options
| author | sei0o inoue <sei0okun@gmail.com> | 2018-10-07 16:51:46 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2018-10-07 16:51:46 +0900 |
| commit | 3e897727ca7c8b0b5ba11c9d1866dc87ea136c22 (patch) | |
| tree | 2bb4f17b3720bdac291dbad1b77c34a53e75cb60 /src/client/app | |
| parent | V10 (#2826) (diff) | |
| download | sharkey-3e897727ca7c8b0b5ba11c9d1866dc87ea136c22.tar.gz sharkey-3e897727ca7c8b0b5ba11c9d1866dc87ea136c22.tar.bz2 sharkey-3e897727ca7c8b0b5ba11c9d1866dc87ea136c22.zip | |
Fix #2773 (#2841)
* Added an API endpoint to check the existence of the file
* fix #2773: Now we can prevent users from posting the same images
* bug fix
Diffstat (limited to 'src/client/app')
| -rw-r--r-- | src/client/app/common/scripts/get-md5.ts | 8 | ||||
| -rw-r--r-- | src/client/app/common/views/components/uploader.vue | 94 |
2 files changed, 68 insertions, 34 deletions
diff --git a/src/client/app/common/scripts/get-md5.ts b/src/client/app/common/scripts/get-md5.ts new file mode 100644 index 0000000000..24ac04c1ad --- /dev/null +++ b/src/client/app/common/scripts/get-md5.ts @@ -0,0 +1,8 @@ +const crypto = require('crypto'); + +export default (data: ArrayBuffer) => { + const buf = new Buffer(data); + const hash = crypto.createHash("md5"); + hash.update(buf); + return hash.digest("hex"); +};
\ No newline at end of file diff --git a/src/client/app/common/views/components/uploader.vue b/src/client/app/common/views/components/uploader.vue index 19b0d15708..fed6477c05 100644 --- a/src/client/app/common/views/components/uploader.vue +++ b/src/client/app/common/views/components/uploader.vue @@ -20,6 +20,7 @@ <script lang="ts"> import Vue from 'vue'; import { apiUrl } from '../../../config'; +import getMD5 from '../../scripts/get-md5'; export default Vue.extend({ data() { @@ -28,53 +29,78 @@ export default Vue.extend({ }; }, methods: { - upload(file, folder) { - if (folder && typeof folder == 'object') folder = folder.id; + checkExistence(fileData: ArrayBuffer): Promise<any> { + return new Promise((resolve, reject) => { + const data = new FormData(); + data.append('md5', getMD5(fileData)); - const id = Math.random(); + (this as any).api('drive/files/check_existence', { + md5: getMD5(fileData) + }).then(resp => { + resolve(resp.file); + }); + }); + }, - const ctx = { - id: id, - name: file.name || 'untitled', - progress: undefined, - img: undefined - }; + upload(file: File, folder: any) { + if (folder && typeof folder == 'object') folder = folder.id; - this.uploads.push(ctx); - this.$emit('change', this.uploads); + const id = Math.random(); const reader = new FileReader(); reader.onload = (e: any) => { - ctx.img = e.target.result; - }; - reader.readAsDataURL(file); + this.checkExistence(e.target.result).then(result => { + console.log(result); + if (result !== null) { + this.$emit('uploaded', result); + return; + } + + // Upload if the file didn't exist yet + const buf = new Uint8Array(e.target.result); + let bin = ""; + // We use for-of loop instead of apply() to avoid RangeError + // SEE: https://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string + for (const byte of buf) bin += String.fromCharCode(byte); + const ctx = { + id: id, + name: file.name || 'untitled', + progress: undefined, + img: 'data:*/*;base64,' + btoa(bin) + }; + + this.uploads.push(ctx); + this.$emit('change', this.uploads); - const data = new FormData(); - data.append('i', this.$store.state.i.token); - data.append('file', file); + const data = new FormData(); + data.append('i', this.$store.state.i.token); + data.append('file', file); - if (folder) data.append('folderId', folder); + if (folder) data.append('folderId', folder); - const xhr = new XMLHttpRequest(); - xhr.open('POST', apiUrl + '/drive/files/create', true); - xhr.onload = (e: any) => { - const driveFile = JSON.parse(e.target.response); + const xhr = new XMLHttpRequest(); + xhr.open('POST', apiUrl + '/drive/files/create', true); + xhr.onload = (e: any) => { + const driveFile = JSON.parse(e.target.response); - this.$emit('uploaded', driveFile); + this.$emit('uploaded', driveFile); - this.uploads = this.uploads.filter(x => x.id != id); - this.$emit('change', this.uploads); - }; + this.uploads = this.uploads.filter(x => x.id != id); + this.$emit('change', this.uploads); + }; - xhr.upload.onprogress = e => { - if (e.lengthComputable) { - if (ctx.progress == undefined) ctx.progress = {}; - ctx.progress.max = e.total; - ctx.progress.value = e.loaded; - } - }; + xhr.upload.onprogress = e => { + if (e.lengthComputable) { + if (ctx.progress == undefined) ctx.progress = {}; + ctx.progress.max = e.total; + ctx.progress.value = e.loaded; + } + }; - xhr.send(data); + xhr.send(data); + }) + } + reader.readAsArrayBuffer(file); } } }); |