1717import tempfile
1818import typing
1919import traceback
20+ from dataclasses import asdict
2021
2122import concurrent .futures
2223
23- from dataclasses import asdict
2424
2525from .common import CHUNK_SIZE , ClientError , DeltaChangeType , PullActionType
2626from .models import ProjectDelta , ProjectDeltaItem , PullAction
@@ -135,7 +135,7 @@ def merge(self):
135135 raise ClientError ("Download of file {} failed. Please try it again." .format (self .dest_file ))
136136
137137
138- def get_download_items (file_path : str , file_size : int , file_version : str , directory , diff_only = False ):
138+ def get_download_items (file_path : str , file_size : int , file_version : str , directory : str , diff_only = False ):
139139 """Returns an array of download queue items"""
140140
141141 file_dir = os .path .dirname (os .path .normpath (os .path .join (directory , file_path )))
@@ -433,6 +433,7 @@ def __init__(
433433 )
434434 self .mc = mc
435435 self .futures = [] # list of concurrent.futures.Future instances
436+ self .v2_pull = mc .server_features ().get ("v2_pull_enabled" , False )
436437
437438 def dump (self ):
438439 print ("--- JOB ---" , self .total_size , "bytes" )
@@ -447,7 +448,7 @@ def dump(self):
447448 print ("--- END ---" )
448449
449450
450- def prepare_chunks_destination (target_dir : str , path : str ) -> str :
451+ def prepare_file_destination (target_dir : str , path : str ) -> str :
451452 """Prepares destination path for downloaded files chunks"""
452453
453454 # figure out destination path for the file
@@ -458,46 +459,19 @@ def prepare_chunks_destination(target_dir: str, path: str) -> str:
458459 return dest_file_path
459460
460461
461- _pulling_file_with_diffs = lambda f : "diffs" in f and len (f ["diffs" ]) != 0
462-
463-
464462def get_diff_merge_files (delta_item : ProjectDeltaItem , target_dir : str ) -> List [FileToMerge ]:
465463 """
466- Extracts list of diff files to be downloaded delta item.
464+ Extracts list of diff files to be downloaded from delta item using v1 endpoint .
467465 """
468466 result = []
469467
470468 for diff in delta_item .diffs :
471- dest_file_path = prepare_chunks_destination (target_dir , diff .id )
469+ dest_file_path = prepare_file_destination (target_dir , diff .id )
472470 download_items = get_download_items (diff .id , diff .size , diff .version , target_dir , True )
473471 result .append (FileToMerge (dest_file_path , download_items ))
474472 return result
475473
476474
477- def get_delta_download_files (
478- delta_items : List [ProjectDeltaItem ], target_dir : str
479- ) -> Tuple [List [FileToMerge ], List [DownloadDiffQueueItem ]]:
480- """
481- Extracts list of files to be merged from delta dictionary. If there is any diff files to be downloaded, they
482- are returned as a separate list.
483- """
484- merge_files = []
485- diff_files = []
486- for item in delta_items :
487- change = item .change
488- if change == DeltaChangeType .CREATE or change == DeltaChangeType .UPDATE :
489- path = item .path
490- download_items = get_download_items (asdict (item ), target_dir , False )
491- dest_file_path = prepare_chunks_destination (target_dir , path )
492- merge_files .append (FileToMerge (dest_file_path , download_items ))
493- elif change == DeltaChangeType .UPDATE_DIFF :
494- diffs = item .diffs
495- for diff in diffs :
496- diff_path = diff .id
497- diff_files .append (DownloadDiffQueueItem (diff_path , os .path .join (target_dir , diff_path )))
498- return merge_files , diff_files
499-
500-
501475def pull_project_async (mc , directory ) -> Optional [PullJob ]:
502476 """
503477 Starts project pull in background and returns handle to the pending job.
@@ -531,7 +505,7 @@ def pull_project_async(mc, directory) -> Optional[PullJob]:
531505 else :
532506 server_info = mc .project_info (project_path , since = local_version )
533507 server_version = server_info .get ("version" )
534- delta = ProjectDelta ( to_version = server_version , items = mp .get_pull_delta (server_info ) )
508+ delta = mp .get_pull_delta (server_info )
535509 except ClientError as err :
536510 mp .log .error ("Error getting project info: " + str (err ))
537511 mp .log .info ("--- pull aborted" )
@@ -562,13 +536,7 @@ def pull_project_async(mc, directory) -> Optional[PullJob]:
562536 continue # no action needed
563537
564538 pull_actions .append (PullAction (pull_action , item , local_item ))
565- if pull_action == PullActionType .COPY :
566- # simply download the server version of the files
567- dest_file_path = prepare_chunks_destination (tmp_dir .name , item .path )
568- download_items = get_download_items (item .path , item .size , server_version , mp .cache_dir )
569- merge_files .append (FileToMerge (dest_file_path , download_items ))
570-
571- elif pull_action == PullActionType .APPLY_DIFF or (
539+ if pull_action == PullActionType .APPLY_DIFF or (
572540 pull_action == PullActionType .COPY_CONFLICT and item .change == DeltaChangeType .UPDATE_DIFF
573541 ):
574542 # if we have diff to apply, let's download the diff files
@@ -594,12 +562,10 @@ def pull_project_async(mc, directory) -> Optional[PullJob]:
594562 dest_file_path = mp .fpath (item .path , tmp_dir .name )
595563 merge_files .append (FileToMerge (dest_file_path , items ))
596564 basefiles_to_patch .append ((item .path , [diff .id for diff in item .diffs ]))
597-
598- elif pull_action == PullActionType .COPY_CONFLICT :
599- # if we have conflict and create or update action, let's just download the server version of the file
600- # let's download server version of the file
601- dest_file_path = prepare_chunks_destination (tmp_dir .name , item .path )
602- download_items = get_download_items (item .path , item .size , server_version , mp .cache_dir )
565+ elif pull_action == PullActionType .COPY or pull_action == PullActionType .COPY_CONFLICT :
566+ # simply download the server version of the files
567+ dest_file_path = prepare_file_destination (tmp_dir .name , item .path )
568+ download_items = get_download_items (item .path , item .size , server_version , tmp_dir .name )
603569 merge_files .append (FileToMerge (dest_file_path , download_items ))
604570 # Do nothing for DELETE actions
605571
@@ -696,8 +662,11 @@ def pull_project_finalize(job: PullJob):
696662 raise future .exception ()
697663
698664 job .mp .log .info ("finalizing pull" )
699- if not job .project_info :
700- job .project_info = job .mc .project_info_v2 (job .mp .project_id (), files_at_version = job .version )
665+ if not job .project_info and job .v2_pull :
666+ project_info_response = job .mc .project_info (job .project_path , version = job .version )
667+ job .project_info = asdict (project_info_response )
668+ else :
669+ raise ClientError ("Missing project info for pull finalization" )
701670
702671 # merge downloaded chunks
703672 try :
@@ -729,7 +698,7 @@ def pull_project_finalize(job: PullJob):
729698 job .mp .log .info ("--- pull aborted" )
730699 os .remove (basefile )
731700 raise ClientError ("Cannot patch basefile {}! Please try syncing again." .format (basefile ))
732-
701+ conflicts = []
733702 try :
734703 if job .pull_actions :
735704 conflicts = job .mp .apply_pull_actions (job .pull_actions , job .tmp_dir .name , job .project_info , job .mc )
0 commit comments