@@ -72,6 +72,10 @@ class ChannelIncompleteError(Exception):
7272 pass
7373
7474
75+ class NoneContentNodeTreeError (Exception ):
76+ pass
77+
78+
7579class SlowPublishError (Exception ):
7680 """
7781 Used to track slow Publishing operations. We don't raise this error,
@@ -111,17 +115,17 @@ def send_emails(channel, user_id, version_notes=''):
111115 user .email_user (subject , message , settings .DEFAULT_FROM_EMAIL , html_message = message )
112116
113117
114- def create_content_database (channel , force , user_id , force_exercises , progress_tracker = None ):
118+ def create_content_database (channel , force , user_id , force_exercises , progress_tracker = None , use_staging_tree = False ):
115119 """
116120 :type progress_tracker: contentcuration.utils.celery.ProgressTracker|None
117121 """
118122 # increment the channel version
119- if not force :
123+ if not use_staging_tree and not force :
120124 raise_if_nodes_are_all_unchanged (channel )
121125 fh , tempdb = tempfile .mkstemp (suffix = ".sqlite3" )
122126
123127 with using_content_database (tempdb ):
124- if not channel .main_tree .publishing :
128+ if not use_staging_tree and not channel .main_tree .publishing :
125129 channel .mark_publishing (user_id )
126130
127131 call_command ("migrate" ,
@@ -130,8 +134,9 @@ def create_content_database(channel, force, user_id, force_exercises, progress_t
130134 no_input = True )
131135 if progress_tracker :
132136 progress_tracker .track (10 )
137+ base_tree = channel .staging_tree if use_staging_tree else channel .main_tree
133138 tree_mapper = TreeMapper (
134- channel . main_tree ,
139+ base_tree ,
135140 channel .language ,
136141 channel .id ,
137142 channel .name ,
@@ -141,14 +146,16 @@ def create_content_database(channel, force, user_id, force_exercises, progress_t
141146 inherit_metadata = bool (channel .ricecooker_version ),
142147 )
143148 tree_mapper .map_nodes ()
144- kolibri_channel = map_channel_to_kolibri_channel (channel )
149+ kolibri_channel = map_channel_to_kolibri_channel (channel , use_staging_tree )
145150 # It should be at this percent already, but just in case.
146151 if progress_tracker :
147152 progress_tracker .track (90 )
148- map_prerequisites (channel .main_tree )
153+ map_prerequisites (base_tree )
154+ # Need to save as version being published, not current version
155+ version = "next" if use_staging_tree else channel .version + 1
149156 save_export_database (
150- channel .pk , channel . version + 1
151- ) # Need to save as version being published, not current version
157+ channel .pk , version , use_staging_tree ,
158+ )
152159 if channel .public :
153160 mapper = ChannelMapper (kolibri_channel )
154161 mapper .run ()
@@ -732,17 +739,18 @@ def map_prerequisites(root_node):
732739 logging .error ('Unable to find source node for prerequisite relationship {}' .format (str (e )))
733740
734741
735- def map_channel_to_kolibri_channel (channel ):
742+ def map_channel_to_kolibri_channel (channel , use_staging_tree = False ):
736743 logging .debug ("Generating the channel metadata." )
744+ base_tree = channel .staging_tree if use_staging_tree else channel .main_tree
737745 kolibri_channel = kolibrimodels .ChannelMetadata .objects .create (
738746 id = channel .id ,
739747 name = channel .name ,
740748 description = channel .description ,
741749 tagline = channel .tagline ,
742750 version = channel .version + 1 , # Need to save as version being published, not current version
743751 thumbnail = channel .icon_encoding ,
744- root_pk = channel . main_tree .node_id ,
745- root_id = channel . main_tree .node_id ,
752+ root_pk = base_tree .node_id ,
753+ root_id = base_tree .node_id ,
746754 min_schema_version = MIN_SCHEMA_VERSION , # Need to modify Kolibri so we can import this without importing models
747755 )
748756 logging .info ("Generated the channel metadata." )
@@ -805,25 +813,27 @@ def raise_if_nodes_are_all_unchanged(channel):
805813 logging .info ("Some nodes are changed." )
806814
807815
808- def mark_all_nodes_as_published (channel ):
816+ def mark_all_nodes_as_published (tree ):
809817 logging .debug ("Marking all nodes as published." )
810818
811- channel . main_tree .get_family ().update (changed = False , published = True )
819+ tree .get_family ().update (changed = False , published = True )
812820
813821 logging .info ("Marked all nodes as published." )
814822
815823
816- def save_export_database (channel_id , version ):
824+ def save_export_database (channel_id , version , use_staging_tree = False ):
817825 logging .debug ("Saving export database" )
818826 current_export_db_location = get_active_content_database ()
819827 target_paths = [
820- os .path .join (
821- settings .DB_ROOT , "{id}.sqlite3" .format (id = channel_id )
822- ),
823828 os .path .join (
824829 settings .DB_ROOT , "{}-{}.sqlite3" .format (channel_id , version )
825- ),
830+ )
826831 ]
832+ # Only create non-version path if not using the staging tree
833+ if not use_staging_tree :
834+ target_paths .append (
835+ os .path .join (settings .DB_ROOT , "{id}.sqlite3" .format (id = channel_id )
836+ ))
827837
828838 for target_export_db_location in target_paths :
829839 with open (current_export_db_location , 'rb' ) as currentf :
@@ -919,30 +929,43 @@ def publish_channel(
919929 send_email = False ,
920930 progress_tracker = None ,
921931 language = settings .LANGUAGE_CODE ,
932+ use_staging_tree = False ,
922933):
923934 """
924935 :type progress_tracker: contentcuration.utils.celery.ProgressTracker|None
925936 """
926937 channel = ccmodels .Channel .objects .get (pk = channel_id )
938+ base_tree = channel .staging_tree if use_staging_tree else channel .main_tree
939+ if base_tree is None :
940+ tree_name = "staging_tree" if use_staging_tree else "main_tree"
941+ raise NoneContentNodeTreeError (f"{ tree_name } is None!" )
927942 kolibri_temp_db = None
928943 start = time .time ()
929944 try :
930945 set_channel_icon_encoding (channel )
931- kolibri_temp_db = create_content_database (channel , force , user_id , force_exercises , progress_tracker = progress_tracker )
932- increment_channel_version (channel )
946+ kolibri_temp_db = create_content_database (
947+ channel ,
948+ force ,
949+ user_id ,
950+ force_exercises ,
951+ progress_tracker = progress_tracker ,
952+ use_staging_tree = use_staging_tree ,
953+ )
933954 add_tokens_to_channel (channel )
934- sync_contentnode_and_channel_tsvectors (channel_id = channel .id )
935- mark_all_nodes_as_published (channel )
936- fill_published_fields (channel , version_notes )
955+ if not use_staging_tree :
956+ increment_channel_version (channel )
957+ sync_contentnode_and_channel_tsvectors (channel_id = channel .id )
958+ mark_all_nodes_as_published (base_tree )
959+ fill_published_fields (channel , version_notes )
937960
938961 # Attributes not getting set for some reason, so just save it here
939- channel . main_tree .publishing = False
940- channel . main_tree .changed = False
941- channel . main_tree .published = True
942- channel . main_tree .save ()
962+ base_tree .publishing = False
963+ base_tree .changed = False
964+ base_tree .published = True
965+ base_tree .save ()
943966
944967 # Delete public channel cache.
945- if channel .public :
968+ if not use_staging_tree and channel .public :
946969 delete_public_channel_cache_keys ()
947970
948971 if send_email :
@@ -960,8 +983,8 @@ def publish_channel(
960983 finally :
961984 if kolibri_temp_db and os .path .exists (kolibri_temp_db ):
962985 os .remove (kolibri_temp_db )
963- channel . main_tree .publishing = False
964- channel . main_tree .save ()
986+ base_tree .publishing = False
987+ base_tree .save ()
965988
966989 elapsed = time .time () - start
967990
0 commit comments