channel.ts 7.6 KB

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