import { fromPairs } from 'ramda' ; import { oc } from 'ts-optchain' ; import { IssuePublicationIdentifier , IssueSummary , ImageSize , imageSizes , notNull , } from '../../../../common' ; import { getPublishedId } from '../../../utils/path-builder' ; import { issue } from '../../../../main' ; import { getEditionDisplayName } from '../../../services/editions-mappings' ; import { Bucket , s3 } from '../../../utils/s3' ; const identifyAssetFiles = ( assetKeys ) => { return fromPairs ( assetKeys . map ( ( key ) : [ ImageSize | 'data' | 'html' , string ] | null => { const filename = key . split ( '/' ) . slice ( - 1 ) [ 0 ] . replace ( '.zip' , '' ) ; if ( filename === 'data' || filename === 'html' ) { return [ filename , key ] ; } const breakpoint = imageSizes . find ( size => size === filename ) ; if ( breakpoint === undefined ) return null ; return [ breakpoint , key ] ; } ) . filter ( notNull ) ) ; } ; const makeImageAssetObject = ( assetFiles ) : { [ key in ImageSize ] ? : string ; } => { return fromPairs ( imageSizes . map ( ( size ) : [ ImageSize , string ] | null => { const asset = assetFiles [ size ] ; if ( asset == null ) return null ; return [ size , asset ] ; } ) . filter ( notNull ) ) ; } ; const getAssestKeysFromBucket = async ( bucket , prefix ) : Promise < string [ ] > => { const assetKeyList = await s3 . listObjectsV2 ( { Bucket : bucket . name , Prefix : prefix , } ) . promise ( ) ; const assetKeys = oc ( assetKeyList ) . Contents ( [ ] ) . map ( _ => _ . Key ) . filter ( notNull ) ; console . log ( `getIssueSummary, get assetKeyList from s3://${ bucket . name }/${ prefix }` , JSON . stringify ( assetKeyList ) ) ; return assetKeys ; } ; export const getIssueSummaryInternal = async ( issuePublication , assetKeys , assetKeysSSR , name ) : Promise < IssueSummary | undefined > => { const { edition , issueDate } = issuePublication ; const publishedIssuePrefix = getPublishedId ( issuePublication ) ; const dateFromIssue = new Date ( issueDate ) ; if ( isNaN ( dateFromIssue . getTime ( ) ) ) { console . warn ( `Issue with path ${ issueDate } is not a valid date` ) ; return undefined ; } const assetFiles = identifyAssetFiles ( assetKeys ) ; if ( assetFiles . data == null ) { console . log ( `No data for ${ issue }` ) ; return undefined ; } const images = makeImageAssetObject ( assetFiles ) ; const assets = { data : assetFiles . data , ... images } ; const assetFilesSSR = identifyAssetFiles ( assetKeysSSR ) ; if ( assetFilesSSR . html == null ) { console . log ( `No html in ssr folder for ${ issue }` ) ; return undefined ; } const imagesSSR = makeImageAssetObject ( assetFilesSSR ) ; const assetsSSR = { data : assetFiles . data , html : assetFilesSSR . html , ... imagesSSR , } ; const localId = `${ edition }/${ issueDate }` ; const key = localId ; return { key , localId , publishedId : publishedIssuePrefix , name , date : issueDate , assets , assetsSSR , } ; } ; export const getIssueSummary = async ( issuePublication , bucket ) : Promise < IssueSummary | undefined > => { const displayName = await getEditionDisplayName ( issuePublication . edition ) ; const publishedIssuePrefix = getPublishedId ( issuePublication ) ; const prefix = `zips/${ publishedIssuePrefix }/` ; const assetKeys = await getAssestKeysFromBucket ( bucket , prefix ) ; const assetWithoutSSR = assetKeys . filter ( key => key . indexOf ( '/ssr' ) == - 1 ) ; const prefixSSR = `zips/${ publishedIssuePrefix }/ssr` ; const assetKeysSSR = await getAssestKeysFromBucket ( bucket , prefixSSR ) ; return getIssueSummaryInternal ( issuePublication , assetWithoutSSR , assetKeysSSR , displayName ) ; } ;