channel.ts 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. eslint-disable @typescript-eslint/naming-convention
  3. */
  4. import { EventContext, StoreContext } from '@joystream/hydra-common'
  5. import { Content } from '../generated/types'
  6. import { convertContentActorToChannelOwner, processChannelMetadata } from './utils'
  7. import { AssetNone, Channel, ChannelCategory, StorageDataObject } from 'query-node/dist/model'
  8. import { deserializeMetadata, inconsistentState, logger } from '../common'
  9. import { ChannelCategoryMetadata, ChannelMetadata } from '@joystream/metadata-protobuf'
  10. import { integrateMeta } from '@joystream/metadata-protobuf/utils'
  11. import { In } from 'typeorm'
  12. import { removeDataObject } from '../storage/utils'
  13. export async function content_ChannelCreated(ctx: EventContext & StoreContext): Promise<void> {
  14. const { store, event } = ctx
  15. // read event data
  16. const [contentActor, channelId, runtimeChannel, channelCreationParameters] = new Content.ChannelCreatedEvent(
  17. event
  18. ).params
  19. // create entity
  20. const channel = new Channel({
  21. // main data
  22. id: channelId.toString(),
  23. isCensored: false,
  24. videos: [],
  25. createdInBlock: event.blockNumber,
  26. rewardAccount: channelCreationParameters.reward_account.unwrapOr(undefined)?.toString(),
  27. deletionPrizeDestAccount: runtimeChannel.deletion_prize_source_account_id.toString(),
  28. // assets
  29. coverPhoto: new AssetNone(),
  30. avatarPhoto: new AssetNone(),
  31. // fill in auto-generated fields
  32. createdAt: new Date(event.blockTimestamp),
  33. updatedAt: new Date(event.blockTimestamp),
  34. // prepare channel owner (handles fields `ownerMember` and `ownerCuratorGroup`)
  35. ...(await convertContentActorToChannelOwner(store, contentActor)),
  36. })
  37. // deserialize & process metadata
  38. const metadata = deserializeMetadata(ChannelMetadata, channelCreationParameters.meta) || {}
  39. await processChannelMetadata(ctx, channel, metadata, channelCreationParameters.assets)
  40. // save entity
  41. await store.save<Channel>(channel)
  42. // emit log event
  43. logger.info('Channel has been created', { id: channel.id })
  44. }
  45. export async function content_ChannelUpdated(ctx: EventContext & StoreContext): Promise<void> {
  46. const { store, event } = ctx
  47. // read event data
  48. const [, channelId, , channelUpdateParameters] = new Content.ChannelUpdatedEvent(event).params
  49. // load channel
  50. const channel = await store.get(Channel, { where: { id: channelId.toString() } })
  51. // ensure channel exists
  52. if (!channel) {
  53. return inconsistentState('Non-existing channel update requested', channelId)
  54. }
  55. // prepare changed metadata
  56. const newMetadataBytes = channelUpdateParameters.new_meta.unwrapOr(null)
  57. // update metadata if it was changed
  58. if (newMetadataBytes) {
  59. const newMetadata = deserializeMetadata(ChannelMetadata, newMetadataBytes) || {}
  60. await processChannelMetadata(ctx, channel, newMetadata, channelUpdateParameters.assets.unwrapOr(undefined))
  61. }
  62. // prepare changed reward account
  63. const newRewardAccount = channelUpdateParameters.reward_account.unwrapOr(null)
  64. // reward account change happened?
  65. if (newRewardAccount) {
  66. // this will change the `channel`!
  67. channel.rewardAccount = newRewardAccount.unwrapOr(undefined)?.toString()
  68. }
  69. // set last update time
  70. channel.updatedAt = new Date(event.blockTimestamp)
  71. // save channel
  72. await store.save<Channel>(channel)
  73. // emit log event
  74. logger.info('Channel has been updated', { id: channel.id })
  75. }
  76. export async function content_ChannelAssetsRemoved({ store, event }: EventContext & StoreContext): Promise<void> {
  77. const [, , dataObjectIds] = new Content.ChannelAssetsRemovedEvent(event).params
  78. const assets = await store.getMany(StorageDataObject, {
  79. where: {
  80. id: In(Array.from(dataObjectIds).map((item) => item.toString())),
  81. },
  82. })
  83. await Promise.all(assets.map((a) => removeDataObject(store, a)))
  84. logger.info('Channel assets have been removed', { ids: dataObjectIds.toJSON() })
  85. }
  86. export async function content_ChannelCensorshipStatusUpdated({
  87. store,
  88. event,
  89. }: EventContext & StoreContext): Promise<void> {
  90. // read event data
  91. const [, channelId, isCensored] = new Content.ChannelCensorshipStatusUpdatedEvent(event).params
  92. // load event
  93. const channel = await store.get(Channel, { where: { id: channelId.toString() } })
  94. // ensure channel exists
  95. if (!channel) {
  96. return inconsistentState('Non-existing channel censoring requested', channelId)
  97. }
  98. // update channel
  99. channel.isCensored = isCensored.isTrue
  100. // set last update time
  101. channel.updatedAt = new Date(event.blockTimestamp)
  102. // save channel
  103. await store.save<Channel>(channel)
  104. // emit log event
  105. logger.info('Channel censorship status has been updated', { id: channelId, isCensored: isCensored.isTrue })
  106. }
  107. /// //////////////// ChannelCategory ////////////////////////////////////////////
  108. export async function content_ChannelCategoryCreated({ store, event }: EventContext & StoreContext): Promise<void> {
  109. // read event data
  110. const [channelCategoryId, , channelCategoryCreationParameters] = new Content.ChannelCategoryCreatedEvent(event).params
  111. // read metadata
  112. const metadata = deserializeMetadata(ChannelCategoryMetadata, channelCategoryCreationParameters.meta) || {}
  113. // create new channel category
  114. const channelCategory = new ChannelCategory({
  115. // main data
  116. id: channelCategoryId.toString(),
  117. channels: [],
  118. createdInBlock: event.blockNumber,
  119. // fill in auto-generated fields
  120. createdAt: new Date(event.blockTimestamp),
  121. updatedAt: new Date(event.blockTimestamp),
  122. })
  123. integrateMeta(channelCategory, metadata, ['name'])
  124. // save channel
  125. await store.save<ChannelCategory>(channelCategory)
  126. // emit log event
  127. logger.info('Channel category has been created', { id: channelCategory.id })
  128. }
  129. export async function content_ChannelCategoryUpdated({ store, event }: EventContext & StoreContext): Promise<void> {
  130. // read event data
  131. const [, channelCategoryId, channelCategoryUpdateParameters] = new Content.ChannelCategoryUpdatedEvent(event).params
  132. // load channel category
  133. const channelCategory = await store.get(ChannelCategory, {
  134. where: {
  135. id: channelCategoryId.toString(),
  136. },
  137. })
  138. // ensure channel exists
  139. if (!channelCategory) {
  140. return inconsistentState('Non-existing channel category update requested', channelCategoryId)
  141. }
  142. // read metadata
  143. const newMeta = deserializeMetadata(ChannelCategoryMetadata, channelCategoryUpdateParameters.new_meta) || {}
  144. integrateMeta(channelCategory, newMeta, ['name'])
  145. // set last update time
  146. channelCategory.updatedAt = new Date(event.blockTimestamp)
  147. // save channel category
  148. await store.save<ChannelCategory>(channelCategory)
  149. // emit log event
  150. logger.info('Channel category has been updated', { id: channelCategory.id })
  151. }
  152. export async function content_ChannelCategoryDeleted({ store, event }: EventContext & StoreContext): Promise<void> {
  153. // read event data
  154. const [, channelCategoryId] = new Content.ChannelCategoryDeletedEvent(event).params
  155. // load channel category
  156. const channelCategory = await store.get(ChannelCategory, {
  157. where: {
  158. id: channelCategoryId.toString(),
  159. },
  160. })
  161. // ensure channel category exists
  162. if (!channelCategory) {
  163. return inconsistentState('Non-existing channel category deletion requested', channelCategoryId)
  164. }
  165. // delete channel category
  166. await store.remove<ChannelCategory>(channelCategory)
  167. // emit log event
  168. logger.info('Channel category has been deleted', { id: channelCategory.id })
  169. }