Skip to content
Snippets Groups Projects
Commit 45345e73 authored by Andri Joos's avatar Andri Joos :blush:
Browse files

Merge branch 'download'

parents 90461684 03902b68
No related merge requests found
......@@ -5,7 +5,7 @@
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"name": "Python: upload",
"type": "python",
"request": "launch",
"program": "main.py",
......@@ -19,7 +19,25 @@
"--username",
"test",
"--password",
"test123"
"test123",
"up"
]
},
{
"name": "Python: download",
"type": "python",
"request": "launch",
"program": "main.py",
"console": "integratedTerminal",
"justMyCode": true,
"args": [
"--in",
"/",
"--out",
"/home/andri/tmp/test",
"-l",
"test",
"down"
]
}
]
......
......@@ -6,7 +6,7 @@ import humanize
chunk_size = 50*1024*1024 # 50MB
def exists_remote_path(path: str) -> bool:
def exists_remote_path(path: str, nc: Client) -> bool:
try:
nc.list(path)
except HTTPResponseError as e:
......@@ -17,7 +17,7 @@ def exists_remote_path(path: str) -> bool:
return True
def create_path_if_not_exists(path: str):
def create_remote_path_if_not_exists(path: str, nc: Client):
path_splits = path.split(os.sep)
current_path = "/"
......@@ -28,52 +28,91 @@ def create_path_if_not_exists(path: str):
print("creating directory {}".format(current_path))
nc.mkdir(current_path)
parser = ArgumentParser(prog="NextcloudUpload", description="Upload folders to nextcloud (specifically created for big files)")
parser.add_argument("--in", action="store", required=True, type=str)
parser.add_argument("--out", action="store", required=True, type=str)
parser.add_argument("--server-address", action="store", default="https://cloud.420joos.dev/", required=False, type=str)
parser.add_argument("--username", action="store", required=False, type=str)
parser.add_argument("--password", action="store", required=False, type=str)
parser.add_argument("--public-link", action="store", required=False, type=str)
args = vars(parser.parse_args())
in_path = args["in"]
out_path = args["out"]
server_address = args["server_address"]
username = args["username"]
password = args["password"]
public_link = args["public_link"]
nc: Client = None
if public_link is not None:
nc = Client.from_public_link(public_link)
else:
nc = Client(server_address)
nc.login(username, password)
files_and_directories = glob.glob(os.path.join(in_path, "**/*"), recursive=True)
uploading_files = [f for f in files_and_directories if os.path.isfile(f)]
already_uploaded = []
if exists_remote_path(out_path):
already_uploaded = nc.list(out_path, depth="infinity")
already_uploaded_files = [a.path for a in already_uploaded if not a.is_dir()]
# already_uploaded_filenames = [a.name for a in already_uploaded]
uploading_files.sort()
for file_path in uploading_files:
file_name = os.path.basename(file_path)
relative_file_path = os.path.relpath(file_path, in_path)
remote_file_path = os.path.join(out_path, relative_file_path)
if remote_file_path not in already_uploaded_files:
remote_dir_path = os.path.dirname(remote_file_path)
create_path_if_not_exists(remote_dir_path)
file_stats = os.stat(file_path)
file_size = humanize.naturalsize(file_stats.st_size)
print("uploading {} from {} to {}".format(file_size, file_path, remote_file_path))
nc.put_file(remote_file_path, file_path, chunk_size=chunk_size)
def create_client(server_address: str = None, username: str = None, password: str = None, public_link: str = None) -> Client:
if public_link is not None:
nc = Client.from_public_link(public_link)
else:
print("{} exists already at {}".format(file_path, remote_file_path))
nc = Client(server_address)
nc.login(username, password)
return nc
def upload(_in: str, out: str, server_address: str = None, username: str = None, password: str = None, public_link: str = None, func=None):
nc = create_client(server_address, username, password, public_link)
files_and_directories = glob.glob(os.path.join(_in, "**/*"), recursive=True)
uploading_files = [f for f in files_and_directories if os.path.isfile(f)]
already_uploaded = []
if exists_remote_path(out):
already_uploaded = nc.list(out, depth="infinity")
already_uploaded_files = [a.path for a in already_uploaded if not a.is_dir()]
# already_uploaded_filenames = [a.name for a in already_uploaded]
uploading_files.sort()
for file_path in uploading_files:
relative_file_path = os.path.relpath(file_path, _in)
remote_file_path = os.path.join(out, relative_file_path)
if remote_file_path not in already_uploaded_files:
remote_dir_path = os.path.dirname(remote_file_path)
create_remote_path_if_not_exists(remote_dir_path)
file_stats = os.stat(file_path)
file_size = humanize.naturalsize(file_stats.st_size)
print("uploading {} from {} to {}".format(file_size, file_path, remote_file_path))
nc.put_file(remote_file_path, file_path, chunk_size=chunk_size)
else:
print("{} exists already at {}".format(file_path, remote_file_path))
def download(_in: str, out: str, server_address: str = None, username: str = None, password: str = None, public_link: str = None, depth: str = None, func=None):
nc = create_client(server_address, username, password, public_link)
parsed_depth: int|str = None
try:
parsed_depth = int(depth)
except ValueError:
parsed_depth = depth
remote_listing = nc.list(_in, depth=parsed_depth)
remote_files = [(a.path, a.attributes["{DAV:}getcontentlength"]) for a in remote_listing if not a.is_dir()]
already_downloaded_files = glob.glob(os.path.join(out, "**/*"), recursive=True)
for file_path, file_size in remote_files:
relative_path = os.path.relpath(file_path, _in)
local_path = os.path.join(out, relative_path)
if local_path not in already_downloaded_files:
local_dir = os.path.dirname(local_path)
os.makedirs(local_dir, exist_ok=True)
file_size_humanized = humanize.naturalsize(file_size)
print("downloading {} from {} to {}".format(file_size_humanized, file_path, local_path))
nc.get_file(file_path, local_path)
else:
print("{} exists already at {}".format(file_path, local_path))
def main():
parser = ArgumentParser(prog="NextcloudTool", description="Upload/Download folders to nextcloud (specifically created for big files)")
parser.add_argument("--in", "-i", action="store", required=True, type=str, dest="_in")
parser.add_argument("--out", "-o", action="store", required=True, type=str)
parser.add_argument("--server-address", "-s", action="store", default="https://cloud.420joos.dev/", required=False, type=str)
parser.add_argument("--username", "-u", action="store", required=False, type=str)
parser.add_argument("--password", "-p", action="store", required=False, type=str)
parser.add_argument("--public-link", "-l", action="store", required=False, type=str)
subparsers = parser.add_subparsers(title="action")
up_parser = subparsers.add_parser("up", aliases=["u"])
up_parser.set_defaults(func=upload)
down_parser = subparsers.add_parser("down", aliases=["d"])
down_parser.add_argument("--depth", "-d", action="store", required=False, type=str, default="infinity")
down_parser.set_defaults(func=download)
parsed_args = parser.parse_args()
args = vars(parsed_args)
parsed_args.func(**args)
if __name__ == "__main__":
main()
pyncclient
humanize
./
\ No newline at end of file
from setuptools import setup, find_packages
setup(name='nctool', version='1.0', packages=find_packages(), entry_points={
"console_scripts": [
"nctool = main:main"
]
})
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment