22import os
33import subprocess
44import posixpath
5+ from urllib .parse import urljoin , quote
6+
57
68def compute_sha256_and_length (filepath ):
79 sha256 = hashlib .sha256 ()
@@ -42,20 +44,24 @@ def upload_to_nextcloud(source_paths: list[str], remote_name: str, remote_path:
4244
4345 if os .path .isdir (path ):
4446 rel_file = os .path .relpath (file , abs_path )
47+ # Normalize to POSIX for WebDAV/URLs
48+ rel_file = rel_file .replace (os .sep , "/" )
4549 remote_webdav_path = posixpath .join (remote_path , basename , rel_file )
4650 else :
4751 remote_webdav_path = posixpath .join (remote_path , os .path .basename (file ))
4852
49- url = posixpath .join (webdav_url ,remote_webdav_path )
53+ # Preserve scheme/host and percent-encode path segments
54+ url = urljoin (webdav_url .rstrip ("/" ) + "/" , quote (remote_webdav_path .lstrip ("/" ), safe = "/" ))
5055
5156 filename = os .path .basename (file )
5257 tmp_results .append ((filename , checksum , size , url ))
5358
59+ dest_subpath = posixpath .join (remote_path .lstrip ("/" ), basename )
5460 if os .path .isdir (path ):
55- destination = f"{ remote_name } :{ remote_path } / { basename } "
61+ destination = f"{ remote_name } :{ dest_subpath } "
5662 command = ["rclone" , "copy" , abs_path , destination , "--progress" ]
5763 else :
58- destination = f"{ remote_name } :{ remote_path } / { basename } "
64+ destination = f"{ remote_name } :{ dest_subpath } "
5965 command = ["rclone" , "copyto" , abs_path , destination , "--progress" ]
6066
6167 print (f"Upload: { path } → { destination } " )
@@ -65,6 +71,7 @@ def upload_to_nextcloud(source_paths: list[str], remote_name: str, remote_path:
6571 print ("✅ Uploaded successfully.\n " )
6672 except subprocess .CalledProcessError as e :
6773 print (f"❌ Error uploading { path } : { e } \n " )
68-
74+ except FileNotFoundError :
75+ print ("❌ rclone not found on PATH. Install rclone and retry." )
6976
7077 return result
0 commit comments