hexo-qiniu.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * This file is part of HexoEditor.
  3. *
  4. * Copyright (c) 2018 zhuzhuyule
  5. */
  6. var qiniuServer = (function () {
  7. const path = require('path');
  8. let log = log4js.getLogger('hexo-qiniu.js');
  9. class QiniuServer {
  10. constructor(acessKey, secretKey) {
  11. this.request = require('request');
  12. this.qiniu = require('qiniu');
  13. this.bucket = '';
  14. this.qiniu.conf.ACCESS_KEY = acessKey;
  15. this.qiniu.conf.SECRET_KEY = secretKey;
  16. this.mac = new this.qiniu.auth.digest.Mac(acessKey, secretKey);
  17. }
  18. /**
  19. * 更新信息
  20. * @param acessKey
  21. * @param secretKey
  22. * @param bucket
  23. * @param url
  24. */
  25. update(acessKey, secretKey, bucket, url) {
  26. acessKey = acessKey || moeApp.config.get('image-qiniu-accessKey');
  27. secretKey = secretKey || moeApp.config.get('image-qiniu-secretKey');
  28. this.qiniu.conf.ACCESS_KEY = acessKey;
  29. this.qiniu.conf.SECRET_KEY = secretKey;
  30. this.mac = new this.qiniu.auth.digest.Mac(acessKey, secretKey);
  31. this.bucket = bucket || this.bucket || '';
  32. this.url = url || this.url || '';
  33. log.debug('update options.')
  34. }
  35. /**
  36. * 生成空间 文件名
  37. * @param bucket 空间名(必传)
  38. * @param key Key值
  39. * @returns {string}
  40. */
  41. getUptoken(bucket, key) {
  42. var options = {
  43. scope: bucket + ":" + key
  44. };
  45. var putPolicy = new this.qiniu.rs.PutPolicy(options);
  46. return putPolicy.uploadToken();
  47. }
  48. /**
  49. * 生成 AccessToken
  50. * @param url
  51. * @returns {string}
  52. */
  53. getAccessToken(url) {
  54. return this.qiniu.util.generateAccessToken(this.mac, url);
  55. }
  56. /**
  57. * 异步获取空间列表
  58. */
  59. getBuckets(callback) {
  60. const url_api_bukets = 'https://rs.qbox.me/buckets';
  61. var request = this.request({
  62. url: url_api_bukets,
  63. method: 'GET',
  64. headers: {
  65. 'Authorization': this.getAccessToken(url_api_bukets),
  66. 'Content-Type': 'application/x-www-form-urlencoded'
  67. }
  68. }, (error, res, body) => {
  69. if(res.statusCode == 200 ) {
  70. log.info(`getBuckets->[${body}]`)
  71. } else {
  72. log.error(`getBuckets->[${body}]`)
  73. }
  74. if (typeof callback === "function") {
  75. callback({
  76. statusCode: res.statusCode,
  77. data: JSON.parse(body)
  78. })
  79. }
  80. });
  81. return;
  82. }
  83. /**
  84. * 异步获取空间地址URL列表
  85. * @param buketName 空间名(必传)
  86. */
  87. getBucketsUrl(buketName, callback) {
  88. const url_api_bukets = 'https://api.qiniu.com/v6/domain/list?tbl=' + buketName;
  89. var request = this.request({
  90. url: url_api_bukets,
  91. method: 'GET',
  92. headers: {
  93. 'Authorization': this.getAccessToken(url_api_bukets),
  94. 'Content-Type': 'application/x-www-form-urlencoded'
  95. }
  96. }, (error, res, body) => {
  97. if(res.statusCode == 200 ) {
  98. log.info(`getBucketsUrl->[${body}]`)
  99. } else {
  100. log.error(`getBucketsUrl->[${body}]`)
  101. }
  102. if (typeof callback === "function") {
  103. callback({
  104. statusCode: res.statusCode,
  105. data: JSON.parse(body)
  106. })
  107. }
  108. });
  109. }
  110. /**
  111. * 异步获取服务器文件列表
  112. * @param buketName 空间名称(必传)
  113. * @param prefix 虚拟目录(选填)
  114. */
  115. getBucketsFiles(buketName, prefix, callback) {
  116. if (!buketName) return;
  117. const url_api_bukets = require('util').format(
  118. 'https://rsf.qbox.me/list?bucket=%s&marker=&limit=1&prefix=%s&delimiter=/', buketName, prefix || '')
  119. var request = this.request({
  120. url: url_api_bukets,
  121. method: 'GET',
  122. headers: {
  123. 'Authorization': this.getAccessToken(url_api_bukets),
  124. 'Content-Type': 'application/x-www-form-urlencoded'
  125. }
  126. }, (error, res, body) => {
  127. if (typeof callback === "function") {
  128. callback({
  129. statusCode: res.statusCode,
  130. data: JSON.parse(body)
  131. })
  132. } else {
  133. console.log(res)
  134. }
  135. });
  136. }
  137. /**
  138. * 删除文件
  139. * @param key
  140. * @param callback
  141. */
  142. deleteFile(key,callback){
  143. if(key.startsWith('/')) key = key.slice(1);
  144. var config = new this.qiniu.conf.Config();
  145. var bucketManager = new this.qiniu.rs.BucketManager(this.mac, config);
  146. bucketManager.delete(this.bucket, key, function(error, data, response) {
  147. if([200].includes(response.statusCode) ) {
  148. log.info(`[${key}]: was deleted!`)
  149. } else {
  150. log.error(`[${key}]:`+data.error);
  151. }
  152. if (typeof callback === "function") {
  153. callback({
  154. statusCode: response.statusCode,
  155. data: data
  156. })
  157. }
  158. });
  159. }
  160. /**
  161. * 异步上传单个文件
  162. * @param localFile 本地文件全路径
  163. * @param serverFileName 服务器保存名称(可带地址)
  164. * @param callback callback(response) //回调函数
  165. * response = {
  166. * id: 'localFileAbsolutePath', //传入文件本地绝对路径
  167. * statusCode: 200|int, //服务器代码,200:正常,其他:报错
  168. * data: {
  169. * localname: 'abc.png', //本地文件名
  170. * storename: '5a6bea876702d.png', //服务器文件名,SM.MS随机生成
  171. * path: '/abc/abc/5a6bea876702d.png', //服务器路径
  172. * url: 'https://...../abc/abc/5a6bea876702d.png' //图片地址
  173. * },
  174. * msg: 'error message' //一般只有报错才使用到
  175. * errorlist: 'url' //一般只有报错才使用到
  176. * }
  177. */
  178. uploadFile(localFile, serverFileName, callback) {
  179. //生成上传 Token
  180. let token = this.getUptoken(this.bucket, serverFileName);
  181. var formUploader = new this.qiniu.form_up.FormUploader(this.qiniu.conf);
  182. var extra = new this.qiniu.form_up.PutExtra();
  183. let qiniuServer = this;
  184. formUploader.putFile(token, serverFileName, localFile, extra,
  185. function (respErr, respBody, respInfo) {
  186. if (typeof callback == 'function') {
  187. let result = {type:10,id: localFile};
  188. try {
  189. if (respInfo.statusCode == 200 || respInfo.statusCode == 579) {
  190. result.type = 20;
  191. result.statusCode = 200;
  192. result.data = {
  193. localname: path.basename(localFile),
  194. storename: path.basename(serverFileName),
  195. path: respBody.key,
  196. url: qiniuServer.url + respBody.key
  197. }
  198. result.msg = '';
  199. result.errorlist = '';
  200. } else {
  201. result.msg = respInfo.statusCode + respBody.error;
  202. result.errorlist = 'https://developer.qiniu.com/kodo/api/3928/error-responses#2';
  203. }
  204. }catch (e){
  205. log.error('uploadFile',localFile,e)
  206. }finally {
  207. callback(result)
  208. }
  209. }
  210. });
  211. }
  212. }
  213. return QiniuServer;
  214. })();
  215. module.exports = qiniuServer;