|
@@ -1,20 +1,16 @@
|
|
|
// TODO: finish db cascade on save/remove; right now there is manually added `cascade: ["insert", "update"]` directive
|
|
|
// to all relations in `query-node/generated/graphql-server/src/modules/**/*.model.ts`. That should ensure all records
|
|
|
-// are saved on one `db.save(...)` call. Missing features
|
|
|
+// are saved on one `store.save(...)` call. Missing features
|
|
|
// - find a proper way to cascade on remove or implement custom removals for every entity
|
|
|
// - convert manual changes done to `*model.ts` file into some patch or bash commands that can be executed
|
|
|
// every time query node codegen is run (that will overwrite said manual changes)
|
|
|
// - verify in integration tests that the records are trully created/updated/removed as expected
|
|
|
|
|
|
-import { SubstrateEvent } from '@dzlzv/hydra-common'
|
|
|
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
|
|
|
+import { DatabaseManager } from '@dzlzv/hydra-common'
|
|
|
import { Bytes } from '@polkadot/types'
|
|
|
import ISO6391 from 'iso-639-1'
|
|
|
-import { u64 } from '@polkadot/types/primitive'
|
|
|
import { FindConditions } from 'typeorm'
|
|
|
-import * as jspb from "google-protobuf"
|
|
|
-
|
|
|
-// protobuf definitions
|
|
|
+import * as jspb from 'google-protobuf'
|
|
|
import {
|
|
|
ChannelMetadata,
|
|
|
ChannelCategoryMetadata,
|
|
@@ -24,19 +20,7 @@ import {
|
|
|
VideoMetadata,
|
|
|
VideoCategoryMetadata,
|
|
|
} from '@joystream/content-metadata-protobuf'
|
|
|
-
|
|
|
-import {
|
|
|
- Content,
|
|
|
-} from '../../../generated/types'
|
|
|
-
|
|
|
-import {
|
|
|
- invalidMetadata,
|
|
|
- inconsistentState,
|
|
|
- logger,
|
|
|
- prepareDataObject,
|
|
|
-} from '../common'
|
|
|
-
|
|
|
-
|
|
|
+import { invalidMetadata, inconsistentState, logger, prepareDataObject } from '../common'
|
|
|
import {
|
|
|
// primary entities
|
|
|
CuratorGroup,
|
|
@@ -44,32 +28,20 @@ import {
|
|
|
ChannelCategory,
|
|
|
Video,
|
|
|
VideoCategory,
|
|
|
-
|
|
|
// secondary entities
|
|
|
Language,
|
|
|
License,
|
|
|
- VideoMediaEncoding,
|
|
|
VideoMediaMetadata,
|
|
|
-
|
|
|
// asset
|
|
|
DataObjectOwner,
|
|
|
- DataObjectOwnerMember,
|
|
|
DataObjectOwnerChannel,
|
|
|
DataObject,
|
|
|
LiaisonJudgement,
|
|
|
AssetAvailability,
|
|
|
-
|
|
|
Membership,
|
|
|
-} from 'query-node'
|
|
|
-
|
|
|
+} from 'query-node/dist/model'
|
|
|
// Joystream types
|
|
|
-import {
|
|
|
- ChannelId,
|
|
|
- ContentParameters,
|
|
|
- NewAsset,
|
|
|
- ContentActor,
|
|
|
-} from '@joystream/types/augment'
|
|
|
-
|
|
|
+import { ContentParameters, NewAsset, ContentActor } from '@joystream/types/augment'
|
|
|
import { ContentParameters as Custom_ContentParameters } from '@joystream/types/storage'
|
|
|
import { registry } from '@joystream/types'
|
|
|
|
|
@@ -91,7 +63,7 @@ function isAssetInStorage(dataObject: AssetStorageOrUrls): dataObject is DataObj
|
|
|
|
|
|
export interface IReadProtobufArguments {
|
|
|
metadata: Bytes
|
|
|
- db: DatabaseManager
|
|
|
+ store: DatabaseManager
|
|
|
blockNumber: number
|
|
|
}
|
|
|
|
|
@@ -107,7 +79,6 @@ export interface IReadProtobufArgumentsWithAssets extends IReadProtobufArguments
|
|
|
Change - set the new value
|
|
|
*/
|
|
|
export class PropertyChange<T> {
|
|
|
-
|
|
|
static newUnset<T>(): PropertyChange<T> {
|
|
|
return new PropertyChange<T>('unset')
|
|
|
}
|
|
@@ -123,11 +94,10 @@ export class PropertyChange<T> {
|
|
|
/*
|
|
|
Determines property change from the given object property.
|
|
|
*/
|
|
|
- static fromObjectProperty<
|
|
|
- T,
|
|
|
- Key extends string,
|
|
|
- ChangedObject extends {[key in Key]?: T}
|
|
|
- >(object: ChangedObject, key: Key): PropertyChange<T> {
|
|
|
+ static fromObjectProperty<T, Key extends string, ChangedObject extends { [key in Key]?: T }>(
|
|
|
+ object: ChangedObject,
|
|
|
+ key: Key
|
|
|
+ ): PropertyChange<T> {
|
|
|
if (!(key in object)) {
|
|
|
return PropertyChange.newNoChange<T>()
|
|
|
}
|
|
@@ -148,27 +118,25 @@ export class PropertyChange<T> {
|
|
|
}
|
|
|
|
|
|
public isUnset(): boolean {
|
|
|
- return this.type == 'unset'
|
|
|
+ return this.type === 'unset'
|
|
|
}
|
|
|
|
|
|
public isNoChange(): boolean {
|
|
|
- return this.type == 'nochange'
|
|
|
+ return this.type === 'nochange'
|
|
|
}
|
|
|
|
|
|
public isValue(): boolean {
|
|
|
- return this.type == 'change'
|
|
|
+ return this.type === 'change'
|
|
|
}
|
|
|
|
|
|
public getValue(): T | undefined {
|
|
|
- return this.type == 'change'
|
|
|
- ? this.value
|
|
|
- : undefined
|
|
|
+ return this.type === 'change' ? this.value : undefined
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
Integrates the value into the given dictionary.
|
|
|
*/
|
|
|
- public integrateInto(object: Object, key: string): void {
|
|
|
+ public integrateInto(object: Record<string, unknown>, key: string): void {
|
|
|
if (this.isNoChange()) {
|
|
|
return
|
|
|
}
|
|
@@ -198,7 +166,7 @@ export interface RawVideoMetadata {
|
|
|
*/
|
|
|
export async function readProtobuf<T extends ChannelCategory | VideoCategory>(
|
|
|
type: T,
|
|
|
- parameters: IReadProtobufArguments,
|
|
|
+ parameters: IReadProtobufArguments
|
|
|
): Promise<Partial<T>> {
|
|
|
// true option here is crucial, it indicates that we want just the underlying bytes (by default it will also include bytes encoding the length)
|
|
|
const metaU8a = parameters.metadata.toU8a(true)
|
|
@@ -220,8 +188,8 @@ export async function readProtobuf<T extends ChannelCategory | VideoCategory>(
|
|
|
}
|
|
|
|
|
|
// this should never happen
|
|
|
- logger.error('Not implemented metadata type', {type})
|
|
|
- throw `Not implemented metadata type`
|
|
|
+ logger.error('Not implemented metadata type', { type })
|
|
|
+ throw new Error(`Not implemented metadata type`)
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -231,7 +199,7 @@ export async function readProtobuf<T extends ChannelCategory | VideoCategory>(
|
|
|
|
|
|
export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
type: T,
|
|
|
- parameters: IReadProtobufArgumentsWithAssets,
|
|
|
+ parameters: IReadProtobufArgumentsWithAssets
|
|
|
): Promise<Partial<T>> {
|
|
|
// true option here is crucial, it indicates that we want just the underlying bytes (by default it will also include bytes encoding the length)
|
|
|
const metaU8a = parameters.metadata.toU8a(true)
|
|
@@ -240,15 +208,15 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
if (type instanceof Channel) {
|
|
|
const meta = ChannelMetadata.deserializeBinary(metaU8a)
|
|
|
const metaAsObject = convertMetadataToObject<ChannelMetadata.AsObject>(meta)
|
|
|
- const result = metaAsObject as any as Partial<Channel>
|
|
|
+ const result = (metaAsObject as any) as Partial<Channel>
|
|
|
|
|
|
// prepare cover photo asset if needed
|
|
|
if ('coverPhoto' in metaAsObject) {
|
|
|
const asset = await extractAsset({
|
|
|
- //assetIndex: metaAsObject.coverPhoto,
|
|
|
+ // assetIndex: metaAsObject.coverPhoto,
|
|
|
assetIndex: metaAsObject.coverPhoto,
|
|
|
assets: parameters.assets,
|
|
|
- db: parameters.db,
|
|
|
+ store: parameters.store,
|
|
|
blockNumber: parameters.blockNumber,
|
|
|
contentOwner: parameters.contentOwner,
|
|
|
})
|
|
@@ -261,7 +229,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
const asset = await extractAsset({
|
|
|
assetIndex: metaAsObject.avatarPhoto,
|
|
|
assets: parameters.assets,
|
|
|
- db: parameters.db,
|
|
|
+ store: parameters.store,
|
|
|
blockNumber: parameters.blockNumber,
|
|
|
contentOwner: parameters.contentOwner,
|
|
|
})
|
|
@@ -271,7 +239,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
|
|
|
// prepare language if needed
|
|
|
if ('language' in metaAsObject) {
|
|
|
- const language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.blockNumber)
|
|
|
+ const language = await prepareLanguage(metaAsObject.language, parameters.store, parameters.blockNumber)
|
|
|
delete metaAsObject.language // make sure temporary value will not interfere
|
|
|
language.integrateInto(result, 'language')
|
|
|
}
|
|
@@ -283,11 +251,11 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
if (type instanceof Video) {
|
|
|
const meta = VideoMetadata.deserializeBinary(metaU8a)
|
|
|
const metaAsObject = convertMetadataToObject<VideoMetadata.AsObject>(meta)
|
|
|
- const result = metaAsObject as any as Partial<Video>
|
|
|
+ const result = (metaAsObject as any) as Partial<Video>
|
|
|
|
|
|
// prepare video category if needed
|
|
|
if ('category' in metaAsObject) {
|
|
|
- const category = await prepareVideoCategory(metaAsObject.category, parameters.db)
|
|
|
+ const category = await prepareVideoCategory(metaAsObject.category, parameters.store)
|
|
|
delete metaAsObject.category // make sure temporary value will not interfere
|
|
|
category.integrateInto(result, 'category')
|
|
|
}
|
|
@@ -299,7 +267,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
|
|
|
// NOTE: type hack - `RawVideoMetadata` is inserted instead of VideoMediaMetadata - it should be edited in `video.ts`
|
|
|
// see `integrateVideoMetadata()` in `video.ts` for more info
|
|
|
- result.mediaMetadata = prepareVideoMetadata(metaAsObject, videoSize, parameters.blockNumber) as unknown as VideoMediaMetadata
|
|
|
+ result.mediaMetadata = (prepareVideoMetadata(metaAsObject, videoSize) as unknown) as VideoMediaMetadata
|
|
|
|
|
|
// remove extra values
|
|
|
delete metaAsObject.mediaType
|
|
@@ -317,7 +285,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
const asset = await extractAsset({
|
|
|
assetIndex: metaAsObject.thumbnailPhoto,
|
|
|
assets: parameters.assets,
|
|
|
- db: parameters.db,
|
|
|
+ store: parameters.store,
|
|
|
blockNumber: parameters.blockNumber,
|
|
|
contentOwner: parameters.contentOwner,
|
|
|
})
|
|
@@ -330,7 +298,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
const asset = await extractAsset({
|
|
|
assetIndex: metaAsObject.video,
|
|
|
assets: parameters.assets,
|
|
|
- db: parameters.db,
|
|
|
+ store: parameters.store,
|
|
|
blockNumber: parameters.blockNumber,
|
|
|
contentOwner: parameters.contentOwner,
|
|
|
})
|
|
@@ -340,7 +308,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
|
|
|
// prepare language if needed
|
|
|
if ('language' in metaAsObject) {
|
|
|
- const language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.blockNumber)
|
|
|
+ const language = await prepareLanguage(metaAsObject.language, parameters.store, parameters.blockNumber)
|
|
|
delete metaAsObject.language // make sure temporary value will not interfere
|
|
|
language.integrateInto(result, 'language')
|
|
|
}
|
|
@@ -355,17 +323,20 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
|
|
|
}
|
|
|
|
|
|
// this should never happen
|
|
|
- logger.error('Not implemented metadata type', {type})
|
|
|
- throw `Not implemented metadata type`
|
|
|
+ logger.error('Not implemented metadata type', { type })
|
|
|
+ throw new Error(`Not implemented metadata type`)
|
|
|
}
|
|
|
|
|
|
-export async function convertContentActorToChannelOwner(db: DatabaseManager, contentActor: ContentActor): Promise<{
|
|
|
- ownerMember?: Membership,
|
|
|
- ownerCuratorGroup?: CuratorGroup,
|
|
|
+export async function convertContentActorToChannelOwner(
|
|
|
+ store: DatabaseManager,
|
|
|
+ contentActor: ContentActor
|
|
|
+): Promise<{
|
|
|
+ ownerMember?: Membership
|
|
|
+ ownerCuratorGroup?: CuratorGroup
|
|
|
}> {
|
|
|
if (contentActor.isMember) {
|
|
|
const memberId = contentActor.asMember.toNumber()
|
|
|
- const member = await db.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
|
|
|
+ const member = await store.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
|
|
|
|
|
|
// ensure member exists
|
|
|
if (!member) {
|
|
@@ -380,7 +351,9 @@ export async function convertContentActorToChannelOwner(db: DatabaseManager, con
|
|
|
|
|
|
if (contentActor.isCurator) {
|
|
|
const curatorGroupId = contentActor.asCurator[0].toNumber()
|
|
|
- const curatorGroup = await db.get(CuratorGroup, { where: { id: curatorGroupId.toString() } as FindConditions<CuratorGroup> })
|
|
|
+ const curatorGroup = await store.get(CuratorGroup, {
|
|
|
+ where: { id: curatorGroupId.toString() } as FindConditions<CuratorGroup>,
|
|
|
+ })
|
|
|
|
|
|
// ensure curator group exists
|
|
|
if (!curatorGroup) {
|
|
@@ -395,13 +368,16 @@ export async function convertContentActorToChannelOwner(db: DatabaseManager, con
|
|
|
|
|
|
// TODO: contentActor.isLead
|
|
|
|
|
|
- logger.error('Not implemented ContentActor type', {contentActor: contentActor.toString()})
|
|
|
- throw 'Not-implemented ContentActor type used'
|
|
|
+ logger.error('Not implemented ContentActor type', { contentActor: contentActor.toString() })
|
|
|
+ throw new Error('Not-implemented ContentActor type used')
|
|
|
}
|
|
|
|
|
|
-export function convertContentActorToDataObjectOwner(contentActor: ContentActor, channelId: number): typeof DataObjectOwner {
|
|
|
+export function convertContentActorToDataObjectOwner(
|
|
|
+ contentActor: ContentActor,
|
|
|
+ channelId: number
|
|
|
+): typeof DataObjectOwner {
|
|
|
const owner = new DataObjectOwnerChannel()
|
|
|
- owner.channel = channelId
|
|
|
+ owner.channelId = channelId.toString()
|
|
|
|
|
|
return owner
|
|
|
|
|
@@ -425,21 +401,22 @@ export function convertContentActorToDataObjectOwner(contentActor: ContentActor,
|
|
|
*/
|
|
|
}
|
|
|
|
|
|
-function handlePublishedBeforeJoystream(video: Partial<Video>, metadata: PublishedBeforeJoystreamMetadata.AsObject): PropertyChange<Date> {
|
|
|
+function handlePublishedBeforeJoystream(
|
|
|
+ video: Partial<Video>,
|
|
|
+ metadata: PublishedBeforeJoystreamMetadata.AsObject
|
|
|
+): PropertyChange<Date> {
|
|
|
// is publish being unset
|
|
|
if ('isPublished' in metadata && !metadata.isPublished) {
|
|
|
return PropertyChange.newUnset()
|
|
|
}
|
|
|
|
|
|
// try to parse timestamp from publish date
|
|
|
- const timestamp = metadata.date
|
|
|
- ? Date.parse(metadata.date)
|
|
|
- : NaN
|
|
|
+ const timestamp = metadata.date ? Date.parse(metadata.date) : NaN
|
|
|
|
|
|
// ensure date is valid
|
|
|
if (isNaN(timestamp)) {
|
|
|
invalidMetadata(`Invalid date used for publishedBeforeJoystream`, {
|
|
|
- timestamp
|
|
|
+ timestamp,
|
|
|
})
|
|
|
return PropertyChange.newNoChange()
|
|
|
}
|
|
@@ -450,7 +427,7 @@ function handlePublishedBeforeJoystream(video: Partial<Video>, metadata: Publish
|
|
|
|
|
|
interface IConvertAssetParameters {
|
|
|
rawAsset: NewAsset
|
|
|
- db: DatabaseManager
|
|
|
+ store: DatabaseManager
|
|
|
blockNumber: number
|
|
|
contentOwner: typeof DataObjectOwner
|
|
|
}
|
|
@@ -461,7 +438,7 @@ interface IConvertAssetParameters {
|
|
|
async function convertAsset(parameters: IConvertAssetParameters): Promise<AssetStorageOrUrls> {
|
|
|
// is asset describing list of URLs?
|
|
|
if (parameters.rawAsset.isUrls) {
|
|
|
- const urls = parameters.rawAsset.asUrls.toArray().map(item => item.toString())
|
|
|
+ const urls = parameters.rawAsset.asUrls.toArray().map((item) => item.toString())
|
|
|
|
|
|
return urls
|
|
|
}
|
|
@@ -478,7 +455,7 @@ async function convertAsset(parameters: IConvertAssetParameters): Promise<AssetS
|
|
|
interface IExtractAssetParameters {
|
|
|
assetIndex: number | undefined
|
|
|
assets: NewAsset[]
|
|
|
- db: DatabaseManager
|
|
|
+ store: DatabaseManager
|
|
|
blockNumber: number
|
|
|
contentOwner: typeof DataObjectOwner
|
|
|
}
|
|
@@ -504,7 +481,7 @@ async function extractAsset(parameters: IExtractAssetParameters): Promise<Proper
|
|
|
// convert asset to data object record
|
|
|
const asset = await convertAsset({
|
|
|
rawAsset: parameters.assets[parameters.assetIndex],
|
|
|
- db: parameters.db,
|
|
|
+ store: parameters.store,
|
|
|
blockNumber: parameters.blockNumber,
|
|
|
contentOwner: parameters.contentOwner,
|
|
|
})
|
|
@@ -518,7 +495,11 @@ async function extractAsset(parameters: IExtractAssetParameters): Promise<Proper
|
|
|
|
|
|
Changes `result` argument!
|
|
|
*/
|
|
|
-function integrateAsset<T>(propertyName: string, result: Object, asset: PropertyChange<AssetStorageOrUrls>): void {
|
|
|
+function integrateAsset<T>(
|
|
|
+ propertyName: string,
|
|
|
+ result: Record<string, unknown>,
|
|
|
+ asset: PropertyChange<AssetStorageOrUrls>
|
|
|
+): void {
|
|
|
// helpers - property names
|
|
|
const nameUrl = propertyName + 'Urls'
|
|
|
const nameDataObject = propertyName + 'DataObject'
|
|
@@ -570,7 +551,7 @@ function extractVideoSize(assets: NewAsset[], assetIndex: number | undefined): n
|
|
|
|
|
|
// ensure asset index is valid
|
|
|
if (assetIndex > assets.length) {
|
|
|
- invalidMetadata(`Non-existing asset video size extraction requested`, {assetsProvided: assets.length, assetIndex})
|
|
|
+ invalidMetadata(`Non-existing asset video size extraction requested`, { assetsProvided: assets.length, assetIndex })
|
|
|
return undefined
|
|
|
}
|
|
|
|
|
@@ -591,7 +572,11 @@ function extractVideoSize(assets: NewAsset[], assetIndex: number | undefined): n
|
|
|
return videoSize
|
|
|
}
|
|
|
|
|
|
-async function prepareLanguage(languageIso: string | undefined, db: DatabaseManager, blockNumber: number): Promise<PropertyChange<Language>> {
|
|
|
+async function prepareLanguage(
|
|
|
+ languageIso: string | undefined,
|
|
|
+ store: DatabaseManager,
|
|
|
+ blockNumber: number
|
|
|
+): Promise<PropertyChange<Language>> {
|
|
|
// is language being unset?
|
|
|
if (languageIso === undefined) {
|
|
|
return PropertyChange.newUnset()
|
|
@@ -607,14 +592,13 @@ async function prepareLanguage(languageIso: string | undefined, db: DatabaseMana
|
|
|
}
|
|
|
|
|
|
// load language
|
|
|
- const language = await db.get(Language, { where: { iso: languageIso } as FindConditions<Language> })
|
|
|
+ const language = await store.get(Language, { where: { iso: languageIso } as FindConditions<Language> })
|
|
|
|
|
|
// return existing language if any
|
|
|
if (language) {
|
|
|
return PropertyChange.newChange(language)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// create new language
|
|
|
const newLanguage = new Language({
|
|
|
iso: languageIso,
|
|
@@ -625,7 +609,7 @@ async function prepareLanguage(languageIso: string | undefined, db: DatabaseMana
|
|
|
updatedById: '1',
|
|
|
})
|
|
|
|
|
|
- await db.save<Language>(newLanguage)
|
|
|
+ await store.save<Language>(newLanguage)
|
|
|
|
|
|
return PropertyChange.newChange(newLanguage)
|
|
|
}
|
|
@@ -660,39 +644,56 @@ async function prepareLicense(licenseProtobuf: LicenseMetadata.AsObject | undefi
|
|
|
Empty object means deletion is requested.
|
|
|
*/
|
|
|
function isLicenseEmpty(licenseObject: LicenseMetadata.AsObject): boolean {
|
|
|
- let somePropertySet = Object.entries(licenseObject).reduce((acc, [key, value]) => {
|
|
|
- return acc || value !== undefined
|
|
|
- }, false)
|
|
|
+ const somePropertySet = Object.entries(licenseObject).reduce((acc, [key, value]) => {
|
|
|
+ return acc || value !== undefined
|
|
|
+ }, false)
|
|
|
|
|
|
- return !somePropertySet
|
|
|
+ return !somePropertySet
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-function prepareVideoMetadata(videoProtobuf: VideoMetadata.AsObject, videoSize: number | undefined, blockNumber: number): RawVideoMetadata {
|
|
|
+function prepareVideoMetadata(videoProtobuf: VideoMetadata.AsObject, videoSize: number | undefined): RawVideoMetadata {
|
|
|
const rawMeta = {
|
|
|
encoding: {
|
|
|
- codecName: PropertyChange.fromObjectProperty<string, 'codecName', MediaTypeMetadata.AsObject>(videoProtobuf.mediaType || {}, 'codecName'),
|
|
|
- container: PropertyChange.fromObjectProperty<string, 'container', MediaTypeMetadata.AsObject>(videoProtobuf.mediaType || {}, 'container'),
|
|
|
- mimeMediaType: PropertyChange.fromObjectProperty<string, 'mimeMediaType', MediaTypeMetadata.AsObject>(videoProtobuf.mediaType || {}, 'mimeMediaType'),
|
|
|
+ codecName: PropertyChange.fromObjectProperty<string, 'codecName', MediaTypeMetadata.AsObject>(
|
|
|
+ videoProtobuf.mediaType || {},
|
|
|
+ 'codecName'
|
|
|
+ ),
|
|
|
+ container: PropertyChange.fromObjectProperty<string, 'container', MediaTypeMetadata.AsObject>(
|
|
|
+ videoProtobuf.mediaType || {},
|
|
|
+ 'container'
|
|
|
+ ),
|
|
|
+ mimeMediaType: PropertyChange.fromObjectProperty<string, 'mimeMediaType', MediaTypeMetadata.AsObject>(
|
|
|
+ videoProtobuf.mediaType || {},
|
|
|
+ 'mimeMediaType'
|
|
|
+ ),
|
|
|
},
|
|
|
- pixelWidth: PropertyChange.fromObjectProperty<number, 'mediaPixelWidth', VideoMetadata.AsObject>(videoProtobuf, 'mediaPixelWidth'),
|
|
|
- pixelHeight: PropertyChange.fromObjectProperty<number, 'mediaPixelHeight', VideoMetadata.AsObject>(videoProtobuf, 'mediaPixelHeight'),
|
|
|
- size: videoSize === undefined
|
|
|
- ? PropertyChange.newNoChange()
|
|
|
- : PropertyChange.newChange(videoSize)
|
|
|
+ pixelWidth: PropertyChange.fromObjectProperty<number, 'mediaPixelWidth', VideoMetadata.AsObject>(
|
|
|
+ videoProtobuf,
|
|
|
+ 'mediaPixelWidth'
|
|
|
+ ),
|
|
|
+ pixelHeight: PropertyChange.fromObjectProperty<number, 'mediaPixelHeight', VideoMetadata.AsObject>(
|
|
|
+ videoProtobuf,
|
|
|
+ 'mediaPixelHeight'
|
|
|
+ ),
|
|
|
+ size: videoSize === undefined ? PropertyChange.newNoChange() : PropertyChange.newChange(videoSize),
|
|
|
} as RawVideoMetadata
|
|
|
|
|
|
return rawMeta
|
|
|
}
|
|
|
|
|
|
-async function prepareVideoCategory(categoryId: number | undefined, db: DatabaseManager): Promise<PropertyChange<VideoCategory>> {
|
|
|
+async function prepareVideoCategory(
|
|
|
+ categoryId: number | undefined,
|
|
|
+ store: DatabaseManager
|
|
|
+): Promise<PropertyChange<VideoCategory>> {
|
|
|
// is category being unset?
|
|
|
if (categoryId === undefined) {
|
|
|
return PropertyChange.newUnset()
|
|
|
}
|
|
|
|
|
|
// load video category
|
|
|
- const category = await db.get(VideoCategory, { where: { id: categoryId.toString() } as FindConditions<VideoCategory> })
|
|
|
+ const category = await store.get(VideoCategory, {
|
|
|
+ where: { id: categoryId.toString() } as FindConditions<VideoCategory>,
|
|
|
+ })
|
|
|
|
|
|
// ensure video category exists
|
|
|
if (!category) {
|
|
@@ -703,22 +704,22 @@ async function prepareVideoCategory(categoryId: number | undefined, db: Database
|
|
|
return PropertyChange.newChange(category)
|
|
|
}
|
|
|
|
|
|
-function convertMetadataToObject<T extends Object>(metadata: jspb.Message): T {
|
|
|
+function convertMetadataToObject<T>(metadata: jspb.Message): T {
|
|
|
const metaAsObject = metadata.toObject()
|
|
|
const result = {} as T
|
|
|
|
|
|
for (const key in metaAsObject) {
|
|
|
const funcNameBase = key.charAt(0).toUpperCase() + key.slice(1)
|
|
|
const hasFuncName = 'has' + funcNameBase
|
|
|
- const isSet = funcNameBase == 'PersonsList' // there is no `VideoMetadata.hasPersonsList` method from unkown reason -> create exception
|
|
|
- ? true
|
|
|
- : metadata[hasFuncName]()
|
|
|
+ const isSet =
|
|
|
+ funcNameBase === 'PersonsList' // there is no `VideoMetadata.hasPersonsList` method from unkown reason -> create exception
|
|
|
+ ? true
|
|
|
+ : metadata[hasFuncName]()
|
|
|
|
|
|
if (!isSet) {
|
|
|
continue
|
|
|
}
|
|
|
|
|
|
-
|
|
|
const getFuncName = 'get' + funcNameBase
|
|
|
const value = metadata[getFuncName]()
|
|
|
|