|
@@ -4,9 +4,9 @@ module.exports = function(crowi) {
|
|
|
'use strict';
|
|
'use strict';
|
|
|
|
|
|
|
|
var aws = require('aws-sdk')
|
|
var aws = require('aws-sdk')
|
|
|
|
|
+ , fs = require('fs')
|
|
|
|
|
+ , path = require('path')
|
|
|
, debug = require('debug')('crowi:lib:fileUploaderAws')
|
|
, debug = require('debug')('crowi:lib:fileUploaderAws')
|
|
|
- , Config = crowi.model('Config')
|
|
|
|
|
- , config = crowi.getConfig()
|
|
|
|
|
, lib = {}
|
|
, lib = {}
|
|
|
, getAwsConfig = function() {
|
|
, getAwsConfig = function() {
|
|
|
var config = crowi.getConfig();
|
|
var config = crowi.getConfig();
|
|
@@ -18,17 +18,13 @@ module.exports = function(crowi) {
|
|
|
};
|
|
};
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- lib.deleteFile = function(filePath) {
|
|
|
|
|
- return new Promise(function(resolve, reject) {
|
|
|
|
|
- debug('Unsupported file deletion.');
|
|
|
|
|
- resolve('TODO: ...');
|
|
|
|
|
- });
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ function S3Factory() {
|
|
|
|
|
+ const awsConfig = getAwsConfig();
|
|
|
|
|
+ const Config = crowi.model('Config');
|
|
|
|
|
+ const config = crowi.getConfig();
|
|
|
|
|
|
|
|
- lib.uploadFile = function(filePath, contentType, fileStream, options) {
|
|
|
|
|
- var awsConfig = getAwsConfig();
|
|
|
|
|
if (!Config.isUploadable(config)) {
|
|
if (!Config.isUploadable(config)) {
|
|
|
- return Promise.reject(new Error('AWS is not configured.'));
|
|
|
|
|
|
|
+ throw new Error('AWS is not configured.');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
aws.config.update({
|
|
aws.config.update({
|
|
@@ -36,7 +32,37 @@ module.exports = function(crowi) {
|
|
|
secretAccessKey: awsConfig.secretAccessKey,
|
|
secretAccessKey: awsConfig.secretAccessKey,
|
|
|
region: awsConfig.region
|
|
region: awsConfig.region
|
|
|
});
|
|
});
|
|
|
- var s3 = new aws.S3();
|
|
|
|
|
|
|
+
|
|
|
|
|
+ return new aws.S3();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ lib.deleteFile = function(fileId, filePath) {
|
|
|
|
|
+ const s3 = S3Factory();
|
|
|
|
|
+ const awsConfig = getAwsConfig();
|
|
|
|
|
+
|
|
|
|
|
+ const params = {
|
|
|
|
|
+ Bucket: awsConfig.bucket,
|
|
|
|
|
+ Key: filePath,
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ s3.deleteObject(params, (err, data) => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ debug('Failed to delete object from s3', err);
|
|
|
|
|
+ return reject(err);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // asynclonousely delete cache
|
|
|
|
|
+ lib.clearCache(fileId);
|
|
|
|
|
+
|
|
|
|
|
+ resolve(data);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ lib.uploadFile = function(filePath, contentType, fileStream, options) {
|
|
|
|
|
+ const s3 = S3Factory();
|
|
|
|
|
+ const awsConfig = getAwsConfig();
|
|
|
|
|
|
|
|
var params = {Bucket: awsConfig.bucket};
|
|
var params = {Bucket: awsConfig.bucket};
|
|
|
params.ContentType = contentType;
|
|
params.ContentType = contentType;
|
|
@@ -62,6 +88,78 @@ module.exports = function(crowi) {
|
|
|
return url;
|
|
return url;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ lib.findDeliveryFile = function (fileId, filePath) {
|
|
|
|
|
+ var cacheFile = lib.createCacheFileName(fileId);
|
|
|
|
|
+
|
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
|
+ debug('find delivery file', cacheFile);
|
|
|
|
|
+ if (!lib.shouldUpdateCacheFile(cacheFile)) {
|
|
|
|
|
+ return resolve(cacheFile);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var loader = require('https');
|
|
|
|
|
+
|
|
|
|
|
+ var fileStream = fs.createWriteStream(cacheFile);
|
|
|
|
|
+ var fileUrl = lib.generateUrl(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);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ lib.clearCache = function(fileId) {
|
|
|
|
|
+ const cacheFile = lib.createCacheFileName(fileId);
|
|
|
|
|
+
|
|
|
|
|
+ (new Promise((resolve, reject) => {
|
|
|
|
|
+ fs.unlink(cacheFile, (err) => {
|
|
|
|
|
+ if (err) {
|
|
|
|
|
+ debug('Failed to delete cache file', err);
|
|
|
|
|
+ // through
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ resolve();
|
|
|
|
|
+ });
|
|
|
|
|
+ })).then(data => {
|
|
|
|
|
+ // success
|
|
|
|
|
+ }).catch(err => {
|
|
|
|
|
+ debug('Failed to delete cache file (file may not exists).', err);
|
|
|
|
|
+ // through
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // private
|
|
|
|
|
+ lib.createCacheFileName = function(fileId) {
|
|
|
|
|
+ return path.join(crowi.cacheDir, `attachment-${fileId}`);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // private
|
|
|
|
|
+ lib.shouldUpdateCacheFile = function(filePath) {
|
|
|
|
|
+ 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;
|
|
return lib;
|
|
|
};
|
|
};
|
|
|
|
|
|