123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- var util = require("thinkjs-util");
- var request = require("request");
- var fs = require("fs");
- var path = require("path");
- module.exports = util.Class(function () {
- return {
- /**
- * 接口的域名
- * @type {String}
- */
- domain: "v0.api.upyun.com",
- /**
- * 初始化
- * @param {[type]} bucketname [description]
- * @param {[type]} username [description]
- * @param {[type]} password [description]
- * @return {[type]} [description]
- */
- init: function (bucketname, username, password) {
- this.bucketname = bucketname;
- this.username = username;
- this.password = util.md5(password);
- },
- /**
- * 设置接口的domain
- * @param {[type]} domain [description]
- */
- setDomain: function (domain) {
- this.domain = domain;
- return this;
- },
- /**
- * 签名
- * @param {[type]} method [description]
- * @param {[type]} uri [description]
- * @param {[type]} date [description]
- * @param {[type]} length [description]
- * @return {[type]} [description]
- */
- sign: function (method, uri, date, length) {
- var sign = method + '&' + uri + '&' + date + '&' + length + '&' + this.password;
- return 'UpYun ' + this.username + ':' + util.md5(sign);
- },
- /**
- * 获取文件或者文件夹的信息
- * @param {[type]} file [description]
- * @return {[type]} [description]
- */
- getInfo: function (file) {
- return this.request(file, 'HEAD').then(function (response) {
- var headers = response.headers;
- return {
- type: headers['x-upyun-file-type'],
- size: headers['x-upyun-file-size'],
- date: headers['x-upyun-file-date']
- };
- });
- },
- /**
- * 查看空间占用信息
- * @return {[type]} [description]
- */
- getUsage: function (path) {
- path = path || "/";
- return this.request(path + "?usage").then(function (response) {
- return parseInt(response.body, 10);
- });
- },
- /**
- * 从返回的headers里获取图片的信息
- * @param {[type]} response [description]
- * @return {[type]} [description]
- */
- getPicInfo: function (response) {
- var headers = response.headers;
- return {
- width: headers['x-upyun-width'],
- height: headers['x-upyun-height'],
- frames: headers['x-upyun-frames'],
- type: headers['x-upyun-file-type']
- };
- },
- /**
- * 上传文件或者文件夹
- * @param {[type]} savePath [description]
- * @param {[type]} filePath [description]
- * @return {[type]} [description]
- */
- upload: function (savePath, filePath, headers) {
- var defaultHeaders = {
- mkdir: true
- };
- if (util.isObject(headers)) {
- defaultHeaders = util.extend(defaultHeaders, headers);
- } else if (headers) {
- defaultHeaders["Content-Secret"] = headers;
- }
- var self = this;
- //文件上传
- if (util.isFile(filePath)) {
- var stream = fs.readFileSync(filePath);
- var filename;
- if (!(/\.\w+$/.test(savePath))) {
- filename = filePath.split('/');
- filename = filename[filename.length - 1];
- savePath += '/' + filename;
- }
- return this.request(savePath, 'PUT', stream, defaultHeaders).then(function (response) {
- return self.getPicInfo(response);
- }).then(function (data) {
- if (filename) {
- data.filename = filename;
- }
- return data;
- });
- } else if (util.isDir(filePath)) { //文件夹上传
- if (savePath.slice(-1) !== '/') {
- savePath += '/';
- }
- if (filePath.slice(-1) !== '/') {
- filePath += '/';
- }
- var promises = [];
- var files = fs.readdirSync(filePath);
- files.forEach(function (item) {
- var nFilePath = filePath + item;
- var state = fs.statSync(nFilePath);
- if (state.isFile() || state.isDirectory()) {
- var promise = self.upload(savePath + item, nFilePath);
- promises.push(promise);
- }
- });
- if (promises.length) {
- return util.Promise.all(promises);
- } else {
- return self.mkDir(savePath);
- }
- } else { //普通内容上传
- return this.request(savePath, 'PUT', filePath, defaultHeaders).then(function (response) {
- return self.getPicInfo(response);
- });
- }
- },
- /**
- * 文件或者文件夹下载
- * @param {[type]} path [description]
- * @param {[type]} savePath [description]
- * @return {[type]} [description]
- */
- download: function (sourcePath, savePath, typeData) {
- sourcePath = sourcePath || "/";
- //if (savePath && savePath.slice(-1) !== "/") {
- // savePath += "/";
- //}
- var self = this;
- var promise = typeData ? util.getPromise(typeData) : this.getInfo(sourcePath);
- return promise.then(function (data) {
- if (data.type === 'folder') {
- if (sourcePath.slice(-1) !== "/") {
- sourcePath += "/";
- }
- return self.readDir(sourcePath).then(function (data) {
- var promises = [];
- data.forEach(function (item) {
- var nPath = sourcePath + item.name;
- var promise;
- //文件夹
- if (item.type === 'F') {
- promise = self.download(nPath + "/", savePath + item.name + "/", {
- type: 'folder'
- });
- } else if (item.type) { //文件
- promise = self.download(nPath, savePath, {
- type: 'file'
- });
- }
- promises.push(promise);
- });
- return util.Promise.all(promises);
- });
- } else {
- //单个文件
- return self.request(sourcePath, 'GET', '', {}, {
- encoding: null
- }).then(function (response) {
- if (!savePath) {
- return response.body;
- }
- var sourceExt = path.extname(sourcePath);
- var saveExt = path.extname(savePath);
- var fileSavePath = savePath;
- if (sourceExt && sourceExt === saveExt) {
- util.mkdir(path.dirname(savePath));
- } else {
- util.mkdir(savePath);
- fileSavePath = savePath + path.basename(sourcePath);
- }
- fs.writeFileSync(fileSavePath, response.body);
- });
- }
- });
- },
- /**
- * 删除文件或者文件夹
- * @param {[type]} path [description]
- * @param {[type]} force [description]
- * @return {[type]} [description]
- */
- rm: function (path, force) {
- if (!path) {
- return util.getPromise(new Error("path can't empty"), true);
- }
- if (path.slice(-1) !== '/') {
- path += '/';
- }
- var self = this;
- return this.getInfo(path).then(function (data) {
- if (data.type === 'folder') {
- if (!force) {
- return self.request(path, 'DELETE').then(function (response) {
- return response.body;
- });
- }
- return self.readDir(path).then(function (data) {
- var promises = [];
- data.forEach(function (item) {
- var nPath = path + item.name;
- var promise;
- //文件夹
- if (item.type === 'F') {
- promise = self.rm(nPath + "/", true);
- } else if (item.type) { //文件
- promise = self.rm(nPath);
- }
- promises.push(promise);
- });
- if (promises.length) {
- return util.Promise.all(promises);
- }
- }).then(function () {
- return self.rm(path, false);
- });
- } else {
- return self.request(path, 'DELETE').then(function (response) {
- return response.body;
- });
- }
- });
- },
- /**
- * 递归创建目录
- * @param {[type]} path [description]
- * @return {[type]} [description]
- */
- mkDir: function (path) {
- return this.request(path, 'PUT', '', {
- mkdir: true,
- folder: true
- }).then(function (response) {
- return response.body;
- });
- },
- /**
- * 读取目录下的文件和子目录
- * @param {[type]} dir [description]
- * @return {[type]} [description]
- */
- readDir: function (path, recursive) {
- path = path || "/";
- if (path.slice(-1) !== '/') {
- path += '/';
- }
- var self = this;
- return this.request(path, "GET").then(function (response) {
- var dirs = response.body.split("\n");
- var result = [];
- var promises = [];
- for (var i = 0; i < dirs.length; i++) {
- var dir = dirs[i];
- var attrs = dir.split("\t");
- dir = {
- name: attrs[0],
- type: attrs[1],
- size: attrs[2],
- time: attrs[3]
- };
- if (recursive && dir.type === 'F') {
- var promise = self.readDir(path + dir.name, true).then(function (data) {
- dir.children = data;
- });
- promises.push(promise);
- }
- result.push(dir);
- }
- if (promises.length) {
- return util.Promise.all(promises).then(function () {
- return result;
- });
- } else {
- return result;
- }
- });
- },
- /**
- * 请求数据
- * @param {[type]} uri [description]
- * @param {[type]} method [description]
- * @param {[type]} data [description]
- * @param {[type]} headers [description]
- * @param {[type]} options [description]
- * @return {[type]} [description]
- */
- request: function (uri, method, data, headers, options) {
- uri = "/" + this.bucketname + uri;
- method = method || "GET";
- headers = headers || {};
- var length = 0;
- if (data) {
- length = !util.isBuffer(data) ? Buffer.byteLength(data) : data.length;
- }
- var date = (new Date()).toUTCString();
- var Authorization = this.sign(method, uri, date, length);
- headers = util.extend(headers, {
- 'Content-Length': length,
- 'Date': date,
- 'Authorization': Authorization
- });
- var deferred = util.getDefer();
- var opts = util.extend({
- url: "http://" + this.domain + uri,
- method: method,
- body: data || "",
- headers: headers
- }, options);
- request(opts, function (error, response, body) {
- if (error || response.statusCode !== 200) {
- deferred.reject(error || "statusCode: " + response.statusCode + "; body: " + body);
- } else {
- deferred.resolve(response);
- }
- });
- return deferred.promise;
- }
- };
- });
|