Merge branch 'master' into webseed-merged
authorChocobozzz <florian.bigard@gmail.com>
Sun, 2 Oct 2016 13:39:09 +0000 (15:39 +0200)
committerChocobozzz <florian.bigard@gmail.com>
Sun, 2 Oct 2016 13:39:09 +0000 (15:39 +0200)
14 files changed:
1  2 
.gitignore
client/src/app/shared/auth/auth.service.ts
client/src/app/videos/video-watch/video-watch.component.ts
config/default.yaml
config/test-1.yaml
config/test-2.yaml
config/test-3.yaml
config/test-4.yaml
config/test-5.yaml
config/test-6.yaml
package.json
server.js
server/initializers/constants.js
server/models/video.js

diff --cc .gitignore
index ec5b4b2f03e602cd8f4fe84d055fa86263d7c1d4,18a2e808d45b8df3bae5bf6edf221202de316917..7ca89dca8532625749c8e09c466040913187a17b
@@@ -14,4 -14,7 +14,11 @@@ upload
  thumbnails
  config/production.yaml
  ffmpeg
++<<<<<<< HEAD
 +torrents
++=======
+ .tags
+ *.sublime-project
+ *.sublime-workspace
+ torrents/
++>>>>>>> master
index 584298fff585605b69f11dc9ebb9ad85273a12b7,c57486d9ae3e048d9f72eaeaf91e760c9b97ceb6..a30c79c8685edafb59aa2bbdc6ba2d64afd17789
@@@ -106,9 -123,9 +123,10 @@@ export class AuthService 
    logout() {
      // TODO: make an HTTP request to revoke the tokens
      this.user = null;
-     User.flush();
 +
-     this.setStatus(AuthStatus.LoggedIn);
+     AuthUser.flush();
+     this.setStatus(AuthStatus.LoggedOut);
    }
  
    refreshAccessToken() {
index 9a8a57879340980f4db1477cd910ec8bfa88fb8d,d32d3e17b26ff464b2a4f6dcf9a35ea9b9916148..b44be31b0ab2ad92fd0295a161e976e5032901fc
@@@ -17,10 -17,6 +17,7 @@@ storage
    uploads: 'uploads/'
    logs: 'logs/'
    thumbnails: 'thumbnails/'
 +  torrents: 'torrents/'
  
- network:
-   friends: []
  electron:
    debug: false
index 0998eaea1ae59221d589ee067822683f0e62dc01,0a8dd39379d05d5e8d0dd58ed75b82505efcec7e..a59566cc4f3362154565ec7817ac611b2835ade4
@@@ -14,8 -14,3 +14,4 @@@ storage
    uploads: 'test1/uploads/'
    logs: 'test1/logs/'
    thumbnails: 'test1/thumbnails/'
- network:
-   friends:
-     - 'http://localhost:9002'
 +  torrents: 'test1/torrents/'
index ec2cff811b357ff43cfee9d01f4a5a826f4511df,40f410559b7b2ea58d0f310e534b7e220e3bb12f..1b937898feac428179aee63d1b0f7e5eb87b8112
@@@ -14,8 -14,3 +14,4 @@@ storage
    uploads: 'test2/uploads/'
    logs: 'test2/logs/'
    thumbnails: 'test2/thumbnails/'
- network:
-   friends:
-     - 'http://localhost:9003'
 +  torrents: 'test2/torrents/'
index 24f5533e0a48f0bc77ee607a94ce694ce51a65e4,87b33522895a519080384e2e666e9de6dba03363..e522c13e7fcaa25d1c10b89172d0ce5bed350ea5
@@@ -14,8 -14,3 +14,4 @@@ storage
    uploads: 'test3/uploads/'
    logs: 'test3/logs/'
    thumbnails: 'test3/thumbnails/'
- network:
-   friends:
-     - 'http://localhost:9001'
 +  torrents: 'test3/torrents/'
index 1f884dbf2114b338ebd261e34113eabcffdeee36,22abc0a583b7c0bab5dee382bd70ae6565b4bdb6..e30cd79789490fba263be80f8f70ba9b263a6618
@@@ -14,8 -14,3 +14,4 @@@ storage
    uploads: 'test4/uploads/'
    logs: 'test4/logs/'
    thumbnails: 'test4/thumbnails/'
- network:
-   friends:
-     - 'http://localhost:9002'
 +  torrents: 'test4/torrents/'
index 08ed9f06870023cd28e0dc4699f2ed82f7765879,af561999496866327e2a8b3ae9ad67342177fe16..3a54599f5555761d5a1a506e91a0d09b93be3692
@@@ -14,9 -14,3 +14,4 @@@ storage
    uploads: 'test5/uploads/'
    logs: 'test5/logs/'
    thumbnails: 'test5/thumbnails/'
- network:
-   friends:
-     - 'http://localhost:9001'
-     - 'http://localhost:9004'
 +  torrents: 'test5/torrents/'
index a57784cca484d6282d29faa5723ab1253bee2edf,5b8bf306b4a408d9d2dde6da59821f3061135ec0..31608add2ac32fd42bede89980bb00ee25f55d33
@@@ -14,10 -14,3 +14,4 @@@ storage
    uploads: 'test6/uploads/'
    logs: 'test6/logs/'
    thumbnails: 'test6/thumbnails/'
- network:
-   friends:
-     - 'http://localhost:9001'
-     - 'http://localhost:9002'
-     - 'http://localhost:9003'
 +  torrents: 'test6/torrents/'
diff --cc package.json
index 63d01437621dab774d44561ec27a5948c6b3408a,27958dd43eafc51b24db27f6ebfe6c09ad7117bd..59c7a4332cae749448fe5e328458dbcb65d2f4ef
@@@ -59,8 -60,8 +60,7 @@@
      "request": "^2.57.0",
      "request-replay": "^1.0.2",
      "scripty": "^1.5.0",
-     "segfault-handler": "^1.0.0",
      "ursa": "^0.9.1",
 -    "webtorrent": "^0.96.0",
      "winston": "^2.1.1",
      "ws": "^1.1.1"
    },
diff --cc server.js
index 0033ed1dbb70e25d10cb3a0957373d6da2063788,ca275ccec5df51351636b28951381cede16e8b5a..5feb214764f183f10cd7f8b58e5407ff3ce0a98c
+++ b/server.js
@@@ -32,9 -32,13 +32,10 @@@ if (miss.length !== 0) 
  // ----------- PeerTube modules -----------
  const customValidators = require('./server/helpers/custom-validators')
  const installer = require('./server/initializers/installer')
+ const migrator = require('./server/initializers/migrator')
  const mongoose = require('mongoose')
  const routes = require('./server/controllers')
 -const utils = require('./server/helpers/utils')
 -const webtorrent = require('./server/lib/webtorrent')
  const Request = mongoose.model('Request')
 -const Video = mongoose.model('Video')
  
  // Get configurations
  const port = config.get('listen.port')
@@@ -125,14 -125,38 +129,19 @@@ app.use(function (err, req, res, next) 
  installer.installApplication(function (err) {
    if (err) throw err
  
-   // ----------- Make the server listening -----------
-   server.listen(port, function () {
-     // Activate the pool requests
-     Request.activate()
+   // Run the migration scripts if needed
+   migrator.migrate(function (err) {
+     if (err) throw err
 -    // Create/activate the webtorrent module
 -    webtorrent.create(function () {
 -      function cleanForExit () {
 -        utils.cleanForExit(webtorrent.app)
 -      }
 -
 -      function exitGracefullyOnSignal () {
 -        process.exit(-1)
 -      }
 -
 -      process.on('exit', cleanForExit)
 -      process.on('SIGINT', exitGracefullyOnSignal)
 -      process.on('SIGTERM', exitGracefullyOnSignal)
 -
 -      // ----------- Make the server listening -----------
 -      server.listen(port, function () {
 -        // Activate the pool requests
 -        Request.activate()
 -
 -        Video.seedAllExisting(function (err) {
 -          if (err) throw err
 -
 -          logger.info('Seeded all the videos')
 -          logger.info('Server listening on port %d', port)
 -          app.emit('ready')
 -        })
 -      })
++    // ----------- Make the server listening -----------
++    server.listen(port, function () {
++      // Activate the pool requests
++      Request.activate()
 +
-     logger.info('Seeded all the videos')
-     logger.info('Server listening on port %d', port)
-     app.emit('ready')
++      logger.info('Seeded all the videos')
++      logger.info('Server listening on port %d', port)
++      app.emit('ready')
+     })
    })
  })
  
index e0ea188af77ca549bac07b09d06fbecb642390ab,b1d0333771fc429b487814217e8b1a2a031bd02f..be2e3e9439bcf9bc6d8354a8ded910968b21814d
@@@ -35,67 -117,58 +117,62 @@@ const REQUESTS_LIMIT = 1
  // Number of requests to retry for replay requests module
  const RETRY_REQUESTS = 5
  
- // Sortable columns per schema
- const SEARCHABLE_COLUMNS = {
-   VIDEOS: [ 'name', 'magnetUri', 'podUrl', 'author', 'tags' ]
- }
- // Seeds in parallel we send to electron when "seed all"
- // Once a video is in seeding state we seed another video etc
- const SEEDS_IN_PARALLEL = 3
+ // ---------------------------------------------------------------------------
  
- // Sortable columns per schema
- const SORTABLE_COLUMNS = {
-   VIDEOS: [ 'name', '-name', 'duration', '-duration', 'createdDate', '-createdDate' ]
- }
+ // Password encryption
+ const BCRYPT_SALT_SIZE = 10
  
 +// Express static paths (router)
 +const STATIC_PATHS = {
 +  THUMBNAILS: '/static/thumbnails',
 +  TORRENTS: '/static/torrents/',
 +  WEBSEED: '/static/webseed/'
 +}
 +
  // Videos thumbnail size
  const THUMBNAILS_SIZE = '200x110'
  
- const VIDEOS_CONSTRAINTS_FIELDS = {
-   NAME: { min: 3, max: 50 }, // Length
-   DESCRIPTION: { min: 3, max: 250 }, // Length
-   MAGNET_URI: { min: 10 }, // Length
-   DURATION: { min: 1, max: 7200 }, // Number
-   AUTHOR: { min: 3, max: 20 }, // Length
-   TAGS: { min: 1, max: 3 }, // Number of total tags
-   TAG: { min: 2, max: 10 }, // Length
-   THUMBNAIL: { min: 2, max: 30 },
-   THUMBNAIL64: { min: 0, max: 20000 } // Bytes
 -// Path for access to thumbnails with express router
 -const THUMBNAILS_STATIC_PATH = '/static/thumbnails'
 -
+ const USER_ROLES = {
+   ADMIN: 'admin',
+   USER: 'user'
  }
  
+ // Seeds in parallel we send to electron when "seed all"
+ // Once a video is in seeding state we seed another video etc
+ const SEEDS_IN_PARALLEL = 3
+ // ---------------------------------------------------------------------------
  // Special constants for a test instance
  if (isTestInstance() === true) {
+   CONSTRAINTS_FIELDS.VIDEOS.DURATION.max = 14
    FRIEND_SCORE.BASE = 20
-   INTERVAL = 10000
-   VIDEOS_CONSTRAINTS_FIELDS.DURATION.max = 14
+   REQUESTS_INTERVAL = 10000
  }
  
  // ---------------------------------------------------------------------------
  
  module.exports = {
-   API_VERSION: API_VERSION,
-   FRIEND_SCORE: FRIEND_SCORE,
-   INTERVAL: INTERVAL,
-   OAUTH_LIFETIME: OAUTH_LIFETIME,
-   PAGINATION_COUNT_DEFAULT: PAGINATION_COUNT_DEFAULT,
-   PODS_SCORE: PODS_SCORE,
-   REQUESTS_IN_PARALLEL: REQUESTS_IN_PARALLEL,
-   REQUESTS_LIMIT: REQUESTS_LIMIT,
-   RETRY_REQUESTS: RETRY_REQUESTS,
-   SEARCHABLE_COLUMNS: SEARCHABLE_COLUMNS,
-   SEEDS_IN_PARALLEL: SEEDS_IN_PARALLEL,
-   SORTABLE_COLUMNS: SORTABLE_COLUMNS,
-   STATIC_PATHS: STATIC_PATHS,
-   THUMBNAILS_SIZE: THUMBNAILS_SIZE,
-   VIDEOS_CONSTRAINTS_FIELDS: VIDEOS_CONSTRAINTS_FIELDS
+   API_VERSION,
+   BCRYPT_SALT_SIZE,
+   CONFIG,
+   CONSTRAINTS_FIELDS,
+   FRIEND_SCORE,
+   LAST_MONGO_SCHEMA_VERSION,
+   MONGO_MIGRATION_SCRIPTS,
+   OAUTH_LIFETIME,
+   PAGINATION_COUNT_DEFAULT,
+   PODS_SCORE,
+   REQUESTS_IN_PARALLEL,
+   REQUESTS_INTERVAL,
+   REQUESTS_LIMIT,
+   RETRY_REQUESTS,
+   SEARCHABLE_COLUMNS,
+   SEEDS_IN_PARALLEL,
+   SORTABLE_COLUMNS,
++  STATIC_PATHS,
+   THUMBNAILS_SIZE,
 -  THUMBNAILS_STATIC_PATH,
+   USER_ROLES
  }
  
  // ---------------------------------------------------------------------------
index 14e0df6f26cb96873264c276ffe9781782992a04,b9999c8f66f0c4fd000e96455692a3cba6975095..7d073cffa97cb33b43b03246909f7a6fe4e58b53
@@@ -11,17 -8,11 +11,18 @@@ const magnet = require('magnet-uri'
  const mongoose = require('mongoose')
  
  const constants = require('../initializers/constants')
- const customValidators = require('../helpers/custom-validators')
+ const customVideosValidators = require('../helpers/custom-validators').videos
  const logger = require('../helpers/logger')
+ const modelUtils = require('./utils')
  const utils = require('../helpers/utils')
 -const webtorrent = require('../lib/webtorrent')
 +
 +const http = config.get('webserver.https') === true ? 'https' : 'http'
 +const host = config.get('webserver.host')
 +const port = config.get('webserver.port')
 +const uploadsDir = pathUtils.join(__dirname, '..', '..', config.get('storage.uploads'))
 +const thumbnailsDir = pathUtils.join(__dirname, '..', '..', config.get('storage.thumbnails'))
 +const torrentsDir = pathUtils.join(__dirname, '..', '..', config.get('storage.torrents'))
 +const webseedBaseUrl = http + '://' + host + ':' + port + constants.STATIC_PATHS.WEBSEED
  
  // ---------------------------------------------------------------------------
  
@@@ -62,14 -53,16 +63,15 @@@ VideoSchema.methods = 
  }
  
  VideoSchema.statics = {
-   getDurationFromFile: getDurationFromFile,
-   list: list,
-   listByUrlAndMagnet: listByUrlAndMagnet,
-   listByUrls: listByUrls,
-   listOwned: listOwned,
-   listRemotes: listRemotes,
-   load: load,
-   search: search
+   getDurationFromFile,
+   listForApi,
+   listByUrlAndMagnet,
+   listByUrls,
+   listOwned,
+   listOwnedByAuthor,
+   listRemotes,
+   load,
 -  search,
 -  seedAllExisting
++  search
  }
  
  VideoSchema.pre('remove', function (next) {
@@@ -101,25 -94,12 +103,25 @@@ VideoSchema.pre('save', function (next
    const tasks = []
  
    if (video.isOwned()) {
-     const videoPath = pathUtils.join(uploadsDir, video.filename)
-     this.podUrl = http + '://' + host + ':' + port
+     const videoPath = pathUtils.join(constants.CONFIG.STORAGE.UPLOAD_DIR, video.filename)
+     this.podUrl = constants.CONFIG.WEBSERVER.URL
  
      tasks.push(
 +      // TODO: refractoring
        function (callback) {
 -        seed(videoPath, callback)
 +        createTorrent(videoPath, { announceList: [ [ 'ws://' + host + ':' + port + '/tracker/socket' ] ], urlList: [ webseedBaseUrl + video.filename ] }, function (err, torrent) {
 +          if (err) return callback(err)
 +
 +          fs.writeFile(torrentsDir + video.filename + '.torrent', torrent, function (err) {
 +            if (err) return callback(err)
 +
 +            const parsedTorrent = parseTorrent(torrent)
 +            parsedTorrent.xs = video.podUrl + constants.STATIC_PATHS.TORRENTS + video.filename + '.torrent'
 +            video.magnetUri = magnet.encode(parsedTorrent)
 +
 +            callback(null)
 +          })
 +        })
        },
        function (callback) {
          createThumbnail(videoPath, callback)
@@@ -242,32 -227,24 +248,13 @@@ function search (value, field, start, c
      query[field] = new RegExp(value)
    }
  
-   findWithCount.call(this, query, start, count, sort, callback)
+   modelUtils.listForApiWithCount.call(this, query, start, count, sort, callback)
  }
  
 -function seedAllExisting (callback) {
 -  listOwned.call(this, function (err, videos) {
 -    if (err) return callback(err)
 -
 -    eachLimit(videos, constants.SEEDS_IN_PARALLEL, function (video, callbackEach) {
 -      const videoPath = pathUtils.join(constants.CONFIG.STORAGE.UPLOAD_DIR, video.filename)
 -      seed(videoPath, callbackEach)
 -    }, callback)
 -  })
 -}
 -
  // ---------------------------------------------------------------------------
  
- function findWithCount (query, start, count, sort, callback) {
-   const self = this
-   parallel([
-     function (asyncCallback) {
-       self.find(query).skip(start).limit(count).sort(sort).exec(asyncCallback)
-     },
-     function (asyncCallback) {
-       self.count(query, asyncCallback)
-     }
-   ], function (err, results) {
-     if (err) return callback(err)
-     const videos = results[0]
-     const totalVideos = results[1]
-     return callback(null, videos, totalVideos)
-   })
- }
  function removeThumbnail (video, callback) {
-   fs.unlink(thumbnailsDir + video.thumbnail, callback)
+   fs.unlink(constants.CONFIG.STORAGE.THUMBNAILS_DIR + video.thumbnail, callback)
  }
  
  function removeFile (video, callback) {