Skip to content

Commit

Permalink
feat(core): add class for accessing the newer media catalog
Browse files Browse the repository at this point in the history
DTO structure is kept the same for compatibility, previous methods are marked deprecated

closes #55
  • Loading branch information
BenShelton committed Jun 23, 2021
1 parent 81da56e commit 881d264
Show file tree
Hide file tree
Showing 19 changed files with 510 additions and 29 deletions.
4 changes: 2 additions & 2 deletions docs/core/interfaces/types_media.catalogschemaversionrow.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The Media Catalog version.

#### Defined in

types/media.d.ts:20
[types/media.d.ts:20](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L20)

___

Expand All @@ -31,4 +31,4 @@ ___

#### Defined in

types/media.d.ts:16
[types/media.d.ts:16](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L16)
4 changes: 2 additions & 2 deletions docs/core/interfaces/types_media.categoryrow.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#### Defined in

types/media.d.ts:112
[types/media.d.ts:112](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L112)

___

Expand All @@ -29,4 +29,4 @@ ___

#### Defined in

types/media.d.ts:111
[types/media.d.ts:111](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L111)
6 changes: 3 additions & 3 deletions docs/core/interfaces/types_media.categoryrowobjcontainer.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

#### Defined in

types/media.d.ts:94
[types/media.d.ts:94](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L94)

___

Expand All @@ -42,7 +42,7 @@ A list of `naturalKey` values that can be used to link to a [MediaItemRow](types

#### Defined in

types/media.d.ts:105
[types/media.d.ts:105](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L105)

___

Expand All @@ -56,4 +56,4 @@ The media available is under `media`.

#### Defined in

types/media.d.ts:93
[types/media.d.ts:93](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L93)
8 changes: 4 additions & 4 deletions docs/core/interfaces/types_media.categoryrowobjondemand.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

#### Defined in

types/media.d.ts:79
[types/media.d.ts:79](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L79)

___

Expand All @@ -31,7 +31,7 @@ ___

#### Defined in

types/media.d.ts:80
[types/media.d.ts:80](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L80)

___

Expand All @@ -43,7 +43,7 @@ Nested "pages" of categories.

#### Defined in

types/media.d.ts:84
[types/media.d.ts:84](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L84)

___

Expand All @@ -57,4 +57,4 @@ The nested categories are under `subcategories`.

#### Defined in

types/media.d.ts:78
[types/media.d.ts:78](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L78)
10 changes: 5 additions & 5 deletions docs/core/interfaces/types_media.imagesizes.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Large size.

#### Defined in

types/media.d.ts:43
[types/media.d.ts:43](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L43)

___

Expand All @@ -38,7 +38,7 @@ Medium size.

#### Defined in

types/media.d.ts:38
[types/media.d.ts:38](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L38)

___

Expand All @@ -51,7 +51,7 @@ Small size.

#### Defined in

types/media.d.ts:33
[types/media.d.ts:33](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L33)

___

Expand All @@ -66,7 +66,7 @@ Isn't always available. If not use `lg` instead.

#### Defined in

types/media.d.ts:50
[types/media.d.ts:50](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L50)

___

Expand All @@ -79,4 +79,4 @@ Extra small size.

#### Defined in

types/media.d.ts:28
[types/media.d.ts:28](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L28)
4 changes: 2 additions & 2 deletions docs/core/interfaces/types_media.languagerow.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Details about the language being used in this Media Catalog.

#### Defined in

types/media.d.ts:58
[types/media.d.ts:58](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L58)

___

Expand All @@ -43,4 +43,4 @@ ___

#### Defined in

types/media.d.ts:54
[types/media.d.ts:54](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L54)
4 changes: 2 additions & 2 deletions docs/core/interfaces/types_media.mediacatalogctor.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The Meps Language Id of this publication.

#### Defined in

types/media.d.ts:12
[types/media.d.ts:12](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L12)

___

Expand All @@ -35,4 +35,4 @@ The path to the downloaded Media Catalog.

#### Defined in

types/media.d.ts:8
[types/media.d.ts:8](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L8)
4 changes: 2 additions & 2 deletions docs/core/interfaces/types_media.mediaitemrow.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

#### Defined in

types/media.d.ts:117
[types/media.d.ts:117](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L117)

___

Expand All @@ -45,4 +45,4 @@ ___

#### Defined in

types/media.d.ts:116
[types/media.d.ts:116](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L116)
4 changes: 2 additions & 2 deletions docs/core/interfaces/types_media.signaturerow.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ A hash of some sort.

#### Defined in

types/media.d.ts:189
[types/media.d.ts:189](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L189)

___

Expand All @@ -31,4 +31,4 @@ ___

#### Defined in

types/media.d.ts:185
[types/media.d.ts:185](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L185)
4 changes: 2 additions & 2 deletions docs/core/modules/types_media.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

#### Defined in

types/media.d.ts:108
[types/media.d.ts:108](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L108)

___

Expand All @@ -43,4 +43,4 @@ Rows can have different structures and are identified using `type`.

#### Defined in

types/media.d.ts:197
[types/media.d.ts:197](https://github.com/BenShelton/library-api/blob/master/packages/core/types/media.d.ts#L197)
33 changes: 32 additions & 1 deletion packages/core/src/catalog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { downloadCatalog } from './download'
import { join } from 'path'

import { downloadCatalog, downloadMediaCatalog } from './download'
import { getLanguageById } from './language'
import { checkExists } from './utils'
import { MediaCatalog } from './classes/Media'

/**
* @todo Check for latest version, currently just checks existence of file.
Expand All @@ -18,3 +22,30 @@ export async function updateCatalog (path: string): Promise<boolean> {
}
return false
}

/**
* @todo Check for latest version, currently just checks existence of file.
*
* Retrieves a media catalog file and returns a {@link MediaCatalog} instance if it exists.
* Will download the file if it is not yet downloaded.
*
* @param dir The directory where media catalogs are to be stored.
* @param languageId The Meps Language Id to use.
*
* @returns A {@link MediaCatalog} if it exists, `null` if not found.
*/
export async function getMediaCatalog (dir: string, languageId: number): Promise<MediaCatalog | null> {
const language = getLanguageById(languageId)
if (!language) return null
const code = language.symbol
const path = join(dir, `media-catalog-${code}.ndjson`)
const exists = await checkExists(path)
if (!exists) {
try {
await downloadMediaCatalog(code, path)
} catch (err) {
return null
}
}
return new MediaCatalog({ path, languageId })
}
3 changes: 3 additions & 0 deletions packages/core/src/classes/Database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ export class CatalogDatabase extends Database {
}

/**
* @deprecated These details are no longer found in the main catalog.
* Use {@link getMediaCatalog} instead and use the `getMediaDetails` method on the returned class.
*
* Retrieves information about a video from the main catalog.
* The video details found within a publication's database contain limited information about the video itself.
* Most of this information is contained within the main catalog but mapped completely differently.
Expand Down
23 changes: 22 additions & 1 deletion packages/core/src/classes/Mapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ImageRow, LanguageRow, MediaDetailsRow, VideoRow } from '../../types/database'
import { ImageDTO, LanguageDTO, MediaDetailsDTO, VideoDTO } from '../../types/dto'
import { ImageDTO, LanguageDTO, MediaCatalogItemDTO, MediaDetailsDTO, VideoDTO } from '../../types/dto'

interface PublicationMapperCtor {
filename: string
Expand Down Expand Up @@ -163,3 +163,24 @@ export class LanguageMapper {
return languages.map(language => this.MapLanguage(language))
}
}

/**
* Maps Media Catalog database details to more accessible DTOs.
*/
export class MediaCatalogMapper {
/**
* Maps a Media Catalog media details row to a Media Details DTO.
*
* @param details The database row.
*/
public MapMediaDetails (details: MediaCatalogItemDTO): MediaDetailsDTO {
return {
id: `media#${details.id}`,
filename: details.id,
caption: details.title,
height: 0,
width: 0,
url: details.image
}
}
}
104 changes: 104 additions & 0 deletions packages/core/src/classes/Media.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { MediaCatalogMapper } from './Mapper'
import { readLines } from '../utils'

import { MediaDetailsDTO, MediaCatalogDatabaseDTO } from '../../types/dto'
import { MediaCatalogCtor, MediaCatalogRow } from '../../types/media'

export class MediaCatalog {
private _database: MediaCatalogDatabaseDTO | null = null
private _mapper: MediaCatalogMapper
path: string
languageId: number

/**
* @param {Object} ctor See {@link MediaCatalogCtor}
*/
constructor ({ path, languageId }: MediaCatalogCtor) {
this.path = path
this.languageId = languageId
this._mapper = new MediaCatalogMapper()
}

/**
* Loads the media catalog from the NDJSON file and transforms it into an object that is easier to work with
*
* Will cache the loaded database so subsequent calls will be quicker.
*/
async getDatabase (): Promise<MediaCatalogDatabaseDTO> {
if (this._database) return this._database
const newDatabase: MediaCatalogDatabaseDTO = {
version: 0,
categories: [],
mediaItems: []
}
await readLines(this.path, line => {
const json: MediaCatalogRow = JSON.parse(line)
switch (json.type) {
case 'catalogSchemaVersion':
newDatabase.version = json.o
break
case 'category':
newDatabase.categories.push(json.o)
break
case 'media-item': {
const details = json.o
const { lsr, sqr } = details.images
newDatabase.mediaItems.push({
languageAgnosticId: details.languageAgnosticNaturalKey,
id: details.naturalKey,
doc: 'docID' in details.keyParts ? details.keyParts.docID : details.keyParts.pubSymbol,
issue: 'issueDate' in details.keyParts ? details.keyParts.issueDate : undefined,
track: details.keyParts.track,
format: details.keyParts.formatCode,
key: details.primaryCategory,
title: details.title,
duration: details.duration,
image: lsr ? (lsr.xl || lsr.lg || lsr.md || lsr.sm || lsr.xs) : '',
imageSqr: sqr ? (sqr.xl || sqr.lg || sqr.md || sqr.sm || sqr.xs) : ''
})
}
}
})
this._database = newDatabase
return newDatabase
}

/**
* Retrieves information about a video from the media catalog.
* The video details found within a publication's database contain limited information about the video itself.
* Most of this information is contained within a separate file which is divided per language.
*
* This method allows passing in the video returned from the publication to get more details from the media catalog.
* The returned image will be of the highest quality available (biggest size).
*
* @param video Pass in a returned {@link VideoDTO} from another method, see example.
*
* @returns MediaDetails if they exist, `null` if they are not found.
*
* @example
* ```ts
* const video = publication.getVideo(...)
* const details = await mediaCatalog.getMediaDetails(video)
* ```
*/
async getMediaDetails ({ doc, issue, track }: { doc: string | number, issue: string | number, track: string | number }): Promise<MediaDetailsDTO | null> {
const db = await this.getDatabase()
const issueNum = Number(issue || 0)
const detailIssue = issueNum ? String(issueNum).substr(0, 6) : null
const details = db.mediaItems.find(item => {
if (detailIssue) {
if (detailIssue !== item.issue) return false
}
if (typeof item.doc === 'number') {
if (item.doc !== +doc) return false
} else {
if (item.doc !== String(doc)) return false
}
if (item.track !== +track) return false

return true
})
if (!details) return null
return this._mapper.MapMediaDetails(details)
}
}
Loading

0 comments on commit 881d264

Please sign in to comment.