summaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorotofune <otofune@gmail.com>2017-11-14 04:54:47 +0900
committerotofune <otofune@gmail.com>2017-11-14 05:01:24 +0900
commit51faa7a227ad8f8489d03da937c78667442beb0e (patch)
treea9a16969ffbc0b6d2fde84bb7bf55c57d204b9b7 /src/api
parentadd-file-to-drive - バッファ受け付けを削除 (diff)
downloadsharkey-51faa7a227ad8f8489d03da937c78667442beb0e.tar.gz
sharkey-51faa7a227ad8f8489d03da937c78667442beb0e.tar.bz2
sharkey-51faa7a227ad8f8489d03da937c78667442beb0e.zip
add-file-to-drive - 見通しを良くする
Diffstat (limited to 'src/api')
-rw-r--r--src/api/common/add-file-to-drive.ts279
1 files changed, 141 insertions, 138 deletions
diff --git a/src/api/common/add-file-to-drive.ts b/src/api/common/add-file-to-drive.ts
index e5d9dd7c1d..eeb92005ae 100644
--- a/src/api/common/add-file-to-drive.ts
+++ b/src/api/common/add-file-to-drive.ts
@@ -32,29 +32,18 @@ const addToGridFS = (name: string, readable: stream.Readable, type: string, meta
readable.pipe(writeStream);
}));
-/**
- * Add file to drive
- *
- * @param user User who wish to add file
- * @param file File path or readableStream
- * @param comment Comment
- * @param type File type
- * @param folderId Folder ID
- * @param force If set to true, forcibly upload the file even if there is a file with the same hash.
- * @return Object that represents added file
- */
-export default (
+const addFile = async (
user: any,
file: string | stream.Readable,
name: string = null,
comment: string = null,
folderId: mongodb.ObjectID = null,
force: boolean = false
-) => new Promise<any>((resolve, reject) => {
+) => {
log(`registering ${name} (user: ${user.username})`);
// Get file path
- new Promise((res: (v: string) => void, rej) => {
+ const path = await new Promise((res: (v: string) => void, rej) => {
if (typeof file === 'string') {
res(file);
return;
@@ -75,141 +64,155 @@ export default (
.catch(rej);
}
rej(new Error('un-compatible file.'));
- })
- // Calculate hash, get content type and get file size
- .then(path => Promise.all([
- path,
- // hash
- ((): Promise<string> => new Promise((res, rej) => {
- const readable = fs.createReadStream(path);
- const hash = crypto.createHash('md5');
- const chunks = [];
- readable
- .on('error', rej)
- .pipe(hash)
- .on('error', rej)
- .on('data', (chunk) => chunks.push(chunk))
- .on('end', () => {
- const buffer = Buffer.concat(chunks);
- res(buffer.toString('hex'));
- });
- }))(),
- // mime
- ((): Promise<[string, string | null]> => new Promise((res, rej) => {
- const readable = fs.createReadStream(path);
- readable
- .on('error', rej)
- .once('data', (buffer: Buffer) => {
- readable.destroy();
- const type = fileType(buffer);
- if (!type) {
- return res(['application/octet-stream', null]);
- }
- return res([type.mime, type.ext]);
- });
- }))(),
- // size
- ((): Promise<number> => new Promise((res, rej) => {
- fs.stat(path, (err, stats) => {
- if (err) return rej(err);
- res(stats.size);
+ });
+
+ // Calculate hash, get content type and get file size
+ const [hash, [mime, ext], size] = await Promise.all([
+ // hash
+ ((): Promise<string> => new Promise((res, rej) => {
+ const readable = fs.createReadStream(path);
+ const hash = crypto.createHash('md5');
+ const chunks = [];
+ readable
+ .on('error', rej)
+ .pipe(hash)
+ .on('error', rej)
+ .on('data', (chunk) => chunks.push(chunk))
+ .on('end', () => {
+ const buffer = Buffer.concat(chunks);
+ res(buffer.toString('hex'));
});
- }))()
- ]))
- .then(async ([path, hash, [mime, ext], size]) => {
- log(`hash: ${hash}, mime: ${mime}, ext: ${ext}, size: ${size}`);
+ }))(),
+ // mime
+ ((): Promise<[string, string | null]> => new Promise((res, rej) => {
+ const readable = fs.createReadStream(path);
+ readable
+ .on('error', rej)
+ .once('data', (buffer: Buffer) => {
+ readable.destroy();
+ const type = fileType(buffer);
+ if (!type) {
+ return res(['application/octet-stream', null]);
+ }
+ return res([type.mime, type.ext]);
+ });
+ }))(),
+ // size
+ ((): Promise<number> => new Promise((res, rej) => {
+ fs.stat(path, (err, stats) => {
+ if (err) return rej(err);
+ res(stats.size);
+ });
+ }))()
+ ]);
- // detect name
- const detectedName: string = name || (ext ? `untitled.${ext}` : 'untitled');
+ log(`hash: ${hash}, mime: ${mime}, ext: ${ext}, size: ${size}`);
- if (!force) {
- // Check if there is a file with the same hash
- const much = await DriveFile.findOne({
- md5: hash,
- 'metadata.user_id': user._id
- });
+ // detect name
+ const detectedName: string = name || (ext ? `untitled.${ext}` : 'untitled');
- if (much !== null) {
- log('file with same hash is found');
- return resolve(much);
- } else {
- log('file with same hash is not found');
- }
- }
+ if (!force) {
+ // Check if there is a file with the same hash
+ const much = await DriveFile.findOne({
+ md5: hash,
+ 'metadata.user_id': user._id
+ });
- const [properties, folder] = await Promise.all([
- // properties
- (async () => {
- if (!/^image\/.*$/.test(mime)) {
- return null;
- }
- // If the file is an image, calculate width and height to save in property
- const g = gm(fs.createReadStream(path), name);
- const size = await prominence(g).size();
- const properties = {
- width: size.width,
- height: size.height
- };
- log('image width and height is calculated');
- return properties;
- })(),
- // folder
- (async () => {
- if (!folderId) {
- return null;
+ if (much !== null) {
+ log('file with same hash is found');
+ return much;
+ } else {
+ log('file with same hash is not found');
+ }
+ }
+
+ const [properties, folder] = await Promise.all([
+ // properties
+ (async () => {
+ if (!/^image\/.*$/.test(mime)) {
+ return null;
+ }
+ // If the file is an image, calculate width and height to save in property
+ const g = gm(fs.createReadStream(path), name);
+ const size = await prominence(g).size();
+ const properties = {
+ width: size.width,
+ height: size.height
+ };
+ log('image width and height is calculated');
+ return properties;
+ })(),
+ // folder
+ (async () => {
+ if (!folderId) {
+ return null;
+ }
+ const driveFolder = await DriveFolder.findOne({
+ _id: folderId,
+ user_id: user._id
+ });
+ if (!driveFolder) {
+ throw 'folder-not-found';
+ }
+ return driveFolder;
+ })(),
+ // usage checker
+ (async () => {
+ // Calculate drive usage
+ const usage = await DriveFile
+ .aggregate([
+ { $match: { 'metadata.user_id': user._id } },
+ {
+ $project: {
+ length: true
+ }
+ },
+ {
+ $group: {
+ _id: null,
+ usage: { $sum: '$length' }
+ }
}
- const driveFolder = await DriveFolder.findOne({
- _id: folderId,
- user_id: user._id
- });
- if (!driveFolder) {
- throw 'folder-not-found';
+ ])
+ .then((aggregates: any[]) => {
+ if (aggregates.length > 0) {
+ return aggregates[0].usage;
}
- return driveFolder;
- })(),
- // usage checker
- (async () => {
- // Calculate drive usage
- const usage = await DriveFile
- .aggregate([
- { $match: { 'metadata.user_id': user._id } },
- {
- $project: {
- length: true
- }
- },
- {
- $group: {
- _id: null,
- usage: { $sum: '$length' }
- }
- }
- ])
- .then((aggregates: any[]) => {
- if (aggregates.length > 0) {
- return aggregates[0].usage;
- }
- return 0;
- });
+ return 0;
+ });
- log(`drive usage is ${usage}`);
+ log(`drive usage is ${usage}`);
- // If usage limit exceeded
- if (usage + size > user.drive_capacity) {
- throw 'no-free-space';
- }
- })()
- ]);
+ // If usage limit exceeded
+ if (usage + size > user.drive_capacity) {
+ throw 'no-free-space';
+ }
+ })()
+ ]);
- const readable = fs.createReadStream(path);
+ const readable = fs.createReadStream(path);
- return addToGridFS(detectedName, readable, mime, {
- user_id: user._id,
- folder_id: folder !== null ? folder._id : null,
- comment: comment,
- properties: properties
- });
- })
+ return addToGridFS(detectedName, readable, mime, {
+ user_id: user._id,
+ folder_id: folder !== null ? folder._id : null,
+ comment: comment,
+ properties: properties
+ });
+};
+
+/**
+ * Add file to drive
+ *
+ * @param user User who wish to add file
+ * @param file File path or readableStream
+ * @param comment Comment
+ * @param type File type
+ * @param folderId Folder ID
+ * @param force If set to true, forcibly upload the file even if there is a file with the same hash.
+ * @return Object that represents added file
+ */
+export default (user: any, file: string | stream.Readable, ...args) => new Promise<any>((resolve, reject) => {
+ addFile(user, file, ...args)
.then(file => {
log(`drive file has been created ${file._id}`);
resolve(file);