12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103 |
- // Ensure we're `no_std` when compiling for Wasm.
- #![cfg_attr(not(feature = "std"), no_std)]
- #![recursion_limit = "256"]
- // #[cfg(test)]
- // mod tests;
- mod errors;
- mod permissions;
- pub use errors::*;
- pub use permissions::*;
- use core::hash::Hash;
- use codec::Codec;
- use codec::{Decode, Encode};
- use frame_support::{
- decl_event, decl_module, decl_storage, dispatch::DispatchResult, ensure, traits::Get, Parameter,
- };
- #[cfg(feature = "std")]
- pub use serde::{Deserialize, Serialize};
- use sp_arithmetic::traits::{BaseArithmetic, One, Zero};
- use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
- use sp_std::collections::btree_set::BTreeSet;
- // use sp_std::vec;
- use sp_std::vec::Vec;
- use system::ensure_signed;
- pub use common::storage::{ContentParameters, StorageSystem};
- pub use common::{
- currency::{BalanceOf, GovernanceCurrency},
- MembershipTypes, StorageOwnership, Url,
- };
- pub(crate) type ContentId<T> = <T as StorageOwnership>::ContentId;
- pub(crate) type DataObjectTypeId<T> = <T as StorageOwnership>::DataObjectTypeId;
- /// Type, used in diffrent numeric constraints representations
- pub type MaxNumber = u32;
- /// A numeric identifier trait
- pub trait NumericIdentifier:
- Parameter
- + Member
- + BaseArithmetic
- + Codec
- + Default
- + Copy
- + Clone
- + Hash
- + MaybeSerializeDeserialize
- + Eq
- + PartialEq
- + Ord
- + Zero
- {
- }
- impl NumericIdentifier for u64 {}
- /// Module configuration trait for Content Directory Module
- pub trait Trait:
- system::Trait
- + ContentActorAuthenticator
- + Clone
- + StorageOwnership
- + MembershipTypes
- + GovernanceCurrency
- {
- /// The overarching event type.
- type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
- /// Channel Transfer Payments Escrow Account seed for ModuleId to compute deterministic AccountId
- type ChannelOwnershipPaymentEscrowId: Get<[u8; 8]>;
- /// Type of identifier for Videos
- type VideoId: NumericIdentifier;
- /// Type of identifier for Video Categories
- type VideoCategoryId: NumericIdentifier;
- /// Type of identifier for Channel Categories
- type ChannelCategoryId: NumericIdentifier;
- /// Type of identifier for Playlists
- type PlaylistId: NumericIdentifier;
- /// Type of identifier for Persons
- type PersonId: NumericIdentifier;
- /// Type of identifier for Channels
- type SeriesId: NumericIdentifier;
- /// Type of identifier for Channel transfer requests
- type ChannelOwnershipTransferRequestId: NumericIdentifier;
- /// The maximum number of curators per group constraint
- type MaxNumberOfCuratorsPerGroup: Get<MaxNumber>;
- // Type that handles asset uploads to storage system
- type StorageSystem: StorageSystem<Self>;
- }
- /// Specifies how a new asset will be provided on creating and updating
- /// Channels, Videos, Series and Person
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
- pub enum NewAsset<ContentParameters> {
- /// Upload to the storage system
- Upload(ContentParameters),
- /// Multiple url strings pointing at an asset
- Urls(Vec<Url>),
- }
- /// The owner of a channel, is the authorized "actor" that can update
- /// or delete or transfer a channel and its contents.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
- pub enum ChannelOwner<MemberId, CuratorGroupId, DAOId> {
- /// A Member owns the channel
- Member(MemberId),
- /// A specific curation group owns the channel
- CuratorGroup(CuratorGroupId),
- // Native DAO owns the channel
- Dao(DAOId),
- }
- // Default trait implemented only because its used in a Channel which needs to implement a Default trait
- // since it is a StorageValue.
- impl<MemberId: Default, CuratorGroupId, DAOId> Default
- for ChannelOwner<MemberId, CuratorGroupId, DAOId>
- {
- fn default() -> Self {
- ChannelOwner::Member(MemberId::default())
- }
- }
- /// A category which channels can belong to.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct ChannelCategory {
- // No runtime information is currently stored for a Category.
- }
- /// Information on the category being created.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct ChannelCategoryCreationParameters {
- /// Metadata for the category.
- meta: Vec<u8>,
- }
- /// Information on the category being updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct ChannelCategoryUpdateParameters {
- // as this is the only field it is not an Option
- /// Metadata update for the category.
- new_meta: Vec<u8>,
- }
- /// Type representing an owned channel which videos, playlists, and series can belong to.
- /// If a channel is deleted, all videos, playlists and series will also be deleted.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct ChannelRecord<MemberId, CuratorGroupId, DAOId, AccountId, VideoId, PlaylistId, SeriesId>
- {
- /// The owner of a channel
- owner: ChannelOwner<MemberId, CuratorGroupId, DAOId>,
- /// The videos under this channel
- videos: Vec<VideoId>,
- /// The playlists under this channel
- playlists: Vec<PlaylistId>,
- /// The series under this channel
- series: Vec<SeriesId>,
- /// If curators have censored this channel or not
- is_censored: bool,
- /// Reward account where revenue is sent if set.
- reward_account: Option<AccountId>,
- }
- // Channel alias type for simplification.
- pub type Channel<T> = ChannelRecord<
- <T as MembershipTypes>::MemberId,
- <T as ContentActorAuthenticator>::CuratorGroupId,
- <T as StorageOwnership>::DAOId,
- <T as system::Trait>::AccountId,
- <T as Trait>::VideoId,
- <T as Trait>::PlaylistId,
- <T as Trait>::SeriesId,
- >;
- /// A request to buy a channel by a new ChannelOwner.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct ChannelOwnershipTransferRequestRecord<
- ChannelId,
- MemberId,
- CuratorGroupId,
- DAOId,
- Balance,
- > {
- channel_id: ChannelId,
- new_owner: ChannelOwner<MemberId, CuratorGroupId, DAOId>,
- payment: Balance,
- }
- // ChannelOwnershipTransferRequest type alias for simplification.
- pub type ChannelOwnershipTransferRequest<T> = ChannelOwnershipTransferRequestRecord<
- <T as StorageOwnership>::ChannelId,
- <T as MembershipTypes>::MemberId,
- <T as ContentActorAuthenticator>::CuratorGroupId,
- <T as StorageOwnership>::DAOId,
- BalanceOf<T>,
- >;
- /// Information about channel being created.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct ChannelCreationParameters {
- /// Metadata about the channel.
- meta: Vec<u8>,
- }
- /// Information about channel being updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct ChannelUpdateParameters {
- /// If set, metadata update for the channel.
- new_meta: Option<Vec<u8>>,
- }
- /// A category that videos can belong to.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct VideoCategory {
- // No runtime information is currently stored for a Category.
- }
- /// Information about the video category being created.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct VideoCategoryCreationParameters {
- /// Metadata about the video category.
- meta: Vec<u8>,
- }
- /// Information about the video category being updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct VideoCategoryUpdateParameters {
- // Because it is the only field it is not an Option
- /// Metadata update for the video category.
- new_meta: Vec<u8>,
- }
- /// Information about the video being created.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct VideoCreationParameters {
- /// Metadata for the video.
- meta: Vec<u8>,
- }
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct VideoUpdateParameters {
- /// If set, metadata update for the video.
- new_meta: Option<Vec<u8>>,
- }
- /// A video which belongs to a channel. A video may be part of a series or playlist.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct Video<ChannelId, SeriesId> {
- in_channel: ChannelId,
- // keep track of which season the video is in if it is an 'episode'
- // - prevent removing a video if it is in a season (because order is important)
- in_series: Option<SeriesId>,
- /// Whether the curators have censored the video or not.
- is_censored: bool,
- /// Whether the curators have chosen to feature the video or not.
- is_featured: bool,
- }
- /// Information about the plyalist being created.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct PlaylistCreationParameters<VideoId> {
- /// The full list of videos that make up the playlist.
- videos: Vec<VideoId>,
- /// Metadata about the playlist.
- meta: Vec<u8>,
- }
- /// Information about the playlist being updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct PlaylistUpdateParameters<VideoId> {
- /// If set, the new full list of videos that make up the playlist.
- new_videos: Option<Vec<VideoId>>,
- /// If set, metadata update for the playlist.
- new_meta: Option<Vec<u8>>,
- }
- /// A playlist is an ordered collection of videos.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct Playlist<ChannelId, VideoId> {
- /// The channel the playlist belongs to.
- in_channel: ChannelId,
- /// The videos that make up the playlist.
- videos: Vec<VideoId>,
- }
- /// Information about the episode being created or updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
- pub enum EpisodeParameters<VideoId> {
- /// A new video is being added as the episode.
- NewVideo(VideoCreationParameters),
- /// An existing video is being made into an episode.
- ExistingVideo(VideoId),
- }
- /// Information about the season being created or updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct SeasonParameters<VideoId> {
- // ?? It might just be more straighforward to always provide full list of episodes at cost of larger tx.
- /// If set, updates the episodes of a season. Extends the number of episodes in a season
- /// when length of new_episodes is greater than previously set. Last elements must all be
- /// 'Some' in that case.
- /// Will truncate existing season when length of new_episodes is less than previously set.
- episodes: Option<Vec<Option<EpisodeParameters<VideoId>>>>,
- /// If set, Metadata update for season.
- meta: Option<Vec<u8>>,
- }
- /// Information about the series being created or updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct SeriesParameters<VideoId> {
- // ?? It might just be more straighforward to always provide full list of seasons at cost of larger tx.
- /// If set, updates the seasons of a series. Extend a series when length of seasons is
- /// greater than previoulsy set. Last elements must all be 'Some' in that case.
- /// Will truncate existing series when length of seasons is less than previously set.
- seasons: Option<Vec<Option<SeasonParameters<VideoId>>>>,
- meta: Option<Vec<u8>>,
- }
- /// A season is an ordered list of videos (episodes).
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct Season<VideoId> {
- episodes: Vec<VideoId>,
- }
- /// A series is an ordered list of seasons that belongs to a channel.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct Series<ChannelId, VideoId> {
- in_channel: ChannelId,
- seasons: Vec<Season<VideoId>>,
- }
- // The actor the caller/origin is trying to act as for Person creation and update and delete calls.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
- pub enum PersonActor<MemberId, CuratorId> {
- Member(MemberId),
- Curator(CuratorId),
- }
- /// The authorized actor that may update or delete a Person.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Clone, PartialEq, Eq, Debug)]
- pub enum PersonController<MemberId> {
- /// Member controls the person
- Member(MemberId),
- /// Any curator controls the person
- Curators,
- }
- // Default trait implemented only because its used in Person which needs to implement a Default trait
- // since it is a StorageValue.
- impl<MemberId: Default> Default for PersonController<MemberId> {
- fn default() -> Self {
- PersonController::Member(MemberId::default())
- }
- }
- /// Information for Person being created.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct PersonCreationParameters {
- /// Metadata for person.
- meta: Vec<u8>,
- }
- /// Information for Persion being updated.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct PersonUpdateParameters {
- /// Metadata to update person.
- new_meta: Vec<u8>,
- }
- /// A Person represents a real person that may be associated with a video.
- #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
- #[derive(Encode, Decode, Default, Clone, PartialEq, Eq, Debug)]
- pub struct Person<MemberId> {
- /// Who can update or delete this person.
- controlled_by: PersonController<MemberId>,
- }
- decl_storage! {
- trait Store for Module<T: Trait> as Content {
- pub ChannelById get(fn channel_by_id): map hasher(blake2_128_concat) T::ChannelId => Channel<T>;
- pub ChannelCategoryById get(fn channel_category_by_id): map hasher(blake2_128_concat) T::ChannelCategoryId => ChannelCategory;
- pub VideoById get(fn video_by_id): map hasher(blake2_128_concat) T::VideoId => Video<T::ChannelId, T::SeriesId>;
- pub VideoCategoryById get(fn video_category_by_id): map hasher(blake2_128_concat) T::VideoCategoryId => VideoCategory;
- pub PlaylistById get(fn playlist_by_id): map hasher(blake2_128_concat) T::PlaylistId => Playlist<T::ChannelId, T::VideoId>;
- pub SeriesById get(fn series_by_id): map hasher(blake2_128_concat) T::SeriesId => Series<T::ChannelId, T::VideoId>;
- pub PersonById get(fn person_by_id): map hasher(blake2_128_concat) T::PersonId => Person<T::MemberId>;
- pub ChannelOwnershipTransferRequestById get(fn channel_ownership_transfer_request_by_id):
- map hasher(blake2_128_concat) T::ChannelOwnershipTransferRequestId => ChannelOwnershipTransferRequest<T>;
- pub NextChannelCategoryId get(fn next_channel_category_id) config(): T::ChannelCategoryId;
- pub NextChannelId get(fn next_channel_id) config(): T::ChannelId;
- pub NextVideoCategoryId get(fn next_video_category_id) config(): T::VideoCategoryId;
- pub NextVideoId get(fn next_video_id) config(): T::VideoId;
- pub NextPlaylistId get(fn next_playlist_id) config(): T::PlaylistId;
- pub NextPersonId get(fn next_person_id) config(): T::PersonId;
- pub NextSeriesId get(fn next_series_id) config(): T::SeriesId;
- pub NextChannelOwnershipTransferRequestId get(fn next_channel_transfer_request_id) config(): T::ChannelOwnershipTransferRequestId;
- pub NextCuratorGroupId get(fn next_curator_group_id) config(): T::CuratorGroupId;
- /// Map, representing CuratorGroupId -> CuratorGroup relation
- pub CuratorGroupById get(fn curator_group_by_id): map hasher(blake2_128_concat) T::CuratorGroupId => CuratorGroup<T>;
- }
- }
- decl_module! {
- pub struct Module<T: Trait> for enum Call where origin: T::Origin {
- /// Predefined errors
- type Error = Error<T>;
- /// Initializing events
- fn deposit_event() = default;
- /// Exports const - max number of curators per group
- const MaxNumberOfCuratorsPerGroup: MaxNumber = T::MaxNumberOfCuratorsPerGroup::get();
- // ======
- // Next set of extrinsics can only be invoked by lead.
- // ======
- /// Add new curator group to runtime storage
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_curator_group(
- origin,
- ) -> DispatchResult {
- // Ensure given origin is lead
- ensure_is_lead::<T>(origin)?;
- //
- // == MUTATION SAFE ==
- //
- let curator_group_id = Self::next_curator_group_id();
- // Insert empty curator group with `active` parameter set to false
- <CuratorGroupById<T>>::insert(curator_group_id, CuratorGroup::<T>::default());
- // Increment the next curator curator_group_id:
- <NextCuratorGroupId<T>>::mutate(|n| *n += T::CuratorGroupId::one());
- // Trigger event
- Self::deposit_event(RawEvent::CuratorGroupCreated(curator_group_id));
- Ok(())
- }
- /// Remove curator group under given `curator_group_id` from runtime storage
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_curator_group(
- origin,
- curator_group_id: T::CuratorGroupId,
- ) -> DispatchResult {
- // Ensure given origin is lead
- ensure_is_lead::<T>(origin)?;
- // Ensure CuratorGroup under given curator_group_id exists
- let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
- // We should previously ensure that curator_group owns no channels to be able to remove it
- curator_group.ensure_curator_group_owns_no_channels()?;
- //
- // == MUTATION SAFE ==
- //
- // Remove curator group under given curator group id from runtime storage
- <CuratorGroupById<T>>::remove(curator_group_id);
- // Trigger event
- Self::deposit_event(RawEvent::CuratorGroupDeleted(curator_group_id));
- Ok(())
- }
- /// Set `is_active` status for curator group under given `curator_group_id`
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn set_curator_group_status(
- origin,
- curator_group_id: T::CuratorGroupId,
- is_active: bool,
- ) -> DispatchResult {
- // Ensure given origin is lead
- ensure_is_lead::<T>(origin)?;
- // Ensure curator group under provided curator_group_id already exist
- Self::ensure_curator_group_under_given_id_exists(&curator_group_id)?;
- //
- // == MUTATION SAFE ==
- //
- // Set `is_active` status for curator group under given `curator_group_id`
- <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
- curator_group.set_status(is_active)
- });
- // Trigger event
- Self::deposit_event(RawEvent::CuratorGroupStatusSet(curator_group_id, is_active));
- Ok(())
- }
- /// Add curator to curator group under given `curator_group_id`
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn add_curator_to_group(
- origin,
- curator_group_id: T::CuratorGroupId,
- curator_id: T::CuratorId,
- ) -> DispatchResult {
- // Ensure given origin is lead
- ensure_is_lead::<T>(origin)?;
- // Ensure curator group under provided curator_group_id already exist, retrieve corresponding one
- let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
- // Ensure max number of curators per group limit not reached yet
- curator_group.ensure_max_number_of_curators_limit_not_reached()?;
- // Ensure curator under provided curator_id isn`t a CuratorGroup member yet
- curator_group.ensure_curator_in_group_does_not_exist(&curator_id)?;
- //
- // == MUTATION SAFE ==
- //
- // Insert curator_id into curator_group under given curator_group_id
- <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
- curator_group.get_curators_mut().insert(curator_id);
- });
- // Trigger event
- Self::deposit_event(RawEvent::CuratorAdded(curator_group_id, curator_id));
- Ok(())
- }
- /// Remove curator from a given curator group
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn remove_curator_from_group(
- origin,
- curator_group_id: T::CuratorGroupId,
- curator_id: T::CuratorId,
- ) -> DispatchResult {
- // Ensure given origin is lead
- ensure_is_lead::<T>(origin)?;
- // Ensure curator group under provided curator_group_id already exist, retrieve corresponding one
- let curator_group = Self::ensure_curator_group_exists(&curator_group_id)?;
- // Ensure curator under provided curator_id is CuratorGroup member
- curator_group.ensure_curator_in_group_exists(&curator_id)?;
- //
- // == MUTATION SAFE ==
- //
- // Remove curator_id from curator_group under given curator_group_id
- <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
- curator_group.get_curators_mut().remove(&curator_id);
- });
- // Trigger event
- Self::deposit_event(RawEvent::CuratorRemoved(curator_group_id, curator_id));
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_channel(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: ChannelCreationParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn update_channel(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- new_assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: ChannelUpdateParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_channel(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn request_channel_transfer(
- origin,
- new_owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- payment: BalanceOf<T>,
- ) -> DispatchResult {
- // requester must be new_owner
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn cancel_channel_transfer_request(
- origin,
- request_id: T::ChannelOwnershipTransferRequestId,
- ) -> DispatchResult {
- // origin must be original requester (ie. proposed new channel owner)
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn accept_channel_transfer(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- request_id: T::ChannelOwnershipTransferRequestId,
- ) -> DispatchResult {
- // only current owner of channel can approve
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_video(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: VideoCreationParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn update_video(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- video: T::VideoId,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: VideoUpdateParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_video(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- video: T::VideoId,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_playlist(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: PlaylistCreationParameters<T::VideoId>,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn update_playlist(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- playlist: T::PlaylistId,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: PlaylistUpdateParameters<T::VideoId>,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_playlist(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- playlist: T::PlaylistId,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn set_featured_videos(
- origin,
- list: Vec<T::VideoId>
- ) -> DispatchResult {
- // can only be set by lead
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_video_category(
- origin,
- curator: T::CuratorId,
- params: VideoCategoryCreationParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn update_video_category(
- origin,
- curator: T::CuratorId,
- category: T::VideoCategoryId,
- params: VideoCategoryUpdateParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_video_category(
- origin,
- curator: T::CuratorId,
- category: T::VideoCategoryId,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_channel_category(
- origin,
- curator: T::CuratorId,
- params: ChannelCategoryCreationParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn update_channel_category(
- origin,
- curator: T::CuratorId,
- category: T::ChannelCategoryId,
- params: ChannelCategoryUpdateParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_channel_category(
- origin,
- curator: T::CuratorId,
- category: T::ChannelCategoryId,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_person(
- origin,
- actor: PersonActor<T::MemberId, T::CuratorId>,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: PersonCreationParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn update_person(
- origin,
- actor: PersonActor<T::MemberId, T::CuratorId>,
- person: T::PersonId,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: PersonUpdateParameters,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_person(
- origin,
- actor: PersonActor<T::MemberId, T::CuratorId>,
- person: T::PersonId,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn add_person_to_video(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- video_id: T::VideoId,
- person: T::PersonId
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn remove_person_from_video(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- video_id: T::VideoId
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn censor_video(
- origin,
- curator_id: T::CuratorId,
- video_id: T::VideoId,
- rationale: Vec<u8>,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn censor_channel(
- origin,
- curator_id: T::CuratorId,
- channel_id: T::ChannelId,
- rationale: Vec<u8>,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn uncensor_video(
- origin,
- curator_id: T::CuratorId,
- video_id: T::VideoId,
- rationale: Vec<u8>
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn uncensor_channel(
- origin,
- curator_id: T::CuratorId,
- channel_id: T::ChannelId,
- rationale: Vec<u8>,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn create_series(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: SeriesParameters<T::VideoId>,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn update_series(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- channel_id: T::ChannelId,
- assets: Vec<NewAsset<ContentParameters<T::ContentId, T::DataObjectTypeId>>>,
- params: SeriesParameters<T::VideoId>,
- ) -> DispatchResult {
- Ok(())
- }
- #[weight = 10_000_000] // TODO: adjust weight
- pub fn delete_series(
- origin,
- owner: ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
- series: T::SeriesId,
- ) -> DispatchResult {
- Ok(())
- }
- }
- }
- impl<T: Trait> Module<T> {
- // TODO: make this private again after used in module
- /// Increment number of channels, maintained by each curator group
- pub fn increment_number_of_channels_owned_by_curator_groups(
- curator_group_ids: BTreeSet<T::CuratorGroupId>,
- ) {
- curator_group_ids.into_iter().for_each(|curator_group_id| {
- Self::increment_number_of_channels_owned_by_curator_group(curator_group_id);
- });
- }
- // TODO: make this private again after used in module
- /// Decrement number of channels, maintained by each curator group
- pub fn decrement_number_of_channels_owned_by_curator_groups(
- curator_group_ids: BTreeSet<T::CuratorGroupId>,
- ) {
- curator_group_ids.into_iter().for_each(|curator_group_id| {
- Self::decrement_number_of_channels_owned_by_curator_group(curator_group_id);
- });
- }
- // TODO: make this private again after used in module
- /// Increment number of channels, maintained by curator group
- pub fn increment_number_of_channels_owned_by_curator_group(
- curator_group_id: T::CuratorGroupId,
- ) {
- <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
- curator_group.increment_number_of_channels_owned_count();
- });
- }
- // TODO: make this private again after used in module
- /// Decrement number of channels, maintained by curator group
- pub fn decrement_number_of_channels_owned_by_curator_group(
- curator_group_id: T::CuratorGroupId,
- ) {
- <CuratorGroupById<T>>::mutate(curator_group_id, |curator_group| {
- curator_group.decrement_number_of_channels_owned_count();
- });
- }
- /// Ensure `CuratorGroup` under given id exists
- pub fn ensure_curator_group_under_given_id_exists(
- curator_group_id: &T::CuratorGroupId,
- ) -> Result<(), Error<T>> {
- ensure!(
- <CuratorGroupById<T>>::contains_key(curator_group_id),
- Error::<T>::CuratorGroupDoesNotExist
- );
- Ok(())
- }
- /// Ensure `CuratorGroup` under given id exists, return corresponding one
- pub fn ensure_curator_group_exists(
- curator_group_id: &T::CuratorGroupId,
- ) -> Result<CuratorGroup<T>, Error<T>> {
- Self::ensure_curator_group_under_given_id_exists(curator_group_id)?;
- Ok(Self::curator_group_by_id(curator_group_id))
- }
- /// Ensure all `CuratorGroup`'s under given ids exist
- pub fn ensure_curator_groups_exist(
- curator_groups: &BTreeSet<T::CuratorGroupId>,
- ) -> Result<(), Error<T>> {
- for curator_group in curator_groups {
- // Ensure CuratorGroup under given id exists
- Self::ensure_curator_group_exists(curator_group)?;
- }
- Ok(())
- }
- }
- // Some initial config for the module on runtime upgrade
- impl<T: Trait> Module<T> {
- pub fn on_runtime_upgrade() {
- <NextChannelCategoryId<T>>::put(T::ChannelCategoryId::one());
- <NextVideoCategoryId<T>>::put(T::VideoCategoryId::one());
- <NextVideoId<T>>::put(T::VideoId::one());
- <NextChannelId<T>>::put(T::ChannelId::one());
- <NextPlaylistId<T>>::put(T::PlaylistId::one());
- <NextSeriesId<T>>::put(T::SeriesId::one());
- <NextPersonId<T>>::put(T::PersonId::one());
- <NextChannelOwnershipTransferRequestId<T>>::put(T::ChannelOwnershipTransferRequestId::one());
- }
- }
- decl_event!(
- pub enum Event<T>
- where
- CuratorGroupId = <T as ContentActorAuthenticator>::CuratorGroupId,
- CuratorId = <T as ContentActorAuthenticator>::CuratorId,
- VideoId = <T as Trait>::VideoId,
- VideoCategoryId = <T as Trait>::VideoCategoryId,
- ChannelId = <T as StorageOwnership>::ChannelId,
- MemberId = <T as MembershipTypes>::MemberId,
- NewAsset = NewAsset<ContentParameters<ContentId<T>, DataObjectTypeId<T>>>,
- ChannelCategoryId = <T as Trait>::ChannelCategoryId,
- ChannelOwnershipTransferRequestId = <T as Trait>::ChannelOwnershipTransferRequestId,
- PlaylistId = <T as Trait>::PlaylistId,
- SeriesId = <T as Trait>::SeriesId,
- PersonId = <T as Trait>::PersonId,
- DAOId = <T as StorageOwnership>::DAOId,
- ChannelOwnershipTransferRequest = ChannelOwnershipTransferRequest<T>,
- Series = Series<<T as StorageOwnership>::ChannelId, <T as Trait>::VideoId>,
- {
- // Curators
- CuratorGroupCreated(CuratorGroupId),
- CuratorGroupDeleted(CuratorGroupId),
- CuratorGroupStatusSet(CuratorGroupId, bool /* active status */),
- CuratorAdded(CuratorGroupId, CuratorId),
- CuratorRemoved(CuratorGroupId, CuratorId),
- // Channels
- ChannelCreated(
- ChannelId,
- ChannelOwner<MemberId, CuratorGroupId, DAOId>,
- Vec<NewAsset>,
- ChannelCreationParameters,
- ),
- ChannelUpdated(ChannelId, Vec<NewAsset>, ChannelUpdateParameters),
- ChannelDeleted(ChannelId),
- ChannelCensored(ChannelId, Vec<u8> /* rationale */),
- ChannelUncensored(ChannelId, Vec<u8> /* rationale */),
- // Channel Ownership Transfers
- ChannelOwnershipTransferRequested(
- ChannelOwnershipTransferRequestId,
- ChannelOwnershipTransferRequest,
- ),
- ChannelOwnershipTransferRequestWithdrawn(ChannelOwnershipTransferRequestId),
- ChannelOwnershipTransferred(ChannelOwnershipTransferRequestId),
- // Channel Categories
- ChannelCategoryCreated(ChannelCategoryId, ChannelCategoryCreationParameters),
- ChannelCategoryUpdated(ChannelCategoryUpdateParameters),
- ChannelCategoryDeleted(ChannelCategoryId),
- // Videos
- VideoCategoryCreated(VideoCategoryId, VideoCategoryCreationParameters),
- VideoCategoryUpdated(VideoCategoryId, VideoCategoryUpdateParameters),
- VideoCategoryDeleted(VideoCategoryId),
- VideoCreated(VideoId, Vec<NewAsset>, VideoCreationParameters),
- VideoUpdated(VideoId, Vec<NewAsset>, VideoUpdateParameters),
- VideoDeleted(VideoId),
- VideoCensored(VideoId, Vec<u8> /* rationale */),
- VideoUncensored(VideoId, Vec<u8> /* rationale */),
- // Featured Videos
- FeaturedVideosSet(Vec<VideoId>),
- // Video Playlists
- PlaylistCreated(PlaylistId, PlaylistCreationParameters<VideoId>),
- PlaylistUpdated(PlaylistId, PlaylistUpdateParameters<VideoId>),
- PlaylistDeleted(PlaylistId),
- // Series
- SeriesCreated(SeriesId, Vec<NewAsset>, SeriesParameters<VideoId>, Series),
- SeriesUpdated(SeriesId, Vec<NewAsset>, SeriesParameters<VideoId>, Series),
- SeriesDeleted(SeriesId),
- // Persons
- PersonCreated(PersonId, Vec<NewAsset>, PersonCreationParameters),
- PersonUpdated(PersonId, Vec<NewAsset>, PersonUpdateParameters),
- PersonDeleted(PersonId),
- }
- );
|