]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Merge branch 'feature/webtorrent-disabling' into develop
authorChocobozzz <me@florianbigard.com>
Wed, 17 Oct 2018 08:48:56 +0000 (10:48 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 17 Oct 2018 08:48:56 +0000 (10:48 +0200)
12 files changed:
client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.html
client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
client/src/app/core/auth/auth-user.model.ts
client/src/app/shared/users/user.model.ts
client/src/assets/player/peertube-player-local-storage.ts
client/src/assets/player/peertube-videojs-plugin.ts
server/controllers/api/users/me.ts
server/helpers/custom-validators/users.ts
server/initializers/constants.ts
server/initializers/migrations/0280-webtorrent-policy-user.ts [new file with mode: 0644]
server/models/account/user.ts
shared/models/users/user-update-me.model.ts

index 96629940f9cd4f907b4a9814f93bcfe98ed86a7d..8be8a66ccb7ba650db3b143a292fda4dd6b286ae 100644 (file)
     </div>
   </div>
 
+  <my-peertube-checkbox
+    inputName="webTorrentEnabled" formControlName="webTorrentEnabled"
+    i18n-labelText labelText="Use WebTorrent to exchange parts of the video with others"
+  ></my-peertube-checkbox>
+
   <my-peertube-checkbox
     inputName="autoPlayVideo" formControlName="autoPlayVideo"
     i18n-labelText labelText="Automatically plays video"
index 7089b20572234249790eccb29329a522462fa171..6c9a7ce75aaa6f80ab83155c3739c30948301944 100644 (file)
@@ -29,12 +29,14 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
   ngOnInit () {
     this.buildForm({
       nsfwPolicy: null,
+      webTorrentEnabled: null,
       autoPlayVideo: null
     })
 
     this.userInformationLoaded.subscribe(() => {
       this.form.patchValue({
         nsfwPolicy: this.user.nsfwPolicy,
+        webTorrentEnabled: this.user.webTorrentEnabled,
         autoPlayVideo: this.user.autoPlayVideo === true
       })
     })
@@ -42,9 +44,11 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
 
   updateDetails () {
     const nsfwPolicy = this.form.value['nsfwPolicy']
+    const webTorrentEnabled = this.form.value['webTorrentEnabled']
     const autoPlayVideo = this.form.value['autoPlayVideo']
     const details: UserUpdateMe = {
       nsfwPolicy,
+      webTorrentEnabled,
       autoPlayVideo
     }
 
index 74ed1c5806c5b0730fa957a8052257c4c4f818b8..acd13d9c560ab435b78bad1de1020ec5f4c46909 100644 (file)
@@ -72,6 +72,7 @@ export class AuthUser extends User {
     EMAIL: 'email',
     USERNAME: 'username',
     NSFW_POLICY: 'nsfw_policy',
+    WEBTORRENT_ENABLED: 'peertube-videojs-' + 'webtorrent_enabled',
     AUTO_PLAY_VIDEO: 'auto_play_video'
   }
 
@@ -87,6 +88,7 @@ export class AuthUser extends User {
           email: peertubeLocalStorage.getItem(this.KEYS.EMAIL),
           role: parseInt(peertubeLocalStorage.getItem(this.KEYS.ROLE), 10) as UserRole,
           nsfwPolicy: peertubeLocalStorage.getItem(this.KEYS.NSFW_POLICY) as NSFWPolicyType,
+          webTorrentEnabled: peertubeLocalStorage.getItem(this.KEYS.WEBTORRENT_ENABLED) === 'true',
           autoPlayVideo: peertubeLocalStorage.getItem(this.KEYS.AUTO_PLAY_VIDEO) === 'true'
         },
         Tokens.load()
@@ -101,6 +103,7 @@ export class AuthUser extends User {
     peertubeLocalStorage.removeItem(this.KEYS.ID)
     peertubeLocalStorage.removeItem(this.KEYS.ROLE)
     peertubeLocalStorage.removeItem(this.KEYS.NSFW_POLICY)
+    peertubeLocalStorage.removeItem(this.KEYS.WEBTORRENT_ENABLED)
     peertubeLocalStorage.removeItem(this.KEYS.AUTO_PLAY_VIDEO)
     peertubeLocalStorage.removeItem(this.KEYS.EMAIL)
     Tokens.flush()
@@ -138,6 +141,7 @@ export class AuthUser extends User {
     peertubeLocalStorage.setItem(AuthUser.KEYS.EMAIL, this.email)
     peertubeLocalStorage.setItem(AuthUser.KEYS.ROLE, this.role.toString())
     peertubeLocalStorage.setItem(AuthUser.KEYS.NSFW_POLICY, this.nsfwPolicy.toString())
+    peertubeLocalStorage.setItem(AuthUser.KEYS.WEBTORRENT_ENABLED, JSON.stringify(this.webTorrentEnabled))
     peertubeLocalStorage.setItem(AuthUser.KEYS.AUTO_PLAY_VIDEO, JSON.stringify(this.autoPlayVideo))
     this.tokens.save()
   }
index 877f1bf3a44ba0b438ced30316b651d238ca7441..7c840ffa7054c9109bff031e148a91a18ec988e1 100644 (file)
@@ -18,6 +18,7 @@ export type UserConstructorHash = {
   videoQuota?: number,
   videoQuotaDaily?: number,
   nsfwPolicy?: NSFWPolicyType,
+  webTorrentEnabled?: boolean,
   autoPlayVideo?: boolean,
   createdAt?: Date,
   account?: AccountServerModel,
@@ -32,6 +33,7 @@ export class User implements UserServerModel {
   email: string
   role: UserRole
   nsfwPolicy: NSFWPolicyType
+  webTorrentEnabled: boolean
   autoPlayVideo: boolean
   videoQuota: number
   videoQuotaDaily: number
@@ -52,6 +54,7 @@ export class User implements UserServerModel {
     this.videoQuota = hash.videoQuota
     this.videoQuotaDaily = hash.videoQuotaDaily
     this.nsfwPolicy = hash.nsfwPolicy
+    this.webTorrentEnabled = hash.webTorrentEnabled
     this.autoPlayVideo = hash.autoPlayVideo
     this.createdAt = hash.createdAt
     this.blocked = hash.blocked
index dac54c5a4d5f2f96499508e2b491017b8f98d265..3ac5fe58a4c9f3636ce87e4ac3760805d686bf34 100644 (file)
@@ -10,6 +10,13 @@ function getStoredVolume () {
   return undefined
 }
 
+function getStoredWebTorrentEnabled (): boolean {
+  const value = getLocalStorage('webtorrent_enabled')
+  if (value !== null && value !== undefined) return value === 'true'
+
+  return false
+}
+
 function getStoredMute () {
   const value = getLocalStorage('mute')
   if (value !== null && value !== undefined) return value === 'true'
@@ -56,6 +63,7 @@ function getAverageBandwidthInStore () {
 
 export {
   getStoredVolume,
+  getStoredWebTorrentEnabled,
   getStoredMute,
   getStoredTheater,
   saveVolumeInStore,
index 2330f476f0df03936c5f7c89cbcee5539a000c67..5cebab6d9a65f03f98c01827565bdfb1a5f62c0d 100644 (file)
@@ -11,11 +11,18 @@ import {
   getAverageBandwidthInStore,
   getStoredMute,
   getStoredVolume,
+  getStoredWebTorrentEnabled,
   saveAverageBandwidth,
   saveMuteInStore,
   saveVolumeInStore
 } from './peertube-player-local-storage'
 
+type PlayOptions = {
+  forcePlay?: boolean,
+  seek?: number,
+  delay?: number
+}
+
 const Plugin: VideoJSComponentInterface = videojs.getPlugin('plugin')
 class PeerTubePlugin extends Plugin {
   private readonly playerElement: HTMLVideoElement
@@ -64,6 +71,7 @@ class PeerTubePlugin extends Plugin {
   private autoResolution = true
   private forbidAutoResolution = false
   private isAutoResolutionObservation = false
+  private playerRefusedP2P = false
 
   private videoViewInterval
   private torrentInfoInterval
@@ -80,6 +88,7 @@ class PeerTubePlugin extends Plugin {
 
     // Disable auto play on iOS
     this.autoplay = options.autoplay && this.isIOS() === false
+    this.playerRefusedP2P = !getStoredWebTorrentEnabled()
 
     this.startTime = timeToInt(options.startTime)
     this.videoFiles = options.videoFiles
@@ -178,6 +187,15 @@ class PeerTubePlugin extends Plugin {
     const previousVideoFile = this.currentVideoFile
     this.currentVideoFile = videoFile
 
+    // Don't try on iOS that does not support MediaSource
+    // Or don't use P2P if webtorrent is disabled
+    if (this.isIOS() || this.playerRefusedP2P) {
+      return this.fallbackToHttp(options, () => {
+        this.player.playbackRate(oldPlaybackRate)
+        return done()
+      })
+    }
+
     this.addTorrent(this.currentVideoFile.magnetUri, previousVideoFile, options, () => {
       this.player.playbackRate(oldPlaybackRate)
       return done()
@@ -248,11 +266,7 @@ class PeerTubePlugin extends Plugin {
   private addTorrent (
     magnetOrTorrentUrl: string,
     previousVideoFile: VideoFile,
-    options: {
-      forcePlay?: boolean,
-      seek?: number,
-      delay?: number
-    },
+    options: PlayOptions,
     done: Function
   ) {
     console.log('Adding ' + magnetOrTorrentUrl + '.')
@@ -288,7 +302,7 @@ class PeerTubePlugin extends Plugin {
         renderVideo(torrent.files[ 0 ], this.playerElement, renderVideoOptions, (err, renderer) => {
           this.renderer = renderer
 
-          if (err) return this.fallbackToHttp(done)
+          if (err) return this.fallbackToHttp(options, done)
 
           return this.tryToPlay(err => {
             if (err) return done(err)
@@ -296,7 +310,7 @@ class PeerTubePlugin extends Plugin {
             if (options.seek) this.seek(options.seek)
             if (options.forcePlay === false && paused === true) this.player.pause()
 
-            return done(err)
+            return done()
           })
         })
       }, options.delay || 0)
@@ -432,12 +446,6 @@ class PeerTubePlugin extends Plugin {
       return this.updateVideoFile(undefined, { forcePlay: true, seek: this.startTime })
     }
 
-    // Don't try on iOS that does not support MediaSource
-    if (this.isIOS()) {
-      this.currentVideoFile = this.pickAverageVideoFile()
-      return this.fallbackToHttp(undefined, false)
-    }
-
     // Proxy first play
     const oldPlay = this.player.play.bind(this.player)
     this.player.play = () => {
@@ -567,7 +575,9 @@ class PeerTubePlugin extends Plugin {
     return fetch(url, { method: 'PUT', body, headers })
   }
 
-  private fallbackToHttp (done?: Function, play = true) {
+  private fallbackToHttp (options: PlayOptions, done?: Function) {
+    const paused = this.player.paused()
+
     this.disableAutoResolution(true)
 
     this.flushVideoFile(this.currentVideoFile, true)
@@ -579,9 +589,15 @@ class PeerTubePlugin extends Plugin {
     const httpUrl = this.currentVideoFile.fileUrl
     this.player.src = this.savePlayerSrcFunction
     this.player.src(httpUrl)
-    if (play) this.tryToPlay()
 
-    if (done) return done()
+    return this.tryToPlay(err => {
+      if (err && done) return done(err)
+
+      if (options.seek) this.seek(options.seek)
+      if (options.forcePlay === false && paused === true) this.player.pause()
+
+      if (done) return done()
+    })
   }
 
   private handleError (err: Error | string) {
index ebe6681102554fdfda7c3ccb45c55d92b9d2c234..82299747dab159ca51b839eefdba2090d3249d22 100644 (file)
@@ -328,6 +328,7 @@ async function updateMe (req: express.Request, res: express.Response, next: expr
   if (body.password !== undefined) user.password = body.password
   if (body.email !== undefined) user.email = body.email
   if (body.nsfwPolicy !== undefined) user.nsfwPolicy = body.nsfwPolicy
+  if (body.webTorrentEnabled !== undefined) user.webTorrentEnabled = body.webTorrentEnabled
   if (body.autoPlayVideo !== undefined) user.autoPlayVideo = body.autoPlayVideo
 
   await sequelizeTypescript.transaction(async t => {
index 90fc74a482c9bc45f3c1d4957f9f03f939de1098..1cb5e5b0f514a3d93efe669113ddbe1aadcabeb9 100644 (file)
@@ -42,6 +42,10 @@ function isUserNSFWPolicyValid (value: any) {
   return exists(value) && nsfwPolicies.indexOf(value) !== -1
 }
 
+function isUserWebTorrentEnabledValid (value: any) {
+  return isBooleanValid(value)
+}
+
 function isUserAutoPlayVideoValid (value: any) {
   return isBooleanValid(value)
 }
@@ -78,6 +82,7 @@ export {
   isUserUsernameValid,
   isUserEmailVerifiedValid,
   isUserNSFWPolicyValid,
+  isUserWebTorrentEnabledValid,
   isUserAutoPlayVideoValid,
   isUserDisplayNameValid,
   isUserDescriptionValid,
index cf00da2c7fe7d2cc1170b08f169dccf6019ce9a0..03158e356a02ce7b7f318eac86f37df4b36cfb99 100644 (file)
@@ -16,7 +16,7 @@ let config: IConfig = require('config')
 
 // ---------------------------------------------------------------------------
 
-const LAST_MIGRATION_VERSION = 275
+const LAST_MIGRATION_VERSION = 280
 
 // ---------------------------------------------------------------------------
 
diff --git a/server/initializers/migrations/0280-webtorrent-policy-user.ts b/server/initializers/migrations/0280-webtorrent-policy-user.ts
new file mode 100644 (file)
index 0000000..e648835
--- /dev/null
@@ -0,0 +1,28 @@
+import * as Sequelize from 'sequelize'
+
+async function up (utils: {
+  transaction: Sequelize.Transaction
+  queryInterface: Sequelize.QueryInterface
+  sequelize: Sequelize.Sequelize
+}): Promise<any> {
+  {
+    const data = {
+      type: Sequelize.BOOLEAN,
+      allowNull: false,
+      defaultValue: true
+    }
+
+    await utils.queryInterface.addColumn('user', 'webTorrentEnabled', data)
+  }
+
+}
+
+async function down (utils: {
+  transaction: Sequelize.Transaction
+  queryInterface: Sequelize.QueryInterface
+  sequelize: Sequelize.Sequelize
+}): Promise<any> {
+  await utils.queryInterface.removeColumn('user', 'webTorrentEnabled')
+}
+
+export { up, down }
index 39654cfcf2f51326f71dc538913aa911942fdb44..4b4a562fa96f69ba59ceaa33b03e482975bba407 100644 (file)
@@ -31,7 +31,8 @@ import {
   isUserRoleValid,
   isUserUsernameValid,
   isUserVideoQuotaDailyValid,
-  isUserVideoQuotaValid
+  isUserVideoQuotaValid,
+  isUserWebTorrentEnabledValid
 } from '../../helpers/custom-validators/users'
 import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
 import { OAuthTokenModel } from '../oauth/oauth-token'
@@ -107,6 +108,11 @@ export class UserModel extends Model<UserModel> {
   @Column(DataType.ENUM(values(NSFW_POLICY_TYPES)))
   nsfwPolicy: NSFWPolicyType
 
+  @AllowNull(false)
+  @Is('UserWebTorrentEnabled', value => throwIfNotValid(value, isUserWebTorrentEnabledValid, 'WebTorrent enabled'))
+  @Column
+  webTorrentEnabled: boolean
+
   @AllowNull(false)
   @Default(true)
   @Is('UserAutoPlayVideo', value => throwIfNotValid(value, isUserAutoPlayVideoValid, 'auto play video boolean'))
@@ -355,6 +361,7 @@ export class UserModel extends Model<UserModel> {
       email: this.email,
       emailVerified: this.emailVerified,
       nsfwPolicy: this.nsfwPolicy,
+      webTorrentEnabled: this.webTorrentEnabled,
       autoPlayVideo: this.autoPlayVideo,
       role: this.role,
       roleLabel: USER_ROLE_LABELS[ this.role ],
index bbffe148769ed43e483f3c7cc63788ca00dc1589..10edeee2e657cfe55710a8f87539095448034bb7 100644 (file)
@@ -3,7 +3,8 @@ import { NSFWPolicyType } from '../videos/nsfw-policy.type'
 export interface UserUpdateMe {
   displayName?: string
   description?: string
-  nsfwPolicy?: NSFWPolicyType
+  nsfwPolicy?: NSFWPolicyType,
+  webTorrentEnabled?: boolean,
   autoPlayVideo?: boolean
   email?: string
   currentPassword?: string