mergin/client_pull.py
def download_project_async(mc, project_path, directory, project_version=None):
    """
    Starts project download in background and returns handle to the pending project download.
    Using that object it is possible to watch progress or cancel the ongoing work.
    """

    if '/' not in project_path:
        raise ClientError("Project name needs to be fully qualified, e.g. <username>/<projectname>")
    if os.path.exists(directory):
        raise ClientError("Project directory already exists")
    os.makedirs(directory)
    mp = MerginProject(directory)

    mp.log.info("--- version: " + mc.user_agent_info())
    mp.log.info(f"--- start download {project_path}")

    try:
        # check whether we download the latest version or not
        latest_proj_info = mc.project_info(project_path)
        if project_version:
            project_info = mc.project_info(project_path, version=project_version)
        else:
            project_info = latest_proj_info

    except ClientError:
        _cleanup_failed_download(directory, mp)
        raise

    version = project_info['version'] if project_info['version'] else 'v0'

    mp.log.info(f"got project info. version {version}")

    # prepare download
    update_tasks = []  # stuff to do at the end of download
    for file in project_info['files']:
        file['version'] = version
        items = _download_items(file, directory)
        is_latest_version = project_version == latest_proj_info["version"]
        update_tasks.append(UpdateTask(file['path'], items, latest_version=is_latest_version))

    # make a single list of items to download
    total_size = 0
    download_list = []
    for task in update_tasks:
        download_list.extend(task.download_queue_items)
        for item in task.download_queue_items:
            total_size += item.size

    mp.log.info(f"will download {len(update_tasks)} files in {len(download_list)} chunks, total size {total_size}")

    job = DownloadJob(project_path, total_size, version, update_tasks, download_list, directory, mp, project_info)

    # start download
    job.executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
    job.futures = []
    for item in download_list:
        future = job.executor.submit(_do_download, item, mc, mp, project_path, job)
        job.futures.append(future)

    return job

    Starts project download in background and returns handle to the pending project download.
    Using that object it is possible to watch progress or cancel the ongoing work.
    
Starts project download in background and returns handle to the pending project download.
Using that object it is possible to watch progress or cancel the ongoing work.
Starts project download in background and returns handle to the pending project download . Using that object it is possible to watch progress or cancel the ongoing work .
def download_project_async(mc, project_path, directory, project_version=None):
    if '/' not in project_path:
        raise ClientError("Project name needs to be fully qualified, e.g. <username>/<projectname>")
    if os.path.exists(directory):
        raise ClientError("Project directory already exists")
    os.makedirs(directory)
    mp = MerginProject(directory)
    mp.log.info("--- version: " + mc.user_agent_info())
    mp.log.info(f"--- start download {project_path}")
    try:
        latest_proj_info = mc.project_info(project_path)
        if project_version:
            project_info = mc.project_info(project_path, version=project_version)
        else:
            project_info = latest_proj_info
    except ClientError:
        _cleanup_failed_download(directory, mp)
        raise
    version = project_info['version'] if project_info['version'] else 'v0'
    mp.log.info(f"got project info. version {version}")
    update_tasks = []  
    for file in project_info['files']:
        file['version'] = version
        items = _download_items(file, directory)
        is_latest_version = project_version == latest_proj_info["version"]
        update_tasks.append(UpdateTask(file['path'], items, latest_version=is_latest_version))
    total_size = 0
    download_list = []
    for task in update_tasks:
        download_list.extend(task.download_queue_items)
        for item in task.download_queue_items:
            total_size += item.size
    mp.log.info(f"will download {len(update_tasks)} files in {len(download_list)} chunks, total size {total_size}")
    job = DownloadJob(project_path, total_size, version, update_tasks, download_list, directory, mp, project_info)
    job.executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
    job.futures = []
    for item in download_list:
        future = job.executor.submit(_do_download, item, mc, mp, project_path, job)
        job.futures.append(future)
    return job
def download_project_async ( mc , project_path , directory , project_version = None ) : if '/' not in project_path : raise ClientError ( "Project name needs to be fully qualified, e.g. <username>/<projectname>" ) if os . path . exists ( directory ) : raise ClientError ( "Project directory already exists" ) os . makedirs ( directory ) mp = MerginProject ( directory ) mp . log . info ( "--- version: " + mc . user_agent_info ( ) ) mp . log . info ( f"--- start download {project_path}" ) try : latest_proj_info = mc . project_info ( project_path ) if project_version : project_info = mc . project_info ( project_path , version = project_version ) else : project_info = latest_proj_info except ClientError : _cleanup_failed_download ( directory , mp ) raise version = project_info [ 'version' ] if project_info [ 'version' ] else 'v0' mp . log . info ( f"got project info. version {version}" ) update_tasks = [ ] for file in project_info [ 'files' ] : file [ 'version' ] = version items = _download_items ( file , directory ) is_latest_version = project_version == latest_proj_info [ "version" ] update_tasks . append ( UpdateTask ( file [ 'path' ] , items , latest_version = is_latest_version ) ) total_size = 0 download_list = [ ] for task in update_tasks : download_list . extend ( task . download_queue_items ) for item in task . download_queue_items : total_size += item . size mp . log . info ( f"will download {len(update_tasks)} files in {len(download_list)} chunks, total size {total_size}" ) job = DownloadJob ( project_path , total_size , version , update_tasks , download_list , directory , mp , project_info ) job . executor = concurrent . futures . ThreadPoolExecutor ( max_workers = 4 ) job . futures = [ ] for item in download_list : future = job . executor . submit ( _do_download , item , mc , mp , project_path , job ) job . futures . append ( future ) return job
Starts project download in background and returns handle to the pending project download.
Starts project download in background and returns handle to the pending project download .
"""
    Starts project download in background and returns handle to the pending project download.
    Using that object it is possible to watch progress or cancel the ongoing work.
    """ # check whether we download the latest version or not # prepare download # stuff to do at the end of download # make a single list of items to download # start download
mc
project_path
directory
project_version