11'use strict'
2+
3+ const crypto = require ( 'crypto' )
4+ const fs = require ( 'fs' )
25const URL = require ( 'url' ) . URL
36const path = require ( 'path' )
47
58const config = require ( '../config' )
69const logger = require ( '../logger' )
710
11+ /**
12+ * generate a random filename for uploaded image
13+ */
14+ function randomFilename ( ) {
15+ const buf = crypto . randomBytes ( 16 )
16+ return `upload_${ buf . toString ( 'hex' ) } `
17+ }
18+
19+ /**
20+ * pick a filename not exist in filesystem
21+ * maximum attempt 5 times
22+ */
23+ function pickFilename ( defaultFilename ) {
24+ let retryCounter = 5
25+ let filename = defaultFilename
26+ const extname = path . extname ( defaultFilename )
27+ while ( retryCounter -- > 0 ) {
28+ if ( fs . existsSync ( path . join ( config . uploadsPath , filename ) ) ) {
29+ filename = `${ randomFilename ( ) } ${ extname } `
30+ continue
31+ }
32+ return filename
33+ }
34+ throw new Error ( 'file exists.' )
35+ }
36+
837exports . uploadImage = function ( imagePath , callback ) {
938 if ( ! imagePath || typeof imagePath !== 'string' ) {
1039 callback ( new Error ( 'Image path is missing or wrong' ) , null )
@@ -16,11 +45,24 @@ exports.uploadImage = function (imagePath, callback) {
1645 return
1746 }
1847
48+ let filename = path . basename ( imagePath )
49+ try {
50+ filename = pickFilename ( path . basename ( imagePath ) )
51+ } catch ( e ) {
52+ return callback ( e , null )
53+ }
54+
55+ try {
56+ fs . copyFileSync ( imagePath , path . join ( config . uploadsPath , filename ) )
57+ } catch ( e ) {
58+ return callback ( e , null )
59+ }
60+
1961 let url
2062 try {
21- url = ( new URL ( path . basename ( imagePath ) , config . serverURL + '/uploads/' ) ) . href
63+ url = ( new URL ( filename , config . serverURL + '/uploads/' ) ) . href
2264 } catch ( e ) {
23- url = config . serverURL + '/uploads/' + path . basename ( imagePath )
65+ url = config . serverURL + '/uploads/' + filename
2466 }
2567
2668 callback ( null , url )
0 commit comments