]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/activitypub/playlist.ts
Refresh playlists
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / playlist.ts
index c9b428c92c11083dffd0b6b1519d6340d68e3195..c4a8f12ecbbc1b26e5fc64f50f2402a0e804d985 100644 (file)
@@ -28,7 +28,9 @@ function playlistObjectToDBAttributes (playlistObject: PlaylistObject, byAccount
     url: playlistObject.id,
     uuid: playlistObject.uuid,
     ownerAccountId: byAccount.id,
-    videoChannelId: null
+    videoChannelId: null,
+    createdAt: new Date(playlistObject.published),
+    updatedAt: new Date(playlistObject.updated)
   }
 }
 
@@ -93,7 +95,7 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc
     return Promise.resolve()
   })
 
-  // Empty playlists generally do not have a miniature, so skip it
+  // Empty playlists generally do not have a miniature, so skip this
   if (accItems.length !== 0) {
     try {
       await generateThumbnailFromUrl(playlist, playlistObject.icon)
@@ -105,13 +107,45 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc
   return resetVideoPlaylistElements(accItems, playlist)
 }
 
+async function refreshVideoPlaylistIfNeeded (videoPlaylist: VideoPlaylistModel): Promise<VideoPlaylistModel> {
+  if (!videoPlaylist.isOutdated()) return videoPlaylist
+
+  try {
+    const { statusCode, playlistObject } = await fetchRemoteVideoPlaylist(videoPlaylist.url)
+    if (statusCode === 404) {
+      logger.info('Cannot refresh remote video playlist %s: it does not exist anymore. Deleting it.', videoPlaylist.url)
+
+      await videoPlaylist.destroy()
+      return undefined
+    }
+
+    if (playlistObject === undefined) {
+      logger.warn('Cannot refresh remote playlist %s: invalid body.', videoPlaylist.url)
+
+      await videoPlaylist.setAsRefreshed()
+      return videoPlaylist
+    }
+
+    const byAccount = videoPlaylist.OwnerAccount
+    await createOrUpdateVideoPlaylist(playlistObject, byAccount, playlistObject.to)
+
+    return videoPlaylist
+  } catch (err) {
+    logger.warn('Cannot refresh video playlist %s.', videoPlaylist.url, { err })
+
+    await videoPlaylist.setAsRefreshed()
+    return videoPlaylist
+  }
+}
+
 // ---------------------------------------------------------------------------
 
 export {
   createAccountPlaylists,
   playlistObjectToDBAttributes,
   playlistElementObjectToDBAttributes,
-  createOrUpdateVideoPlaylist
+  createOrUpdateVideoPlaylist,
+  refreshVideoPlaylistIfNeeded
 }
 
 // ---------------------------------------------------------------------------
@@ -160,3 +194,23 @@ function generateThumbnailFromUrl (playlist: VideoPlaylistModel, icon: ActivityI
 
   return downloadImage(icon.url, CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName, THUMBNAILS_SIZE)
 }
+
+async function fetchRemoteVideoPlaylist (playlistUrl: string): Promise<{ statusCode: number, playlistObject: PlaylistObject }> {
+  const options = {
+    uri: playlistUrl,
+    method: 'GET',
+    json: true,
+    activityPub: true
+  }
+
+  logger.info('Fetching remote playlist %s.', playlistUrl)
+
+  const { response, body } = await doRequest(options)
+
+  if (isPlaylistObjectValid(body) === false || checkUrlsSameHost(body.id, playlistUrl) !== true) {
+    logger.debug('Remote video playlist JSON is not valid.', { body })
+    return { statusCode: response.statusCode, playlistObject: undefined }
+  }
+
+  return { statusCode: response.statusCode, playlistObject: body }
+}