import { DatabaseManager, EventContext, StoreContext } from '@joystream/hydra-common' import { FindConditions } from 'typeorm' import { IVideoMetadata, IPublishedBeforeJoystream, ILicense, IMediaType, IChannelMetadata, } from '@joystream/metadata-protobuf' import { integrateMeta, isSet, isValidLanguageCode } from '@joystream/metadata-protobuf/utils' import { invalidMetadata, inconsistentState, logger, deterministicEntityId } from '../common' import { // primary entities CuratorGroup, Channel, Video, VideoCategory, // secondary entities Language, License, VideoMediaMetadata, // asset Membership, VideoMediaEncoding, ChannelCategory, StorageDataObject, DataObjectTypeChannelAvatar, DataObjectTypeChannelCoverPhoto, DataObjectTypeVideoMedia, DataObjectTypeVideoThumbnail, } from 'query-node/dist/model' // Joystream types import { ContentActor, StorageAssets } from '@joystream/types/augment' import { DecodedMetadataObject } from '@joystream/metadata-protobuf/types' import BN from 'bn.js' import { getMostRecentlyCreatedDataObjects } from '../storage/utils' const ASSET_TYPES = { channel: [ { DataObjectTypeConstructor: DataObjectTypeChannelCoverPhoto, metaFieldName: 'coverPhoto', schemaFieldName: 'coverPhoto', }, { DataObjectTypeConstructor: DataObjectTypeChannelAvatar, metaFieldName: 'avatarPhoto', schemaFieldName: 'avatarPhoto', }, ], video: [ { DataObjectTypeConstructor: DataObjectTypeVideoMedia, metaFieldName: 'video', schemaFieldName: 'media', }, { DataObjectTypeConstructor: DataObjectTypeVideoThumbnail, metaFieldName: 'thumbnailPhoto', schemaFieldName: 'thumbnailPhoto', }, ], } as const async function processChannelAssets( { event, store }: EventContext & StoreContext, assets: StorageDataObject[], channel: Channel, meta: DecodedMetadataObject ) { await Promise.all( ASSET_TYPES.channel.map(async ({ metaFieldName, schemaFieldName, DataObjectTypeConstructor }) => { const newAssetIndex = meta[metaFieldName] const currentAsset = channel[schemaFieldName] if (isSet(newAssetIndex)) { const asset = findAssetByIndex(assets, newAssetIndex) if (asset) { if (currentAsset) { currentAsset.unsetAt = new Date(event.blockTimestamp) await store.save(currentAsset) } const dataObjectType = new DataObjectTypeConstructor() dataObjectType.channelId = channel.id asset.type = dataObjectType channel[schemaFieldName] = asset await store.save(asset) } } }) ) } async function processVideoAssets( { event, store }: EventContext & StoreContext, assets: StorageDataObject[], video: Video, meta: DecodedMetadataObject ) { await Promise.all( ASSET_TYPES.video.map(async ({ metaFieldName, schemaFieldName, DataObjectTypeConstructor }) => { const newAssetIndex = meta[metaFieldName] const currentAsset = video[schemaFieldName] if (isSet(newAssetIndex)) { const asset = findAssetByIndex(assets, newAssetIndex) if (asset) { if (currentAsset) { currentAsset.unsetAt = new Date(event.blockTimestamp) await store.save(currentAsset) } const dataObjectType = new DataObjectTypeConstructor() dataObjectType.videoId = video.id asset.type = dataObjectType video[schemaFieldName] = asset await store.save(asset) } } }) ) } export async function processChannelMetadata( ctx: EventContext & StoreContext, channel: Channel, meta: DecodedMetadataObject, assetsParams?: StorageAssets ): Promise { const assets = assetsParams ? await processNewAssets(ctx, assetsParams) : [] integrateMeta(channel, meta, ['title', 'description', 'isPublic']) await processChannelAssets(ctx, assets, channel, meta) // prepare channel category if needed if (isSet(meta.category)) { channel.category = await processChannelCategory(ctx, channel.category, parseInt(meta.category)) } // prepare language if needed if (isSet(meta.language)) { channel.language = await processLanguage(ctx, channel.language, meta.language) } return channel } export async function processVideoMetadata( ctx: EventContext & StoreContext, video: Video, meta: DecodedMetadataObject, assetsParams?: StorageAssets ): Promise