def on_start_download_action(self, action): if action == 1: if self.dialog and self.dialog.dialog_widget: self.window().perform_start_download_request( self.download_uri, self.dialog.dialog_widget.anon_download_checkbox.isChecked( ), self.dialog.dialog_widget.safe_seed_checkbox.isChecked(), self.dialog.dialog_widget.destination_input.currentText(), self.dialog.get_selected_files(), self.dialog.dialog_widget.files_list_view. topLevelItemCount(), add_to_channel=self.dialog.dialog_widget. add_to_channel_checkbox.isChecked(), ) else: ConfirmationDialog.show_error( self, "Tribler UI Error", "Something went wrong. Please try again.") logging.exception( "Error while trying to download. Either dialog or dialog.dialog_widget is None" ) if self.dialog: self.dialog.close_dialog() self.dialog = None self.start_download_dialog_active = False if action == 0: # We do this after removing the dialog since process_uri_request is blocking self.process_uri_request()
def on_config_error_signal(self, stacktrace): self._logger.error(f"Config error: {stacktrace}") user_message = tr( "Tribler recovered from a corrupted config. Please check your settings and update if necessary." ) ConfirmationDialog.show_error(self, tr("Tribler config error"), user_message)
def save_to_file(self, filename, data): base_dir = QFileDialog.getExistingDirectory(self, "Select an export directory", "", QFileDialog.ShowDirsOnly) if len(base_dir) > 0: dest_path = os.path.join(base_dir, filename) try: with open(dest_path, "w") as torrent_file: torrent_file.write(json.dumps(data)) except IOError as exc: ConfirmationDialog.show_error(self.window(), "Error exporting file", str(exc))
def on_create_clicked(self): if self.dialog_widget.create_torrent_files_list.count() == 0: dialog = ConfirmationDialog( self.dialog_widget, "Warning!", "You should add at least one file to your torrent.", [('CLOSE', BUTTON_TYPE_NORMAL)], ) dialog.button_clicked.connect(dialog.close_dialog) dialog.show() return self.dialog_widget.btn_create.setEnabled(False) files_list = [] for ind in range(self.dialog_widget.create_torrent_files_list.count()): file_str = self.dialog_widget.create_torrent_files_list.item( ind).text() files_list.append(file_str) export_dir = self.dialog_widget.file_export_dir.text() if not os.path.exists(export_dir): ConfirmationDialog.show_error( self.dialog_widget, "Cannot save torrent file to %s" % export_dir, "Path does not exist") return is_writable, error = is_dir_writable(export_dir) if not is_writable: ConfirmationDialog.show_error( self.dialog_widget, "Cannot save torrent file to %s" % export_dir, "Error: %s" % error) return self.name = self.dialog_widget.create_torrent_name_field.text() description = self.dialog_widget.create_torrent_description_field.toPlainText( ) post_data = { "name": self.name, "description": description, "files": files_list, "export_dir": export_dir } url = ("createtorrent?download=1" if self.dialog_widget.seed_after_adding_checkbox.isChecked() else "createtorrent") self.rest_request1 = TriblerNetworkRequest(url, self.on_torrent_created, data=post_data, method='POST') self.dialog_widget.edit_channel_create_torrent_progress_label.setText( "Creating torrent. Please wait...")
def on_payment(self, payment): if not payment["success"]: # Error occurred during payment main_text = "Transaction with id %s failed." % payment[ "transaction_number"] self.window().tray_show_message("Transaction failed", main_text) ConfirmationDialog.show_error(self.window(), "Transaction failed", main_text) self.window().hide_status_bar() else: self.window().show_status_bar( "Transaction in process, please don't close Tribler.")
def on_files_list_loaded(self): if self.active_index == -1: largest_index, largest_file = self.window().left_menu_playlist.get_largest_file() if not largest_file: # We don't have a media file in this torrent. Reset everything and show an error ConfirmationDialog.show_error(self.window(), "No media files", "This download contains no media files.") self.window().hide_left_menu_playlist() return self.active_index = largest_index self.play_active_item()
def on_memory_dump_data_available(self, filename, data): if not data: return dest_path = os.path.join(self.export_dir, filename) try: with open(dest_path, "wb") as memory_dump_file: memory_dump_file.write(data) except IOError as exc: ConfirmationDialog.show_error( self.window(), "Error when exporting file", "An error occurred when exporting the torrent file: %s" % str(exc), )
def on_export_download_request_done(self, filename, data): dest_path = os.path.join(self.export_dir, filename) try: torrent_file = open(dest_path, "wb") torrent_file.write(data) torrent_file.close() except OSError as exc: ConfirmationDialog.show_error( self.window(), "Error when exporting file", f"An error occurred when exporting the torrent file: {str(exc)}", ) else: self.window().tray_show_message("Torrent file exported", f"Torrent file exported to {dest_path}")
def should_create_wallet(self, wallet_id): if (wallet_id == "BTC" or wallet_id == "TBTC") and not self.btc_module_available: ConfirmationDialog.show_error( self.window(), "bitcoinlib not found", "bitcoinlib could not be located on your system. " "Please install it using the following command: " "pip install bitcoinlib --user", ) return TriblerNetworkRequest("wallets/%s" % wallet_id, self.on_wallet_created, method='PUT')
def on_channel_thumbnail_clicked(self): if not (self.edit_enabled and self.edit_mode_tab.get_selected_index() == EDIT_BUTTON_NUM): return filename = QFileDialog.getOpenFileName( self, tr("Please select a thumbnail file"), QDir.homePath(), filter=(tr("PNG/XPM/JPG images %s") % '(*.png *.xpm *.jpg)'), )[0] if not filename: return content_type = f"image/{str(Path(filename).suffix)[1:]}" with open(filename, "rb") as f: data = f.read() if len(data) > 1024**2: self.dialog = ConfirmationDialog.show_error( self, tr(tr("Image too large error")), tr(tr("Image file you're trying to upload is too large.")), ) return self.channel_thumbnail_bytes = data self.channel_thumbnail_type = content_type self.update_channel_thumbnail(data, content_type)
def on_download_clicked(self): if self.has_metainfo and len(self.get_selected_files()) == 0: # User deselected all torrents ConfirmationDialog.show_error( self.window(), "No files selected", "Please select at least one file to download." ) else: download_dir = self.dialog_widget.destination_input.currentText() is_writable, error = is_dir_writable(download_dir) if not is_writable: gui_error_message = ( "Tribler cannot download to <i>%s</i> directory. Please add proper write " "permissions to the directory or choose another download directory and try " "to download again. [%s]" % (download_dir, error) ) ConfirmationDialog.show_message(self.dialog_widget, "Insufficient Permissions", gui_error_message, "OK") else: self.button_clicked.emit(1)
def on_memory_dump_button_clicked(self, dump_core): self.export_dir = QFileDialog.getExistingDirectory( self, "Please select the destination directory", "", QFileDialog.ShowDirsOnly ) if len(self.export_dir) > 0: filename = "tribler_mem_dump_%s_%s.json" % ( 'core' if dump_core else 'gui', datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"), ) if dump_core: self.rest_request = TriblerNetworkRequest( "debug/memory/dump", lambda data, _: self.on_memory_dump_data_available(filename, data) ) elif scanner: scanner.dump_all_objects(os.path.join(self.export_dir, filename)) else: ConfirmationDialog.show_error( self.window(), "Error when performing a memory dump", "meliae memory dumper is not compatible with Python 3", )
def start_download_from_uri(self, uri): uri = uri.decode('utf-8') if isinstance(uri, bytes) else uri self.download_uri = uri if get_gui_setting(self.gui_settings, "ask_download_settings", True, is_bool=True): # FIXME: instead of using this workaround, make sure the settings are _available_ by this moment # If tribler settings is not available, fetch the settings and inform the user to try again. if not self.tribler_settings: self.fetch_settings() self.dialog = ConfirmationDialog.show_error( self, "Download Error", "Tribler settings is not available\ yet. Fetching it now. Please try again later.", ) # By re-adding the download uri to the pending list, the request is re-processed # when the settings is received self.pending_uri_requests.append(uri) return # Clear any previous dialog if exists if self.dialog: self.dialog.close_dialog() self.dialog = None self.dialog = StartDownloadDialog(self, self.download_uri) connect(self.dialog.button_clicked, self.on_start_download_action) self.dialog.show() self.start_download_dialog_active = True else: # FIXME: instead of using this workaround, make sure the settings are _available_ by this moment # In the unlikely scenario that tribler settings are not available yet, try to fetch settings again and # add the download uri back to self.pending_uri_requests to process again. if not self.tribler_settings: self.fetch_settings() if self.download_uri not in self.pending_uri_requests: self.pending_uri_requests.append(self.download_uri) return self.window().perform_start_download_request( self.download_uri, self.window().tribler_settings['download_defaults'] ['anonymity_enabled'], self.window().tribler_settings['download_defaults'] ['safeseeding_enabled'], self.tribler_settings['download_defaults']['saveas'], [], ) self.process_uri_request()
def on_emptying_tokens(self, data): if not data: return json_data = json.dumps(data) if has_qr: self.empty_tokens_barcode_dialog = QWidget() self.empty_tokens_barcode_dialog.setWindowTitle("Please scan the following QR code") self.empty_tokens_barcode_dialog.setGeometry(10, 10, 500, 500) qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=10, border=5) qr.add_data(json_data) qr.make(fit=True) img = qr.make_image() # PIL format qim = ImageQt(img) pixmap = QtGui.QPixmap.fromImage(qim).scaled(600, 600, QtCore.Qt.KeepAspectRatio) label = QLabel(self.empty_tokens_barcode_dialog) label.setPixmap(pixmap) self.empty_tokens_barcode_dialog.resize(pixmap.width(), pixmap.height()) self.empty_tokens_barcode_dialog.show() else: ConfirmationDialog.show_error(self.window(), DEPENDENCY_ERROR_TITLE, DEPENDENCY_ERROR_MESSAGE)
def show_new_order_dialog(self, is_ask): if not self.wallets[self.chosen_wallets[0]]['created']: ConfirmationDialog.show_error( self.window(), "Wallet not available", "%s wallet not available, please create it first." % self.chosen_wallets[0], ) return elif not self.wallets[self.chosen_wallets[1]]['created']: ConfirmationDialog.show_error( self.window(), "Wallet not available", "%s wallet not available, please create it first." % self.chosen_wallets[1], ) return self.dialog = NewMarketOrderDialog(self.window().stackedWidget, is_ask, self.chosen_wallets[0], self.chosen_wallets[1], self.wallets) self.dialog.button_clicked.connect(self.on_new_order_action) self.dialog.show()
def confirm_partially_empty_tokens(self, action): tokens = self.empty_partial_tokens_dialog.dialog_widget.dialog_input.text() self.empty_partial_tokens_dialog.close_dialog() self.empty_partial_tokens_dialog = None if action == 0: try: tokens = int(float(tokens)) except ValueError: ConfirmationDialog.show_error(self.window(), "Wrong input", "The provided amount is not a number") return self.confirm_empty_tokens_dialog = ConfirmationDialog( self, "Empty tokens into another account", "Are you sure you want to empty %d bandwidth tokens " "into another account? " "Warning: one-way action that cannot be revered" % tokens, [('EMPTY', BUTTON_TYPE_NORMAL), ('CANCEL', BUTTON_TYPE_CONFIRM)], ) self.confirm_empty_tokens_dialog.button_clicked.connect( lambda action2: self.on_confirm_partially_empty_tokens(action2, tokens) ) self.confirm_empty_tokens_dialog.show()
def save_settings(self, checked): # Create a dictionary with all available settings settings_data = { 'general': {}, 'Tribler': {}, 'download_defaults': {}, 'libtorrent': {}, 'watch_folder': {}, 'tunnel_community': {}, 'trustchain': {}, 'resource_monitor': {}, 'ipv8': {}, 'chant': {}, } settings_data['download_defaults']['saveas'] = self.window( ).download_location_input.text() settings_data['general']['log_dir'] = self.window( ).log_location_input.text() settings_data['watch_folder']['enabled'] = self.window( ).watchfolder_enabled_checkbox.isChecked() if settings_data['watch_folder']['enabled']: settings_data['watch_folder']['directory'] = self.window( ).watchfolder_location_input.text() settings_data['libtorrent']['proxy_type'] = self.window( ).lt_proxy_type_combobox.currentIndex() if (self.window().lt_proxy_server_input.text() and len(self.window().lt_proxy_server_input.text()) > 0 and len(self.window().lt_proxy_port_input.text()) > 0): try: settings_data['libtorrent']['proxy_server'] = "{}:{}".format( self.window().lt_proxy_server_input.text(), int(self.window().lt_proxy_port_input.text()), ) except ValueError: ConfirmationDialog.show_error( self.window(), tr("Invalid proxy port number"), tr("You've entered an invalid format for the proxy port number. Please enter a whole number." ), ) return else: settings_data['libtorrent']['proxy_server'] = ":" if self.window().lt_proxy_username_input.text() and self.window( ).lt_proxy_password_input.text(): settings_data['libtorrent']['proxy_auth'] = "{}:{}".format( self.window().lt_proxy_username_input.text(), self.window().lt_proxy_password_input.text(), ) else: settings_data['libtorrent']['proxy_auth'] = ":" settings_data['libtorrent']['utp'] = self.window( ).lt_utp_checkbox.isChecked() try: max_conn_download = int( self.window().max_connections_download_input.text()) except ValueError: ConfirmationDialog.show_error( self.window(), tr("Invalid number of connections"), tr("You've entered an invalid format for the maximum number of connections. " "Please enter a whole number."), ) return if max_conn_download == 0: max_conn_download = -1 settings_data['libtorrent'][ 'max_connections_download'] = max_conn_download try: if self.window().upload_rate_limit_input.text(): user_upload_rate_limit = int( float(self.window().upload_rate_limit_input.text()) * 1024) if user_upload_rate_limit < MAX_LIBTORRENT_RATE_LIMIT: settings_data['libtorrent'][ 'max_upload_rate'] = user_upload_rate_limit else: raise ValueError if self.window().download_rate_limit_input.text(): user_download_rate_limit = int( float(self.window().download_rate_limit_input.text()) * 1024) if user_download_rate_limit < MAX_LIBTORRENT_RATE_LIMIT: settings_data['libtorrent'][ 'max_download_rate'] = user_download_rate_limit else: raise ValueError except ValueError: ConfirmationDialog.show_error( self.window(), tr("Invalid value for bandwidth limit"), tr("You've entered an invalid value for the maximum upload/download rate. \n" "The rate is specified in KB/s and the value permitted is between 0 and %d KB/s.\n" "Note that the decimal values are truncated.") % (MAX_LIBTORRENT_RATE_LIMIT / 1024), ) return try: if self.window().api_port_input.text(): api_port = int(self.window().api_port_input.text()) if api_port <= 0 or api_port >= 65536: raise ValueError() self.window().gui_settings.setValue("api_port", api_port) except ValueError: ConfirmationDialog.show_error( self.window(), tr("Invalid value for api port"), tr("Please enter a valid port for the api (between 0 and 65536)" ), ) return seeding_modes = ['forever', 'time', 'never', 'ratio'] selected_mode = 'forever' for seeding_mode in seeding_modes: if getattr(self.window(), "seeding_" + seeding_mode + "_radio").isChecked(): selected_mode = seeding_mode break settings_data['download_defaults']['seeding_mode'] = selected_mode settings_data['download_defaults']['seeding_ratio'] = float( self.window().seeding_ratio_combobox.currentText()) try: settings_data['download_defaults'][ 'seeding_time'] = string_to_seconds( self.window().seeding_time_input.text()) except ValueError: ConfirmationDialog.show_error( self.window(), tr("Invalid seeding time"), tr("You've entered an invalid format for the seeding time (expected HH:MM)" ), ) return settings_data['tunnel_community']['exitnode_enabled'] = self.window( ).allow_exit_node_checkbox.isChecked() settings_data['download_defaults']['number_hops'] = self.window( ).number_hops_slider.value() settings_data['download_defaults']['anonymity_enabled'] = self.window( ).download_settings_anon_checkbox.isChecked() settings_data['download_defaults'][ 'safeseeding_enabled'] = self.window( ).download_settings_anon_seeding_checkbox.isChecked() settings_data['download_defaults'][ 'add_download_to_channel'] = self.window( ).download_settings_add_to_channel_checkbox.isChecked() settings_data['resource_monitor']['enabled'] = self.window( ).checkbox_enable_resource_log.isChecked() settings_data['resource_monitor']['cpu_priority'] = int( self.window().slider_cpu_level.value()) # network statistics settings_data['ipv8']['statistics'] = self.window( ).checkbox_enable_network_statistics.isChecked() self.window().settings_save_button.setEnabled(False) # TODO: do it in RESTful style, on the REST return JSON instead # In case the default save dir has changed, add it to the top of the list of last download locations. # Otherwise, the user could absentmindedly click through the download dialog and start downloading into # the last used download dir, and not into the newly designated default download dir. if self.settings['download_defaults']['saveas'] != settings_data[ 'download_defaults']['saveas']: self.window().update_recent_download_locations( settings_data['download_defaults']['saveas']) self.settings = settings_data TriblerNetworkRequest("settings", self.on_settings_saved, method='POST', raw_data=json.dumps(settings_data))
def save_settings(self): # Create a dictionary with all available settings settings_data = { 'general': {}, 'Tribler': {}, 'download_defaults': {}, 'libtorrent': {}, 'watch_folder': {}, 'tunnel_community': {}, 'market_community': {}, 'trustchain': {}, 'resource_monitor': {}, 'ipv8': {}, 'chant': {}, } settings_data['download_defaults']['saveas'] = self.window().download_location_input.text() settings_data['general']['log_dir'] = self.window().log_location_input.text() settings_data['watch_folder']['enabled'] = self.window().watchfolder_enabled_checkbox.isChecked() if settings_data['watch_folder']['enabled']: settings_data['watch_folder']['directory'] = self.window().watchfolder_location_input.text() settings_data['market_community']['enabled'] = self.window().enable_market_checkbox.isChecked() settings_data['libtorrent']['proxy_type'] = self.window().lt_proxy_type_combobox.currentIndex() if ( self.window().lt_proxy_server_input.text() and len(self.window().lt_proxy_server_input.text()) > 0 and len(self.window().lt_proxy_port_input.text()) > 0 ): try: settings_data['libtorrent']['proxy_server'] = "%s:%s" % ( self.window().lt_proxy_server_input.text(), int(self.window().lt_proxy_port_input.text()), ) except ValueError: ConfirmationDialog.show_error( self.window(), "Invalid proxy port number", "You've entered an invalid format for the proxy port number. " "Please enter a whole number.", ) return else: settings_data['libtorrent']['proxy_server'] = ":" if self.window().lt_proxy_username_input.text() and self.window().lt_proxy_password_input.text(): settings_data['libtorrent']['proxy_auth'] = "%s:%s" % ( self.window().lt_proxy_username_input.text(), self.window().lt_proxy_password_input.text(), ) else: settings_data['libtorrent']['proxy_auth'] = ":" settings_data['libtorrent']['utp'] = self.window().lt_utp_checkbox.isChecked() try: max_conn_download = int(self.window().max_connections_download_input.text()) except ValueError: ConfirmationDialog.show_error( self.window(), "Invalid number of connections", "You've entered an invalid format for the maximum number of connections. " "Please enter a whole number.", ) return if max_conn_download == 0: max_conn_download = -1 settings_data['libtorrent']['max_connections_download'] = max_conn_download try: if self.window().upload_rate_limit_input.text(): user_upload_rate_limit = int(self.window().upload_rate_limit_input.text()) * 1024 if user_upload_rate_limit < sys.maxsize: settings_data['libtorrent']['max_upload_rate'] = user_upload_rate_limit else: raise ValueError if self.window().download_rate_limit_input.text(): user_download_rate_limit = int(self.window().download_rate_limit_input.text()) * 1024 if user_download_rate_limit < sys.maxsize: settings_data['libtorrent']['max_download_rate'] = user_download_rate_limit else: raise ValueError except ValueError: ConfirmationDialog.show_error( self.window(), "Invalid value for bandwidth limit", "You've entered an invalid value for the maximum upload/download rate. " "Please enter a whole number (max: %d)" % (sys.maxsize / 1000), ) return try: if self.window().api_port_input.text(): api_port = int(self.window().api_port_input.text()) if api_port <= 0 or api_port >= 65536: raise ValueError() self.window().gui_settings.setValue("api_port", api_port) except ValueError: ConfirmationDialog.show_error( self.window(), "Invalid value for api port", "Please enter a valid port for the api (between 0 and 65536)", ) return seeding_modes = ['forever', 'time', 'never', 'ratio'] selected_mode = 'forever' for seeding_mode in seeding_modes: if getattr(self.window(), "seeding_" + seeding_mode + "_radio").isChecked(): selected_mode = seeding_mode break settings_data['download_defaults']['seeding_mode'] = selected_mode settings_data['download_defaults']['seeding_ratio'] = float(self.window().seeding_ratio_combobox.currentText()) try: settings_data['download_defaults']['seeding_time'] = string_to_seconds( self.window().seeding_time_input.text() ) except ValueError: ConfirmationDialog.show_error( self.window(), "Invalid seeding time", "You've entered an invalid format for the seeding time (expected HH:MM)", ) return settings_data['tunnel_community']['exitnode_enabled'] = self.window().allow_exit_node_checkbox.isChecked() settings_data['download_defaults']['number_hops'] = self.window().number_hops_slider.value() settings_data['download_defaults'][ 'anonymity_enabled' ] = self.window().download_settings_anon_checkbox.isChecked() settings_data['download_defaults'][ 'safeseeding_enabled' ] = self.window().download_settings_anon_seeding_checkbox.isChecked() settings_data['download_defaults'][ 'add_download_to_channel' ] = self.window().download_settings_add_to_channel_checkbox.isChecked() settings_data['resource_monitor']['enabled'] = self.window().checkbox_enable_resource_log.isChecked() settings_data['resource_monitor']['cpu_priority'] = int(self.window().slider_cpu_level.value()) # network statistics settings_data['ipv8']['statistics'] = self.window().checkbox_enable_network_statistics.isChecked() self.window().settings_save_button.setEnabled(False) TriblerNetworkRequest("settings", self.on_settings_saved, method='POST', raw_data=json.dumps(settings_data))