From 7c6765c1960b04542a2b3ebd21cb4ba73d05bae9 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Sun, 25 Jun 2017 01:30:06 +0300 Subject: [PATCH] import/sync: add progress bar for local copy Currently progress bar is only supported for downloading from web(aws,http* etc), but now it is also supported for local files(i.e. LOCAL for 'data sync' and just local files for 'import') Signed-off-by: Ruslan Kuprieiev --- dvc/command/import_file.py | 3 +-- dvc/data_cloud.py | 8 ++++---- dvc/utils.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/dvc/command/import_file.py b/dvc/command/import_file.py index 6e80bfe4d..afe9e5fa8 100644 --- a/dvc/command/import_file.py +++ b/dvc/command/import_file.py @@ -1,5 +1,4 @@ import os -from shutil import copyfile import re import requests from multiprocessing.pool import ThreadPool @@ -13,7 +12,7 @@ from dvc.state_file import StateFile from dvc.system import System from dvc.command.data_sync import POOL_SIZE from dvc.progress import progress - +from dvc.utils import copyfile class ImportFileError(DvcException): def __init__(self, msg): diff --git a/dvc/data_cloud.py b/dvc/data_cloud.py index c19e9c55f..c636e967f 100644 --- a/dvc/data_cloud.py +++ b/dvc/data_cloud.py @@ -3,7 +3,6 @@ import hashlib import os import threading import configparser -import shutil from boto.s3.connection import S3Connection from google.cloud import storage as gc @@ -13,6 +12,7 @@ from dvc.exceptions import DvcException from dvc.config import ConfigError from dvc.settings import Settings from dvc.progress import progress +from dvc.utils import copyfile class DataCloudError(DvcException): def __init__(self, msg): @@ -36,7 +36,7 @@ def percent_cb(name, complete, total): def create_cb(name): - return (lambda cur,tot: return percent_cb(name, cur, tot)) + return (lambda cur,tot: percent_cb(name, cur, tot)) def file_md5(fname): @@ -131,11 +131,11 @@ class DataCloudBase(object): class DataCloudLOCAL(DataCloudBase): def sync_to_cloud(self, item): Logger.debug('sync to cloud ' + item.resolved_cache.dvc + " " + self.storage_path) - shutil.copy(item.resolved_cache.dvc, self.storage_path) + copyfile(item.resolved_cache.dvc, self.storage_path) def sync_from_cloud(self, item): Logger.debug('sync from cloud ' + self.storage_path + " " + item.resolved_cache.dvc) - shutil.copy(self.storage_path, item.resolved_cache.dvc) + copyfile(self.storage_path, item.resolved_cache.dvc) def remove_from_cloud(self, item): Logger.debug('rm from cloud ' + item.resolved_cache.dvc) diff --git a/dvc/utils.py b/dvc/utils.py index 8f73b897c..f7e4dc805 100644 --- a/dvc/utils.py +++ b/dvc/utils.py @@ -2,6 +2,10 @@ import os import stat import shutil +from dvc.progress import progress + +LOCAL_CHUNK_SIZE = 1024*1024*1024 + def cached_property(f): def get(self): try: @@ -24,3 +28,29 @@ def rmtree(dir): os.chmod(dir, stat.S_IWUSR) shutil.rmtree(dir, ignore_errors=True) + + +def copyfile(src, dest): + copied = 0 + name = os.path.basename(src) + total = os.stat(src).st_size + + f = open(src, 'rb') + + if os.path.isdir(dest): + o = open(dest + '/' + name, 'wb+') + else: + o = open(dest, 'wb+') + + while True: + buf = f.read(LOCAL_CHUNK_SIZE) + if not buf: + break + o.write(buf) + copied += len(buf) + progress.update_target(name, copied, total) + + progress.finish_target(name) + + f.close() + o.close()