From 54a52460613bd5e72e2cdf55234307d9f72b6345 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Tue, 9 Apr 2019 01:03:58 +0900
Subject: [PATCH] Update migrate.ts

---
 src/migrate.ts | 87 ++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 73 insertions(+), 14 deletions(-)

diff --git a/src/migrate.ts b/src/migrate.ts
index 64d7d6fd8..eafb28969 100644
--- a/src/migrate.ts
+++ b/src/migrate.ts
@@ -1,20 +1,48 @@
-import mongo from 'monk';
+import monk from 'monk';
+import * as mongo from 'mongodb';
+import * as fs from 'fs';
+import * as uuid from 'uuid';
 import config from './config';
 import { initDb } from './db/postgre';
 import { User } from './models/entities/user';
 import { getRepository } from 'typeorm';
 import generateUserToken from './server/api/common/generate-native-user-token';
 import { DriveFile } from './models/entities/drive-file';
+import { InternalStorage } from './services/drive/internal-storage';
+import { createTemp } from './misc/create-temp';
 
 const u = (config as any).mongodb.user ? encodeURIComponent((config as any).mongodb.user) : null;
 const p = (config as any).mongodb.pass ? encodeURIComponent((config as any).mongodb.pass) : null;
 
 const uri = `mongodb://${u && p ? `${u}:${p}@` : ''}${(config as any).mongodb.host}:${(config as any).mongodb.port}/${(config as any).mongodb.db}`;
 
-const db = mongo(uri);
+const db = monk(uri);
+let mdb: mongo.Db;
+
+const nativeDbConn = async (): Promise<mongo.Db> => {
+	if (mdb) return mdb;
+
+	const db = await ((): Promise<mongo.Db> => new Promise((resolve, reject) => {
+		mongo.MongoClient.connect(uri, { useNewUrlParser: true }, (e: Error, client: any) => {
+			if (e) return reject(e);
+			resolve(client.db((config as any).mongo.db));
+		});
+	}))();
+
+	mdb = db;
+
+	return db;
+};
 
 const _User = db.get<any>('users');
 const _DriveFile = db.get<any>('driveFiles.files');
+const getDriveFileBucket = async (): Promise<mongo.GridFSBucket> => {
+	const db = await nativeDbConn();
+	const bucket = new mongo.GridFSBucket(db, {
+		bucketName: 'driveFiles'
+	});
+	return bucket;
+};
 
 async function main() {
 	await initDb();
@@ -38,8 +66,8 @@ async function main() {
 			autoAcceptFollowed: true,
 			autoWatch: false,
 			name: user.name,
-			location: user.profile.location,
-			birthday: user.profile.birthday,
+			location: user.profile ? user.profile.location : null,
+			birthday: user.profile ? user.profile.birthday : null,
 			followersCount: user.followersCount,
 			followingCount: user.followingCount,
 			notesCount: user.notesCount,
@@ -59,17 +87,48 @@ async function main() {
 		const file = await _DriveFile.findOne({}, {
 			skip: i
 		});
-		await DriveFiles.save({
-			id: file._id.toHexString(),
-			userId: file.userId.toHexString(),
-			createdAt: file.uploadDate || new Date(),
-			md5: file.md5,
-			name: file.filename,
-			type: file.contentType,
-			properties: file.metadata.properties,
-			size: file.length,
+		const user = await _User.findOne({
+			_id: file.metadata.userId
 		});
-		console.log(`USER (${i + 1}/${allDriveFilesCount}) ${file._id} DONE`);
+		if (file.metadata.storage && file.metadata.storage.key) { // when object storage
+			await DriveFiles.save({
+				id: file._id.toHexString(),
+				userId: user._id.toHexString(),
+				userHost: user.host,
+				createdAt: file.uploadDate || new Date(),
+				md5: file.md5,
+				name: file.filename,
+				type: file.contentType,
+				properties: file.metadata.properties,
+				size: file.length,
+				url: file.metadata.url,
+				uri: file.metadata.uri,
+				accessKey: file.metadata.storage.key
+			});
+		} else {
+			const [temp, clean] = await createTemp();
+			const bucket = await getDriveFileBucket();
+			const readable = bucket.openDownloadStream(file._id);
+			fs.writeFileSync(temp, readable);
+			const key = uuid.v4();
+			const url = InternalStorage.saveFromPath(key, temp);
+			await DriveFiles.save({
+				id: file._id.toHexString(),
+				userId: user._id.toHexString(),
+				userHost: user.host,
+				createdAt: file.uploadDate || new Date(),
+				md5: file.md5,
+				name: file.filename,
+				type: file.contentType,
+				properties: file.metadata.properties,
+				size: file.length,
+				url: url,
+				uri: file.metadata.uri,
+				accessKey: key
+			});
+			clean();
+		}
+		console.log(`DRIVEFILE (${i + 1}/${allDriveFilesCount}) ${file._id} DONE`);
 	}
 }