Refactor uploads GUI so that each upload POST has one progess bar, and a list of files, with partial styling

This commit is contained in:
Micah Lee 2018-05-19 22:36:08 -07:00
parent caf87b8d96
commit ee9c0d0abb
No known key found for this signature in database
GPG Key ID: 403C2657CD994F73
6 changed files with 120 additions and 70 deletions

View File

@ -322,6 +322,19 @@ class Common(object):
font-size: 11px; font-size: 11px;
}""", }""",
# Recieve mode and child widget styles
'receive_file': """
QWidget {
background-color: #ffffff;
}
""",
'receive_file_size': """
QLabel {
color: #666666;
font-size: 11px;
}""",
# Settings dialog # Settings dialog
'settings_version': """ 'settings_version': """
QLabel { QLabel {

View File

@ -707,9 +707,16 @@ class ReceiveModeRequest(Request):
self.upload_id = self.web.upload_count self.upload_id = self.web.upload_count
self.web.upload_count += 1 self.web.upload_count += 1
# Figure out the content length
try:
self.content_length = int(self.headers['Content-Length'])
except:
self.content_length = 0
# Tell the GUI # Tell the GUI
self.web.add_request(Web.REQUEST_STARTED, self.path, { self.web.add_request(Web.REQUEST_STARTED, self.path, {
'id': self.upload_id 'id': self.upload_id,
'content_length': self.content_length
}) })
def _get_file_stream(self, total_content_length, content_type, filename=None, content_length=None): def _get_file_stream(self, total_content_length, content_type, filename=None, content_length=None):
@ -726,8 +733,8 @@ class ReceiveModeRequest(Request):
}) })
self.progress[filename] = { self.progress[filename] = {
'total_bytes': total_content_length, 'uploaded_bytes': 0,
'uploaded_bytes': 0 'complete': False
} }
if len(self.progress) > 0: if len(self.progress) > 0:
@ -749,10 +756,14 @@ class ReceiveModeRequest(Request):
Keep track of the bytes uploaded so far for all files. Keep track of the bytes uploaded so far for all files.
""" """
if self.upload_request: if self.upload_request:
# The final write, when upload is complete, length will be 0
if length == 0:
self.progress[filename]['complete'] = True
else:
self.progress[filename]['uploaded_bytes'] += length self.progress[filename]['uploaded_bytes'] += length
uploaded = self.web.common.human_readable_filesize(self.progress[filename]['uploaded_bytes']) uploaded = self.web.common.human_readable_filesize(self.progress[filename]['uploaded_bytes'])
total = self.web.common.human_readable_filesize(self.progress[filename]['total_bytes']) print('{} - {} '.format(uploaded, filename), end='\r')
print('{}/{} - {} '.format(uploaded, total, filename), end='\r')
# Update the GUI on the upload progress # Update the GUI on the upload progress
self.web.add_request(Web.REQUEST_PROGRESS, self.path, { self.web.add_request(Web.REQUEST_PROGRESS, self.path, {

View File

@ -135,7 +135,7 @@ class ReceiveMode(Mode):
""" """
Handle REQUEST_STARTED event. Handle REQUEST_STARTED event.
""" """
self.uploads.add(event["data"]["id"]) self.uploads.add(event["data"]["id"], event["data"]["content_length"])
self.uploads_in_progress += 1 self.uploads_in_progress += 1
self.update_uploads_in_progress() self.update_uploads_in_progress()

View File

@ -32,7 +32,48 @@ class File(QtWidgets.QWidget):
self.started = datetime.now() self.started = datetime.now()
# Filename label # Filename label
self.label = QtWidgets.QLabel(self.filename) self.filename_label = QtWidgets.QLabel(self.filename)
# File size label
self.filesize_label = QtWidgets.QLabel()
self.filesize_label.setStyleSheet(self.common.css['receive_file_size'])
self.filesize_label.hide()
# Folder button
folder_pixmap = QtGui.QPixmap.fromImage(QtGui.QImage(self.common.get_resource_path('images/open_folder.png')))
folder_icon = QtGui.QIcon(folder_pixmap)
self.folder_button = QtWidgets.QPushButton()
self.folder_button.setIcon(folder_icon)
self.folder_button.setIconSize(folder_pixmap.rect().size())
self.folder_button.setFlat(True)
self.folder_button.hide()
# Layouts
layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.filename_label)
layout.addWidget(self.filesize_label)
layout.addStretch()
layout.addWidget(self.folder_button)
self.setLayout(layout)
def update(self, uploaded_bytes, complete):
self.filesize_label.setText(self.common.human_readable_filesize(uploaded_bytes))
self.filesize_label.show()
if complete:
self.folder_button.show()
class Upload(QtWidgets.QWidget):
def __init__(self, common, upload_id, content_length):
super(Upload, self).__init__()
self.common = common
self.upload_id = upload_id
self.content_length = content_length
self.started = datetime.now()
# Label
self.label = QtWidgets.QLabel(strings._('gui_upload_in_progress', True).format(self.started.strftime("%b %d, %I:%M%p")))
# Progress bar # Progress bar
self.progress_bar = QtWidgets.QProgressBar() self.progress_bar = QtWidgets.QProgressBar()
@ -43,79 +84,64 @@ class File(QtWidgets.QWidget):
self.progress_bar.setValue(0) self.progress_bar.setValue(0)
self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar']) self.progress_bar.setStyleSheet(self.common.css['downloads_uploads_progress_bar'])
# Folder button # This layout contains file widgets
self.folder_button = QtWidgets.QPushButton("open folder") self.files_layout = QtWidgets.QVBoxLayout()
self.folder_button.hide() self.files_layout.setContentsMargins(0, 0, 0, 0)
files_widget = QtWidgets.QWidget()
files_widget.setStyleSheet(self.common.css['receive_file'])
files_widget.setLayout(self.files_layout)
# Layouts # Layout
info_layout = QtWidgets.QVBoxLayout() layout = QtWidgets.QVBoxLayout()
info_layout.addWidget(self.label) layout.addWidget(self.label)
info_layout.addWidget(self.progress_bar) layout.addWidget(self.progress_bar)
layout.addWidget(files_widget)
# The horizontal layout has info to the left, folder button to the right layout.addStretch()
layout = QtWidgets.QHBoxLayout()
layout.addLayout(info_layout)
layout.addWidget(self.folder_button)
self.setLayout(layout) self.setLayout(layout)
def update(self, total_bytes, uploaded_bytes):
print('total_bytes: {}, uploaded_bytes: {}'.format(total_bytes, uploaded_bytes))
if total_bytes == uploaded_bytes:
# Hide the progress bar, show the folder button
self.progress_bar.hide()
self.folder_button.show()
else:
# Update the progress bar
self.progress_bar.setMaximum(total_bytes)
self.progress_bar.setValue(uploaded_bytes)
elapsed = datetime.now() - self.started
if elapsed.seconds < 10:
pb_fmt = strings._('gui_download_upload_progress_starting').format(
self.common.human_readable_filesize(uploaded_bytes))
else:
estimated_time_remaining = self.common.estimated_time_remaining(
uploaded_bytes,
total_bytes,
started.timestamp())
pb_fmt = strings._('gui_download_upload_progress_eta').format(
self.common.human_readable_filesize(uploaded_bytes),
estimated_time_remaining)
class Upload(QtWidgets.QGroupBox):
def __init__(self, common, upload_id):
super(Upload, self).__init__()
self.common = common
self.upload_id = upload_id
self.started = datetime.now()
self.uploaded_bytes = 0
# Set the title of the title of the group box based on the start time
self.setTitle(strings._('gui_upload_in_progress', True).format(self.started.strftime("%b %m, %I:%M%p")))
# The layout contains file widgets
self.layout = QtWidgets.QVBoxLayout()
self.setLayout(self.layout)
# We're also making a dictionary of file widgets, to make them easier to access # We're also making a dictionary of file widgets, to make them easier to access
self.files = {} self.files = {}
def update(self, progress): def update(self, progress):
""" """
Using the progress from Web, make sure all the file progress bars exist, Using the progress from Web, update the progress bar and file size labels
and update their progress for each file
""" """
total_uploaded_bytes = 0
for filename in progress:
total_uploaded_bytes += progress[filename]['uploaded_bytes']
if total_uploaded_bytes == self.content_length:
# Hide the progress bar, show the folder button
self.progress_bar.hide()
self.folder_button.show()
else:
# Update the progress bar
self.progress_bar.setMaximum(self.content_length)
self.progress_bar.setValue(total_uploaded_bytes)
elapsed = datetime.now() - self.started
if elapsed.seconds < 10:
pb_fmt = strings._('gui_download_upload_progress_starting').format(
self.common.human_readable_filesize(total_uploaded_bytes))
else:
estimated_time_remaining = self.common.estimated_time_remaining(
total_uploaded_bytes,
self.content_length,
started.timestamp())
pb_fmt = strings._('gui_download_upload_progress_eta').format(
self.common.human_readable_filesize(total_uploaded_bytes),
estimated_time_remaining)
for filename in progress: for filename in progress:
# Add a new file if needed # Add a new file if needed
if filename not in self.files: if filename not in self.files:
self.files[filename] = File(self.common, filename) self.files[filename] = File(self.common, filename)
self.layout.addWidget(self.files[filename]) self.files_layout.addWidget(self.files[filename])
# Update the file # Update the file
self.files[filename].update(progress[filename]['total_bytes'], progress[filename]['uploaded_bytes']) self.files[filename].update(progress[filename]['uploaded_bytes'], progress[filename]['complete'])
class Uploads(QtWidgets.QScrollArea): class Uploads(QtWidgets.QScrollArea):
@ -154,16 +180,16 @@ class Uploads(QtWidgets.QScrollArea):
widget.setLayout(layout) widget.setLayout(layout)
self.setWidget(widget) self.setWidget(widget)
def add(self, upload_id): def add(self, upload_id, content_length):
""" """
Add a new upload. Add a new upload.
""" """
self.common.log('Uploads', 'add', 'upload_id: {}'.format(upload_id)) self.common.log('Uploads', 'add', 'upload_id: {}, content_length: {}'.format(upload_id, content_length))
# Hide the no_uploads_label # Hide the no_uploads_label
self.no_uploads_label.hide() self.no_uploads_label.hide()
# Add it to the list # Add it to the list
upload = Upload(self.common, upload_id) upload = Upload(self.common, upload_id, content_length)
self.uploads[upload_id] = upload self.uploads[upload_id] = upload
self.uploads_layout.addWidget(upload) self.uploads_layout.addWidget(upload)

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

View File

@ -191,6 +191,6 @@
"gui_uploads": "Upload History", "gui_uploads": "Upload History",
"gui_uploads_window_tooltip": "Show/hide uploads", "gui_uploads_window_tooltip": "Show/hide uploads",
"gui_no_uploads": "No uploads yet.", "gui_no_uploads": "No uploads yet.",
"gui_upload_in_progress": "Upload in progress, started {}", "gui_upload_in_progress": "Upload Started {}",
"gui_upload_finished": "Uploaded {} to {}" "gui_upload_finished": "Uploaded {} to {}"
} }