]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/controllers/api/videos/index.ts
Federate video views
[github/Chocobozzz/PeerTube.git] / server / controllers / api / videos / index.ts
index ebc07e17909aeed6ecca03bceb4d6faee4166136..2b5afd632d1f3e92ecfd70972d8db1844bb5affa 100644 (file)
@@ -3,7 +3,6 @@ import * as multer from 'multer'
 import { extname, join } from 'path'
 import { VideoCreate, VideoPrivacy, VideoUpdate } from '../../../../shared'
 import {
-  fetchRemoteVideoDescription,
   generateRandomString,
   getFormattedObjects,
   getVideoFileHeight,
@@ -12,10 +11,15 @@ import {
   resetSequelizeInstance,
   retryTransactionWrapper
 } from '../../../helpers'
-import { getActivityPubUrl } from '../../../helpers/activitypub'
+import { getServerAccount } from '../../../helpers/utils'
 import { CONFIG, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_MIMETYPE_EXT, VIDEO_PRIVACIES } from '../../../initializers'
 import { database as db } from '../../../initializers/database'
-import { sendAddVideo, sendUpdateVideoChannel } from '../../../lib/activitypub/send-request'
+import { sendAddVideo } from '../../../lib/activitypub/send/send-add'
+import { sendUpdateVideo } from '../../../lib/activitypub/send/send-update'
+import { shareVideoByServer } from '../../../lib/activitypub/share'
+import { getVideoActivityPubUrl } from '../../../lib/activitypub/url'
+import { fetchRemoteVideoDescription } from '../../../lib/activitypub/videos'
+import { sendCreateViewToVideoFollowers } from '../../../lib/index'
 import { transcodingJobScheduler } from '../../../lib/jobs/transcoding-job-scheduler/transcoding-job-scheduler'
 import {
   asyncMiddleware,
@@ -36,6 +40,7 @@ import { abuseVideoRouter } from './abuse'
 import { blacklistRouter } from './blacklist'
 import { videoChannelRouter } from './channel'
 import { rateVideoRouter } from './rate'
+import { sendCreateViewToOrigin } from '../../../lib/activitypub/send/send-create'
 
 const videosRouter = express.Router()
 
@@ -56,7 +61,7 @@ const storage = multer.diskStorage({
       randomString = 'fake-random-string'
     }
 
-    cb(null, randomString + '.' + extension)
+    cb(null, randomString + extension)
   }
 })
 
@@ -175,7 +180,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
       channelId: res.locals.videoChannel.id
     }
     const video = db.Video.build(videoData)
-    video.url = getActivityPubUrl('video', video.uuid)
+    video.url = getVideoActivityPubUrl(video)
 
     const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename)
     const videoFileHeight = await getVideoFileHeight(videoFilePath)
@@ -237,6 +242,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
     if (video.privacy === VideoPrivacy.PRIVATE) return undefined
 
     await sendAddVideo(video, t)
+    await shareVideoByServer(video, t)
   })
 
   logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoUUID)
@@ -254,7 +260,7 @@ async function updateVideoRetryWrapper (req: express.Request, res: express.Respo
 }
 
 async function updateVideo (req: express.Request, res: express.Response) {
-  const videoInstance = res.locals.video
+  const videoInstance: VideoInstance = res.locals.video
   const videoFieldsSave = videoInstance.toJSON()
   const videoInfoToUpdate: VideoUpdate = req.body
   const wasPrivateVideo = videoInstance.privacy === VideoPrivacy.PRIVATE
@@ -273,7 +279,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
       if (videoInfoToUpdate.privacy !== undefined) videoInstance.set('privacy', videoInfoToUpdate.privacy)
       if (videoInfoToUpdate.description !== undefined) videoInstance.set('description', videoInfoToUpdate.description)
 
-      await videoInstance.save(sequelizeOptions)
+      const videoInstanceUpdated = await videoInstance.save(sequelizeOptions)
 
       if (videoInfoToUpdate.tags) {
         const tagInstances = await db.Tag.findOrCreateTags(videoInfoToUpdate.tags, t)
@@ -284,12 +290,13 @@ async function updateVideo (req: express.Request, res: express.Response) {
 
       // Now we'll update the video's meta data to our friends
       if (wasPrivateVideo === false) {
-        await sendUpdateVideoChannel(videoInstance, t)
+        await sendUpdateVideo(videoInstanceUpdated, t)
       }
 
       // Video is not private anymore, send a create action to remote servers
       if (wasPrivateVideo === true && videoInstance.privacy !== VideoPrivacy.PRIVATE) {
         await sendAddVideo(videoInstance, t)
+        await shareVideoByServer(videoInstance, t)
       }
     })
 
@@ -307,17 +314,18 @@ async function updateVideo (req: express.Request, res: express.Response) {
 async function getVideo (req: express.Request, res: express.Response) {
   const videoInstance = res.locals.video
 
+  const baseIncrementPromise = videoInstance.increment('views')
+    .then(() => getServerAccount())
+
   if (videoInstance.isOwned()) {
     // The increment is done directly in the database, not using the instance value
-    // FIXME: make a real view system
-    // For example, only add a view when a user watch a video during 30s etc
-    videoInstance.increment('views')
-      .then(() => {
-        // TODO: send to followers a notification
-      })
-      .catch(err => logger.error('Cannot add view to video %s.', videoInstance.uuid, err))
+    baseIncrementPromise
+      .then(serverAccount => sendCreateViewToVideoFollowers(serverAccount, videoInstance, undefined))
+      .catch(err => logger.error('Cannot add view to video/send view to followers for %s.', videoInstance.uuid, err))
   } else {
-    // TODO: send view event to followers
+    baseIncrementPromise
+      .then(serverAccount => sendCreateViewToOrigin(serverAccount, videoInstance, undefined))
+      .catch(err => logger.error('Cannot send view to origin server for %s.', videoInstance.uuid, err))
   }
 
   // Do not wait the view system