5 // TODO: document this script
7 const program = require('commander')
8 const eachSeries = require('async/eachSeries')
9 const series = require('async/series')
10 const waterfall = require('async/waterfall')
11 const fs = require('fs')
12 const path = require('path')
13 const MongoClient = require('mongodb').MongoClient
15 const constants = require('../server/initializers/constants')
18 .option('-mh, --mongo-host [host]', 'MongoDB host', 'localhost')
19 .option('-mp, --mongo-port [weight]', 'MongoDB port', '27017')
20 .option('-md, --mongo-database [dbname]', 'MongoDB database')
23 if (!program.mongoDatabase) {
24 console.error('The mongodb database is mandatory.')
28 const mongoUrl = 'mongodb://' + program.mongoHost + ':' + program.mongoPort + '/' + program.mongoDatabase
29 const dbSequelize = require('../server/initializers/database')
31 console.log('Connecting to ' + mongoUrl)
32 MongoClient.connect(mongoUrl, function (err, dbMongo) {
35 console.log('Connected to ' + mongoUrl)
37 const videoMongo = dbMongo.collection('videos')
38 const userMongo = dbMongo.collection('users')
39 const podMongo = dbMongo.collection('pods')
41 podMongo.count(function (err, podsLength) {
45 console.error('You need to quit friends first.')
49 console.log('Connecting to ' + dbSequelize.sequelize.config.database)
50 dbSequelize.init(true, function (err) {
53 console.log('Connected to SQL database %s.', dbSequelize.sequelize.config.database)
57 dbSequelize.sequelize.sync({ force: true }).asCallback(next)
61 migrateVideos(videoMongo, dbSequelize, next)
65 migrateUsers(userMongo, dbSequelize, next)
68 if (err) console.error(err)
76 // ---------------------------------------------------------------------------
78 function migrateUsers (userMongo, dbSequelize, callback) {
79 userMongo.find().toArray(function (err, mongoUsers) {
80 if (err) return callback(err)
82 eachSeries(mongoUsers, function (mongoUser, callbackEach) {
83 console.log('Migrating user %s', mongoUser.username)
86 username: mongoUser.username,
87 password: mongoUser.password,
94 dbSequelize.User.create(userData, options).asCallback(callbackEach)
99 function migrateVideos (videoMongo, dbSequelize, finalCallback) {
100 videoMongo.find().toArray(function (err, mongoVideos) {
101 if (err) return finalCallback(err)
103 eachSeries(mongoVideos, function (mongoVideo, callbackEach) {
104 console.log('Migrating video %s.', mongoVideo.name)
108 function startTransaction (callback) {
109 dbSequelize.sequelize.transaction().asCallback(function (err, t) {
110 return callback(err, t)
114 function findOrCreatePod (t, callback) {
115 if (mongoVideo.remoteId === null) return callback(null, t, null)
119 host: mongoVideo.podHost
122 host: mongoVideo.podHost
127 dbSequelize.Pod.findOrCreate(query).asCallback(function (err, result) {
128 // [ instance, wasCreated ]
129 const res = result ? result[0] : null
130 return callback(err, t, res)
134 function findOrCreateAuthor (t, pod, callback) {
135 const podId = pod ? pod.id : null
136 const username = mongoVideo.author
150 dbSequelize.Author.findOrCreate(query).asCallback(function (err, result) {
151 // [ instance, wasCreated ]
152 const res = result ? result[0] : null
153 return callback(err, t, res)
157 function findOrCreateTags (t, author, callback) {
158 const tags = mongoVideo.tags
159 const tagInstances = []
161 eachSeries(tags, function (tag, callbackEach) {
172 dbSequelize.Tag.findOrCreate(query).asCallback(function (err, res) {
173 if (err) return callbackEach(err)
175 // res = [ tag, isCreated ]
177 tagInstances.push(tag)
178 return callbackEach()
181 return callback(err, t, author, tagInstances)
185 function createVideoObject (t, author, tagInstances, callback) {
187 name: mongoVideo.name,
188 remoteId: mongoVideo.remoteId,
189 extname: mongoVideo.extname,
190 infoHash: mongoVideo.magnet.infoHash,
191 description: mongoVideo.description,
193 duration: mongoVideo.duration,
194 createdAt: mongoVideo.createdDate
197 const video = dbSequelize.Video.build(videoData)
199 return callback(null, t, tagInstances, video)
202 function moveVideoFile (t, tagInstances, video, callback) {
203 const basePath = constants.CONFIG.STORAGE.VIDEOS_DIR
204 const src = path.join(basePath, mongoVideo._id.toString()) + video.extname
205 const dst = path.join(basePath, video.id) + video.extname
206 fs.rename(src, dst, function (err) {
207 if (err) return callback(err)
209 return callback(null, t, tagInstances, video)
213 function insertVideoIntoDB (t, tagInstances, video, callback) {
218 video.save(options).asCallback(function (err, videoCreated) {
219 return callback(err, t, tagInstances, videoCreated)
223 function associateTagsToVideo (t, tagInstances, video, callback) {
224 const options = { transaction: t }
226 video.setTags(tagInstances, options).asCallback(function (err) {
227 return callback(err, t)
231 ], function (err, t) {
233 // Abort transaction?
236 return callbackEach(err)
239 // Commit transaction
240 return t.commit().asCallback(callbackEach)