def _update(self): state = self._state self._name_label.setText(state.suggested_name) # FIXME: Avoid XSS in all setText calls if state.downloaded_size < state.selected_size: status_text = '{} of {}'.format(humanize_size(state.downloaded_size), humanize_size(state.selected_size)) else: status_text = '{} (complete)'.format(humanize_size(state.selected_size)) status_text += ', Ratio: {:.1f}'.format(state.ratio) self._upper_status_label.setText(status_text) self._progress_bar.setValue(floor(state.progress * 1000)) if self.waiting_control_action: status_text = 'Waiting' elif state.paused: status_text = 'Paused' elif state.complete: status_text = 'Uploading to {} of {} peers'.format(state.uploading_peer_count, state.total_peer_count) if state.upload_speed: status_text += ' on {}'.format(humanize_speed(state.upload_speed)) else: status_text = 'Downloading from {} of {} peers'.format( state.downloading_peer_count, state.total_peer_count) if state.download_speed: status_text += ' on {}'.format(humanize_speed(state.download_speed)) eta_seconds = state.eta_seconds if eta_seconds is not None: status_text += ', {} remaining'.format(humanize_time(eta_seconds) if eta_seconds is not None else None) self._lower_status_label.setText(status_text)
def format_status(state: TorrentState, long_format: bool) -> List[str]: lines = [] if long_format: lines.append('Selected: {}/{} files ({}/{} pieces)\n'.format( state.selected_file_count, state.total_file_count, state.selected_piece_count, state.total_piece_count)) lines.append('Directory: {}\n'.format(state.download_dir)) if state.paused: general_status = 'Paused\n' elif state.complete: general_status = 'Uploading\n' else: general_status = 'Downloading\t' lines.append('State: ' + general_status) if not state.paused and not state.complete: eta_seconds = state.eta_seconds lines.append('ETA: {}\n'.format(humanize_time(eta_seconds) if eta_seconds is not None else 'unknown')) lines.append('Download from: {}/{} peers\t'.format(state.downloading_peer_count, state.total_peer_count)) lines.append('Upload to: {}/{} peers\n'.format(state.uploading_peer_count, state.total_peer_count)) lines.append('Download speed: {}\t'.format( humanize_speed(state.download_speed) if state.download_speed is not None else 'unknown')) lines.append('Upload speed: {}\n'.format( humanize_speed(state.upload_speed) if state.upload_speed is not None else 'unknown')) lines.append('Size: {}/{}\t'.format(humanize_size(state.downloaded_size), humanize_size(state.selected_size))) lines.append('Ratio: {:.1f}\n'.format(state.ratio)) progress = state.progress progress_bar = ('#' * floor(progress * PROGRESS_BAR_WIDTH)).ljust(PROGRESS_BAR_WIDTH) lines.append('Progress: {:5.1f}% [{}]\n'.format(floor_to(progress * 100, 1), progress_bar)) return lines
def format_content(torrent_info: TorrentInfo) -> List[str]: download_info = torrent_info.download_info # type: DownloadInfo lines = ['Announce URLs:\n'] for i, tier in enumerate(torrent_info.announce_list): lines.append(INDENT + 'Tier {}: {}\n'.format(i + 1, ', '.join(tier))) total_size_repr = humanize_size(download_info.total_size) if download_info.single_file_mode: lines.append('Content: single file ({})\n'.format(total_size_repr)) else: lines.append('Content: {} files (total {})\n'.format(len(download_info.files), total_size_repr)) for file_info in download_info.files: lines.append(INDENT + '{} ({})\n'.format('/'.join(file_info.path), humanize_size(file_info.length))) return lines
def format_status(state: TorrentState, long_format: bool) -> List[str]: lines = [] if long_format: lines.append('Selected: {}/{} files ({}/{} pieces)\n'.format( state.selected_file_count, state.total_file_count, state.selected_piece_count, state.total_piece_count)) lines.append('Directory: {}\n'.format(state.download_dir)) if state.paused: general_status = 'Paused\n' elif state.complete: general_status = 'Uploading\n' else: general_status = 'Downloading\t' lines.append('State: ' + general_status) if not state.paused and not state.complete: eta_seconds = state.eta_seconds lines.append('ETA: {}\n'.format( humanize_time(eta_seconds ) if eta_seconds is not None else 'unknown')) lines.append('Download from: {}/{} peers\t'.format( state.downloading_peer_count, state.total_peer_count)) # print("^^^^^^^^^^^ ",'Download from: {}/{} peers\t'.format(state.downloading_peer_count, state.total_peer_count),"^^^^^^^^^^^") lines.append('Upload to: {}/{} peers\n'.format( state.uploading_peer_count, state.total_peer_count)) # print("^^^^^^^^^^^ ",'Upload to: {}/{} peers\n'.format(state.uploading_peer_count, state.total_peer_count),"^^^^^^^^^^^") lines.append('Download speed: {}\t'.format( humanize_speed(state.download_speed) if state. download_speed is not None else 'unknown')) lines.append('Upload speed: {}\n'.format( humanize_speed(state.upload_speed) if state. upload_speed is not None else 'unknown')) lines.append('Size: {}/{}\t'.format(humanize_size(state.downloaded_size), humanize_size(state.selected_size))) lines.append('Ratio: {:.1f}\n'.format(state.ratio)) progress = state.progress progress_bar = ( '#' * floor(progress * PROGRESS_BAR_WIDTH)).ljust(PROGRESS_BAR_WIDTH) lines.append('Progress: {:5.1f}% [{}]\n'.format( floor_to(progress * 100, 1), progress_bar)) # print(" ^^^^^^ ",'Progress: {:5.1f}% [{}]\n'.format(floor_to(progress * 100, 1), progress_bar),"^^^^^^^^^^^") return lines
def format_content(torrent_info: TorrentInfo) -> List[str]: download_info = torrent_info.download_info # type: DownloadInfo lines = ['Announce URLs:\n'] for i, tier in enumerate(torrent_info.announce_list): lines.append(INDENT + 'Tier {}: {}\n'.format(i + 1, ', '.join(tier))) total_size_repr = humanize_size(download_info.total_size) if download_info.single_file_mode: lines.append('Content: single file ({})\n'.format(total_size_repr)) else: lines.append('Content: {} files (total {})\n'.format( len(download_info.files), total_size_repr)) for file_info in download_info.files: lines.append(INDENT + '{} ({})\n'.format( '/'.join(file_info.path), humanize_size(file_info.length))) return lines
def __init__(self, parent: QWidget, filename: str, torrent_info: TorrentInfo, control_thread: 'ControlManagerThread'): super().__init__(parent) self._torrent_info = torrent_info download_info = torrent_info.download_info self._control_thread = control_thread self._control = control_thread.control vbox = QVBoxLayout(self) self._download_dir = get_directory(self._control.last_download_dir) vbox.addWidget(QLabel('Download directory:')) vbox.addWidget(self._get_directory_browse_widget()) #tracker lists.. vbox.addWidget(QLabel('Announce URLs:')) url_tree = QTreeWidget() url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) url_tree.header().close() vbox.addWidget(url_tree) for i, tier in enumerate(torrent_info.announce_list): tier_item = QTreeWidgetItem(url_tree) #level 1 urls tier_item.setText(0, 'Tier {}'.format(i + 1)) for url in tier: url_item = QTreeWidgetItem(tier_item) url_item.setText(0, url) url_tree.expandAll() vbox.addWidget(url_tree, 1) file_tree = QTreeWidget() file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) file_tree.setHeaderLabels(('Name', 'Size')) file_tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self._file_items = [] self._traverse_file_tree(download_info.suggested_name, download_info.file_tree, file_tree) file_tree.sortItems(0, Qt.AscendingOrder) file_tree.expandAll() file_tree.itemClicked.connect(self._update_checkboxes) vbox.addWidget(file_tree, 3) self._selection_label = QLabel(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format( len(download_info.files), humanize_size(download_info.total_size))) vbox.addWidget(self._selection_label) self._button_box = QDialogButtonBox(self) self._button_box.setOrientation(Qt.Horizontal) self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._button_box.button(QDialogButtonBox.Ok).clicked.connect(self.submit_torrent) self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(self.close) vbox.addWidget(self._button_box) self.setFixedSize(470, 550) self.setWindowTitle('Adding "{}"'.format(filename))
def __init__(self, parent: QWidget, filename: str, torrent_info: TorrentInfo, control_thread: 'ControlManagerThread'): super().__init__(parent) self._torrent_info = torrent_info download_info = torrent_info.download_info self._control_thread = control_thread self._control = control_thread.control vbox = QVBoxLayout(self) self._download_dir = get_directory(self._control.last_download_dir) vbox.addWidget(QLabel('Download directory:')) vbox.addWidget(self._get_directory_browse_widget()) vbox.addWidget(QLabel('Announce URLs:')) url_tree = QTreeWidget() url_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) url_tree.header().close() vbox.addWidget(url_tree) for i, tier in enumerate(torrent_info.announce_list): tier_item = QTreeWidgetItem(url_tree) tier_item.setText(0, 'Tier {}'.format(i + 1)) for url in tier: url_item = QTreeWidgetItem(tier_item) url_item.setText(0, url) url_tree.expandAll() vbox.addWidget(url_tree, 1) file_tree = QTreeWidget() file_tree.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel) file_tree.setHeaderLabels(('Name', 'Size')) file_tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents) self._file_items = [] self._traverse_file_tree(download_info.suggested_name, download_info.file_tree, file_tree) file_tree.sortItems(0, Qt.AscendingOrder) file_tree.expandAll() file_tree.itemClicked.connect(self._update_checkboxes) vbox.addWidget(file_tree, 3) self._selection_label = QLabel(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format( len(download_info.files), humanize_size(download_info.total_size))) vbox.addWidget(self._selection_label) self._button_box = QDialogButtonBox(self) self._button_box.setOrientation(Qt.Horizontal) self._button_box.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok) self._button_box.button(QDialogButtonBox.Ok).clicked.connect(self.submit_torrent) self._button_box.button(QDialogButtonBox.Cancel).clicked.connect(self.close) vbox.addWidget(self._button_box) self.setFixedSize(450, 550) self.setWindowTitle('Adding "{}"'.format(filename))
def _traverse_file_tree(self, name: str, node: FileTreeNode, parent: QWidget): item = QTreeWidgetItem(parent) item.setCheckState(0, Qt.Checked) item.setText(0, name) if isinstance(node, FileInfo): item.setText(1, humanize_size(node.length)) item.setIcon(0, file_icon) self._file_items.append((node, item)) return item.setIcon(0, directory_icon) for name, child in node.items(): self._traverse_file_tree(name, child, item)
def _update_selection_label(self): selected_file_count = 0 selected_size = 0 for node, item in self._file_items: if item.checkState(0) == Qt.Checked: selected_file_count += 1 selected_size += node.length ok_button = self._button_box.button(QDialogButtonBox.Ok) if not selected_file_count: ok_button.setEnabled(False) self._selection_label.setText('Nothing to download') else: ok_button.setEnabled(True) self._selection_label.setText(TorrentAddingDialog.SELECTION_LABEL_FORMAT.format( selected_file_count, humanize_size(selected_size)))
async def execute(self): prev_unchoked_peers = set() optimistically_unchoked = None for i in itertools.count(): peer_data = self._peer_manager.peer_data alive_peers = list( sorted(peer_data.keys(), key=self.get_peer_upload_rate, reverse=True)) cur_unchoked_peers = set() interested_count = 0 if Uploader.UPLOAD_PEER_COUNT: if i % Uploader.ITERS_PER_OPTIMISTIC_UNCHOKING == 0: if alive_peers: optimistically_unchoked = self._select_optimistically_unchoked( alive_peers) else: optimistically_unchoked = None if optimistically_unchoked is not None and optimistically_unchoked in peer_data: cur_unchoked_peers.add(optimistically_unchoked) if peer_data[ optimistically_unchoked].client.peer_interested: interested_count += 1 for peer in cast(List[Peer], alive_peers): if interested_count == Uploader.UPLOAD_PEER_COUNT: break if peer_data[peer].client.peer_interested: interested_count += 1 cur_unchoked_peers.add(peer) for peer in prev_unchoked_peers - cur_unchoked_peers: if peer in peer_data: peer_data[peer].client.am_choking = True for peer in cur_unchoked_peers: peer_data[peer].client.am_choking = False self._logger.debug( 'now %s peers are unchoked (total_uploaded = %s)', len(cur_unchoked_peers), humanize_size(self._statistics.total_uploaded)) await asyncio.sleep(Uploader.CHOKING_CHANGING_TIME) prev_unchoked_peers = cur_unchoked_peers
async def execute(self): prev_unchoked_peers = set() optimistically_unchoked = None for i in itertools.count(): peer_data = self._peer_manager.peer_data alive_peers = list(sorted(peer_data.keys(), key=self.get_peer_upload_rate, reverse=True)) cur_unchoked_peers = set() interested_count = 0 if Uploader.UPLOAD_PEER_COUNT: if i % Uploader.ITERS_PER_OPTIMISTIC_UNCHOKING == 0: if alive_peers: optimistically_unchoked = self._select_optimistically_unchoked(alive_peers) else: optimistically_unchoked = None if optimistically_unchoked is not None and optimistically_unchoked in peer_data: cur_unchoked_peers.add(optimistically_unchoked) if peer_data[optimistically_unchoked].client.peer_interested: interested_count += 1 for peer in cast(List[Peer], alive_peers): if interested_count == Uploader.UPLOAD_PEER_COUNT: break if peer_data[peer].client.peer_interested: interested_count += 1 cur_unchoked_peers.add(peer) for peer in prev_unchoked_peers - cur_unchoked_peers: if peer in peer_data: peer_data[peer].client.am_choking = True for peer in cur_unchoked_peers: peer_data[peer].client.am_choking = False self._logger.debug('now %s peers are unchoked (total_uploaded = %s)', len(cur_unchoked_peers), humanize_size(self._statistics.total_uploaded)) await asyncio.sleep(Uploader.CHOKING_CHANGING_TIME) prev_unchoked_peers = cur_unchoked_peers