Skip to content
This repository was archived by the owner on Feb 5, 2024. It is now read-only.

Commit 95ecee0

Browse files
committed
modularized fileupload, add support: local storage
1 parent c27332f commit 95ecee0

File tree

13 files changed

+186
-71
lines changed

13 files changed

+186
-71
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ node_modules/
33
bower_components/
44
public/js/*
55
public/css/*
6+
public/uploads/*

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ $ PASSWORD_SEED=somesecretstring MONGO_URI=mongodb://username:password@localhost
5757
* `REDIS_URL`: URI to connect Redis (to session store). This parameter is also by `REDISTOGO_URL`.
5858
* `PASSWORD_SEED`: A password seed is used by password hash generator.
5959
* `SECRET_TOKEN`: A secret key for verifying the integrity of signed cookies.
60+
* `FILE_UPLOAD`: `aws` (default), `local`, `none`
6061

6162

6263
License

lib/models/attachment.js

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module.exports = function(crowi) {
33
, mongoose = require('mongoose')
44
, ObjectId = mongoose.Schema.Types.ObjectId
55
, Promise = require('bluebird')
6+
, fileUploader = require('../util/fileUploader')(crowi)
67
;
78

89
function generateFileHash (fileName) {
@@ -21,6 +22,14 @@ module.exports = function(crowi) {
2122
fileFormat: { type: String, required: true },
2223
fileSize: { type: Number, default: 0 },
2324
createdAt: { type: Date, default: Date.now }
25+
}, {
26+
toJSON: {
27+
virtuals: true
28+
}
29+
});
30+
31+
attachmentSchema.virtual('fileUrl').get(function() {
32+
return fileUploader.generateUrl(this.filePath);
2433
});
2534

2635
attachmentSchema.statics.getListByPageId = function(id) {

lib/models/config.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,15 @@ module.exports = function(crowi) {
166166

167167
configSchema.statics.isUploadable = function(config)
168168
{
169-
if (!config.crowi['aws:accessKeyId'] ||
169+
if (crowi.env.FILE_UPLOAD == 'aws' && (
170+
!config.crowi['aws:accessKeyId'] ||
170171
!config.crowi['aws:secretAccessKey'] ||
171172
!config.crowi['aws:region'] ||
172-
!config.crowi['aws:bucket']) {
173+
!config.crowi['aws:bucket'])) {
173174
return false;
174175
}
175176

176-
return true;
177+
return crowi.env.FILE_UPLOAD != 'none';
177178
};
178179

179180
/*

lib/models/user.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ module.exports = function(crowi) {
5555

5656
function generatePassword (password) {
5757
var hasher = crypto.createHash('sha256');
58-
hasher.update(process.env.PASSWORD_SEED + password);
58+
hasher.update(crowi.env.PASSWORD_SEED + password);
5959

6060
return hasher.digest('hex');
6161
}

lib/routes/attachment.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = function(crowi, app) {
88
, Promise = require('bluebird')
99
, config = crowi.getConfig()
1010
, fs = require('fs')
11+
, fileUploader = require('../util/fileUploader')(crowi, app)
1112
, actions = {}
1213
, api = {};
1314

@@ -21,7 +22,6 @@ module.exports = function(crowi, app) {
2122
res.json({
2223
status: true,
2324
data: {
24-
fileBaseUrl: 'https://' + config.crowi['aws:bucket'] +'.s3.amazonaws.com/', // FIXME: ベタ書きよくない
2525
attachments: attachments
2626
}
2727
});
@@ -39,7 +39,6 @@ module.exports = function(crowi, app) {
3939

4040
debug('id and path are: ', id, path);
4141

42-
var fileUploader = require('../util/fileUploader')(crowi, app);
4342
var tmpFile = req.files.file || null;
4443
debug('Uploaded tmpFile: ', tmpFile);
4544
if (!tmpFile) {
@@ -88,7 +87,7 @@ module.exports = function(crowi, app) {
8887
// TODO size
8988
return Attachment.create(id, req.user, filePath, originalName, fileName, fileType, fileSize);
9089
}).then(function(data) {
91-
var imageUrl = fileUploader.generateS3FileUrl(data.filePath);
90+
var imageUrl = fileUploader.generateUrl(data.filePath);
9291
return res.json({
9392
status: true,
9493
filename: imageUrl,

lib/routes/me.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module.exports = function(crowi, app) {
5050

5151
fileUploader.uploadFile(filePath, tmpFile.mimetype, tmpFileStream, {})
5252
.then(function(data) {
53-
var imageUrl = fileUploader.generateS3FileUrl(filePath);
53+
var imageUrl = fileUploader.generateUrl(filePath);
5454
req.user.updateImage(imageUrl, function(err, data) {
5555
fs.unlink(tmpPath, function (err) {
5656
// エラー自体は無視

lib/util/fileUploader.js

+4-61
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,12 @@
22
* fileUploader
33
*/
44

5-
65
module.exports = function(crowi) {
76
'use strict';
87

9-
var aws = require('aws-sdk')
10-
, debug = require('debug')('crowi:lib:fileUploader')
11-
, Promise = require('bluebird')
12-
, Config = crowi.model('Config')
13-
, config = crowi.getConfig()
14-
, lib = {}
15-
;
16-
17-
lib.getAwsConfig = function()
18-
{
19-
return {
20-
accessKeyId: config.crowi['aws:accessKeyId'],
21-
secretAccessKey: config.crowi['aws:secretAccessKey'],
22-
region: config.crowi['aws:region'],
23-
bucket: config.crowi['aws:bucket']
24-
};
25-
};
26-
27-
// lib.deleteFile = function(filePath, callback) {
28-
// // TODO 実装する
29-
// };
30-
//
31-
32-
lib.uploadFile = function(filePath, contentType, fileStream, options) {
33-
var awsConfig = lib.getAwsConfig();
34-
if (!Config.isUploadable(config)) {
35-
return new Promise.reject(new Error('AWS is not configured.'));
36-
}
37-
38-
aws.config.update({
39-
accessKeyId: awsConfig.accessKeyId,
40-
secretAccessKey: awsConfig.secretAccessKey,
41-
region: awsConfig.region
42-
});
43-
var s3 = new aws.S3();
44-
45-
var params = {Bucket: awsConfig.bucket};
46-
params.ContentType = contentType;
47-
params.Key = filePath;
48-
params.Body = fileStream;
49-
params.ACL = 'public-read';
50-
51-
return new Promise(function(resolve, reject) {
52-
s3.putObject(params, function(err, data) {
53-
if (err) {
54-
return reject(err);
55-
}
56-
57-
return resolve(data);
58-
});
59-
});
60-
};
61-
62-
lib.generateS3FileUrl = function(filePath) {
63-
var awsConfig = lib.getAwsConfig();
64-
var url = 'https://' + awsConfig.bucket +'.s3.amazonaws.com/' + filePath;
65-
66-
return url;
67-
};
8+
var debug = require('debug')('crowi:lib:fileUploader')
9+
, method = crowi.env.FILE_UPLOAD || 'aws'
10+
, lib = '../../local_modules/crowi-fileupload-' + method;
6811

69-
return lib;
12+
return require(lib)(crowi);
7013
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// crowi-fileupload-aws
2+
3+
module.exports = function(crowi) {
4+
'use strict';
5+
6+
var aws = require('aws-sdk')
7+
, debug = require('debug')('crowi:lib:fileUploaderAws')
8+
, Promise = require('bluebird')
9+
, Config = crowi.model('Config')
10+
, config = crowi.getConfig()
11+
, lib = {}
12+
, getAwsConfig = function() {
13+
return {
14+
accessKeyId: config.crowi['aws:accessKeyId'],
15+
secretAccessKey: config.crowi['aws:secretAccessKey'],
16+
region: config.crowi['aws:region'],
17+
bucket: config.crowi['aws:bucket']
18+
};
19+
};
20+
21+
lib.deleteFile = function(filePath) {
22+
return new Promise(function(resolve, reject) {
23+
debug('Unsupported file deletion.');
24+
resolve('TODO: ...');
25+
});
26+
};
27+
28+
lib.uploadFile = function(filePath, contentType, fileStream, options) {
29+
var awsConfig = lib.getAwsConfig();
30+
if (!Config.isUploadable(config)) {
31+
return new Promise.reject(new Error('AWS is not configured.'));
32+
}
33+
34+
aws.config.update({
35+
accessKeyId: awsConfig.accessKeyId,
36+
secretAccessKey: awsConfig.secretAccessKey,
37+
region: awsConfig.region
38+
});
39+
var s3 = new aws.S3();
40+
41+
var params = {Bucket: awsConfig.bucket};
42+
params.ContentType = contentType;
43+
params.Key = filePath;
44+
params.Body = fileStream;
45+
params.ACL = 'public-read';
46+
47+
return new Promise(function(resolve, reject) {
48+
s3.putObject(params, function(err, data) {
49+
if (err) {
50+
return reject(err);
51+
}
52+
53+
return resolve(data);
54+
});
55+
});
56+
};
57+
58+
lib.generateUrl = function(filePath) {
59+
var awsConfig = lib.getAwsConfig()
60+
, url = 'https://' + awsConfig.bucket +'.s3.amazonaws.com/' + filePath;
61+
62+
return url;
63+
};
64+
65+
return lib;
66+
};
67+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// crowi-fileupload-local
2+
3+
module.exports = function(crowi) {
4+
'use strict';
5+
6+
var debug = require('debug')('crowi:lib:fileUploaderLocal')
7+
, fs = require('fs')
8+
, path = require('path')
9+
, mkdir = require('mkdirp')
10+
, Promise = require('bluebird')
11+
, Config = crowi.model('Config')
12+
, config = crowi.getConfig()
13+
, lib = {}
14+
, basePath = path.join(crowi.publicDir, 'uploads'); // TODO: to configurable
15+
16+
lib.deleteFile = function(filePath) {
17+
debug('File deletion: ' + filePath);
18+
return new Promise(function(resolve, reject) {
19+
fs.unlink(path.join(basePath, filePath), function(err) {
20+
if (err) {
21+
debug(err);
22+
return reject(err);
23+
}
24+
25+
resolve();
26+
});
27+
});
28+
};
29+
30+
lib.uploadFile = function(filePath, contentType, fileStream, options) {
31+
debug('File uploading: ' + filePath);
32+
return new Promise(function(resolve, reject) {
33+
var localFilePath = path.join(basePath, filePath)
34+
, dirpath = path.dirname(localFilePath);
35+
36+
mkdir(dirpath, function(err) {
37+
if (err) {
38+
return reject(err);
39+
}
40+
41+
var writer = fs.createWriteStream(localFilePath);
42+
43+
writer.on('error', function(err) {
44+
reject(err);
45+
}).on('finish', function() {
46+
resolve();
47+
});
48+
49+
fileStream.pipe(writer);
50+
});
51+
});
52+
};
53+
54+
lib.generateUrl = function(filePath) {
55+
return path.join('/uploads', filePath);
56+
};
57+
58+
return lib;
59+
};
60+
61+

local_modules/crowi-fileupload-none/index.js

+33
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"kerberos": "0.0.17",
6666
"marked": "~0.3.5",
6767
"method-override": "~2.3.1",
68+
"mkdirp": "^0.5.1",
6869
"mongoose": "4.2.5",
6970
"mongoose-paginate": "4.2.0",
7071
"morgan": "~1.5.1",

resource/js/crowi.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -380,11 +380,10 @@ $(function() {
380380
var $pageAttachmentList = $('.page-attachments ul');
381381
$.get('/_api/attachment/page/' + pageId, function(res) {
382382
var attachments = res.data.attachments;
383-
var urlBase = res.data.fileBaseUrl;
384383
if (attachments.length > 0) {
385384
$.each(attachments, function(i, file) {
386385
$pageAttachmentList.append(
387-
'<li><a href="' + urlBase + file.filePath + '">' + (file.originalName || file.fileName) + '</a> <span class="label label-default">' + file.fileFormat + '</span></li>'
386+
'<li><a href="' + file.fileUrl + '">' + (file.originalName || file.fileName) + '</a> <span class="label label-default">' + file.fileFormat + '</span></li>'
388387
);
389388
})
390389
} else {

0 commit comments

Comments
 (0)