1
0
Fork 0
mirror of https://github.com/Chocobozzz/PeerTube.git synced 2025-10-03 09:49:20 +02:00

Fix fetching latest elements of a playlist

This commit is contained in:
Chocobozzz 2025-08-11 14:52:09 +02:00
parent 6fce7c808c
commit b4df49b87f
No known key found for this signature in database
GPG key ID: 583A612D890159BE
2 changed files with 25 additions and 10 deletions

View file

@ -29,17 +29,22 @@ export class VideoChannelSyncLatestScheduler extends AbstractScheduler {
logger.info( logger.info(
'Creating video import jobs for "%s" sync with external channel "%s"', 'Creating video import jobs for "%s" sync with external channel "%s"',
channel.Actor.preferredUsername, sync.externalChannelUrl channel.Actor.preferredUsername,
sync.externalChannelUrl
) )
const onlyAfter = sync.lastSyncAt || sync.createdAt // We can't rely on publication date for playlist elements
// For example, an old video may have been added to a playlist since the last sync
const skipPublishedBefore = this.isPlaylistUrl(sync.externalChannelUrl)
? undefined
: sync.lastSyncAt || sync.createdAt
await synchronizeChannel({ await synchronizeChannel({
channel, channel,
externalChannelUrl: sync.externalChannelUrl, externalChannelUrl: sync.externalChannelUrl,
videosCountLimit: CONFIG.IMPORT.VIDEO_CHANNEL_SYNCHRONIZATION.VIDEOS_LIMIT_PER_SYNCHRONIZATION, videosCountLimit: CONFIG.IMPORT.VIDEO_CHANNEL_SYNCHRONIZATION.VIDEOS_LIMIT_PER_SYNCHRONIZATION,
channelSync: sync, channelSync: sync,
onlyAfter skipPublishedBefore
}) })
} }
} }
@ -47,4 +52,14 @@ export class VideoChannelSyncLatestScheduler extends AbstractScheduler {
static get Instance () { static get Instance () {
return this.instance || (this.instance = new this()) return this.instance || (this.instance = new this())
} }
private isPlaylistUrl (url: string): boolean {
const parsed = new URL(url)
const pathname = parsed.pathname.toLowerCase()
return pathname.startsWith('/playlist/') || // Dailymotion playlist
pathname.startsWith('/showcase/') || // Vimeo playlist
pathname.startsWith('/playlist?') || // YouTube playlist
pathname.startsWith('/w/p/') // PeerTube playlist
}
} }

View file

@ -16,9 +16,9 @@ export async function synchronizeChannel (options: {
externalChannelUrl: string externalChannelUrl: string
videosCountLimit: number videosCountLimit: number
channelSync?: MChannelSync channelSync?: MChannelSync
onlyAfter?: Date skipPublishedBefore?: Date
}) { }) {
const { channel, externalChannelUrl, videosCountLimit, onlyAfter, channelSync } = options const { channel, externalChannelUrl, videosCountLimit, skipPublishedBefore, channelSync } = options
if (channelSync) { if (channelSync) {
channelSync.state = VideoChannelSyncState.PROCESSING channelSync.state = VideoChannelSyncState.PROCESSING
@ -58,7 +58,7 @@ export async function synchronizeChannel (options: {
logger.debug(`Import candidate: ${targetUrl}`, lTags()) logger.debug(`Import candidate: ${targetUrl}`, lTags())
try { try {
if (await skipImport({ channel, channelSync, targetUrl, onlyAfter })) continue if (await skipImport({ channel, channelSync, targetUrl, skipPublishedBefore })) continue
const { job } = await buildYoutubeDLImport({ const { job } = await buildYoutubeDLImport({
user, user,
@ -98,9 +98,9 @@ async function skipImport (options: {
channel: MChannelAccountDefault channel: MChannelAccountDefault
channelSync: MChannelSync channelSync: MChannelSync
targetUrl: string targetUrl: string
onlyAfter?: Date skipPublishedBefore?: Date
}) { }) {
const { channel, channelSync, targetUrl, onlyAfter } = options const { channel, channelSync, targetUrl, skipPublishedBefore } = options
if (await VideoImportModel.urlAlreadyImported({ channelId: channel.id, channelSyncId: channelSync?.id, targetUrl })) { if (await VideoImportModel.urlAlreadyImported({ channelId: channel.id, channelSyncId: channelSync?.id, targetUrl })) {
logger.debug( logger.debug(
@ -110,7 +110,7 @@ async function skipImport (options: {
return true return true
} }
if (onlyAfter) { if (skipPublishedBefore) {
const youtubeDL = new YoutubeDLWrapper( const youtubeDL = new YoutubeDLWrapper(
targetUrl, targetUrl,
ServerConfigManager.Instance.getEnabledResolutions('vod'), ServerConfigManager.Instance.getEnabledResolutions('vod'),
@ -119,7 +119,7 @@ async function skipImport (options: {
const videoInfo = await youtubeDL.getInfoForDownload() const videoInfo = await youtubeDL.getInfoForDownload()
const onlyAfterWithoutTime = new Date(onlyAfter) const onlyAfterWithoutTime = new Date(skipPublishedBefore)
onlyAfterWithoutTime.setHours(0, 0, 0, 0) onlyAfterWithoutTime.setHours(0, 0, 0, 0)
if (videoInfo.originallyPublishedAtWithoutTime.getTime() < onlyAfterWithoutTime.getTime()) { if (videoInfo.originallyPublishedAtWithoutTime.getTime() < onlyAfterWithoutTime.getTime()) {