2021-06-24 15:18:54 +02:00
|
|
|
import { IndexablePlaylist } from 'server/types/playlist.model'
|
2023-08-07 11:21:26 +02:00
|
|
|
import { ResultList, Video, VideoChannel, VideoDetails, VideoPlaylist, VideosCommonQuery } from '@peertube/peertube-types'
|
2021-06-24 15:18:54 +02:00
|
|
|
import { doRequestWithRetries } from '../../helpers/requests'
|
|
|
|
import { INDEXER_COUNT, REQUESTS } from '../../initializers/constants'
|
|
|
|
import { IndexableChannel } from '../../types/channel.model'
|
|
|
|
import { IndexableDoc } from '../../types/indexable-doc.model'
|
|
|
|
import { IndexableVideo } from '../../types/video.model'
|
2020-02-19 15:39:35 +01:00
|
|
|
|
|
|
|
async function getVideo (host: string, uuid: string): Promise<IndexableVideo> {
|
|
|
|
const url = 'https://' + host + '/api/v1/videos/' + uuid
|
|
|
|
|
2020-03-04 15:32:39 +01:00
|
|
|
const res = await doRequestWithRetries<VideoDetails>({
|
2020-02-19 15:39:35 +01:00
|
|
|
uri: url,
|
|
|
|
json: true
|
2020-03-04 15:32:39 +01:00
|
|
|
}, REQUESTS.MAX_RETRIES, REQUESTS.WAIT)
|
2020-02-19 15:39:35 +01:00
|
|
|
|
|
|
|
return prepareVideoForDB(res.body, host)
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getChannel (host: string, name: string): Promise<IndexableChannel> {
|
|
|
|
const url = 'https://' + host + '/api/v1/video-channels/' + name
|
|
|
|
|
2020-03-04 15:32:39 +01:00
|
|
|
const res = await doRequestWithRetries<VideoChannel>({
|
2020-02-19 15:39:35 +01:00
|
|
|
uri: url,
|
|
|
|
json: true
|
2020-03-04 15:32:39 +01:00
|
|
|
}, REQUESTS.MAX_RETRIES, REQUESTS.WAIT)
|
2020-02-19 15:39:35 +01:00
|
|
|
|
2021-11-24 11:36:42 +01:00
|
|
|
const videosCount = await getChannelVideosCount(host, name)
|
|
|
|
|
|
|
|
return prepareChannelForDB(res.body, host, videosCount)
|
|
|
|
}
|
|
|
|
|
|
|
|
async function getChannelVideosCount (host: string, name: string): Promise<number> {
|
|
|
|
const url = 'https://' + host + '/api/v1/video-channels/' + name + '/videos'
|
|
|
|
|
|
|
|
const res = await doRequestWithRetries<ResultList<Video>>({
|
|
|
|
uri: url,
|
|
|
|
qs: {
|
|
|
|
start: 0,
|
|
|
|
count: 0
|
|
|
|
},
|
|
|
|
json: true
|
|
|
|
}, REQUESTS.MAX_RETRIES, REQUESTS.WAIT)
|
|
|
|
|
|
|
|
const total = res.body?.total
|
|
|
|
if (!total || typeof total !== 'number') return 0
|
|
|
|
|
|
|
|
return total
|
2020-02-19 15:39:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
async function getVideos (host: string, start: number): Promise<IndexableVideo[]> {
|
|
|
|
const url = 'https://' + host + '/api/v1/videos'
|
|
|
|
|
2020-03-04 15:32:39 +01:00
|
|
|
const res = await doRequestWithRetries<ResultList<Video>>({
|
2020-02-19 15:39:35 +01:00
|
|
|
uri: url,
|
|
|
|
qs: {
|
|
|
|
start,
|
2023-08-03 16:32:22 +02:00
|
|
|
filter: 'local', // Deprecated filter for old PeerTube instances
|
|
|
|
isLocal: true,
|
2020-06-12 16:08:43 +02:00
|
|
|
nsfw: 'both',
|
2020-02-19 15:39:35 +01:00
|
|
|
skipCount: true,
|
2021-06-24 15:18:54 +02:00
|
|
|
count: INDEXER_COUNT
|
2023-08-07 11:21:26 +02:00
|
|
|
} as VideosCommonQuery,
|
2020-02-19 15:39:35 +01:00
|
|
|
json: true
|
2020-03-04 15:32:39 +01:00
|
|
|
}, REQUESTS.MAX_RETRIES, REQUESTS.WAIT)
|
2020-02-19 15:39:35 +01:00
|
|
|
|
2020-06-08 15:50:20 +02:00
|
|
|
if (!res.body || !Array.isArray(res.body.data)) {
|
|
|
|
throw new Error('Invalid video data from ' + url)
|
|
|
|
}
|
|
|
|
|
2020-02-19 15:39:35 +01:00
|
|
|
return res.body.data.map(v => prepareVideoForDB(v, host))
|
|
|
|
}
|
|
|
|
|
2021-06-24 15:18:54 +02:00
|
|
|
async function getPlaylistsOf (host: string, handle: string, start: number): Promise<IndexablePlaylist[]> {
|
|
|
|
const url = 'https://' + host + '/api/v1/video-channels/' + handle + '/video-playlists'
|
|
|
|
|
|
|
|
const res = await doRequestWithRetries<ResultList<VideoPlaylist>>({
|
|
|
|
uri: url,
|
|
|
|
qs: {
|
|
|
|
start,
|
|
|
|
count: INDEXER_COUNT
|
|
|
|
},
|
|
|
|
json: true
|
|
|
|
}, REQUESTS.MAX_RETRIES, REQUESTS.WAIT)
|
|
|
|
|
|
|
|
if (!res.body || !Array.isArray(res.body.data)) {
|
|
|
|
throw new Error('Invalid playlist data from ' + url)
|
|
|
|
}
|
|
|
|
|
|
|
|
return res.body.data.map(v => preparePlaylistForDB(v, host))
|
|
|
|
}
|
|
|
|
|
2020-02-19 15:39:35 +01:00
|
|
|
function prepareVideoForDB <T extends Video> (video: T, host: string): T & IndexableDoc {
|
2020-06-05 14:37:39 +02:00
|
|
|
return Object.assign(video, {
|
|
|
|
elasticSearchId: host + video.id,
|
|
|
|
host,
|
|
|
|
url: 'https://' + host + '/videos/watch/' + video.uuid
|
|
|
|
})
|
2020-02-19 15:39:35 +01:00
|
|
|
}
|
|
|
|
|
2021-11-24 11:36:42 +01:00
|
|
|
function prepareChannelForDB (channel: VideoChannel, host: string, videosCount: number): IndexableChannel {
|
2020-06-05 14:37:39 +02:00
|
|
|
return Object.assign(channel, {
|
|
|
|
elasticSearchId: host + channel.id,
|
|
|
|
host,
|
2021-11-24 11:36:42 +01:00
|
|
|
videosCount,
|
2020-06-05 14:37:39 +02:00
|
|
|
url: 'https://' + host + '/video-channels/' + channel.name
|
|
|
|
})
|
2020-02-19 15:39:35 +01:00
|
|
|
}
|
|
|
|
|
2021-06-24 15:18:54 +02:00
|
|
|
function preparePlaylistForDB (playlist: VideoPlaylist, host: string): IndexablePlaylist {
|
|
|
|
return Object.assign(playlist, {
|
|
|
|
elasticSearchId: host + playlist.id,
|
|
|
|
host,
|
|
|
|
url: 'https://' + host + '/videos/watch/playlist/' + playlist.uuid
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-02-19 15:39:35 +01:00
|
|
|
export {
|
|
|
|
getVideo,
|
|
|
|
getChannel,
|
2021-06-24 15:18:54 +02:00
|
|
|
|
2020-02-19 15:39:35 +01:00
|
|
|
getVideos,
|
2021-06-24 15:18:54 +02:00
|
|
|
getPlaylistsOf,
|
|
|
|
|
|
|
|
prepareVideoForDB,
|
|
|
|
prepareChannelForDB,
|
|
|
|
preparePlaylistForDB
|
2020-02-19 15:39:35 +01:00
|
|
|
}
|