Skip to content

Commit 3910a2d

Browse files
Change upload script to upload whole directory
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 0bad893 commit 3910a2d

File tree

1 file changed

+85
-25
lines changed

1 file changed

+85
-25
lines changed

scripts/upload-webdav.py

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,48 @@
11
#!/usr/bin/env python3
22
"""
3-
Upload a file to WebDAV server.
3+
Upload a directory to WebDAV server.
44
5-
Usage: ./upload-webdav.py <local_file> <remote_path> --url <webdav_url> --user <username> --pass <password>
5+
Usage: ./upload-webdav.py <local_dir> <remote_dir> --url <webdav_url> --user <username> --pass <password>
66
77
Example:
8-
./upload-webdav.py video.mp4 /processed/video.mp4 --url https://nextcloud.example.com/remote.php/webdav --user admin --pass secret
8+
./upload-webdav.py ~/videos/processed /processed --url https://nextcloud.example.com/remote.php/webdav --user admin --pass secret
99
"""
1010

1111
import argparse
12-
import os
1312
import sys
1413
from pathlib import Path
1514

1615
import requests
1716
from requests.auth import HTTPBasicAuth
1817

1918

20-
def upload_file(local_path: str, remote_path: str, webdav_url: str, username: str, password: str) -> bool:
21-
"""Upload a file to WebDAV server."""
19+
def create_folder(webdav_url: str, remote_path: str, username: str, password: str) -> bool:
20+
"""Create a folder on WebDAV server."""
21+
webdav_url = webdav_url.rstrip('/')
22+
remote_path = remote_path.strip('/')
23+
url = f"{webdav_url}/{remote_path}"
2224

23-
if not Path(local_path).exists():
24-
print(f"Error: File not found: {local_path}")
25+
try:
26+
response = requests.request(
27+
"MKCOL",
28+
url,
29+
auth=HTTPBasicAuth(username, password),
30+
)
31+
# 201 = created, 405 = already exists
32+
return response.status_code in (201, 405)
33+
except Exception as e:
34+
print(f"Error creating folder: {e}")
2535
return False
2636

27-
# Build the full URL
37+
38+
def upload_file(local_path: Path, remote_path: str, webdav_url: str, username: str, password: str) -> bool:
39+
"""Upload a single file to WebDAV server."""
2840
webdav_url = webdav_url.rstrip('/')
2941
remote_path = remote_path.lstrip('/')
3042
url = f"{webdav_url}/{remote_path}"
3143

32-
file_size = Path(local_path).stat().st_size
33-
print(f"Uploading: {local_path}")
34-
print(f"Size: {file_size / (1024*1024):.1f} MB")
35-
print(f"To: {url}")
36-
print()
44+
file_size = local_path.stat().st_size
45+
print(f" Uploading: {local_path.name} ({file_size / (1024*1024):.1f} MB)")
3746

3847
try:
3948
with open(local_path, 'rb') as f:
@@ -45,37 +54,88 @@ def upload_file(local_path: str, remote_path: str, webdav_url: str, username: st
4554
)
4655

4756
if response.status_code in (200, 201, 204):
48-
print("Upload successful!")
57+
print(f" Done!")
4958
return True
5059
else:
51-
print(f"Upload failed: {response.status_code} {response.reason}")
52-
print(response.text[:500] if response.text else "")
60+
print(f" Failed: {response.status_code} {response.reason}")
5361
return False
5462

5563
except Exception as e:
56-
print(f"Error: {e}")
64+
print(f" Error: {e}")
5765
return False
5866

5967

68+
def upload_directory(local_dir: str, remote_dir: str, webdav_url: str, username: str, password: str) -> tuple[int, int]:
69+
"""Upload all files in a directory to WebDAV server."""
70+
local_path = Path(local_dir)
71+
72+
if not local_path.exists():
73+
print(f"Error: Directory not found: {local_dir}")
74+
return 0, 0
75+
76+
if not local_path.is_dir():
77+
print(f"Error: Not a directory: {local_dir}")
78+
return 0, 0
79+
80+
# Get all files
81+
files = list(local_path.glob("*"))
82+
files = [f for f in files if f.is_file()]
83+
84+
if not files:
85+
print("No files found in directory")
86+
return 0, 0
87+
88+
print(f"Found {len(files)} file(s) to upload")
89+
print(f"Destination: {webdav_url}/{remote_dir.strip('/')}/")
90+
print()
91+
92+
# Create remote directory
93+
remote_dir = remote_dir.strip('/')
94+
if remote_dir:
95+
print(f"Creating remote folder: {remote_dir}")
96+
create_folder(webdav_url, remote_dir, username, password)
97+
print()
98+
99+
# Upload each file
100+
success = 0
101+
failed = 0
102+
103+
for i, file in enumerate(files, 1):
104+
print(f"[{i}/{len(files)}]", end="")
105+
remote_path = f"{remote_dir}/{file.name}" if remote_dir else file.name
106+
107+
if upload_file(file, remote_path, webdav_url, username, password):
108+
success += 1
109+
else:
110+
failed += 1
111+
112+
return success, failed
113+
114+
60115
def main():
61-
parser = argparse.ArgumentParser(description="Upload a file to WebDAV server")
62-
parser.add_argument("local_file", help="Local file to upload")
63-
parser.add_argument("remote_path", help="Remote path (e.g., /processed/video.mp4)")
116+
parser = argparse.ArgumentParser(description="Upload a directory to WebDAV server")
117+
parser.add_argument("local_dir", help="Local directory to upload")
118+
parser.add_argument("remote_dir", help="Remote directory (e.g., /processed)")
64119
parser.add_argument("--url", required=True, help="WebDAV URL")
65120
parser.add_argument("--user", required=True, help="Username")
66121
parser.add_argument("--pass", dest="password", required=True, help="Password")
67122

68123
args = parser.parse_args()
69124

70-
success = upload_file(
71-
args.local_file,
72-
args.remote_path,
125+
success, failed = upload_directory(
126+
args.local_dir,
127+
args.remote_dir,
73128
args.url,
74129
args.user,
75130
args.password
76131
)
77132

78-
sys.exit(0 if success else 1)
133+
print()
134+
print("=" * 40)
135+
print(f"Upload complete: {success} succeeded, {failed} failed")
136+
print("=" * 40)
137+
138+
sys.exit(0 if failed == 0 else 1)
79139

80140

81141
if __name__ == "__main__":

0 commit comments

Comments
 (0)