Skip to content

Commit e886dfc

Browse files
committed
Fix test and filter_changes()
1 parent bafd30f commit e886dfc

File tree

2 files changed

+127
-161
lines changed

2 files changed

+127
-161
lines changed

mergin/client_push.py

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -96,36 +96,15 @@ class ChangesHandler:
9696
- Generating upload-ready change groups for asynchronous job creation.
9797
"""
9898

99-
def __init__(self, client, mp):
99+
def __init__(self, client, project_dir):
100100
self.client = client
101-
self.mp = MerginProject(mp)
101+
self.mp = MerginProject(project_dir)
102102
self._raw_changes = self.mp.get_push_changes()
103103

104104
@staticmethod
105105
def is_blocking_file(file):
106106
return is_qgis_file(file["path"]) or is_versioned_file(file["path"])
107107

108-
def _filter_changes(self, changes: Dict[str, List[dict]]) -> Dict[str, List[dict]]:
109-
"""
110-
Filters the given changes dictionary based on the editor's enabled state.
111-
112-
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.
113-
114-
Args:
115-
changes (dict[str, list[dict]]): A dictionary mapping file paths to lists of change dictionaries.
116-
117-
Returns:
118-
dict[str, list[dict]]: The filtered changes dictionary.
119-
"""
120-
project_name = self.mp.project_full_name()
121-
try:
122-
project_info = self.client.project_info(project_name)
123-
except Exception as e:
124-
self.mp.log.error(f"Failed to get project info for project {project_name}: {e}")
125-
if not is_editor_enabled(self.client, project_info):
126-
return changes
127-
return _apply_editor_filters(changes)
128-
129108
def _split_by_type(self, changes: Dict[str, List[dict]]) -> List[Dict[str, List[dict]]]:
130109
"""
131110
Split raw filtered changes into two batches:
@@ -159,12 +138,35 @@ def split(self) -> List[Dict[str, List[dict]]]:
159138
"""
160139
Applies all configured internal filters and returns a list of change ready to be uploaded.
161140
"""
162-
changes = self._filter_changes(self._raw_changes)
141+
project_name = self.mp.project_full_name()
142+
try:
143+
project_info = self.client.project_info(project_name)
144+
except ClientError as e:
145+
self.mp.log.error(f"Failed to get project info for project {project_name}: {e}")
146+
raise
147+
changes = self.filter_changes(self.client, project_info, self._raw_changes)
163148
changes_list = self._split_by_type(changes)
164149
# TODO: apply limits; changes = self._limit_by_file_count(changes)
165150
return changes_list
166151

167152

153+
def filter_changes(mc, project_info, changes: Dict[str, List[dict]]) -> Dict[str, List[dict]]:
154+
"""
155+
Filters the given changes dictionary based on the editor's enabled state.
156+
157+
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.
158+
159+
Args:
160+
changes (dict[str, list[dict]]): A dictionary mapping file paths to lists of change dictionaries.
161+
162+
Returns:
163+
dict[str, list[dict]]: The filtered changes dictionary.
164+
"""
165+
if is_editor_enabled(mc, project_info):
166+
changes = _apply_editor_filters(changes)
167+
return changes
168+
169+
168170
def get_change_batch(mc, project_dir) -> Tuple[Optional[Dict[str, List[dict]]], bool]:
169171
"""
170172
Return the next changes dictionary and flag if there are more changes (to be uploaded in the next upload job)
@@ -176,13 +178,14 @@ def get_change_batch(mc, project_dir) -> Tuple[Optional[Dict[str, List[dict]]],
176178
return changes_list[0], non_empty_length > 1
177179

178180

179-
def push_project_async(mc, directory, change_batch=None) -> Optional[UploadJob]:
181+
def push_project_async(mc, directory, changes=None) -> Optional[UploadJob]:
180182
"""
181183
Starts push in background and returns pending upload job.
182184
Pushes all project changes unless change_batch is provided.
183185
When specific change is provided, initial version check is skipped (the pull has just been done).
184186
185-
:param change_batch: A dictionary of changes that was split to blocking and non-blocking.
187+
:param changes: The changes to upload are either (1) provided (and already split to blocking and bob-blocking batches)
188+
or (2) all local changes are retrieved to upload
186189
Pushing only non-blocking changes results in non-exclusive upload which server allows to be concurrent.
187190
"""
188191

@@ -197,7 +200,7 @@ def push_project_async(mc, directory, change_batch=None) -> Optional[UploadJob]:
197200
mp.log.info(f"--- start push {project_path}")
198201

199202
# if we have specific change to push we don't need version check
200-
if not change_batch:
203+
if not changes:
201204
try:
202205
project_info = mc.project_info(project_path)
203206
except ClientError as err:
@@ -222,8 +225,8 @@ def push_project_async(mc, directory, change_batch=None) -> Optional[UploadJob]:
222225
"There is a new version of the project on the server. Please update your local copy."
223226
+ f"\n\nLocal version: {local_version}\nServer version: {server_version}"
224227
)
228+
changes = filter_changes(mc, project_info, mp.get_push_changes())
225229

226-
changes = change_batch or mp.get_push_changes()
227230
mp.log.debug("push change:\n" + pprint.pformat(changes))
228231

229232
tmp_dir = tempfile.TemporaryDirectory(prefix="python-api-client-")

0 commit comments

Comments
 (0)