Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions mergin/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from mergin.client_pull import (
download_project_async,
download_project_cancel,
download_file_async,
download_file_finalize,
download_project_finalize,
download_project_is_running,
)
Expand Down Expand Up @@ -260,6 +262,41 @@ def download(ctx, project, directory, version):
_print_unhandled_exception()


@cli.command()
@click.argument("filepath")
@click.argument("output")
@click.option("--version", help="Project version tag, for example 'v3'")
@click.pass_context
def download_file(ctx, filepath, output, version):
"""
Download project file at specified version. `project` needs to be a combination of namespace/project.
If no version is given, the latest will be fetched.
"""
mc = ctx.obj["client"]
if mc is None:
return
mp = MerginProject(os.getcwd())
project_path = mp.metadata["name"]
try:
job = download_file_async(mc, project_path, filepath, output, version)
with click.progressbar(length=job.total_size) as bar:
last_transferred_size = 0
while download_project_is_running(job):
time.sleep(1 / 10) # 100ms
new_transferred_size = job.transferred_size
bar.update(new_transferred_size - last_transferred_size) # the update() needs increment only
last_transferred_size = new_transferred_size
download_file_finalize(job)
click.echo("Done")
except KeyboardInterrupt:
click.secho("Cancelling...")
download_project_cancel(job)
except ClientError as e:
click.secho("Error: " + str(e), fg="red")
except Exception as e:
_print_unhandled_exception()


def num_version(name):
return int(name.lstrip("v"))

Expand Down
49 changes: 46 additions & 3 deletions mergin/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,20 @@
import dateutil.parser
import ssl

from .common import ClientError, LoginError
from .common import ClientError, LoginError, InvalidProject
from .merginproject import MerginProject
from .client_pull import download_project_async, download_project_wait, download_project_finalize
from .client_pull import (
download_file_finalize,
download_project_async,
download_file_async,
download_diffs_async,
download_project_finalize,
download_project_wait,
download_diffs_finalize,
)
from .client_pull import pull_project_async, pull_project_wait, pull_project_finalize
from .client_push import push_project_async, push_project_wait, push_project_finalize
from .utils import DateTimeEncoder
from .utils import DateTimeEncoder, get_versions_with_file_changes
from .version import __version__

this_dir = os.path.dirname(os.path.realpath(__file__))
Expand Down Expand Up @@ -618,3 +626,38 @@ def get_projects_by_names(self, projects):

resp = self.post("/v1/project/by_names", {"projects": projects}, {"Content-Type": "application/json"})
return json.load(resp)

def download_file(self, project_dir, file_path, output_filename, version=None):
"""
Download project file at specified version. Get the latest if no version specified.

:param project_dir: project local directory
:type project_dir: String
:param file_path: relative path of file to download in the project directory
:type file_path: String
:param output_filename: full destination path for saving the downloaded file
:type output_filename: String
:param version: optional version tag for downloaded file
:type version: String
"""
job = download_file_async(self, project_dir, file_path, output_filename, version=version)
pull_project_wait(job)
download_file_finalize(job)

def get_file_diff(self, project_dir, file_path, output_diff, version_from, version_to):
""" Create concatenated diff for project file diffs between versions version_from and version_to.

:param project_dir: project local directory
:type project_dir: String
:param file_path: relative path of file to download in the project directory
:type file_path: String
:param output_diff: full destination path for concatenated diff file
:type output_diff: String
:param version_from: starting project version tag for getting diff, for example 'v3'
:type version_from: String
:param version_to: ending project version tag for getting diff
:type version_to: String
"""
job = download_diffs_async(self, project_dir, file_path, version_from, version_to)
pull_project_wait(job)
download_diffs_finalize(job, output_diff)
Loading