Skip to content

Commit 70c48a9

Browse files
authored
Merge pull request #222 from MerginMaps/project-history
Project history : Add functionnalities for the version viewerin the QGIS plugin
2 parents 74222e4 + dcbeb22 commit 70c48a9

File tree

3 files changed

+77
-13
lines changed

3 files changed

+77
-13
lines changed

mergin/client.py

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,17 @@ def workspace_service(self, workspace_id):
372372

373373
return response
374374

375+
def workspace_usage(self, workspace_id):
376+
"""
377+
This Requests information about a workspace usage from /workspace/{id}/usage endpoint,
378+
if such exists in self.url server.
379+
380+
Returns response from server as JSON dict or None if endpoint is not found
381+
"""
382+
383+
resp = self.get(f"/v1/workspace/{workspace_id}/usage")
384+
return json.load(resp)
385+
375386
def server_type(self):
376387
"""
377388
Returns the deployment type of the server
@@ -700,41 +711,84 @@ def project_info(self, project_path_or_id, since=None, version=None):
700711
resp = self.get("/v1/project/{}".format(project_path_or_id), params)
701712
return json.load(resp)
702713

703-
def project_versions(self, project_path, since=None, to=None):
714+
def paginated_project_versions(self, project_path, page, per_page=100, descending=False):
715+
"""
716+
Get records of project's versions (history) using calculated pagination.
717+
wrapper around the /v1/project/versions/paginated/{} API end point
718+
719+
:param project_path: Project's full name (<namespace>/<name>)
720+
:type project_path: String | Int
721+
:param page: page number
722+
:type page: Int
723+
:param per_page: number of results per page default 100
724+
:type per_page: Int
725+
:param descending: order of sorting
726+
:type descending: Bool
727+
728+
:rtype: List[Dict], Int
729+
"""
730+
params = {"page": page, "per_page": per_page, "descending": descending}
731+
resp = self.get("/v1/project/versions/paginated/{}".format(project_path), params)
732+
resp_json = json.load(resp)
733+
return resp_json["versions"], resp_json["count"]
734+
735+
def project_versions_count(self, project_path):
736+
"""
737+
return the total count of versions
738+
To note we fetch only one page and one item as we only need the "count" response
739+
740+
:param project_path_or_id: Project's full name (<namespace>/<name>) or id
741+
:type project_path_or_id: String
742+
743+
:rtype: Int
744+
"""
745+
params = {"page": 1, "per_page": 1, "descending": False}
746+
resp = self.get("/v1/project/versions/paginated/{}".format(project_path), params)
747+
resp_json = json.load(resp)
748+
return resp_json["count"]
749+
750+
def project_versions(self, project_path, since=1, to=None):
704751
"""
705752
Get records of project's versions (history) in ascending order.
706753
If neither 'since' nor 'to' is specified it will return all versions.
707754
708755
:param project_path: Project's full name (<namespace>/<name>)
709756
:type project_path: String
710757
:param since: Version to track project history from
711-
:type since: String
758+
:type since: String | Int
712759
:param to: Version to track project history to
713-
:type to: String
760+
:type to: String | Int
714761
715762
:rtype: List[Dict]
716763
"""
717764
versions = []
718765
per_page = 100 # server limit
719-
num_since = int_version(since) if since else 1
720-
num_to = int_version(to) if to else None # we may not know yet
766+
767+
if type(since) == str:
768+
num_since = int_version(since)
769+
else:
770+
# keep the since parameter as is
771+
num_since = since
772+
773+
if type(to) == str:
774+
num_to = int_version(to)
775+
else:
776+
# keep the to parameter as is
777+
num_to = to
778+
721779
start_page = math.ceil(num_since / per_page)
722780
if not num_to:
723781
# let's get first page and count
724-
params = {"page": start_page, "per_page": per_page, "descending": False}
725-
resp = self.get("/v1/project/versions/paginated/{}".format(project_path), params)
726-
resp_json = json.load(resp)
727-
versions = resp_json["versions"]
728-
num_to = resp_json["count"]
782+
versions, num_to = self.paginated_project_versions(project_path, start_page, per_page)
783+
729784
latest_version = int_version(versions[-1]["name"])
730785
if latest_version < num_to:
731786
versions += self.project_versions(project_path, f"v{latest_version+1}", f"v{num_to}")
732787
else:
733788
end_page = math.ceil(num_to / per_page)
734789
for page in range(start_page, end_page + 1):
735-
params = {"page": page, "per_page": per_page, "descending": False}
736-
resp = self.get("/v1/project/versions/paginated/{}".format(project_path), params)
737-
versions += json.load(resp)["versions"]
790+
page_versions, _ = self.paginated_project_versions(project_path, page, per_page)
791+
versions += page_versions
738792

739793
# filter out versions not within range
740794
filtered_versions = list(filter(lambda v: (num_since <= int_version(v["name"]) <= num_to), versions))

mergin/client_pull.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,8 @@ def download_diffs_async(mc, project_directory, file_path, versions):
687687
fetch_files = []
688688

689689
for version in versions:
690+
if version not in file_history["history"]:
691+
continue # skip if this file was not modified at this version
690692
version_data = file_history["history"][version]
691693
if "diff" not in version_data:
692694
continue # skip if there is no diff in history

mergin/test/test_client.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,6 +2013,14 @@ def test_project_versions_list(mc):
20132013
assert versions[0]["name"] == "v2"
20142014
assert versions[-1]["name"] == "v4"
20152015

2016+
versions_count = mc.project_versions_count(project)
2017+
assert versions_count == 5
2018+
2019+
versions, _ = mc.paginated_project_versions(project, page=1, descending=True)
2020+
assert len(versions) == 5
2021+
assert versions[0]["name"] == "v5"
2022+
assert versions[-1]["name"] == "v1"
2023+
20162024

20172025
def test_report(mc):
20182026
test_project = "test_report"

0 commit comments

Comments
 (0)