2019-11-11 02:20:00 +00:00
'use strict' ;
const config = require ( 'config' ) ;
const Promise = require ( 'bluebird' ) ;
const path = require ( 'path' ) ;
const fs = require ( 'fs-extra' ) ;
const bhttp = require ( 'bhttp' ) ;
const mime = require ( 'mime' ) ;
const sharp = require ( 'sharp' ) ;
const blake2 = require ( 'blake2' ) ;
const knex = require ( './knex' ) ;
function getHash ( buffer ) {
const hash = blake2 . createHash ( 'blake2b' , { digestLength : 24 } ) ;
hash . update ( buffer ) ;
return hash . digest ( 'hex' ) ;
}
2019-11-12 00:22:20 +00:00
async function getThumbnail ( buffer ) {
return sharp ( buffer )
. resize ( {
height : config . media . thumbnailSize ,
withoutEnlargement : true ,
} )
. toBuffer ( ) ;
}
2019-11-16 02:33:36 +00:00
async function createMediaDirectory ( release , releaseId ) {
if ( release . poster || ( release . photos && release . photos . length ) ) {
await fs . mkdir (
path . join ( config . media . path , release . site . network . slug , release . site . slug , releaseId . toString ( ) ) ,
{ recursive : true } ,
) ;
}
}
2019-11-11 02:20:00 +00:00
async function storePoster ( release , releaseEntry ) {
2019-11-16 02:33:36 +00:00
if ( ! release . poster ) {
console . warn ( ` No poster available for ( ${ release . site . name } , ${ releaseEntry . id } }) " ${ release . title } " ` ) ;
return ;
}
2019-11-11 02:20:00 +00:00
console . log ( ` Storing poster for ( ${ release . site . name } , ${ releaseEntry . id } ) " ${ release . title } " ` ) ;
const res = await bhttp . get ( release . poster ) ;
2019-11-12 00:22:20 +00:00
const thumbnail = await getThumbnail ( res . body ) ;
2019-11-11 02:20:00 +00:00
if ( res . statusCode === 200 ) {
const { pathname } = new URL ( release . poster ) ;
const mimetype = res . headers [ 'content-type' ] || mime . getType ( pathname ) || 'image/jpeg' ;
const extension = mime . getExtension ( mimetype ) ;
const filepath = path . join ( release . site . network . slug , release . site . slug , releaseEntry . id . toString ( ) , ` poster. ${ extension } ` ) ;
const thumbpath = path . join ( release . site . network . slug , release . site . slug , releaseEntry . id . toString ( ) , ` poster_thumb. ${ extension } ` ) ;
const hash = getHash ( res . body ) ;
await Promise . all ( [
fs . writeFile ( path . join ( config . media . path , filepath ) , res . body ) ,
fs . writeFile ( path . join ( config . media . path , thumbpath ) , thumbnail ) ,
] ) ;
await knex ( 'media' ) . insert ( {
path : filepath ,
thumbnail : thumbpath ,
mime : mimetype ,
hash ,
2019-11-12 00:22:20 +00:00
source : release . poster ,
2019-11-11 02:20:00 +00:00
domain : 'releases' ,
target _id : releaseEntry . id ,
role : 'poster' ,
} ) ;
return ;
}
console . warn ( ` Failed to store poster for ( ${ release . site . name } , ${ releaseEntry . id } ) " ${ release . title } ": ${ res . statusCode } ` ) ;
}
async function storePhotos ( release , releaseEntry ) {
2019-11-16 02:33:36 +00:00
if ( release . photos . length === 0 ) {
console . warn ( ` No photos available for ( ${ release . site . name } , ${ releaseEntry . id } }) " ${ release . title } " ` ) ;
return ;
}
2019-11-11 02:20:00 +00:00
console . log ( ` Storing ${ release . photos . length } photos for ( ${ release . site . name } , ${ releaseEntry . id } ) " ${ release . title } " ` ) ;
const files = await Promise . map ( release . photos , async ( photoUrl , index ) => {
const { pathname } = new URL ( photoUrl ) ;
const mimetype = mime . getType ( pathname ) ;
2019-11-12 00:22:20 +00:00
try {
const res = await bhttp . get ( photoUrl ) ;
const thumbnail = await getThumbnail ( res . body ) ;
2019-11-11 02:20:00 +00:00
2019-11-12 00:22:20 +00:00
if ( res . statusCode === 200 ) {
const extension = mime . getExtension ( mimetype ) ;
2019-11-11 02:20:00 +00:00
2019-11-12 00:22:20 +00:00
const filepath = path . join ( release . site . network . slug , release . site . slug , releaseEntry . id . toString ( ) , ` ${ index + 1 } . ${ extension } ` ) ;
const thumbpath = path . join ( release . site . network . slug , release . site . slug , releaseEntry . id . toString ( ) , ` ${ index + 1 } _thumb. ${ extension } ` ) ;
const hash = getHash ( res . body ) ;
2019-11-11 02:20:00 +00:00
2019-11-12 00:22:20 +00:00
await Promise . all ( [
fs . writeFile ( path . join ( config . media . path , filepath ) , res . body ) ,
fs . writeFile ( path . join ( config . media . path , thumbpath ) , thumbnail ) ,
] ) ;
2019-11-11 02:20:00 +00:00
2019-11-12 00:22:20 +00:00
return {
filepath ,
thumbpath ,
mimetype ,
hash ,
source : photoUrl ,
} ;
}
2019-11-11 02:20:00 +00:00
2019-11-12 00:22:20 +00:00
throw new Error ( ` Response ${ res . statusCode } not OK ` ) ;
} catch ( error ) {
console . warn ( ` Failed to store photo ${ index + 1 } for " ${ release . title } " ( ${ photoUrl } , ${ release . url } , ${ release . site . name } , ${ releaseEntry . id } ): ${ error } ` ) ;
2019-11-11 02:20:00 +00:00
2019-11-12 00:22:20 +00:00
return null ;
}
2019-11-11 02:20:00 +00:00
} , {
concurrency : 2 ,
} ) ;
await knex ( 'media' )
. insert ( files . filter ( file => file )
. map ( ( file , index ) => ( {
path : file . filepath ,
thumbnail : file . thumbpath ,
mime : file . mimetype ,
hash : file . hash ,
2019-11-12 00:22:20 +00:00
source : file . source ,
2019-11-11 02:20:00 +00:00
index ,
domain : 'releases' ,
target _id : releaseEntry . id ,
role : 'photo' ,
} ) ) ) ;
}
async function storeTrailer ( release , releaseEntry ) {
2019-11-16 02:33:36 +00:00
if ( ! release . trailer || ! release . trailer . src ) {
console . warn ( ` No trailer available for ( ${ release . site . name } , ${ releaseEntry . id } }) " ${ release . title } " ` ) ;
return ;
}
2019-11-11 02:20:00 +00:00
console . log ( ` Storing trailer for ( ${ release . site . name } , ${ releaseEntry . id } ) " ${ release . title } " ` ) ;
const { pathname } = new URL ( release . trailer . src ) ;
const mimetype = release . trailer . type || mime . getType ( pathname ) ;
const res = await bhttp . get ( release . trailer . src ) ;
const filepath = path . join ( release . site . network . slug , release . site . slug , releaseEntry . id . toString ( ) , ` trailer ${ release . trailer . quality ? ` _ ${ release . trailer . quality } ` : '' } . ${ mime . getExtension ( mimetype ) } ` ) ;
await Promise . all ( [
fs . writeFile ( path . join ( config . media . path , filepath ) , res . body ) ,
knex ( 'media' ) . insert ( {
path : filepath ,
mime : mimetype ,
2019-11-12 00:22:20 +00:00
source : release . trailer . src ,
2019-11-11 02:20:00 +00:00
domain : 'releases' ,
target _id : releaseEntry . id ,
role : 'trailer' ,
quality : release . trailer . quality || null ,
} ) ,
] ) ;
}
module . exports = {
2019-11-16 02:33:36 +00:00
createMediaDirectory ,
2019-11-11 02:20:00 +00:00
storePoster ,
storePhotos ,
storeTrailer ,
} ;