hexo-uploadServer.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. module.exports = (function () {
  2. const log = log4js.getLogger('uploadServer.js');
  3. const path = require('path');
  4. let isUploading = false;
  5. let imgType = {
  6. "png": '.png',
  7. "jpg": '.jpg',
  8. "jpeg": '.jpg',
  9. "bmp": '.bmp',
  10. ".png": '.png',
  11. ".jpg": '.jpg',
  12. ".jpeg": '.jpg',
  13. ".bmp": '.bmp'
  14. }
  15. //help varible
  16. let smmsServer, qiniuServer, cosServer;
  17. let finishedCount, totalCount, pathIndex;
  18. let statusList, successList, errorList;
  19. let timeout, startDate;
  20. let typeServer;
  21. let typeBack;
  22. let order;
  23. //
  24. let baseDir, uploadArray, finishedCallback;
  25. function getSmmsServer() {
  26. if (!smmsServer) {
  27. log.info('create SmmsServer');
  28. smmsServer = new (require('./hexo-smms'))();
  29. }
  30. return smmsServer;
  31. }
  32. function getQiNiuServer() {
  33. if (!qiniuServer) {
  34. log.info('create qiniuServer');
  35. qiniuServer = new (require('./hexo-qiniu'))();
  36. qiniuServer.update(
  37. moeApp.config.get('image-qiniu-accessKey'),
  38. moeApp.config.get('image-qiniu-secretKey'),
  39. moeApp.config.get('image-qiniu-bucket'),
  40. moeApp.config.get('image-qiniu-url-protocol') + moeApp.config.get('image-qiniu-url') + '/'
  41. );
  42. }
  43. return qiniuServer;
  44. }
  45. function getCOSServer() {
  46. if (!cosServer) {
  47. log.info('create cosServer');
  48. cosServer = new (require('./hexo-cos'))();
  49. let bucketObj = moeApp.config.get('image-cos-bucket');
  50. bucketObj = (bucketObj || "|").split('|');
  51. cosServer.update(
  52. moeApp.config.get('image-cos-accessKey'),
  53. moeApp.config.get('image-cos-secretKey'),
  54. bucketObj[0],
  55. bucketObj[1],
  56. moeApp.config.get('image-cos-url-protocol'),
  57. moeApp.config.get('image-cos-customize-enable') ? moeApp.config.get('image-cos-customize') : ''
  58. );
  59. }
  60. return cosServer;
  61. }
  62. function asyncUploadToSmms(imgPath, callback) {
  63. statusList[imgPath] = {type: 0};
  64. log.debug(`upload [${imgPath}] to SM.MS`);
  65. getSmmsServer().uploadFile(imgPath, '', callback);
  66. }
  67. function asyncUploadToQiNiu(imgPath, serverName, callback) {
  68. log.debug(`upload [${imgPath}] to QiNiu [${serverName}]`);
  69. getQiNiuServer().uploadFile(imgPath, serverName, callback);
  70. }
  71. function asyncUploadToCOS(imgPath, serverName, callback) {
  72. log.debug(`upload [${imgPath}] to Cos [${serverName}]`);
  73. getCOSServer().sliceUploadFile(imgPath, serverName, callback);
  74. }
  75. function relativePath(p) {
  76. return path.relative(baseDir, p).replace(/\\/g, '/');
  77. }
  78. function asyncUploadFile(imgPath, callback) {
  79. switch (typeServer) {
  80. case 'qiniu':
  81. asyncUploadToQiNiu(imgPath, relativePath(imgPath), callback)
  82. break;
  83. case 'cos':
  84. asyncUploadToCOS(imgPath, relativePath(imgPath), callback)
  85. break;
  86. default: {
  87. if (typeBack > 2) {
  88. if (statusList[imgPath]) {
  89. if (statusList[imgPath].typeServer == 'qiniu') {
  90. asyncUploadToQiNiu(imgPath, statusList[imgPath].pathname, callback)
  91. } else {
  92. asyncUploadToCOS(imgPath, statusList[imgPath].pathname, callback)
  93. }
  94. } else {
  95. asyncUploadToSmms(imgPath, callback);
  96. }
  97. } else {
  98. asyncUploadToSmms(imgPath, callback);
  99. }
  100. }
  101. }
  102. }
  103. function checktime() {
  104. clearTimeout(timeout);
  105. timeout = setTimeout(() => {
  106. log.warn(`upload operate timeout !`);
  107. uploadEnd(true);
  108. }, 30000)
  109. }
  110. /**
  111. * 回调函数
  112. * @param fileID
  113. * @param result
  114. * response = {
  115. * id: 'localFileAbsolutePath', //传入文件本地绝对路径
  116. * type: '1|2|10|20|100|200', //1|2 Smms; 10|20 Qiniu; 100|200 Cos (1:失败,2:成功)
  117. * statusCode: 200|int, //服务器代码,200:正常,其他:报错
  118. * data: {
  119. * localname: 'abc.png', //本地文件名
  120. * storename: '5a6bea876702d.png', //服务器文件名,SM.MS随机生成
  121. * path: '/abc/abc/5a6bea876702d.png', //服务器路径
  122. * url: 'https://...../abc/abc/5a6bea876702d.png' //图片地址
  123. * hash: 'asdf7sdf8asdf78' //删除Hash
  124. * },
  125. * msg: 'error message' //一般只有报错才使用到
  126. * errorlist: 'url' //一般只有报错才使用到,报错列表是个官网地址
  127. * }
  128. * }
  129. */
  130. function uploaded(response) {
  131. order++;
  132. let result = response;
  133. let uploadNext = true;
  134. let imgPath = result.id;
  135. let nextType = '';
  136. if( result.statusCode == 200){
  137. log.info(`sucess:[${result.id}]-->[${result.data.url}]`);
  138. }else{
  139. log.warn(`failed:[${result.statusCode}][${+result.id}]-->[${result.msg}]`);
  140. }
  141. if (typeServer == 'smms' && typeBack > 2) { //是否需要备份
  142. statusList[imgPath].type += result.type;
  143. if (statusList[imgPath].type == 2) { //Smsm
  144. statusList[imgPath].hash = result.data.hash;
  145. statusList[imgPath].url = result.data.url;
  146. if (result.data.path.startsWith('/'))
  147. statusList[imgPath].pathname = result.data.path.slice(1);
  148. else
  149. statusList[imgPath].pathname = result.data.path;
  150. uploadNext = backUpload(result)
  151. } else if (statusList[imgPath].type == 22) { //Qiniu
  152. uploadNext = backUpload(result)
  153. }
  154. nextType = statusList[imgPath].serverType;
  155. }
  156. let info = {
  157. order: order,
  158. isLoading: (finishedCount !== totalCount),
  159. finishedCount: finishedCount,
  160. totalCount: totalCount,
  161. useTime: new Date() - startDate,
  162. timeout: false,
  163. serverType: typeServer,
  164. response: response,
  165. nextPath: imgPath,
  166. nextType: nextType
  167. }
  168. if (!uploadNext) {
  169. asyncUploadFile(imgPath, uploaded);
  170. finishedCallback(info, successList, errorList);
  171. } else {
  172. finishedCount++;
  173. console.log(finishedCount + '/' + totalCount);
  174. if (typeServer == 'smms' && typeBack > 2) {
  175. if (statusList[imgPath].type == typeBack) {
  176. result.data.hash = statusList[imgPath].hash;
  177. result.data.url = statusList[imgPath].url;
  178. successList.push(result)
  179. } else {
  180. errorList.push(result)
  181. }
  182. } else {
  183. if (result.statusCode == 200) {
  184. successList.push(result)
  185. } else {
  186. errorList.push(result)
  187. }
  188. }
  189. if (pathIndex < totalCount) {
  190. info.nextPath = uploadArray[pathIndex];
  191. finishedCallback(info, successList, errorList);
  192. asyncUploadFile(info.nextPath, uploaded)
  193. pathIndex++;
  194. } else if (finishedCount == totalCount) {
  195. uploadEnd();
  196. return;
  197. }
  198. }
  199. checktime();
  200. }
  201. function backUpload(response) {
  202. let imgPath = response.id;
  203. if (typeBack == 22) {
  204. if (statusList[imgPath].type == 2) {
  205. statusList[imgPath].typeServer = 'qiniu';
  206. return false;
  207. } else {
  208. statusList[imgPath].typeServer = ''
  209. return true;
  210. }
  211. } else if (typeBack == 202) {
  212. if (statusList[imgPath].type == 2) {
  213. statusList[imgPath].typeServer = 'cos';
  214. return false;
  215. } else {
  216. statusList[imgPath].typeServer = ''
  217. return true;
  218. }
  219. } else if (typeBack == 222) {
  220. if (statusList[imgPath].type == 2) {
  221. statusList[imgPath].typeServer = 'qiniu';
  222. return false;
  223. } else if (statusList[imgPath].type == 22) {
  224. statusList[imgPath].typeServer = 'cos';
  225. return false;
  226. } else {
  227. statusList[imgPath].typeServer = ''
  228. return true;
  229. }
  230. }
  231. }
  232. function uploadEnd(isTimeout) {
  233. try {
  234. clearTimeout(timeout);
  235. if (isTimeout)
  236. errorList.push('Upload time out!', {msg: 'Place check your net!'});
  237. } finally {
  238. let info = {
  239. order: order,
  240. isLoading: false,
  241. finishedCount: finishedCount,
  242. totalCount: totalCount,
  243. useTime: new Date() - startDate,
  244. timeout: !!isTimeout,
  245. serverType: typeServer
  246. }
  247. finishedCallback(info, successList, errorList);
  248. isUploading = false;
  249. log.info(`---End upload---[S:${successList.length}| F:${errorList.length}][time:${ new Date() - startDate}]`);
  250. }
  251. }
  252. class UploadServer {
  253. constructor() {
  254. isUploading = false;
  255. }
  256. isLoading() {
  257. return isUploading;
  258. }
  259. //SM.MS
  260. del(hash){
  261. getSmmsServer().del(hash)
  262. }
  263. clearSmmsList(){
  264. getSmmsServer().clear()
  265. }
  266. getSmmsList(callback){
  267. getSmmsServer().getList(callback);
  268. }
  269. //Qiniu
  270. updateQiniu(acessKey, secretKey, bucket, url) {
  271. getQiNiuServer().update(acessKey, secretKey, bucket, url)
  272. }
  273. getQiniuAccessToken(url) {
  274. getQiNiuServer().getAccessToken(url)
  275. }
  276. getQiniuBuckets(callback) {
  277. getQiNiuServer().getBuckets(callback)
  278. }
  279. getQiniuBucketsUrl(buketName, callback) {
  280. getQiNiuServer().getBucketsUrl(buketName, callback)
  281. }
  282. deleteQiniuFile(fileanme, cb) {
  283. getQiNiuServer().deleteFile(fileanme, cb)
  284. }
  285. //Cos
  286. updateCos(acessKey, secretKey, bucket, region, protocol,customize) {
  287. getCOSServer().update(acessKey, secretKey, bucket, region, protocol,customize||'')
  288. }
  289. getCosService(cb) {
  290. getCOSServer().getService(cb)
  291. }
  292. getCosFileURL(key, cb) {
  293. getCOSServer().getFileURL(key, cb)
  294. }
  295. getCosBucketLocation(cb) {
  296. getCOSServer().getBucketLocation(cb)
  297. }
  298. deleteCosFile(fileanme, cb) {
  299. getCOSServer().deleteObject(fileanme, cb)
  300. }
  301. //upload file
  302. upload(pathArray, srcDir, callback) {
  303. if (isUploading || typeof callback !== 'function')
  304. return;
  305. if (!(pathArray instanceof Array))
  306. return;
  307. log.info(`---Begin upload---[${pathArray.length}]`);
  308. startDate = new Date();
  309. isUploading = true;
  310. baseDir = srcDir;
  311. uploadArray = pathArray;
  312. finishedCallback = callback;
  313. totalCount = uploadArray.length;
  314. finishedCount = 0;
  315. timeout = 0;
  316. order = 0;
  317. typeServer = moeApp.config.get('image-web-type');
  318. typeBack = moeApp.config.get('image-back-type');
  319. successList = []
  320. errorList = [];
  321. if (!statusList) statusList = new Map();
  322. statusList.clear();
  323. if (totalCount > 0) {
  324. checktime();
  325. let len = (totalCount > 5) ? 5 : totalCount;
  326. for (pathIndex = 0; pathIndex < len; pathIndex++) {
  327. asyncUploadFile(uploadArray[pathIndex], uploaded)
  328. }
  329. } else {
  330. uploadEnd();
  331. }
  332. }
  333. }
  334. return UploadServer;
  335. })();