Explorar o código

Merge pull request #206 from crowi/files-routing

Files routing
Sotaro KARASAWA %!s(int64=9) %!d(string=hai) anos
pai
achega
3b2c071fd1

+ 8 - 19
lib/models/attachment.js

@@ -24,11 +24,11 @@ module.exports = function(crowi) {
   }, {
     toJSON: {
       virtuals: true
-    }
+    },
   });
 
   attachmentSchema.virtual('fileUrl').get(function() {
-    return fileUploader.generateUrl(this.filePath);
+    return `/files/${this._id}`;
   });
 
   attachmentSchema.statics.findById = function(id) {
@@ -121,24 +121,13 @@ module.exports = function(crowi) {
 
   };
 
-  attachmentSchema.statics.createCacheFileName = function(attachment) {
-    return crowi.cacheDir + 'attachment-' + attachment._id;
-  };
+  attachmentSchema.statics.findDeliveryFile = function(attachment, forceUpdate) {
+    var Attachment = this;
+
+    // TODO
+    var forceUpdate = forceUpdate || false;
 
-  attachmentSchema.statics.findDeliveryFile = function(attachment) {
-    // find local
-    var fs = require('fs');
-    var deliveryFile = {
-      filename: '',
-      options: {
-        headers: {
-          'Content-Type': attachment.fileFormat,
-        },
-      },
-    };
-    var cacheFileName = this.createCacheFileName(attachment);
-    // とちゅう
-    return deliveryFile;
+    return fileUploader.findDeliveryFile(attachment);
   };
 
   return mongoose.model('Attachment', attachmentSchema);

+ 43 - 9
lib/routes/attachment.js

@@ -14,19 +14,38 @@ module.exports = function(crowi, app) {
 
   actions.api = api;
 
-  api.redirector = function(req, res){
+  api.redirector = function(req, res, next){
     var id = req.params.id;
 
     Attachment.findById(id)
     .then(function(data) {
 
       // TODO: file delivery plugin for cdn
-      var deliveryFile = Attachment.findDeliveryFile(data);
-      return res.sendFile(deliveryFile.filename, deliveryFile.options);
-    }).catch(function(err) {
-
+      Attachment.findDeliveryFile(data)
+      .then(fileName => {
+
+        var deliveryFile = {
+          fileName: fileName,
+          options: {
+            headers: {
+              'Content-Type': data.fileFormat,
+            },
+          },
+        };
+
+        if (deliveryFile.fileName.match(/^\/uploads/)) {
+          debug('Using loacal file module, just redirecting.')
+          return res.redirect(deliveryFile.fileName);
+        } else {
+          return res.sendFile(deliveryFile.fileName, deliveryFile.options);
+        }
+      }).catch(err => {
+        //debug('error', err);
+      });
+    }).catch((err) => {
+      debug('err', err);
       // not found
-      return res.sendFile(crowi.publicDir + '/images/file-not-found.png');
+      return res.status(404).sendFile(crowi.publicDir + '/images/file-not-found.png');
     });
   };
 
@@ -45,8 +64,15 @@ module.exports = function(crowi, app) {
 
     Attachment.getListByPageId(id)
     .then(function(attachments) {
+      var config = crowi.getConfig();
+      var baseUrl = (config.crowi['app:url'] || '');
       return res.json(ApiResponse.success({
-        attachments: attachments
+        attachments: attachments.map(at => {
+          var fileUrl = at.fileUrl;
+          at = at.toObject();
+          at.url = baseUrl + fileUrl;
+          return at;
+        })
       }));
     });
   };
@@ -107,11 +133,19 @@ module.exports = function(crowi, app) {
           // TODO size
           return Attachment.create(id, req.user, filePath, originalName, fileName, fileType, fileSize);
         }).then(function(data) {
-          var imageUrl = fileUploader.generateUrl(data.filePath);
+          var fileUrl = data.fileUrl;
+          var config = crowi.getConfig();
+
+          // isLocalUrl??
+          if (!fileUrl.match(/^https?/)) {
+            fileUrl = (config.crowi['app:url'] || '') + fileUrl;
+          }
+
           var result = {
             page: page.toObject(),
             attachment: data.toObject(),
-            filename: imageUrl,
+            url: fileUrl,
+            filename: fileUrl, // this is for inline-attachemnets plugin http://inlineattachment.readthedocs.io/en/latest/pages/configuration.html
             pageCreated: pageCreated,
           };
 

+ 0 - 1
lib/routes/page.js

@@ -612,7 +612,6 @@ module.exports = function(crowi, app) {
       debug('error on _api/pages.update', err);
       return res.json(ApiResponse.error(err));
     });
-
   };
 
   /**

+ 55 - 0
local_modules/crowi-fileupload-aws/index.js

@@ -62,6 +62,61 @@ module.exports = function(crowi) {
     return url;
   };
 
+  lib.findDeliveryFile = function (attachment) {
+    var cacheFile = lib.createCacheFileName(attachment);
+
+    return new Promise((resolve, reject) => {
+      debug('find delivery file', cacheFile);
+      if (!lib.shouldUpdateCacheFile(cacheFile)) {
+        return resolve(cacheFile);
+      }
+
+      var fs = require('fs');
+      var loader = require('https');
+
+      var fileStream = fs.createWriteStream(cacheFile);
+      var fileUrl = lib.generateUrl(attachment.filePath);
+      debug('Load attachement file into local cache file', fileUrl, cacheFile);
+      var request = loader.get(fileUrl, function(response) {
+        response.pipe(fileStream, { end: false });
+        response.on('end', () => {
+          fileStream.end();
+          resolve(cacheFile);
+        });
+      });
+    });
+  };
+
+  // private
+  lib.createCacheFileName = function(attachment) {
+    return crowi.cacheDir + '/attachment-' + attachment._id;
+  };
+
+  // private
+  lib.shouldUpdateCacheFile = function(filePath) {
+    var fs = require('fs');
+
+    try {
+      var stats = fs.statSync(filePath);
+
+      if (!stats.isFile()) {
+        debug('Cache file not found or the file is not a regular fil.');
+        return true;
+      }
+
+      if (stats.size <= 0) {
+        debug('Cache file found but the size is 0');
+        return true;
+      }
+    } catch (e) {
+      // no such file or directory
+      debug('Stats error', e);
+      return true;
+    }
+
+    return false;
+  };
+
   return lib;
 };
 

+ 4 - 0
local_modules/crowi-fileupload-local/index.js

@@ -54,6 +54,10 @@ module.exports = function(crowi) {
     return path.join('/uploads', filePath);
   };
 
+  lib.findDeliveryFile = function (attachment) {
+    return Promise.resolve(lib.generateUrl(attachment.filePath));
+  };
+
   return lib;
 };
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 785 - 44
npm-shrinkwrap.json


+ 1 - 1
package.json

@@ -54,7 +54,7 @@
     "elasticsearch": "^12.1.3",
     "emojify.js": "^1.1.0",
     "errorhandler": "~1.3.4",
-    "express": "~4.14.0",
+    "express": "~4.15.2",
     "express-form": "~0.12.0",
     "express-session": "~1.14.0",
     "font-awesome": "~4.7.0",

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio