summaryrefslogtreecommitdiff
path: root/src/api/common
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2016-12-29 07:49:51 +0900
committersyuilo <syuilotan@yahoo.co.jp>2016-12-29 07:49:51 +0900
commitb3f42e62af698a67c2250533c437569559f1fdf9 (patch)
treecdf6937576e99cccf85e6fa3aa8860a1173c7cfb /src/api/common
downloadsharkey-b3f42e62af698a67c2250533c437569559f1fdf9.tar.gz
sharkey-b3f42e62af698a67c2250533c437569559f1fdf9.tar.bz2
sharkey-b3f42e62af698a67c2250533c437569559f1fdf9.zip
Initial commit :four_leaf_clover:
Diffstat (limited to 'src/api/common')
-rw-r--r--src/api/common/add-file-to-drive.ts149
-rw-r--r--src/api/common/get-friends.ts25
-rw-r--r--src/api/common/notify.ts32
3 files changed, 206 insertions, 0 deletions
diff --git a/src/api/common/add-file-to-drive.ts b/src/api/common/add-file-to-drive.ts
new file mode 100644
index 0000000000..0bd9f34825
--- /dev/null
+++ b/src/api/common/add-file-to-drive.ts
@@ -0,0 +1,149 @@
+import * as mongodb from 'mongodb';
+import * as crypto from 'crypto';
+import * as gm from 'gm';
+const fileType = require('file-type');
+const prominence = require('prominence');
+import DriveFile from '../models/drive-file';
+import DriveFolder from '../models/drive-folder';
+import serialize from '../serializers/drive-file';
+import event from '../event';
+
+/**
+ * Add file to drive
+ *
+ * @param user User who wish to add file
+ * @param fileName File name
+ * @param data Contents
+ * @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,
+ data: Buffer,
+ name: string = null,
+ comment: string = null,
+ folderId: mongodb.ObjectID = null,
+ force: boolean = false
+) => new Promise<any>(async (resolve, reject) => {
+ // File size
+ const size = data.byteLength;
+
+ // File type
+ let mime = 'application/octet-stream';
+ const type = fileType(data);
+ if (type !== null) {
+ mime = type.mime;
+
+ if (name === null) {
+ name = `untitled.${type.ext}`;
+ }
+ } else {
+ if (name === null) {
+ name = 'untitled';
+ }
+ }
+
+ // Generate hash
+ const hash = crypto
+ .createHash('sha256')
+ .update(data)
+ .digest('hex') as string;
+
+ if (!force) {
+ // Check if there is a file with the same hash and same data size (to be safe)
+ const much = await DriveFile.findOne({
+ user_id: user._id,
+ hash: hash,
+ datasize: size
+ });
+
+ if (much !== null) {
+ resolve(much);
+ return;
+ }
+ }
+
+ // Fetch all files to calculate drive usage
+ const files = await DriveFile
+ .find({ user_id: user._id }, {
+ datasize: true,
+ _id: false
+ })
+ .toArray();
+
+ // Calculate drive usage (in byte)
+ const usage = files.map(file => file.datasize).reduce((x, y) => x + y, 0);
+
+ // If usage limit exceeded
+ if (usage + size > user.drive_capacity) {
+ return reject('no-free-space');
+ }
+
+ // If the folder is specified
+ let folder: any = null;
+ if (folderId !== null) {
+ folder = await DriveFolder
+ .findOne({
+ _id: folderId,
+ user_id: user._id
+ });
+
+ if (folder === null) {
+ return reject('folder-not-found');
+ }
+ }
+
+ let properties: any = null;
+
+ // If the file is an image
+ if (/^image\/.*$/.test(mime)) {
+ // Calculate width and height to save in property
+ const g = gm(data, name);
+ const size = await prominence(g).size();
+ properties = {
+ width: size.width,
+ height: size.height
+ };
+ }
+
+ // Create DriveFile document
+ const res = await DriveFile.insert({
+ created_at: new Date(),
+ user_id: user._id,
+ folder_id: folder !== null ? folder._id : null,
+ data: data,
+ datasize: size,
+ type: mime,
+ name: name,
+ comment: comment,
+ hash: hash,
+ properties: properties
+ });
+
+ const file = res.ops[0];
+
+ resolve(file);
+
+ // Serialize
+ const fileObj = await serialize(file);
+
+ // Publish drive_file_created event
+ event(user._id, 'drive_file_created', fileObj);
+
+ // Register to search database
+ if (config.elasticsearch.enable) {
+ const es = require('../../db/elasticsearch');
+ es.index({
+ index: 'misskey',
+ type: 'drive_file',
+ id: file._id.toString(),
+ body: {
+ name: file.name,
+ user_id: user._id.toString()
+ }
+ });
+ }
+});
diff --git a/src/api/common/get-friends.ts b/src/api/common/get-friends.ts
new file mode 100644
index 0000000000..5d50bcdb13
--- /dev/null
+++ b/src/api/common/get-friends.ts
@@ -0,0 +1,25 @@
+import * as mongodb from 'mongodb';
+import Following from '../models/following';
+
+export default async (me: mongodb.ObjectID, includeMe: boolean = true) => {
+ // Fetch relation to other users who the I follows
+ // SELECT followee
+ const myfollowing = await Following
+ .find({
+ follower_id: me,
+ // 削除されたドキュメントは除く
+ deleted_at: { $exists: false }
+ }, {
+ followee_id: true
+ })
+ .toArray();
+
+ // ID list of other users who the I follows
+ const myfollowingIds = myfollowing.map(follow => follow.followee_id);
+
+ if (includeMe) {
+ myfollowingIds.push(me);
+ }
+
+ return myfollowingIds;
+};
diff --git a/src/api/common/notify.ts b/src/api/common/notify.ts
new file mode 100644
index 0000000000..c4c94ee704
--- /dev/null
+++ b/src/api/common/notify.ts
@@ -0,0 +1,32 @@
+import * as mongo from 'mongodb';
+import Notification from '../models/notification';
+import event from '../event';
+import serialize from '../serializers/notification';
+
+export default (
+ notifiee: mongo.ObjectID,
+ notifier: mongo.ObjectID,
+ type: string,
+ content: any
+) => new Promise<any>(async (resolve, reject) => {
+ if (notifiee.equals(notifier)) {
+ return resolve();
+ }
+
+ // Create notification
+ const res = await Notification.insert(Object.assign({
+ created_at: new Date(),
+ notifiee_id: notifiee,
+ notifier_id: notifier,
+ type: type,
+ is_read: false
+ }, content));
+
+ const notification = res.ops[0];
+
+ resolve(notification);
+
+ // Publish notification event
+ event(notifiee, 'notification',
+ await serialize(notification));
+});