-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathChunkedUploadHandler.py
96 lines (84 loc) · 3.42 KB
/
ChunkedUploadHandler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from http.server import BaseHTTPRequestHandler
from urllib.parse import unquote
import json
import os
import cgi
import logging
from datetime import datetime
# Set up logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
class ChunkedUploadHandler(BaseHTTPRequestHandler):
def do_GET(self):
"""Serve the HTML upload page and static files."""
if self.path == '/' or self.path == '/index.html':
# Serve index.html
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
with open('frontend/index.html', 'rb') as f:
self.wfile.write(f.read())
elif self.path == '/script.js':
# Serve script.js
self.send_response(200)
self.send_header("Content-type", "text/javascript")
self.end_headers()
with open('frontend/script.js', 'rb') as f:
self.wfile.write(f.read())
elif self.path == '/style.css':
# Serve style.css
self.send_response(200)
self.send_header("Content-type", "text/css")
self.end_headers()
with open('frontend/style.css', 'rb') as f:
self.wfile.write(f.read())
else:
# File not found
self.send_error(404)
def do_POST(self):
"""Handle chunked file uploads."""
try:
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': self.headers['Content-Type']}
)
file_item = form['file']
filename = form.getvalue('filename')
file_data = file_item.file.read()
chunk_num = int(form.getvalue('chunk', '0'))
total_chunks = int(form.getvalue('totalChunks', '1'))
offset = int(form.getvalue('offset', '0'))
# Generate safe filename for first chunk
if chunk_num == 0:
filename = self._make_safe_filename(filename)
# Define uploads directory
uploads_dir = "Uploads"
# Check if uploads directory exists, create if it doesn't
if not os.path.exists(uploads_dir):
os.makedirs(uploads_dir)
# Save to uploads directory
filepath = os.path.join(uploads_dir, filename)
# Append chunk
if chunk_num == 0:
with open(filepath, 'wb') as f:
f.write(file_data)
else:
with open(filepath, 'r+b') as f:
f.seek(offset)
f.write(file_data)
self._send_json_response(True, filename=filename)
except Exception as e:
logger.error(f"Error: {e}")
self._send_json_response(False, error=str(e))
def _make_safe_filename(self, filename):
base, ext = os.path.splitext(unquote(filename))
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
return f"{base}_{timestamp}{ext}"
def _send_json_response(self, success, **kwargs):
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
self.wfile.write(json.dumps({'success': success, **kwargs}).encode())