hexo-uploadServer.js 11 KB

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