def upload( ctx, localpaths, remotedir, encrypt_password, encrypt_type, max_workers, no_ignore_existing, no_show_progress, check_md5, ): """上传文件""" # Keyboard listener start keyboard_listener_start() api = _recent_api(ctx) if not api: return encrypt_password = encrypt_password or _encrypt_password(ctx) if encrypt_type != EncryptType.No.name and not encrypt_password: raise ValueError(f"Encrypting with {encrypt_type} must have a key") pwd = _pwd(ctx) remotedir = join_path(pwd, remotedir) rapiduploadinfo_file = _rapiduploadinfo_file(ctx) user_id, user_name = _recent_user_id_and_name(ctx) from_to_list = from_tos(localpaths, remotedir) _upload( api, from_to_list, encrypt_password=encrypt_password, encrypt_type=getattr(EncryptType, encrypt_type), max_workers=max_workers, ignore_existing=not no_ignore_existing, show_progress=not no_show_progress, rapiduploadinfo_file=rapiduploadinfo_file, user_id=user_id, user_name=user_name, check_md5=check_md5, )
def upload(ctx, localpaths, remotedir, max_workers, no_ignore_existing, no_show_progress): """上传文件""" api = _recent_api(ctx) if not api: return pwd = _pwd(ctx) remotedir = join_path(pwd, remotedir) from_to_list = from_tos(localpaths, remotedir) _upload( api, from_to_list, max_workers=max_workers, ignore_existing=not no_ignore_existing, show_progress=not no_show_progress, )
def upload( ctx, localpaths, remotedir, encrypt_key, encrypt_type, max_workers, no_ignore_existing, no_show_progress, ): """上传文件""" # Keyboard listener start keyboard_listener_start() api = _recent_api(ctx) if not api: return encrypt_key = encrypt_key or _encrypt_key(ctx) if encrypt_type != EncryptType.No.name and not encrypt_key: raise ValueError(f"Encrypting with {encrypt_type} must have a key") salt = _salt(ctx) pwd = _pwd(ctx) remotedir = join_path(pwd, remotedir) from_to_list = from_tos(localpaths, remotedir) _upload( api, from_to_list, encrypt_key=encrypt_key, salt=salt, encrypt_type=getattr(EncryptType, encrypt_type), max_workers=max_workers, ignore_existing=not no_ignore_existing, show_progress=not no_show_progress, )
def sync( api: BaiduPCSApi, localdir: str, remotedir: str, encrypt_key: Any = None, salt: Any = None, encrypt_type: EncryptType = EncryptType.No, max_workers: int = CPU_NUM, slice_size: int = DEFAULT_SLICE_SIZE, show_progress: bool = True, ): localdir = Path(localdir).as_posix() remotedir = Path(remotedir).as_posix() is_file = api.is_file(remotedir) assert not is_file, "remotedir must be a directory" if not api.exists(remotedir): all_pcs_files = {} else: all_pcs_files = { pcs_file.path[len(remotedir) + 1:]: pcs_file for pcs_file in recursive_list(api, remotedir) } fts: List[FromTo] = [] check_list: List[Tuple[str, PcsFile]] = [] all_localpaths = set() for localpath in walk(localdir): path = localpath[len(localdir) + 1:] all_localpaths.add(path) if path not in all_pcs_files: fts.append(FromTo(localpath, join_path(remotedir, path))) else: check_list.append((localpath, all_pcs_files[path])) semaphore = Semaphore(max_workers) with ThreadPoolExecutor(max_workers=CPU_NUM) as executor: tasks = {} for lp, pf in check_list: semaphore.acquire() fut = executor.submit(sure_release, semaphore, check_file_md5, lp, pf) tasks[fut] = (lp, pf) for fut in as_completed(tasks): is_equal = fut.result() lp, pf = tasks[fut] if not is_equal: fts.append(FromTo(lp, pf.path)) _upload( api, fts, encrypt_key=encrypt_key, salt=salt, encrypt_type=encrypt_type, max_workers=max_workers, slice_size=slice_size, ignore_existing=False, show_progress=show_progress, ) to_deletes = [] for rp in all_pcs_files.keys(): if rp not in all_localpaths: to_deletes.append(all_pcs_files[rp].path) if to_deletes: api.remove(*to_deletes) print(f"Delete: [i]{len(to_deletes)}[/i] remote paths")
def sync( api: BaiduPCSApi, localdir: str, remotedir: str, encrypt_password: bytes = b"", encrypt_type: EncryptType = EncryptType.No, max_workers: int = CPU_NUM, slice_size: int = DEFAULT_SLICE_SIZE, show_progress: bool = True, rapiduploadinfo_file: Optional[str] = None, user_id: Optional[int] = None, user_name: Optional[str] = None, check_md5: bool = False, ): localdir = Path(localdir).as_posix() remotedir = Path(remotedir).as_posix() is_file = api.is_file(remotedir) assert not is_file, "remotedir must be a directory" if not api.exists(remotedir): all_pcs_files = {} else: all_pcs_files = { pcs_file.path[len(remotedir) + 1 :]: pcs_file for pcs_file in recursive_list(api, remotedir) } fts: List[FromTo] = [] check_list: List[Tuple[str, PcsFile]] = [] all_localpaths = set() for localpath in walk(localdir): path = localpath[len(localdir) + 1 :] all_localpaths.add(path) if path not in all_pcs_files: fts.append(FromTo(localpath, join_path(remotedir, path))) else: check_list.append((localpath, all_pcs_files[path])) for lp, pf in check_list: lstat = Path(lp).stat() if int(lstat.st_mtime) != pf.local_mtime or lstat.st_size != pf.size: fts.append(FromTo(lp, pf.path)) to_deletes = [] for rp in all_pcs_files.keys(): if rp not in all_localpaths: to_deletes.append(all_pcs_files[rp].path) logger.debug( "`sync`: all localpaths: %s, " "localpaths needed to upload: %s, " "remotepaths needed to delete: %s", len(all_localpaths), len(fts), len(to_deletes), ) # The md5 of remote file is incorrect at most time, so we don't compare md5 # # # Compare localpath content md5 with remotepath content md5 # semaphore = Semaphore(max_workers) # with ThreadPoolExecutor(max_workers=CPU_NUM) as executor: # tasks = {} # for lp, pf in check_list: # semaphore.acquire() # fut = executor.submit(sure_release, semaphore, check_file_md5, lp, pf) # tasks[fut] = (lp, pf) # # for fut in as_completed(tasks): # is_equal = fut.result() # lp, pf = tasks[fut] # if not is_equal: # fts.append(FromTo(lp, pf.path)) _upload( api, fts, encrypt_password=encrypt_password, encrypt_type=encrypt_type, max_workers=max_workers, slice_size=slice_size, ignore_existing=False, show_progress=show_progress, rapiduploadinfo_file=rapiduploadinfo_file, user_id=user_id, user_name=user_name, check_md5=check_md5, ) if to_deletes: api.remove(*to_deletes) print(f"Delete: [i]{len(to_deletes)}[/i] remote paths")