summaryrefslogtreecommitdiff
path: root/src/api/endpoints/drive
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/endpoints/drive')
-rw-r--r--src/api/endpoints/drive/files.js82
-rw-r--r--src/api/endpoints/drive/files/create.js59
-rw-r--r--src/api/endpoints/drive/files/find.js48
-rw-r--r--src/api/endpoints/drive/files/show.js40
-rw-r--r--src/api/endpoints/drive/files/update.js89
-rw-r--r--src/api/endpoints/drive/folders.js82
-rw-r--r--src/api/endpoints/drive/folders/create.js79
-rw-r--r--src/api/endpoints/drive/folders/find.js46
-rw-r--r--src/api/endpoints/drive/folders/show.js41
-rw-r--r--src/api/endpoints/drive/folders/update.js114
-rw-r--r--src/api/endpoints/drive/stream.js85
11 files changed, 765 insertions, 0 deletions
diff --git a/src/api/endpoints/drive/files.js b/src/api/endpoints/drive/files.js
new file mode 100644
index 0000000000..7e8ff59f2a
--- /dev/null
+++ b/src/api/endpoints/drive/files.js
@@ -0,0 +1,82 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFile from '../../models/drive-file';
+import serialize from '../../serializers/drive-file';
+
+/**
+ * Get drive files
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @param {Object} app
+ * @return {Promise<object>}
+ */
+module.exports = (params, user, app) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'limit' parameter
+ let limit = params.limit;
+ if (limit !== undefined && limit !== null) {
+ limit = parseInt(limit, 10);
+
+ // From 1 to 100
+ if (!(1 <= limit && limit <= 100)) {
+ return rej('invalid limit range');
+ }
+ } else {
+ limit = 10;
+ }
+
+ const since = params.since_id || null;
+ const max = params.max_id || null;
+
+ // Check if both of since_id and max_id is specified
+ if (since !== null && max !== null) {
+ return rej('cannot set since_id and max_id');
+ }
+
+ // Get 'folder_id' parameter
+ let folder = params.folder_id;
+ if (folder === undefined || folder === null || folder === 'null') {
+ folder = null;
+ } else {
+ folder = new mongo.ObjectID(folder);
+ }
+
+ // Construct query
+ const sort = {
+ _id: -1
+ };
+ const query = {
+ user_id: user._id,
+ folder_id: folder
+ };
+ if (since !== null) {
+ sort._id = 1;
+ query._id = {
+ $gt: new mongo.ObjectID(since)
+ };
+ } else if (max !== null) {
+ query._id = {
+ $lt: new mongo.ObjectID(max)
+ };
+ }
+
+ // Issue query
+ const files = await DriveFile
+ .find(query, {
+ data: false
+ }, {
+ limit: limit,
+ sort: sort
+ })
+ .toArray();
+
+ // Serialize
+ res(await Promise.all(files.map(async file =>
+ await serialize(file))));
+});
diff --git a/src/api/endpoints/drive/files/create.js b/src/api/endpoints/drive/files/create.js
new file mode 100644
index 0000000000..5966499c59
--- /dev/null
+++ b/src/api/endpoints/drive/files/create.js
@@ -0,0 +1,59 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as fs from 'fs';
+import * as mongo from 'mongodb';
+import File from '../../../models/drive-file';
+import { validateFileName } from '../../../models/drive-file';
+import User from '../../../models/user';
+import serialize from '../../../serializers/drive-file';
+import create from '../../../common/add-file-to-drive';
+
+/**
+ * Create a file
+ *
+ * @param {Object} file
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (file, params, user) =>
+ new Promise(async (res, rej) =>
+{
+ const buffer = fs.readFileSync(file.path);
+ fs.unlink(file.path);
+
+ // Get 'name' parameter
+ let name = file.originalname;
+ if (name !== undefined && name !== null) {
+ name = name.trim();
+ if (name.length === 0) {
+ name = null;
+ } else if (name === 'blob') {
+ name = null;
+ } else if (!validateFileName(name)) {
+ return rej('invalid name');
+ }
+ } else {
+ name = null;
+ }
+
+ // Get 'folder_id' parameter
+ let folder = params.folder_id;
+ if (folder === undefined || folder === null || folder === 'null') {
+ folder = null;
+ } else {
+ folder = new mongo.ObjectID(folder);
+ }
+
+ // Create file
+ const driveFile = await create(user, buffer, name, null, folder);
+
+ // Serialize
+ const fileObj = await serialize(driveFile);
+
+ // Response
+ res(fileObj);
+});
diff --git a/src/api/endpoints/drive/files/find.js b/src/api/endpoints/drive/files/find.js
new file mode 100644
index 0000000000..e4e4c230d2
--- /dev/null
+++ b/src/api/endpoints/drive/files/find.js
@@ -0,0 +1,48 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFile from '../../../models/drive-file';
+import serialize from '../../../serializers/drive-file';
+
+/**
+ * Find a file(s)
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'name' parameter
+ const name = params.name;
+ if (name === undefined || name === null) {
+ return rej('name is required');
+ }
+
+ // Get 'folder_id' parameter
+ let folder = params.folder_id;
+ if (folder === undefined || folder === null || folder === 'null') {
+ folder = null;
+ } else {
+ folder = new mongo.ObjectID(folder);
+ }
+
+ // Issue query
+ const files = await DriveFile
+ .find({
+ name: name,
+ user_id: user._id,
+ folder_id: folder
+ }, {
+ data: false
+ })
+ .toArray();
+
+ // Serialize
+ res(await Promise.all(files.map(async file =>
+ await serialize(file))));
+});
diff --git a/src/api/endpoints/drive/files/show.js b/src/api/endpoints/drive/files/show.js
new file mode 100644
index 0000000000..79b07dace2
--- /dev/null
+++ b/src/api/endpoints/drive/files/show.js
@@ -0,0 +1,40 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFile from '../../../models/drive-file';
+import serialize from '../../../serializers/drive-file';
+
+/**
+ * Show a file
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'file_id' parameter
+ const fileId = params.file_id;
+ if (fileId === undefined || fileId === null) {
+ return rej('file_id is required');
+ }
+
+ const file = await DriveFile
+ .findOne({
+ _id: new mongo.ObjectID(fileId),
+ user_id: user._id
+ }, {
+ data: false
+ });
+
+ if (file === null) {
+ return rej('file-not-found');
+ }
+
+ // Serialize
+ res(await serialize(file));
+});
diff --git a/src/api/endpoints/drive/files/update.js b/src/api/endpoints/drive/files/update.js
new file mode 100644
index 0000000000..bbcb10b42d
--- /dev/null
+++ b/src/api/endpoints/drive/files/update.js
@@ -0,0 +1,89 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFolder from '../../../models/drive-folder';
+import DriveFile from '../../../models/drive-file';
+import { validateFileName } from '../../../models/drive-file';
+import serialize from '../../../serializers/drive-file';
+import event from '../../../event';
+
+/**
+ * Update a file
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'file_id' parameter
+ const fileId = params.file_id;
+ if (fileId === undefined || fileId === null) {
+ return rej('file_id is required');
+ }
+
+ const file = await DriveFile
+ .findOne({
+ _id: new mongo.ObjectID(fileId),
+ user_id: user._id
+ }, {
+ data: false
+ });
+
+ if (file === null) {
+ return rej('file-not-found');
+ }
+
+ // Get 'name' parameter
+ let name = params.name;
+ if (name) {
+ name = name.trim();
+ if (validateFileName(name)) {
+ file.name = name;
+ } else {
+ return rej('invalid file name');
+ }
+ }
+
+ // Get 'folder_id' parameter
+ let folderId = params.folder_id;
+ if (folderId !== undefined && folderId !== 'null') {
+ folderId = new mongo.ObjectID(folderId);
+ }
+
+ let folder = null;
+ if (folderId !== undefined && folderId !== null) {
+ if (folderId === 'null') {
+ file.folder_id = null;
+ } else {
+ folder = await DriveFolder
+ .findOne({
+ _id: folderId,
+ user_id: user._id
+ });
+
+ if (folder === null) {
+ return reject('folder-not-found');
+ }
+
+ file.folder_id = folder._id;
+ }
+ }
+
+ DriveFile.updateOne({ _id: file._id }, {
+ $set: file
+ });
+
+ // Serialize
+ const fileObj = await serialize(file);
+
+ // Response
+ res(fileObj);
+
+ // Publish drive_file_updated event
+ event(user._id, 'drive_file_updated', fileObj);
+});
diff --git a/src/api/endpoints/drive/folders.js b/src/api/endpoints/drive/folders.js
new file mode 100644
index 0000000000..f95a60036f
--- /dev/null
+++ b/src/api/endpoints/drive/folders.js
@@ -0,0 +1,82 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFolder from '../../models/drive-folder';
+import serialize from '../../serializers/drive-folder';
+
+/**
+ * Get drive folders
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @param {Object} app
+ * @return {Promise<object>}
+ */
+module.exports = (params, user, app) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'limit' parameter
+ let limit = params.limit;
+ if (limit !== undefined && limit !== null) {
+ limit = parseInt(limit, 10);
+
+ // From 1 to 100
+ if (!(1 <= limit && limit <= 100)) {
+ return rej('invalid limit range');
+ }
+ } else {
+ limit = 10;
+ }
+
+ const since = params.since_id || null;
+ const max = params.max_id || null;
+
+ // Check if both of since_id and max_id is specified
+ if (since !== null && max !== null) {
+ return rej('cannot set since_id and max_id');
+ }
+
+ // Get 'folder_id' parameter
+ let folder = params.folder_id;
+ if (folder === undefined || folder === null || folder === 'null') {
+ folder = null;
+ } else {
+ folder = new mongo.ObjectID(folder);
+ }
+
+ // Construct query
+ const sort = {
+ created_at: -1
+ };
+ const query = {
+ user_id: user._id,
+ parent_id: folder
+ };
+ if (since !== null) {
+ sort.created_at = 1;
+ query._id = {
+ $gt: new mongo.ObjectID(since)
+ };
+ } else if (max !== null) {
+ query._id = {
+ $lt: new mongo.ObjectID(max)
+ };
+ }
+
+ // Issue query
+ const folders = await DriveFolder
+ .find(query, {
+ data: false
+ }, {
+ limit: limit,
+ sort: sort
+ })
+ .toArray();
+
+ // Serialize
+ res(await Promise.all(folders.map(async folder =>
+ await serialize(folder))));
+});
diff --git a/src/api/endpoints/drive/folders/create.js b/src/api/endpoints/drive/folders/create.js
new file mode 100644
index 0000000000..ba40d1763e
--- /dev/null
+++ b/src/api/endpoints/drive/folders/create.js
@@ -0,0 +1,79 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFolder from '../../../models/drive-folder';
+import { isValidFolderName } from '../../../models/drive-folder';
+import serialize from '../../../serializers/drive-folder';
+import event from '../../../event';
+
+/**
+ * Create drive folder
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'name' parameter
+ let name = params.name;
+ if (name !== undefined && name !== null) {
+ name = name.trim();
+ if (name.length === 0) {
+ name = null;
+ } else if (!isValidFolderName(name)) {
+ return rej('invalid name');
+ }
+ } else {
+ name = null;
+ }
+
+ if (name == null) {
+ name = '無題のフォルダー';
+ }
+
+ // Get 'folder_id' parameter
+ let parentId = params.folder_id;
+ if (parentId === undefined || parentId === null) {
+ parentId = null;
+ } else {
+ parentId = new mongo.ObjectID(parentId);
+ }
+
+ // If the parent folder is specified
+ let parent = null;
+ if (parentId !== null) {
+ parent = await DriveFolder
+ .findOne({
+ _id: parentId,
+ user_id: user._id
+ });
+
+ if (parent === null) {
+ return reject('parent-not-found');
+ }
+ }
+
+ // Create folder
+ const inserted = await DriveFolder.insert({
+ created_at: new Date(),
+ name: name,
+ parent_id: parent !== null ? parent._id : null,
+ user_id: user._id
+ });
+
+ const folder = inserted.ops[0];
+
+ // Serialize
+ const folderObj = await serialize(folder);
+
+ // Response
+ res(folderObj);
+
+ // Publish drive_folder_created event
+ event(user._id, 'drive_folder_created', folderObj);
+});
diff --git a/src/api/endpoints/drive/folders/find.js b/src/api/endpoints/drive/folders/find.js
new file mode 100644
index 0000000000..01805dc910
--- /dev/null
+++ b/src/api/endpoints/drive/folders/find.js
@@ -0,0 +1,46 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFolder from '../../../models/drive-folder';
+import serialize from '../../../serializers/drive-folder';
+
+/**
+ * Find a folder(s)
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'name' parameter
+ const name = params.name;
+ if (name === undefined || name === null) {
+ return rej('name is required');
+ }
+
+ // Get 'parent_id' parameter
+ let parentId = params.parent_id;
+ if (parentId === undefined || parentId === null || parentId === 'null') {
+ parentId = null;
+ } else {
+ parentId = new mongo.ObjectID(parentId);
+ }
+
+ // Issue query
+ const folders = await DriveFolder
+ .find({
+ name: name,
+ user_id: user._id,
+ parent_id: parentId
+ })
+ .toArray();
+
+ // Serialize
+ res(await Promise.all(folders.map(async folder =>
+ await serialize(folder))));
+});
diff --git a/src/api/endpoints/drive/folders/show.js b/src/api/endpoints/drive/folders/show.js
new file mode 100644
index 0000000000..4424361a87
--- /dev/null
+++ b/src/api/endpoints/drive/folders/show.js
@@ -0,0 +1,41 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFolder from '../../../models/drive-folder';
+import serialize from '../../../serializers/drive-folder';
+
+/**
+ * Show a folder
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'folder_id' parameter
+ const folderId = params.folder_id;
+ if (folderId === undefined || folderId === null) {
+ return rej('folder_id is required');
+ }
+
+ // Get folder
+ const folder = await DriveFolder
+ .findOne({
+ _id: new mongo.ObjectID(folderId),
+ user_id: user._id
+ });
+
+ if (folder === null) {
+ return rej('folder-not-found');
+ }
+
+ // Serialize
+ res(await serialize(folder, {
+ includeParent: true
+ }));
+});
diff --git a/src/api/endpoints/drive/folders/update.js b/src/api/endpoints/drive/folders/update.js
new file mode 100644
index 0000000000..ff26a09aae
--- /dev/null
+++ b/src/api/endpoints/drive/folders/update.js
@@ -0,0 +1,114 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFolder from '../../../models/drive-folder';
+import { isValidFolderName } from '../../../models/drive-folder';
+import serialize from '../../../serializers/drive-file';
+import event from '../../../event';
+
+/**
+ * Update a folder
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'folder_id' parameter
+ const folderId = params.folder_id;
+ if (folderId === undefined || folderId === null) {
+ return rej('folder_id is required');
+ }
+
+ // Fetch folder
+ const folder = await DriveFolder
+ .findOne({
+ _id: new mongo.ObjectID(folderId),
+ user_id: user._id
+ });
+
+ if (folder === null) {
+ return rej('folder-not-found');
+ }
+
+ // Get 'name' parameter
+ let name = params.name;
+ if (name) {
+ name = name.trim();
+ if (isValidFolderName(name)) {
+ folder.name = name;
+ } else {
+ return rej('invalid folder name');
+ }
+ }
+
+ // Get 'parent_id' parameter
+ let parentId = params.parent_id;
+ if (parentId !== undefined && parentId !== 'null') {
+ parentId = new mongo.ObjectID(parentId);
+ }
+
+ let parent = null;
+ if (parentId !== undefined && parentId !== null) {
+ if (parentId === 'null') {
+ folder.parent_id = null;
+ } else {
+ // Get parent folder
+ parent = await DriveFolder
+ .findOne({
+ _id: parentId,
+ user_id: user._id
+ });
+
+ if (parent === null) {
+ return rej('parent-folder-not-found');
+ }
+
+ // Check if the circular reference will be occured
+ async function checkCircle(folderId) {
+ // Fetch folder
+ const folder2 = await DriveFolder.findOne({
+ _id: folderId
+ }, {
+ _id: true,
+ parent_id: true
+ });
+
+ if (folder2._id.equals(folder._id)) {
+ return true;
+ } else if (folder2.parent_id) {
+ return await checkCircle(folder2.parent_id);
+ } else {
+ return false;
+ }
+ }
+
+ if (parent.parent_id !== null) {
+ if (await checkCircle(parent.parent_id)) {
+ return rej('detected-circular-definition');
+ }
+ }
+
+ folder.parent_id = parent._id;
+ }
+ }
+
+ // Update
+ DriveFolder.updateOne({ _id: folder._id }, {
+ $set: folder
+ });
+
+ // Serialize
+ const folderObj = await serialize(folder);
+
+ // Response
+ res(folderObj);
+
+ // Publish drive_folder_updated event
+ event(user._id, 'drive_folder_updated', folderObj);
+});
diff --git a/src/api/endpoints/drive/stream.js b/src/api/endpoints/drive/stream.js
new file mode 100644
index 0000000000..0f407f5591
--- /dev/null
+++ b/src/api/endpoints/drive/stream.js
@@ -0,0 +1,85 @@
+'use strict';
+
+/**
+ * Module dependencies
+ */
+import * as mongo from 'mongodb';
+import DriveFile from '../../models/drive-file';
+import serialize from '../../serializers/drive-file';
+
+/**
+ * Get drive stream
+ *
+ * @param {Object} params
+ * @param {Object} user
+ * @return {Promise<object>}
+ */
+module.exports = (params, user) =>
+ new Promise(async (res, rej) =>
+{
+ // Get 'limit' parameter
+ let limit = params.limit;
+ if (limit !== undefined && limit !== null) {
+ limit = parseInt(limit, 10);
+
+ // From 1 to 100
+ if (!(1 <= limit && limit <= 100)) {
+ return rej('invalid limit range');
+ }
+ } else {
+ limit = 10;
+ }
+
+ const since = params.since_id || null;
+ const max = params.max_id || null;
+
+ // Check if both of since_id and max_id is specified
+ if (since !== null && max !== null) {
+ return rej('cannot set since_id and max_id');
+ }
+
+ // Get 'type' parameter
+ let type = params.type;
+ if (type === undefined || type === null) {
+ type = null;
+ } else if (!/^[a-zA-Z\/\-\*]+$/.test(type)) {
+ return rej('invalid type format');
+ } else {
+ type = new RegExp(`^${type.replace(/\*/g, '.+?')}$`);
+ }
+
+ // Construct query
+ const sort = {
+ created_at: -1
+ };
+ const query = {
+ user_id: user._id
+ };
+ if (since !== null) {
+ sort.created_at = 1;
+ query._id = {
+ $gt: new mongo.ObjectID(since)
+ };
+ } else if (max !== null) {
+ query._id = {
+ $lt: new mongo.ObjectID(max)
+ };
+ }
+ if (type !== null) {
+ query.type = type;
+ }
+
+ // Issue query
+ const files = await DriveFile
+ .find(query, {
+ data: false
+ }, {
+ limit: limit,
+ sort: sort
+ })
+ .toArray();
+
+ // Serialize
+ res(await Promise.all(files.map(async file =>
+ await serialize(file))));
+});