diff options
author | Chocobozzz <me@florianbigard.com> | 2019-03-19 14:13:53 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-03-19 14:13:53 +0100 |
commit | 9f79ade627f0044606a9fbbe16ca0154661d12b9 (patch) | |
tree | ccfc1876da591bc52cbb4b8ccddedbeae7876679 /server/lib | |
parent | 0e0c745b62b2f18e228328e8c4f95b17e54f7a5e (diff) | |
download | PeerTube-9f79ade627f0044606a9fbbe16ca0154661d12b9.tar.gz PeerTube-9f79ade627f0044606a9fbbe16ca0154661d12b9.tar.zst PeerTube-9f79ade627f0044606a9fbbe16ca0154661d12b9.zip |
Refresh playlists
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/activitypub/actor.ts | 3 | ||||
-rw-r--r-- | server/lib/activitypub/playlist.ts | 56 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/activitypub-refresher.ts | 14 |
3 files changed, 67 insertions, 6 deletions
diff --git a/server/lib/activitypub/actor.ts b/server/lib/activitypub/actor.ts index f77df8b78..63e810642 100644 --- a/server/lib/activitypub/actor.ts +++ b/server/lib/activitypub/actor.ts | |||
@@ -375,7 +375,8 @@ async function fetchRemoteActor (actorUrl: string): Promise<{ statusCode?: numbe | |||
375 | } | 375 | } |
376 | 376 | ||
377 | if (checkUrlsSameHost(actorJSON.id, actorUrl) !== true) { | 377 | if (checkUrlsSameHost(actorJSON.id, actorUrl) !== true) { |
378 | throw new Error('Actor url ' + actorUrl + ' has not the same host than its AP id ' + actorJSON.id) | 378 | logger.warn('Actor url %s has not the same host than its AP id %s', actorUrl, actorJSON.id) |
379 | return { result: undefined, statusCode: requestResult.response.statusCode } | ||
379 | } | 380 | } |
380 | 381 | ||
381 | const followersCount = await fetchActorTotalItems(actorJSON.followers) | 382 | const followersCount = await fetchActorTotalItems(actorJSON.followers) |
diff --git a/server/lib/activitypub/playlist.ts b/server/lib/activitypub/playlist.ts index 70389044e..c4a8f12ec 100644 --- a/server/lib/activitypub/playlist.ts +++ b/server/lib/activitypub/playlist.ts | |||
@@ -95,7 +95,7 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc | |||
95 | return Promise.resolve() | 95 | return Promise.resolve() |
96 | }) | 96 | }) |
97 | 97 | ||
98 | // Empty playlists generally do not have a miniature, so skip it | 98 | // Empty playlists generally do not have a miniature, so skip this |
99 | if (accItems.length !== 0) { | 99 | if (accItems.length !== 0) { |
100 | try { | 100 | try { |
101 | await generateThumbnailFromUrl(playlist, playlistObject.icon) | 101 | await generateThumbnailFromUrl(playlist, playlistObject.icon) |
@@ -107,13 +107,45 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc | |||
107 | return resetVideoPlaylistElements(accItems, playlist) | 107 | return resetVideoPlaylistElements(accItems, playlist) |
108 | } | 108 | } |
109 | 109 | ||
110 | async function refreshVideoPlaylistIfNeeded (videoPlaylist: VideoPlaylistModel): Promise<VideoPlaylistModel> { | ||
111 | if (!videoPlaylist.isOutdated()) return videoPlaylist | ||
112 | |||
113 | try { | ||
114 | const { statusCode, playlistObject } = await fetchRemoteVideoPlaylist(videoPlaylist.url) | ||
115 | if (statusCode === 404) { | ||
116 | logger.info('Cannot refresh remote video playlist %s: it does not exist anymore. Deleting it.', videoPlaylist.url) | ||
117 | |||
118 | await videoPlaylist.destroy() | ||
119 | return undefined | ||
120 | } | ||
121 | |||
122 | if (playlistObject === undefined) { | ||
123 | logger.warn('Cannot refresh remote playlist %s: invalid body.', videoPlaylist.url) | ||
124 | |||
125 | await videoPlaylist.setAsRefreshed() | ||
126 | return videoPlaylist | ||
127 | } | ||
128 | |||
129 | const byAccount = videoPlaylist.OwnerAccount | ||
130 | await createOrUpdateVideoPlaylist(playlistObject, byAccount, playlistObject.to) | ||
131 | |||
132 | return videoPlaylist | ||
133 | } catch (err) { | ||
134 | logger.warn('Cannot refresh video playlist %s.', videoPlaylist.url, { err }) | ||
135 | |||
136 | await videoPlaylist.setAsRefreshed() | ||
137 | return videoPlaylist | ||
138 | } | ||
139 | } | ||
140 | |||
110 | // --------------------------------------------------------------------------- | 141 | // --------------------------------------------------------------------------- |
111 | 142 | ||
112 | export { | 143 | export { |
113 | createAccountPlaylists, | 144 | createAccountPlaylists, |
114 | playlistObjectToDBAttributes, | 145 | playlistObjectToDBAttributes, |
115 | playlistElementObjectToDBAttributes, | 146 | playlistElementObjectToDBAttributes, |
116 | createOrUpdateVideoPlaylist | 147 | createOrUpdateVideoPlaylist, |
148 | refreshVideoPlaylistIfNeeded | ||
117 | } | 149 | } |
118 | 150 | ||
119 | // --------------------------------------------------------------------------- | 151 | // --------------------------------------------------------------------------- |
@@ -162,3 +194,23 @@ function generateThumbnailFromUrl (playlist: VideoPlaylistModel, icon: ActivityI | |||
162 | 194 | ||
163 | return downloadImage(icon.url, CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName, THUMBNAILS_SIZE) | 195 | return downloadImage(icon.url, CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName, THUMBNAILS_SIZE) |
164 | } | 196 | } |
197 | |||
198 | async function fetchRemoteVideoPlaylist (playlistUrl: string): Promise<{ statusCode: number, playlistObject: PlaylistObject }> { | ||
199 | const options = { | ||
200 | uri: playlistUrl, | ||
201 | method: 'GET', | ||
202 | json: true, | ||
203 | activityPub: true | ||
204 | } | ||
205 | |||
206 | logger.info('Fetching remote playlist %s.', playlistUrl) | ||
207 | |||
208 | const { response, body } = await doRequest(options) | ||
209 | |||
210 | if (isPlaylistObjectValid(body) === false || checkUrlsSameHost(body.id, playlistUrl) !== true) { | ||
211 | logger.debug('Remote video playlist JSON is not valid.', { body }) | ||
212 | return { statusCode: response.statusCode, playlistObject: undefined } | ||
213 | } | ||
214 | |||
215 | return { statusCode: response.statusCode, playlistObject: body } | ||
216 | } | ||
diff --git a/server/lib/job-queue/handlers/activitypub-refresher.ts b/server/lib/job-queue/handlers/activitypub-refresher.ts index 454b975fe..4d6c38cfa 100644 --- a/server/lib/job-queue/handlers/activitypub-refresher.ts +++ b/server/lib/job-queue/handlers/activitypub-refresher.ts | |||
@@ -1,11 +1,12 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { logger } from '../../../helpers/logger' | 2 | import { logger } from '../../../helpers/logger' |
3 | import { fetchVideoByUrl } from '../../../helpers/video' | 3 | import { fetchVideoByUrl } from '../../../helpers/video' |
4 | import { refreshVideoIfNeeded, refreshActorIfNeeded } from '../../activitypub' | 4 | import { refreshActorIfNeeded, refreshVideoIfNeeded, refreshVideoPlaylistIfNeeded } from '../../activitypub' |
5 | import { ActorModel } from '../../../models/activitypub/actor' | 5 | import { ActorModel } from '../../../models/activitypub/actor' |
6 | import { VideoPlaylistModel } from '../../../models/video/video-playlist' | ||
6 | 7 | ||
7 | export type RefreshPayload = { | 8 | export type RefreshPayload = { |
8 | type: 'video' | 'actor' | 9 | type: 'video' | 'video-playlist' | 'actor' |
9 | url: string | 10 | url: string |
10 | } | 11 | } |
11 | 12 | ||
@@ -15,13 +16,13 @@ async function refreshAPObject (job: Bull.Job) { | |||
15 | logger.info('Processing AP refresher in job %d for %s.', job.id, payload.url) | 16 | logger.info('Processing AP refresher in job %d for %s.', job.id, payload.url) |
16 | 17 | ||
17 | if (payload.type === 'video') return refreshVideo(payload.url) | 18 | if (payload.type === 'video') return refreshVideo(payload.url) |
19 | if (payload.type === 'video-playlist') return refreshVideoPlaylist(payload.url) | ||
18 | if (payload.type === 'actor') return refreshActor(payload.url) | 20 | if (payload.type === 'actor') return refreshActor(payload.url) |
19 | } | 21 | } |
20 | 22 | ||
21 | // --------------------------------------------------------------------------- | 23 | // --------------------------------------------------------------------------- |
22 | 24 | ||
23 | export { | 25 | export { |
24 | refreshActor, | ||
25 | refreshAPObject | 26 | refreshAPObject |
26 | } | 27 | } |
27 | 28 | ||
@@ -50,5 +51,12 @@ async function refreshActor (actorUrl: string) { | |||
50 | if (actor) { | 51 | if (actor) { |
51 | await refreshActorIfNeeded(actor, fetchType) | 52 | await refreshActorIfNeeded(actor, fetchType) |
52 | } | 53 | } |
54 | } | ||
55 | |||
56 | async function refreshVideoPlaylist (playlistUrl: string) { | ||
57 | const playlist = await VideoPlaylistModel.loadByUrlAndPopulateAccount(playlistUrl) | ||
53 | 58 | ||
59 | if (playlist) { | ||
60 | await refreshVideoPlaylistIfNeeded(playlist) | ||
61 | } | ||
54 | } | 62 | } |