hexo-uploadServer.js 12 KB

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