import { CONSTRAINTS_FIELDS , VIDEO_CATEGORIES , VIDEO_LANGUAGES , VIDEO_LICENCES } from '../../initializers/constants' ; import { peertubeTruncate } from '../core-utils' ; type YoutubeDLInfo = { name ? : string ; description ? : string ; category ? : number ; language ? : string ; licence ? : number ; nsfw ? : boolean ; tags ? : string [ ] ; thumbnailUrl ? : string ; ext ? : string ; originallyPublishedAt ? : Date ; } ; class YoutubeDLInfoBuilder { private readonly info : any ; constructor ( info ) { this . info = { ... info } ; } getInfo ( ) { const obj = this . buildVideoInfo ( this . normalizeObject ( this . info ) ) ; if ( obj . name && obj . name . length < CONSTRAINTS_FIELDS . VIDEOS . NAME . min ) obj . name += ' video' ; return obj ; } private normalizeObject ( obj ) { const newObj = { } ; for ( const key of Object . keys ( obj ) ) { if ( key === 'resolution' ) continue ; const value = obj [ key ] ; if ( typeof value === 'string' ) { newObj [ key ] = value . normalize ( ) ; } else { newObj [ key ] = value ; } } return newObj ; } private buildOriginallyPublishedAt ( obj ) { let originallyPublishedAt = null ; const uploadDateMatcher = /^(\d{4})(\d{2})(\d{2})$/ . exec ( obj . upload_date ) ; if ( uploadDateMatcher ) { originallyPublishedAt = new Date ( ) ; originallyPublishedAt . setHours ( 0 , 0 , 0 , 0 ) ; const year = parseInt ( uploadDateMatcher [ 1 ] , 10 ) ; const month = parseInt ( uploadDateMatcher [ 2 ] , 10 ) - 1 ; const day = parseInt ( uploadDateMatcher [ 3 ] , 10 ) ; originallyPublishedAt . setFullYear ( year , month , day ) ; } return originallyPublishedAt ; } private buildVideoInfo ( obj ) { return { name : this . titleTruncation ( obj . title ) , description : this . descriptionTruncation ( obj . description ) , category : this . getCategory ( obj . categories ) , licence : this . getLicence ( obj . license ) , language : this . getLanguage ( obj . language ) , nsfw : this . isNSFW ( obj ) , tags : this . getTags ( obj . tags ) , thumbnailUrl : obj . thumbnail || undefined , originallyPublishedAt : this . buildOriginallyPublishedAt ( obj ) , ext : obj . ext } ; } private titleTruncation ( title ) { return peertubeTruncate ( title , { length : CONSTRAINTS_FIELDS . VIDEOS . NAME . max , separator : /,? +/ , omission : ' […]' } ) ; } private descriptionTruncation ( description ) { if ( ! description || description . length < CONSTRAINTS_FIELDS . VIDEOS . DESCRIPTION . min ) return undefined ; return peertubeTruncate ( description , { length : CONSTRAINTS_FIELDS . VIDEOS . DESCRIPTION . max , separator : /,? +/ , omission : ' […]' } ) ; } private isNSFW ( info ) { return info ?. age_limit >= 16 ; } private getTags ( tags ) { if ( Array . isArray ( tags ) === false ) return [ ] ; return tags . filter ( t => t . length < CONSTRAINTS_FIELDS . VIDEOS . TAG . max && t . length > CONSTRAINTS_FIELDS . VIDEOS . TAG . min ) . map ( t => t . normalize ( ) ) . slice ( 0 , 5 ) ; } private getLicence ( licence ) { if ( ! licence ) return undefined ; if ( licence . includes ( 'Creative Commons Attribution' ) ) return 1 ; for ( const key of Object . keys ( VIDEO_LICENCES ) ) { const peertubeLicence = VIDEO_LICENCES [ key ] ; if ( peertubeLicence . toLowerCase ( ) === licence . toLowerCase ( ) ) return parseInt ( key , 10 ) ; } return undefined ; } private getCategory ( categories ) { if ( ! categories ) return undefined ; const categoryString = categories [ 0 ] ; if ( ! categoryString || typeof categoryString !== 'string' ) return undefined ; if ( categoryString === 'News & Politics' ) return 11 ; for ( const key of Object . keys ( VIDEO_CATEGORIES ) ) { const category = VIDEO_CATEGORIES [ key ] ; if ( categoryString . toLowerCase ( ) === category . toLowerCase ( ) ) return parseInt ( key , 10 ) ; } return undefined ; } private getLanguage ( language ) { return VIDEO_LANGUAGES [ language ] ? language : undefined ; } } export { YoutubeDLInfo , YoutubeDLInfoBuilder } ;