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 => { + if (mdb) return mdb; + + const db = await ((): Promise => 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('users'); const _DriveFile = db.get('driveFiles.files'); +const getDriveFileBucket = async (): Promise => { + 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`); } }