]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/models/video/video-channel.ts
Add beautiful loading bar
[github/Chocobozzz/PeerTube.git] / server / models / video / video-channel.ts
index e469383e98a0a25df7000022e6f347aca48e5d36..54f12dce3216273d17925ea1e2eaca21e1f9ebc2 100644 (file)
@@ -1,31 +1,29 @@
 import * as Sequelize from 'sequelize'
-
-import { isVideoChannelNameValid, isVideoChannelDescriptionValid } from '../../helpers'
-import { removeVideoChannelToFriends } from '../../lib'
+import { isVideoChannelDescriptionValid, isVideoChannelNameValid } from '../../helpers'
+import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
+import { sendDeleteVideoChannel } from '../../lib/activitypub/send/send-delete'
 
 import { addMethodsToModel, getSort } from '../utils'
-import {
-  VideoChannelInstance,
-  VideoChannelAttributes,
-
-  VideoChannelMethods
-} from './video-channel-interface'
+import { VideoChannelAttributes, VideoChannelInstance, VideoChannelMethods } from './video-channel-interface'
+import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url'
+import { activityPubCollection } from '../../helpers/activitypub'
+import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
 
 let VideoChannel: Sequelize.Model<VideoChannelInstance, VideoChannelAttributes>
 let toFormattedJSON: VideoChannelMethods.ToFormattedJSON
-let toAddRemoteJSON: VideoChannelMethods.ToAddRemoteJSON
-let toUpdateRemoteJSON: VideoChannelMethods.ToUpdateRemoteJSON
+let toActivityPubObject: VideoChannelMethods.ToActivityPubObject
 let isOwned: VideoChannelMethods.IsOwned
-let countByAuthor: VideoChannelMethods.CountByAuthor
-let listOwned: VideoChannelMethods.ListOwned
+let countByAccount: VideoChannelMethods.CountByAccount
 let listForApi: VideoChannelMethods.ListForApi
-let listByAuthor: VideoChannelMethods.ListByAuthor
-let loadByIdAndAuthor: VideoChannelMethods.LoadByIdAndAuthor
+let listByAccount: VideoChannelMethods.ListByAccount
+let loadByIdAndAccount: VideoChannelMethods.LoadByIdAndAccount
 let loadByUUID: VideoChannelMethods.LoadByUUID
-let loadAndPopulateAuthor: VideoChannelMethods.LoadAndPopulateAuthor
-let loadByUUIDAndPopulateAuthor: VideoChannelMethods.LoadByUUIDAndPopulateAuthor
+let loadAndPopulateAccount: VideoChannelMethods.LoadAndPopulateAccount
+let loadByUUIDAndPopulateAccount: VideoChannelMethods.LoadByUUIDAndPopulateAccount
 let loadByHostAndUUID: VideoChannelMethods.LoadByHostAndUUID
-let loadAndPopulateAuthorAndVideos: VideoChannelMethods.LoadAndPopulateAuthorAndVideos
+let loadAndPopulateAccountAndVideos: VideoChannelMethods.LoadAndPopulateAccountAndVideos
+let loadByUrl: VideoChannelMethods.LoadByUrl
+let loadByUUIDOrUrl: VideoChannelMethods.LoadByUUIDOrUrl
 
 export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
   VideoChannel = sequelize.define<VideoChannelInstance, VideoChannelAttributes>('VideoChannel',
@@ -62,12 +60,22 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
         type: DataTypes.BOOLEAN,
         allowNull: false,
         defaultValue: false
+      },
+      url: {
+        type: DataTypes.STRING(CONSTRAINTS_FIELDS.VIDEO_CHANNELS.URL.max),
+        allowNull: false,
+        validate: {
+          urlValid: value => {
+            const res = isActivityPubUrlValid(value)
+            if (res === false) throw new Error('Video channel URL is not valid.')
+          }
+        }
       }
     },
     {
       indexes: [
         {
-          fields: [ 'authorId' ]
+          fields: [ 'accountId' ]
         }
       ],
       hooks: {
@@ -80,21 +88,21 @@ export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.Da
     associate,
 
     listForApi,
-    listByAuthor,
-    listOwned,
-    loadByIdAndAuthor,
-    loadAndPopulateAuthor,
-    loadByUUIDAndPopulateAuthor,
+    listByAccount,
+    loadByIdAndAccount,
+    loadAndPopulateAccount,
+    loadByUUIDAndPopulateAccount,
     loadByUUID,
     loadByHostAndUUID,
-    loadAndPopulateAuthorAndVideos,
-    countByAuthor
+    loadAndPopulateAccountAndVideos,
+    countByAccount,
+    loadByUrl,
+    loadByUUIDOrUrl
   ]
   const instanceMethods = [
     isOwned,
     toFormattedJSON,
-    toAddRemoteJSON,
-    toUpdateRemoteJSON
+    toActivityPubObject
   ]
   addMethodsToModel(VideoChannel, classMethods, instanceMethods)
 
@@ -118,10 +126,10 @@ toFormattedJSON = function (this: VideoChannelInstance) {
     updatedAt: this.updatedAt
   }
 
-  if (this.Author !== undefined) {
+  if (this.Account !== undefined) {
     json['owner'] = {
-      name: this.Author.name,
-      uuid: this.Author.uuid
+      name: this.Account.name,
+      uuid: this.Account.uuid
     }
   }
 
@@ -132,27 +140,28 @@ toFormattedJSON = function (this: VideoChannelInstance) {
   return json
 }
 
-toAddRemoteJSON = function (this: VideoChannelInstance) {
-  const json = {
-    uuid: this.uuid,
-    name: this.name,
-    description: this.description,
-    createdAt: this.createdAt,
-    updatedAt: this.updatedAt,
-    ownerUUID: this.Author.uuid
-  }
+toActivityPubObject = function (this: VideoChannelInstance) {
+  let sharesObject
+  if (Array.isArray(this.VideoChannelShares)) {
+    const shares: string[] = []
 
-  return json
-}
+    for (const videoChannelShare of this.VideoChannelShares) {
+      const shareUrl = getAnnounceActivityPubUrl(this.url, videoChannelShare.Account)
+      shares.push(shareUrl)
+    }
+
+    sharesObject = activityPubCollection(shares)
+  }
 
-toUpdateRemoteJSON = function (this: VideoChannelInstance) {
   const json = {
+    type: 'VideoChannel' as 'VideoChannel',
+    id: this.url,
     uuid: this.uuid,
+    content: this.description,
     name: this.name,
-    description: this.description,
-    createdAt: this.createdAt,
-    updatedAt: this.updatedAt,
-    ownerUUID: this.Author.uuid
+    published: this.createdAt.toISOString(),
+    updated: this.updatedAt.toISOString(),
+    shares: sharesObject
   }
 
   return json
@@ -161,9 +170,9 @@ toUpdateRemoteJSON = function (this: VideoChannelInstance) {
 // ------------------------------ STATICS ------------------------------
 
 function associate (models) {
-  VideoChannel.belongsTo(models.Author, {
+  VideoChannel.belongsTo(models.Account, {
     foreignKey: {
-      name: 'authorId',
+      name: 'accountId',
       allowNull: false
     },
     onDelete: 'CASCADE'
@@ -178,39 +187,24 @@ function associate (models) {
   })
 }
 
-function afterDestroy (videoChannel: VideoChannelInstance, options: { transaction: Sequelize.Transaction }) {
+function afterDestroy (videoChannel: VideoChannelInstance) {
   if (videoChannel.isOwned()) {
-    const removeVideoChannelToFriendsParams = {
-      uuid: videoChannel.uuid
-    }
-
-    return removeVideoChannelToFriends(removeVideoChannelToFriendsParams, options.transaction)
+    return sendDeleteVideoChannel(videoChannel, undefined)
   }
 
   return undefined
 }
 
-countByAuthor = function (authorId: number) {
+countByAccount = function (accountId: number) {
   const query = {
     where: {
-      authorId
+      accountId
     }
   }
 
   return VideoChannel.count(query)
 }
 
-listOwned = function () {
-  const query = {
-    where: {
-      remote: false
-    },
-    include: [ VideoChannel['sequelize'].models.Author ]
-  }
-
-  return VideoChannel.findAll(query)
-}
-
 listForApi = function (start: number, count: number, sort: string) {
   const query = {
     offset: start,
@@ -218,9 +212,9 @@ listForApi = function (start: number, count: number, sort: string) {
     order: [ getSort(sort) ],
     include: [
       {
-        model: VideoChannel['sequelize'].models.Author,
+        model: VideoChannel['sequelize'].models.Account,
         required: true,
-        include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
+        include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
       }
     ]
   }
@@ -230,17 +224,17 @@ listForApi = function (start: number, count: number, sort: string) {
   })
 }
 
-listByAuthor = function (authorId: number) {
+listByAccount = function (accountId: number) {
   const query = {
     order: [ getSort('createdAt') ],
     include: [
       {
-        model: VideoChannel['sequelize'].models.Author,
+        model: VideoChannel['sequelize'].models.Account,
         where: {
-          id: authorId
+          id: accountId
         },
         required: true,
-        include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
+        include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
       }
     ]
   }
@@ -262,6 +256,34 @@ loadByUUID = function (uuid: string, t?: Sequelize.Transaction) {
   return VideoChannel.findOne(query)
 }
 
+loadByUrl = function (url: string, t?: Sequelize.Transaction) {
+  const query: Sequelize.FindOptions<VideoChannelAttributes> = {
+    where: {
+      url
+    },
+    include: [ VideoChannel['sequelize'].models.Account ]
+  }
+
+  if (t !== undefined) query.transaction = t
+
+  return VideoChannel.findOne(query)
+}
+
+loadByUUIDOrUrl = function (uuid: string, url: string, t?: Sequelize.Transaction) {
+  const query: Sequelize.FindOptions<VideoChannelAttributes> = {
+    where: {
+      [Sequelize.Op.or]: [
+        { uuid },
+        { url }
+      ]
+    }
+  }
+
+  if (t !== undefined) query.transaction = t
+
+  return VideoChannel.findOne(query)
+}
+
 loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Transaction) {
   const query: Sequelize.FindOptions<VideoChannelAttributes> = {
     where: {
@@ -269,10 +291,10 @@ loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Tran
     },
     include: [
       {
-        model: VideoChannel['sequelize'].models.Author,
+        model: VideoChannel['sequelize'].models.Account,
         include: [
           {
-            model: VideoChannel['sequelize'].models.Pod,
+            model: VideoChannel['sequelize'].models.Server,
             required: true,
             where: {
               host: fromHost
@@ -288,16 +310,16 @@ loadByHostAndUUID = function (fromHost: string, uuid: string, t?: Sequelize.Tran
   return VideoChannel.findOne(query)
 }
 
-loadByIdAndAuthor = function (id: number, authorId: number) {
+loadByIdAndAccount = function (id: number, accountId: number) {
   const options = {
     where: {
       id,
-      authorId
+      accountId
     },
     include: [
       {
-        model: VideoChannel['sequelize'].models.Author,
-        include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
+        model: VideoChannel['sequelize'].models.Account,
+        include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
       }
     ]
   }
@@ -305,12 +327,12 @@ loadByIdAndAuthor = function (id: number, authorId: number) {
   return VideoChannel.findOne(options)
 }
 
-loadAndPopulateAuthor = function (id: number) {
+loadAndPopulateAccount = function (id: number) {
   const options = {
     include: [
       {
-        model: VideoChannel['sequelize'].models.Author,
-        include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
+        model: VideoChannel['sequelize'].models.Account,
+        include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
       }
     ]
   }
@@ -318,15 +340,15 @@ loadAndPopulateAuthor = function (id: number) {
   return VideoChannel.findById(id, options)
 }
 
-loadByUUIDAndPopulateAuthor = function (uuid: string) {
+loadByUUIDAndPopulateAccount = function (uuid: string) {
   const options = {
     where: {
       uuid
     },
     include: [
       {
-        model: VideoChannel['sequelize'].models.Author,
-        include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
+        model: VideoChannel['sequelize'].models.Account,
+        include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
       }
     ]
   }
@@ -334,12 +356,12 @@ loadByUUIDAndPopulateAuthor = function (uuid: string) {
   return VideoChannel.findOne(options)
 }
 
-loadAndPopulateAuthorAndVideos = function (id: number) {
+loadAndPopulateAccountAndVideos = function (id: number) {
   const options = {
     include: [
       {
-        model: VideoChannel['sequelize'].models.Author,
-        include: [ { model: VideoChannel['sequelize'].models.Pod, required: false } ]
+        model: VideoChannel['sequelize'].models.Account,
+        include: [ { model: VideoChannel['sequelize'].models.Server, required: false } ]
       },
       VideoChannel['sequelize'].models.Video
     ]