-
Notifications
You must be signed in to change notification settings - Fork 299
Description
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Requires #5170
Overview
As part of this issue we will finally transfer a channel to be part of the Community Library. From the technical implementation perspective, Community Library channels will be identified as channel records in the kolibri_public app models where the public field is set to false. This means that the approved channel version will be mapped to a channel within the kolibri_public application models.
Prerrequisites
- Understand the Studio channel publishing workflow.
- Understand how channel databases are stored in Studio.
- Understand how a channel is made public.
- Understand how the channel changes mechanism works.
Technical requirements
Upon approval of a submission, a new asynchronous task should be enqueued to map the approved channel version's database to the kolibri_public models.
To handle this new asynchronous task, we will leverage our existing changes architecture and integrate this process as a new channel change type, named ADDED_TO_COMMUNITY_LIBRARY.
- We will add a new
ADDED_TO_COMMUNITY_LIBRARYchange type in the sync/constants.py file, and include this new change in theALL_CHANGESarray. - This new
ADDED_TO_COMMUNITY_LIBRARYchange will be enqueued immediately after an admin has approved a submission in theresolutionaction in the Community Library Submission Viewset. To enqueue this task, we can:- Create a new
generate_add_to_community_library_eventfunction in viewsets/sync/utils.py that receives thekey, thechannel_version, and an optionalcategoriesandcountriesarguments. These optional arguments will then be populated with data from the approved submission. - Within the
submissionviewset action, we can then create a newADDED_TO_COMMUNITY_LIBRARYchange using the Change.create_change method where the change will be the one returned from thegenerate_add_to_community_library_eventfunction, and its author will be set to the user who approved the submission. - Finally we will call the
apply_channel_changes_task.fetch_or_enqueuemethod that will enqueue theapply_channel_changes_taskfor this change to be applied. In the publish channel api you can see an example of how to create a new event and subsequently enqueue this task.
- Create a new
- This new change will just be allowed to be created on the server side. So adding a new
ADDED_TO_COMMUNITY_LIBRARYchange through the sync viewset should not be allowed.- We can achieve this by adding a new
SERVER_ONLY_CHANGESconstant in the viewsets/sync/constants.py file. Any change included inSERVER_ONLY_CHANGESarriving via the sync endpoint will then be rejected.
- We can achieve this by adding a new
- Now, to support the new metadata introduced by
CommunityLibrarySubmission. We will need to create two new fields in the ChannelMetadata model of thekolibri_publicapp:categoriesandcountries.- To enable filtering by
categories, we will need to add bitmap fields to theChannelMetadatamodel. However, this will be part of a subsequent issue; let's not focus on it for now.
- To enable filtering by
- In the ChannelViewset we will add a new
add_to_community_library_from_changesmethod that will call anadd_to_community_librarymethod (description of this method below) for each change. Then we will map the newADDED_TO_COMMUNITY_LIBRARYchange to theadd_to_community_library_from_changesmethod in the apply_changes function event handlers. With this, we will be able to applyADDED_TO_COMMUNITY_LIBRARYchanges. - The
add_to_community_librarymethod should receive the channel ID, the channel version to be added to the Community Library, and the categories and countries that will be added to the community library, the categories and the countries that will be added to the kolibri_public ChannelMetadata instance.- To export the channel to the
kolibri_publicmodels, we will reuse the logic that we have in the_export_channelmethod of the export_channels_to_kolibri_public command. - To reuse this
_export_channelmethod across the command and the sync changes task, we will move this logic to a newexport_channel_to_kolibri_publicfile in thekolibri_public/utilsfolder, which will define theexport_channel_to_kolibri_publicfunction. - We should modify this
export_channel_to_kolibri_publicfunction to accommodate the new requirements for adding a channel to the Community Library. Specifically, this function should now receivechannel_idas a required argument, andchannel_version=None,public=True,categories=None, andcountries=Noneas optional arguments. Subsequently, we should modify the ChannelMapper class to receive all these new values as optional arguments in its constructor method. - Within the ChannelMapper's run method we call the
set_channel_metadata_fieldsutil function to annotate additional metadata that this channel will have in the ChannelMetadata model. As we are now introducingcategoriesandcountriesto this model, we should modify the set_channel_metadata_fields function to :- Add the calculation of the
categoriesfield taking into account both: the included channel categories (i.e. querying the categories of all channel contentnodes, similar to what we do for included languages), and the categories obtained from the submission. Included categories can also be obtained from thepublished_datacontent curation channel field, but this field will not be available for older channels, so lets replicate what we do for the included_languages field. - Add the countries list to the channel.
- Add the calculation of the
- The
export_channels_to_kolibri_publiccommand should use this utility function in its handler method, calling it just passing thechannel_idparameter. - The
add_to_community_librarychannel viewset method should call this utility function with all optional parameters set.
- To export the channel to the
- Finally, unit tests should be added to cover at least the following scenarios:
- After a submission has been approved, a new change event is created in the changes model, and the apply channel changes task has been enqueued.
- If a submission is rejected, no new change event is created in the changes model.
- Test that the new
ADDED_TO_COMMUNITY_LIBRARYis not applied if we send it through the sync endpoint. - Test that the channel apply changes task is instantiating the ChannelMapper object with the correct arguments, and its calling the channelMapper.run afterwards.
- Test that a exception is thrown if we try adding a
ADDED_TO_COMMUNITY_LIBRARYchange with a non-existing channel version database. - Add new tests to the ChannelMapper test case to test that the
categoriesfield is being set correctly to thekolibri_publicchannel. - Add new tests to the ChannelMapper test case to test that the
countriesfield is being set correctly to thekolibri_publicchannel.
Acceptance criteria
- New
ADDED_TO_COMMUNITY_LIBRARYchange is enqueued after the submission was approved. - New
categoriesandcountriesfields have been added to thekolibri_public'sChannelMetadatamodel. -
add_to_community_library_from_changesmethod is added to the channel viewset and mapped to the apply changes event handlers. - A new
export_channel_to_kolibri_publicfunction is created to support the apply changes task, and the existingexport_channels_to_kolibri_publiccommand. - The specific channel version records are present in the
kolibri_publicmodels after the task was run. - Described unit tests have been added.
