2023-03-03 16:44:40 +00:00
const { PrismaClient } = require ( '@prisma/client' )
const prisma = new PrismaClient ( )
const DOMPurify = require ( 'isomorphic-dompurify' )
2024-03-30 19:05:11 +00:00
const rtm = require ( 'readable-to-ms' )
2023-03-03 16:44:40 +00:00
const metadata = require ( '../utils/metadata.js' )
2024-02-15 15:13:12 +00:00
const redis = require ( '../utils/redis.js' )
2023-03-03 16:44:40 +00:00
exports . getVideo = async ( req , res ) => {
2024-02-15 15:13:12 +00:00
let info
const cached = await redis . get ( ` video: ${ req . params . id } ` )
if ( cached ) {
info = JSON . parse ( cached )
} else {
info = await prisma . videos . findFirst ( {
where : {
id : req . params . id
} ,
select : {
title : true ,
description : true ,
thumbnail : true ,
source : true ,
published : true ,
archived : true ,
channel : true ,
channelId : true ,
channelAvatar : true ,
channelVerified : true ,
2024-03-15 17:11:12 +00:00
disabled : true ,
hasBeenReported : true
2024-02-15 15:13:12 +00:00
}
} )
if ( ! info ) return res . json ( { error : '404' } )
await redis . set ( ` video: ${ req . params . id } ` , JSON . stringify ( info ) , 'EX' , 3600 )
}
2023-03-03 16:44:40 +00:00
res . json ( {
... info ,
description : DOMPurify . sanitize ( info . description ) ,
} )
}
exports . getChannel = async ( req , res ) => {
2024-02-15 15:13:12 +00:00
const cached = await redis . get ( ` channel: ${ req . params . id } ` )
if ( cached ) return res . json ( JSON . parse ( cached ) )
const [ videos , channel ] = await Promise . all ( [
metadata . getChannelVideos ( req . params . id ) ,
metadata . getChannel ( req . params . id )
] )
2023-03-24 15:49:25 +00:00
2024-03-30 10:11:49 +00:00
if ( ! videos || ! channel || videos . error || channel . error ) {
2024-02-15 15:13:12 +00:00
return res . json ( { error : '404' } ) ;
}
2023-03-03 16:44:40 +00:00
const archived = await prisma . videos . findMany ( {
where : {
channelId : req . params . id
} ,
select : {
id : true ,
title : true ,
thumbnail : true ,
published : true ,
archived : true
}
} )
2024-03-30 19:05:11 +00:00
const processedVideos = videos . map ( video => {
const date = ! isNaN ( new Date ( video . published . text ) . getTime ( ) ) ? new Date ( video . published . text ) : new Date ( ( new Date ( ) ) . getTime ( ) - rtm ( video . published . text ) . ms ) ; // life is great.
return {
id : video . id ,
title : video . title . text ,
thumbnail : video . thumbnails [ 0 ] . url ,
published : new Date ( date ) . toISOString ( ) . slice ( 0 , 10 )
}
} ) ;
2024-02-15 15:13:12 +00:00
archived . forEach ( v => {
const existingVideoIndex = processedVideos . findIndex ( video => video . id === v . id ) ;
if ( existingVideoIndex !== - 1 ) {
processedVideos [ existingVideoIndex ] = v ;
2023-03-03 16:44:40 +00:00
} else {
2024-02-15 15:13:12 +00:00
processedVideos . push ( { ... v , deleted : undefined } ) ;
2023-03-03 16:44:40 +00:00
}
2024-02-15 15:13:12 +00:00
} ) ;
processedVideos . sort ( ( a , b ) => new Date ( b . published ) - new Date ( a . published ) ) ;
const json = {
2024-03-30 10:11:49 +00:00
name : channel . metadata . title ,
avatar : channel . metadata . avatar [ 0 ] . url ,
2024-05-20 19:58:06 +00:00
verified : channel . header . author ? . is _verified ,
2024-02-15 15:13:12 +00:00
videos : processedVideos
}
await redis . set ( ` channel: ${ req . params . id } ` , JSON . stringify ( json ) , 'EX' , 3600 )
res . json ( json )
}
exports . getOnlyChannelVideos = async ( req , res ) => {
const cached = await redis . get ( ` channelVideos: ${ req . params . id } ` )
if ( cached ) return res . json ( JSON . parse ( cached ) )
const archived = await prisma . videos . findMany ( {
where : {
channelId : req . params . id
} ,
select : {
id : true ,
title : true ,
thumbnail : true ,
published : true ,
archived : true
} ,
orderBy : {
published : 'desc'
}
2023-03-03 16:44:40 +00:00
} )
2024-02-15 15:13:12 +00:00
const json = {
videos : archived
}
await redis . set ( ` channelVideos: ${ req . params . id } ` , JSON . stringify ( json ) , 'EX' , 3600 )
res . json ( json )
2023-03-03 16:44:40 +00:00
}
exports . getPlaylist = async ( req , res ) => {
2024-02-15 15:13:12 +00:00
const cached = await redis . get ( ` playlist: ${ req . params . id } ` )
if ( cached ) return res . json ( JSON . parse ( cached ) )
2023-03-24 14:20:06 +00:00
const playlist = await metadata . getPlaylistVideos ( req . params . id )
2024-02-15 15:13:12 +00:00
if ( ! playlist || playlist . error ) return res . json ( { error : '404' } )
2023-03-03 16:44:40 +00:00
const playlistArchived = await prisma . videos . findMany ( {
where : {
playlist : req . params . id
} ,
select : {
id : true ,
title : true ,
thumbnail : true ,
published : true ,
archived : true
}
} )
2024-02-15 15:13:12 +00:00
const allVideos = playlist . relatedStreams . map ( video => ( {
id : video . url . replace ( '/watch?v=' , '' ) ,
published : new Date ( video . uploaded ) . toISOString ( ) . slice ( 0 , 10 ) ,
... video
} ) ) ;
2023-03-03 16:44:40 +00:00
await Promise . all ( playlistArchived . map ( async ( v ) => {
2024-02-15 15:13:12 +00:00
const allVideo = allVideos . find ( o => o . id == v . id ) ;
2023-03-03 16:44:40 +00:00
if ( allVideo ) {
2024-02-15 15:13:12 +00:00
const index = allVideos . findIndex ( o => o . id == v . id ) ;
allVideos [ index ] = v ;
2023-03-03 16:44:40 +00:00
} else {
2024-02-15 15:13:12 +00:00
const live = await metadata . getVideoMetadata ( v . id ) ;
2023-03-03 16:44:40 +00:00
allVideos . push ( {
2024-02-15 15:13:12 +00:00
... v ,
2023-03-03 16:44:40 +00:00
deleted : live . error ? true : false
2024-02-15 15:13:12 +00:00
} ) ;
2023-03-03 16:44:40 +00:00
}
2024-02-15 15:13:12 +00:00
} ) ) ;
await Promise . all ( allVideos . filter ( v => ! v . archived ) . map ( async ( v ) => {
const video = await prisma . videos . findFirst ( {
where : {
id : v . id
} ,
select : {
id : true ,
title : true ,
thumbnail : true ,
published : true ,
archived : true
2023-03-03 16:44:40 +00:00
}
2024-02-15 15:13:12 +00:00
} ) ;
if ( video ) {
const index = allVideos . findIndex ( o => o . id == v . id ) ;
allVideos [ index ] = video ;
2023-03-03 16:44:40 +00:00
}
2024-02-15 15:13:12 +00:00
} ) ) ;
allVideos . sort ( ( a , b ) => new Date ( b . published ) - new Date ( a . published ) ) ;
const json = {
2023-03-03 16:44:40 +00:00
name : playlist . name ,
2024-02-15 15:13:12 +00:00
channel : playlist . uploader ,
2023-03-03 16:44:40 +00:00
url : playlist . uploaderUrl ,
avatar : playlist . uploaderAvatar ,
2024-02-15 15:13:12 +00:00
videos : allVideos
}
await redis . set ( ` playlist: ${ req . params . id } ` , JSON . stringify ( json ) , 'EX' , 3600 )
res . json ( json )
2023-03-03 16:44:40 +00:00
}