1919
2020from .common import UPLOAD_CHUNK_SIZE , ClientError
2121from .merginproject import MerginProject
22- from .editor import filter_changes
22+ from .editor import is_editor_enabled , _apply_editor_filters
2323from .utils import is_qgis_file , is_versioned_file
2424
2525
@@ -84,7 +84,7 @@ def upload_blocking(self, mc, mp):
8484 raise ClientError ("Mismatch between uploaded file chunk {} and local one" .format (self .chunk_id ))
8585
8686
87- class UploadChangesHandler :
87+ class ChangesHandler :
8888 """
8989 Handles preparation of file changes to be uploaded to the server.
9090
@@ -95,49 +95,71 @@ class UploadChangesHandler:
9595 - Generating upload-ready change groups for asynchronous job creation.
9696 """
9797
98- def __init__ (self , mp , client , project_info ):
99- self .mp = mp
98+ def __init__ (self , client , project_info , changes ):
10099 self .client = client
101100 self .project_info = project_info
102- self ._raw_changes = mp .get_push_changes ()
103- self ._filtered_changes = filter_changes (client , project_info , self ._raw_changes )
101+ self ._raw_changes = changes
104102
105103 @staticmethod
106104 def is_blocking_file (file ):
107105 return is_qgis_file (file ["path" ]) or is_versioned_file (file ["path" ])
108106
109- def split_by_type (self ) -> List [Dict [str , List [dict ]]]:
107+ def _filter_changes (self , changes : Dict [str , List [dict ]]) -> Dict [str , List [dict ]]:
108+ """
109+ Filters the given changes dictionary based on the editor's enabled state.
110+
111+ If the editor is not enabled, the changes dictionary is returned as-is. Otherwise, the changes are passed through the `_apply_editor_filters` method to apply any configured filters.
112+
113+ Args:
114+ changes (dict[str, list[dict]]): A dictionary mapping file paths to lists of change dictionaries.
115+
116+ Returns:
117+ dict[str, list[dict]]: The filtered changes dictionary.
118+ """
119+ if not is_editor_enabled (self .client , self .project_info ):
120+ return changes
121+ return _apply_editor_filters (changes )
122+
123+ def _split_by_type (self , changes : Dict [str , List [dict ]]) -> List [Dict [str , List [dict ]]]:
110124 """
111125 Split raw filtered changes into two batches:
112126 1. Blocking: updated/removed and added files that are blocking
113127 2. Non-blocking: added files that are not blocking
114128
115- Returns a list of dicts each with keys:
116- - added, updated, removed, blocking
129+ Adds blocking key with a boolean value for each group
117130 """
118- blocking_group = {"added" : [], "updated" : [], "removed" : [], "blocking" : True }
119- non_blocking_group = {"added" : [], "updated" : [], "removed" : [], "blocking" : False }
131+ blocking_changes = {"added" : [], "updated" : [], "removed" : [], "blocking" : True }
132+ non_blocking_changes = {"added" : [], "updated" : [], "removed" : [], "blocking" : False }
120133
121- for f in self . _filtered_changes .get ("added" , []):
134+ for f in changes .get ("added" , []):
122135 if self .is_blocking_file (f ):
123- blocking_group ["added" ].append (f )
136+ blocking_changes ["added" ].append (f )
124137 else :
125- non_blocking_group ["added" ].append (f )
138+ non_blocking_changes ["added" ].append (f )
126139
127- for f in self . _filtered_changes .get ("updated" , []):
128- blocking_group ["updated" ].append (f )
140+ for f in changes .get ("updated" , []):
141+ blocking_changes ["updated" ].append (f )
129142
130- for f in self . _filtered_changes .get ("removed" , []):
131- blocking_group ["removed" ].append (f )
143+ for f in changes .get ("removed" , []):
144+ blocking_changes ["removed" ].append (f )
132145
133146 result = []
134- if any (blocking_group [k ] for k in ("added" , "updated" , "removed" )):
135- result .append (blocking_group )
136- if any (non_blocking_group ["added" ]):
137- result .append (non_blocking_group )
147+ if any (blocking_changes [k ] for k in ("added" , "updated" , "removed" )):
148+ result .append (blocking_changes )
149+ if any (non_blocking_changes ["added" ]):
150+ result .append (non_blocking_changes )
138151
139152 return result
140153
154+ def split (self ) -> List [Dict [str , List [dict ]]]:
155+ """
156+ Applies all configured internal filters and returns a list of change ready to be uploaded.
157+ """
158+ changes = self ._filter_changes (self ._raw_changes )
159+ changes = self ._split_by_type (changes )
160+ # TODO: apply limits; changes = self._limit_by_file_count(changes)
161+ return changes
162+
141163
142164def push_project_async (mc , directory ) -> Optional [List [UploadJob ]]:
143165 """Starts push of a project and returns pending upload jobs"""
@@ -177,13 +199,14 @@ def push_project_async(mc, directory) -> Optional[List[UploadJob]]:
177199 + f"\n \n Local version: { local_version } \n Server version: { server_version } "
178200 )
179201
180- changes_handler = UploadChangesHandler (mp , mc , project_info )
181- changes_groups = changes_handler .split_by_type ()
202+ changes = mp .get_push_changes ()
203+ changes_handler = ChangesHandler (mc , project_info , changes )
204+ changes_list = changes_handler .split ()
182205
183206 tmp_dir = tempfile .TemporaryDirectory (prefix = "python-api-client-" )
184207 jobs = []
185208
186- for changes in changes_groups :
209+ for changes in changes_list :
187210 mp .log .debug ("push changes:\n " + pprint .pformat (changes ))
188211
189212 # If there are any versioned files (aka .gpkg) that are not updated through a diff,
0 commit comments