diff options
Diffstat (limited to 'onionshare_gui/mode/history.py')
-rw-r--r-- | onionshare_gui/mode/history.py | 283 |
1 files changed, 180 insertions, 103 deletions
diff --git a/onionshare_gui/mode/history.py b/onionshare_gui/mode/history.py index b8baebd1..85eec7e4 100644 --- a/onionshare_gui/mode/history.py +++ b/onionshare_gui/mode/history.py @@ -31,6 +31,7 @@ class HistoryItem(QtWidgets.QWidget): """ The base history item """ + STATUS_STARTED = 0 STATUS_FINISHED = 1 STATUS_CANCELED = 2 @@ -49,34 +50,42 @@ class HistoryItem(QtWidgets.QWidget): When an item finishes, returns a string displaying the start/end datetime range. started is a datetime object. """ - return self._get_label_text('gui_all_modes_transfer_finished', 'gui_all_modes_transfer_finished_range', started) + return self._get_label_text( + "gui_all_modes_transfer_finished", + "gui_all_modes_transfer_finished_range", + started, + ) def get_canceled_label_text(self, started): """ When an item is canceled, returns a string displaying the start/end datetime range. started is a datetime object. """ - return self._get_label_text('gui_all_modes_transfer_canceled', 'gui_all_modes_transfer_canceled_range', started) + return self._get_label_text( + "gui_all_modes_transfer_canceled", + "gui_all_modes_transfer_canceled_range", + started, + ) def _get_label_text(self, string_name, string_range_name, started): """ Return a string that contains a date, or date range. """ ended = datetime.now() - if started.year == ended.year and started.month == ended.month and started.day == ended.day: + if ( + started.year == ended.year + and started.month == ended.month + and started.day == ended.day + ): if started.hour == ended.hour and started.minute == ended.minute: - text = strings._(string_name).format( - started.strftime("%b %d, %I:%M%p") - ) + text = strings._(string_name).format(started.strftime("%b %d, %I:%M%p")) else: text = strings._(string_range_name).format( - started.strftime("%b %d, %I:%M%p"), - ended.strftime("%I:%M%p") + started.strftime("%b %d, %I:%M%p"), ended.strftime("%I:%M%p") ) else: text = strings._(string_range_name).format( - started.strftime("%b %d, %I:%M%p"), - ended.strftime("%b %d, %I:%M%p") + started.strftime("%b %d, %I:%M%p"), ended.strftime("%b %d, %I:%M%p") ) return text @@ -85,6 +94,7 @@ class ShareHistoryItem(HistoryItem): """ Download history item, for share mode """ + def __init__(self, common, id, total_bytes): super(ShareHistoryItem, self).__init__() self.common = common @@ -97,7 +107,11 @@ class ShareHistoryItem(HistoryItem): self.status = HistoryItem.STATUS_STARTED # Label - self.label = QtWidgets.QLabel(strings._('gui_all_modes_transfer_started').format(self.started_dt.strftime("%b %d, %I:%M%p"))) + self.label = QtWidgets.QLabel( + strings._("gui_all_modes_transfer_started").format( + self.started_dt.strftime("%b %d, %I:%M%p") + ) + ) # Progress bar self.progress_bar = QtWidgets.QProgressBar() @@ -107,7 +121,9 @@ class ShareHistoryItem(HistoryItem): self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(total_bytes) 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"] + ) self.progress_bar.total_bytes = total_bytes # Layout @@ -124,8 +140,9 @@ class ShareHistoryItem(HistoryItem): self.progress_bar.setValue(downloaded_bytes) if downloaded_bytes == self.progress_bar.total_bytes: - pb_fmt = strings._('gui_all_modes_progress_complete').format( - self.common.format_seconds(time.time() - self.started)) + pb_fmt = strings._("gui_all_modes_progress_complete").format( + self.common.format_seconds(time.time() - self.started) + ) # Change the label self.label.setText(self.get_finished_label_text(self.started_dt)) @@ -137,24 +154,26 @@ class ShareHistoryItem(HistoryItem): # Wait a couple of seconds for the download rate to stabilize. # This prevents a "Windows copy dialog"-esque experience at # the beginning of the download. - pb_fmt = strings._('gui_all_modes_progress_starting').format( - self.common.human_readable_filesize(downloaded_bytes)) + pb_fmt = strings._("gui_all_modes_progress_starting").format( + self.common.human_readable_filesize(downloaded_bytes) + ) else: - pb_fmt = strings._('gui_all_modes_progress_eta').format( + pb_fmt = strings._("gui_all_modes_progress_eta").format( self.common.human_readable_filesize(downloaded_bytes), - self.estimated_time_remaining) + self.estimated_time_remaining, + ) self.progress_bar.setFormat(pb_fmt) def cancel(self): - self.progress_bar.setFormat(strings._('gui_canceled')) + self.progress_bar.setFormat(strings._("gui_canceled")) self.status = HistoryItem.STATUS_CANCELED @property def estimated_time_remaining(self): - return self.common.estimated_time_remaining(self.downloaded_bytes, - self.total_bytes, - self.started) + return self.common.estimated_time_remaining( + self.downloaded_bytes, self.total_bytes, self.started + ) class ReceiveHistoryItemFile(QtWidgets.QWidget): @@ -162,7 +181,9 @@ class ReceiveHistoryItemFile(QtWidgets.QWidget): super(ReceiveHistoryItemFile, self).__init__() self.common = common - self.common.log('ReceiveHistoryItemFile', '__init__', 'filename: {}'.format(filename)) + self.common.log( + "ReceiveHistoryItemFile", "__init__", "filename: {}".format(filename) + ) self.filename = filename self.dir = None @@ -174,11 +195,13 @@ class ReceiveHistoryItemFile(QtWidgets.QWidget): # File size label self.filesize_label = QtWidgets.QLabel() - self.filesize_label.setStyleSheet(self.common.css['receive_file_size']) + 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_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.clicked.connect(self.open_folder) @@ -213,29 +236,36 @@ class ReceiveHistoryItemFile(QtWidgets.QWidget): """ Open the downloads folder, with the file selected, in a cross-platform manner """ - self.common.log('ReceiveHistoryItemFile', 'open_folder') + self.common.log("ReceiveHistoryItemFile", "open_folder") if not self.dir: - self.common.log('ReceiveHistoryItemFile', 'open_folder', "dir has not been set yet, can't open folder") + self.common.log( + "ReceiveHistoryItemFile", + "open_folder", + "dir has not been set yet, can't open folder", + ) return abs_filename = os.path.join(self.dir, self.filename) # Linux - if self.common.platform == 'Linux' or self.common.platform == 'BSD': + if self.common.platform == "Linux" or self.common.platform == "BSD": try: # If nautilus is available, open it - subprocess.Popen(['nautilus', abs_filename]) + subprocess.Popen(["nautilus", abs_filename]) except: - Alert(self.common, strings._('gui_open_folder_error_nautilus').format(abs_filename)) + Alert( + self.common, + strings._("gui_open_folder_error_nautilus").format(abs_filename), + ) # macOS - elif self.common.platform == 'Darwin': - subprocess.call(['open', '-R', abs_filename]) + elif self.common.platform == "Darwin": + subprocess.call(["open", "-R", abs_filename]) # Windows - elif self.common.platform == 'Windows': - subprocess.Popen(['explorer', '/select,{}'.format(abs_filename)]) + elif self.common.platform == "Windows": + subprocess.Popen(["explorer", "/select,{}".format(abs_filename)]) class ReceiveHistoryItem(HistoryItem): @@ -248,7 +278,11 @@ class ReceiveHistoryItem(HistoryItem): self.status = HistoryItem.STATUS_STARTED # Label - self.label = QtWidgets.QLabel(strings._('gui_all_modes_transfer_started').format(self.started.strftime("%b %d, %I:%M%p"))) + self.label = QtWidgets.QLabel( + strings._("gui_all_modes_transfer_started").format( + self.started.strftime("%b %d, %I:%M%p") + ) + ) # Progress bar self.progress_bar = QtWidgets.QProgressBar() @@ -257,13 +291,15 @@ class ReceiveHistoryItem(HistoryItem): self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) self.progress_bar.setMinimum(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"] + ) # This layout contains file widgets self.files_layout = QtWidgets.QVBoxLayout() self.files_layout.setContentsMargins(0, 0, 0, 0) files_widget = QtWidgets.QWidget() - files_widget.setStyleSheet(self.common.css['receive_file']) + files_widget.setStyleSheet(self.common.css["receive_file"]) files_widget.setLayout(self.files_layout) # Layout @@ -282,10 +318,10 @@ class ReceiveHistoryItem(HistoryItem): Using the progress from Web, update the progress bar and file size labels for each file """ - if data['action'] == 'progress': + if data["action"] == "progress": total_uploaded_bytes = 0 - for filename in data['progress']: - total_uploaded_bytes += data['progress'][filename]['uploaded_bytes'] + for filename in data["progress"]: + total_uploaded_bytes += data["progress"][filename]["uploaded_bytes"] # Update the progress bar self.progress_bar.setMaximum(self.content_length) @@ -293,35 +329,39 @@ class ReceiveHistoryItem(HistoryItem): elapsed = datetime.now() - self.started if elapsed.seconds < 10: - pb_fmt = strings._('gui_all_modes_progress_starting').format( - self.common.human_readable_filesize(total_uploaded_bytes)) + pb_fmt = strings._("gui_all_modes_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, - self.started.timestamp()) - pb_fmt = strings._('gui_all_modes_progress_eta').format( + total_uploaded_bytes, self.content_length, self.started.timestamp() + ) + pb_fmt = strings._("gui_all_modes_progress_eta").format( self.common.human_readable_filesize(total_uploaded_bytes), - estimated_time_remaining) + estimated_time_remaining, + ) # Using list(progress) to avoid "RuntimeError: dictionary changed size during iteration" - for filename in list(data['progress']): + for filename in list(data["progress"]): # Add a new file if needed if filename not in self.files: self.files[filename] = ReceiveHistoryItemFile(self.common, filename) self.files_layout.addWidget(self.files[filename]) # Update the file - self.files[filename].update(data['progress'][filename]['uploaded_bytes'], data['progress'][filename]['complete']) + self.files[filename].update( + data["progress"][filename]["uploaded_bytes"], + data["progress"][filename]["complete"], + ) - elif data['action'] == 'rename': - self.files[data['old_filename']].rename(data['new_filename']) - self.files[data['new_filename']] = self.files.pop(data['old_filename']) + elif data["action"] == "rename": + self.files[data["old_filename"]].rename(data["new_filename"]) + self.files[data["new_filename"]] = self.files.pop(data["old_filename"]) - elif data['action'] == 'set_dir': - self.files[data['filename']].set_dir(data['dir']) + elif data["action"] == "set_dir": + self.files[data["filename"]].set_dir(data["dir"]) - elif data['action'] == 'finished': + elif data["action"] == "finished": # Change the status self.status = HistoryItem.STATUS_FINISHED @@ -331,7 +371,7 @@ class ReceiveHistoryItem(HistoryItem): # Change the label self.label.setText(self.get_finished_label_text(self.started)) - elif data['action'] == 'canceled': + elif data["action"] == "canceled": # Change the status self.status = HistoryItem.STATUS_CANCELED @@ -346,6 +386,7 @@ class IndividualFileHistoryItem(HistoryItem): """ Individual file history item, for share mode viewing of individual files """ + def __init__(self, common, data, path): super(IndividualFileHistoryItem, self).__init__() self.status = HistoryItem.STATUS_STARTED @@ -359,11 +400,15 @@ class IndividualFileHistoryItem(HistoryItem): self.started_dt = datetime.fromtimestamp(self.started) self.status = HistoryItem.STATUS_STARTED - self.directory_listing = 'directory_listing' in data + self.directory_listing = "directory_listing" in data # Labels - self.timestamp_label = QtWidgets.QLabel(self.started_dt.strftime("%b %d, %I:%M%p")) - self.timestamp_label.setStyleSheet(self.common.css['history_individual_file_timestamp_label']) + self.timestamp_label = QtWidgets.QLabel( + self.started_dt.strftime("%b %d, %I:%M%p") + ) + self.timestamp_label.setStyleSheet( + self.common.css["history_individual_file_timestamp_label"] + ) self.path_label = QtWidgets.QLabel("{}".format(self.path)) self.status_code_label = QtWidgets.QLabel() @@ -373,7 +418,9 @@ class IndividualFileHistoryItem(HistoryItem): self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) 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"] + ) # Text layout labels_layout = QtWidgets.QHBoxLayout() @@ -389,21 +436,25 @@ class IndividualFileHistoryItem(HistoryItem): self.setLayout(layout) # Is a status code already sent? - if 'status_code' in data: - self.status_code_label.setText("{}".format(data['status_code'])) - if data['status_code'] >= 200 and data['status_code'] < 300: - self.status_code_label.setStyleSheet(self.common.css['history_individual_file_status_code_label_2xx']) - if data['status_code'] >= 400 and data['status_code'] < 500: - self.status_code_label.setStyleSheet(self.common.css['history_individual_file_status_code_label_4xx']) + if "status_code" in data: + self.status_code_label.setText("{}".format(data["status_code"])) + if data["status_code"] >= 200 and data["status_code"] < 300: + self.status_code_label.setStyleSheet( + self.common.css["history_individual_file_status_code_label_2xx"] + ) + if data["status_code"] >= 400 and data["status_code"] < 500: + self.status_code_label.setStyleSheet( + self.common.css["history_individual_file_status_code_label_4xx"] + ) self.status = HistoryItem.STATUS_FINISHED self.progress_bar.hide() return else: - self.total_bytes = data['filesize'] + self.total_bytes = data["filesize"] self.progress_bar.setMinimum(0) - self.progress_bar.setMaximum(data['filesize']) - self.progress_bar.total_bytes = data['filesize'] + self.progress_bar.setMaximum(data["filesize"]) + self.progress_bar.total_bytes = data["filesize"] # Start at 0 self.update(0) @@ -414,7 +465,9 @@ class IndividualFileHistoryItem(HistoryItem): self.progress_bar.setValue(downloaded_bytes) if downloaded_bytes == self.progress_bar.total_bytes: self.status_code_label.setText("200") - self.status_code_label.setStyleSheet(self.common.css['history_individual_file_status_code_label_2xx']) + self.status_code_label.setStyleSheet( + self.common.css["history_individual_file_status_code_label_2xx"] + ) self.progress_bar.hide() self.status = HistoryItem.STATUS_FINISHED @@ -424,30 +477,33 @@ class IndividualFileHistoryItem(HistoryItem): # Wait a couple of seconds for the download rate to stabilize. # This prevents a "Windows copy dialog"-esque experience at # the beginning of the download. - pb_fmt = strings._('gui_all_modes_progress_starting').format( - self.common.human_readable_filesize(downloaded_bytes)) + pb_fmt = strings._("gui_all_modes_progress_starting").format( + self.common.human_readable_filesize(downloaded_bytes) + ) else: - pb_fmt = strings._('gui_all_modes_progress_eta').format( + pb_fmt = strings._("gui_all_modes_progress_eta").format( self.common.human_readable_filesize(downloaded_bytes), - self.estimated_time_remaining) + self.estimated_time_remaining, + ) self.progress_bar.setFormat(pb_fmt) def cancel(self): - self.progress_bar.setFormat(strings._('gui_canceled')) + self.progress_bar.setFormat(strings._("gui_canceled")) self.status = HistoryItem.STATUS_CANCELED @property def estimated_time_remaining(self): - return self.common.estimated_time_remaining(self.downloaded_bytes, - self.total_bytes, - self.started) + return self.common.estimated_time_remaining( + self.downloaded_bytes, self.total_bytes, self.started + ) class HistoryItemList(QtWidgets.QScrollArea): """ List of items """ + def __init__(self, common): super(HistoryItemList, self).__init__() self.common = common @@ -511,12 +567,14 @@ class HistoryItemList(QtWidgets.QScrollArea): item.close() del self.items[key] + class History(QtWidgets.QWidget): """ A history of what's happened so far in this mode. This contains an internal object full of a scrollable list of items. """ - def __init__(self, common, empty_image, empty_text, header_text, mode=''): + + def __init__(self, common, empty_image, empty_text, header_text, mode=""): super(History, self).__init__() self.common = common self.mode = mode @@ -530,17 +588,19 @@ class History(QtWidgets.QWidget): # In progress, completed, and requests labels self.in_progress_label = QtWidgets.QLabel() - self.in_progress_label.setStyleSheet(self.common.css['mode_info_label']) + self.in_progress_label.setStyleSheet(self.common.css["mode_info_label"]) self.completed_label = QtWidgets.QLabel() - self.completed_label.setStyleSheet(self.common.css['mode_info_label']) + self.completed_label.setStyleSheet(self.common.css["mode_info_label"]) self.requests_label = QtWidgets.QLabel() - self.requests_label.setStyleSheet(self.common.css['mode_info_label']) + self.requests_label.setStyleSheet(self.common.css["mode_info_label"]) # Header self.header_label = QtWidgets.QLabel(header_text) - self.header_label.setStyleSheet(self.common.css['downloads_uploads_label']) - self.clear_button = QtWidgets.QPushButton(strings._('gui_all_modes_clear_history')) - self.clear_button.setStyleSheet(self.common.css['downloads_uploads_clear']) + self.header_label.setStyleSheet(self.common.css["downloads_uploads_label"]) + self.clear_button = QtWidgets.QPushButton( + strings._("gui_all_modes_clear_history") + ) + self.clear_button.setStyleSheet(self.common.css["downloads_uploads_clear"]) self.clear_button.setFlat(True) self.clear_button.clicked.connect(self.reset) header_layout = QtWidgets.QHBoxLayout() @@ -557,14 +617,14 @@ class History(QtWidgets.QWidget): self.empty_image.setPixmap(empty_image) self.empty_text = QtWidgets.QLabel(empty_text) self.empty_text.setAlignment(QtCore.Qt.AlignCenter) - self.empty_text.setStyleSheet(self.common.css['downloads_uploads_empty_text']) + self.empty_text.setStyleSheet(self.common.css["downloads_uploads_empty_text"]) empty_layout = QtWidgets.QVBoxLayout() empty_layout.addStretch() empty_layout.addWidget(self.empty_image) empty_layout.addWidget(self.empty_text) empty_layout.addStretch() self.empty = QtWidgets.QWidget() - self.empty.setStyleSheet(self.common.css['downloads_uploads_empty']) + self.empty.setStyleSheet(self.common.css["downloads_uploads_empty"]) self.empty.setLayout(empty_layout) # When there are items @@ -589,7 +649,7 @@ class History(QtWidgets.QWidget): """ Add a new item. """ - self.common.log('History', 'add', 'id: {}, item: {}'.format(id, item)) + self.common.log("History", "add", "id: {}, item: {}".format(id, item)) # Hide empty, show not empty self.empty.hide() @@ -636,35 +696,47 @@ class History(QtWidgets.QWidget): Update the 'completed' widget. """ if self.completed_count == 0: - image = self.common.get_resource_path('images/history_completed_none.png') + image = self.common.get_resource_path("images/history_completed_none.png") else: - image = self.common.get_resource_path('images/history_completed.png') - self.completed_label.setText('<img src="{0:s}" /> {1:d}'.format(image, self.completed_count)) - self.completed_label.setToolTip(strings._('history_completed_tooltip').format(self.completed_count)) + image = self.common.get_resource_path("images/history_completed.png") + self.completed_label.setText( + '<img src="{0:s}" /> {1:d}'.format(image, self.completed_count) + ) + self.completed_label.setToolTip( + strings._("history_completed_tooltip").format(self.completed_count) + ) def update_in_progress(self): """ Update the 'in progress' widget. """ if self.in_progress_count == 0: - image = self.common.get_resource_path('images/history_in_progress_none.png') + image = self.common.get_resource_path("images/history_in_progress_none.png") else: - image = self.common.get_resource_path('images/history_in_progress.png') + image = self.common.get_resource_path("images/history_in_progress.png") - self.in_progress_label.setText('<img src="{0:s}" /> {1:d}'.format(image, self.in_progress_count)) - self.in_progress_label.setToolTip(strings._('history_in_progress_tooltip').format(self.in_progress_count)) + self.in_progress_label.setText( + '<img src="{0:s}" /> {1:d}'.format(image, self.in_progress_count) + ) + self.in_progress_label.setToolTip( + strings._("history_in_progress_tooltip").format(self.in_progress_count) + ) def update_requests(self): """ Update the 'web requests' widget. """ if self.requests_count == 0: - image = self.common.get_resource_path('images/history_requests_none.png') + image = self.common.get_resource_path("images/history_requests_none.png") else: - image = self.common.get_resource_path('images/history_requests.png') + image = self.common.get_resource_path("images/history_requests.png") - self.requests_label.setText('<img src="{0:s}" /> {1:d}'.format(image, self.requests_count)) - self.requests_label.setToolTip(strings._('history_requests_tooltip').format(self.requests_count)) + self.requests_label.setText( + '<img src="{0:s}" /> {1:d}'.format(image, self.requests_count) + ) + self.requests_label.setToolTip( + strings._("history_requests_tooltip").format(self.requests_count) + ) class ToggleHistory(QtWidgets.QPushButton): @@ -672,6 +744,7 @@ class ToggleHistory(QtWidgets.QPushButton): Widget for toggling showing or hiding the history, as well as keeping track of the indicator counter if it's hidden """ + def __init__(self, common, current_mode, history_widget, icon, selected_icon): super(ToggleHistory, self).__init__() self.common = common @@ -691,7 +764,9 @@ class ToggleHistory(QtWidgets.QPushButton): # Keep track of indicator self.indicator_count = 0 self.indicator_label = QtWidgets.QLabel(parent=self) - self.indicator_label.setStyleSheet(self.common.css['download_uploads_indicator']) + self.indicator_label.setStyleSheet( + self.common.css["download_uploads_indicator"] + ) self.update_indicator() def update_indicator(self, increment=False): @@ -708,14 +783,16 @@ class ToggleHistory(QtWidgets.QPushButton): self.indicator_label.hide() else: size = self.indicator_label.sizeHint() - self.indicator_label.setGeometry(35-size.width(), 0, size.width(), size.height()) + self.indicator_label.setGeometry( + 35 - size.width(), 0, size.width(), size.height() + ) self.indicator_label.show() def toggle_clicked(self): """ Toggle showing and hiding the history widget """ - self.common.log('ToggleHistory', 'toggle_clicked') + self.common.log("ToggleHistory", "toggle_clicked") if self.history_widget.isVisible(): self.history_widget.hide() |