def clear_download_forced(self, widget): """ Clears a download regardless of its status, and updates DB. :param widget: :return: """ widget.cleared = True DownloadViewListener.static_self.updateDownloadTile.emit( DDBDownloadTile(widget)) self.logger.info("Forcibly removing widget for video: {} - {}".format( widget.video.title, widget.__dict__)) try: sip.delete(widget) self.widgets.remove(widget) except RuntimeError as re_exc: if hasattr(self, 'video'): cur_vid = self.video else: cur_vid = "Non-existent video (nullptr)" if str( re_exc ) == "wrapped C/C++ object of type DownloadTile has been deleted": self.logger.exception( "Attempted to delete a nullptr widget: {}".format(cur_vid), exc_info=re_exc) else: self.logger.exception( "Unexpected RuntimeError on deleting widget: {}".format( cur_vid), exc_info=re_exc)
def update_progress(self, event): self.last_event = event if not self.started_date: self.started_date = datetime.utcnow() if "status" in event: if event["status"] == "finished": if not self.video_downloaded: self.video_downloaded = True self.status_value.setText("Finished downloading video") else: # It's not really finished until it calls finished_download() self.status_value.setText("Postprocessing...") elif "downloading" == event["status"]: if self.paused: self.status_value.setText("Download paused") elif self.failed: self.status_value.setText("Download FAILED!") else: if self.video_downloaded: self.status_value.setText("Downloading audio") else: self.status_value.setText("Downloading video") else: self.status_value.setText(event["status"]) # Started/Finished on info self.set_started_finished_on_label() if "_eta_str" in event: self.most_common_eta(event["_eta_str"]) self.eta_value.setText("{} (avg: {})".format(event["_eta_str"], self.common_eta_str)) if "_speed_str" in event: self.calc_avg_speed(event["_speed_str"]) self.speed_value.setText("{} (avg: {}/s)".format(event["_speed_str"], self.avg_speed_str)) if "_total_bytes_str" in event: self.total_size_value.setText(event["_total_bytes_str"]) if "total_bytes" in event or "total_bytes_estimate" in event: if "total_bytes" not in event: event["total_bytes"] = event["total_bytes_estimate"] if self.total_bytes == int(event["total_bytes"]): pass else: self.logger.debug("Downloading new item: {}".format(event)) self.total_bytes = int(event["total_bytes"]) # Store total bytes for video and audio track in a safe place if not self.video_downloaded: self.total_bytes_video = self.total_bytes self.total_bytes_audio = self.total_bytes # self.progress_bar.setMaximum(int(event["total_bytes"])) else: self.logger.warning("total_bytes not in: {}".format(event)) if "downloaded_bytes" in event and self.total_bytes: self.progress_bar.setValue(int(int((event["downloaded_bytes"] / self.total_bytes) * 1000))) percentage_downloaded = int((event["downloaded_bytes"] / self.total_bytes) * 100) if percentage_downloaded > self.percentage_downloaded: self.percentage_downloaded = percentage_downloaded DownloadViewListener.static_self.updateDownloadTileEvent.emit(DDBDownloadTile(self)) else: if "downloaded_bytes" not in event: self.logger.warning("downloaded_bytes not in: {}".format(event)) if "_percent_str" in event: self.progress_bar.setFormat(event["_percent_str"])
def new_download(self, download_progress_listener): self.logger.info("New download signal received: {}".format( download_progress_listener.__dict__)) widget = DownloadTile(self, download_progress_listener) DownloadHandler.static_self.newDownloadTile.emit( DDBDownloadTile(widget)) self.widgets.append(widget) self.sane_layout.addWidget(widget)
def new_download(self, download_progress_listener, widget=None): if not widget: self.logger.info("New download signal received: {}".format( download_progress_listener.__dict__)) widget = DownloadTile(self, download_progress_listener) DownloadViewListener.static_self.newDownloadTile.emit( DDBDownloadTile(widget)) self.widgets.append(widget) self.sane_layout.addWidget(widget) else: self.logger.info("New download retry signal " "received for existing widget: {}".format( download_progress_listener.__dict__)) widget.retry(download_progress_listener)
def update_widgets(self, d_db_download_til_list): self.logger.info( "Adding loaded downloads: {}".format(d_db_download_til_list)) for db_download_tile in d_db_download_til_list: if db_download_tile.video: widget = DownloadTile(self, db_download_tile.progress_listener, db_download_tile=db_download_tile) DownloadHandler.static_self.newDownloadTile.emit( DDBDownloadTile(widget)) self.widgets.append(widget) self.sane_layout.addWidget(widget) else: self.logger.warning( "Download tile without video, grabbed from db: {}".format( db_download_tile.__dict__))
def clear_downloads(self): widgets_to_delete = [] for widget in self.widgets: if widget.finished: widget.cleared = True DownloadHandler.static_self.updateDownloadTile.emit( DDBDownloadTile(widget)) widgets_to_delete.append(widget) else: self.logger.debug("Widget not finished: {}".format( widget.__dict__)) while widgets_to_delete: widget = widgets_to_delete.pop() self.logger.info("Removing widget for video: {} - {}".format( widget.video.title, widget.__dict__)) sip.delete(widget) self.widgets.remove(widget)
def finished_download(self): self.finished = True self.progress_bar.setValue(1000) self.progress_bar.setFormat("100.0%") self.status_value.setText("Finished") self.eta_value.setText("") self.speed_value.setText("Was {}".format(self.speed_value.text())) self.finished_date = datetime.utcnow() self.set_started_finished_on_label() try: combined_size = self.total_bytes_video + self.total_bytes_audio self.total_size_value.setText(self.determine_si_unit(combined_size)) except TypeError as te_exc: self.logger.error("A TypeError exception occurred while combining video+audio track sizes", exc_info=te_exc) self.total_size_value.setText("BUG: GitHub Issue #28") self.progress_bar.finish() DownloadViewListener.static_self.updateDownloadTile.emit(DDBDownloadTile(self))
def update_progress(self, event): self.last_event = event # print(format(event)) if "status" in event: if event["status"] == "finished": if not self.video_downloaded: self.video_downloaded = True self.status_value.setText("Finished downloading video") else: self.status_value.setText("Finished") elif "downloading" == event["status"]: if self.video_downloaded: self.status_value.setText("Downloading audio") else: self.status_value.setText("Downloading video") else: self.status_value.setText(event["status"]) if "_eta_str" in event: self.eta_value.setText(event["_eta_str"]) if "_speed_str" in event: self.speed_value.setText(event["_speed_str"]) if "_total_bytes_str" in event: self.total_size_value.setText(event["_total_bytes_str"]) if "total_bytes" in event or "total_bytes_estimate" in event: if "total_bytes" not in event: event["total_bytes"] = event["total_bytes_estimate"] if self.total_bytes == int(event["total_bytes"]): pass else: self.logger.debug("Downloading new item: {}".format(event)) self.total_bytes = int(event["total_bytes"]) # self.progress_bar.setMaximum(int(event["total_bytes"])) else: self.logger.warning("total_bytes not in: {}".format(event)) if "downloaded_bytes" in event and self.total_bytes: self.progress_bar.setValue(int(int((event["downloaded_bytes"] / self.total_bytes) * 1000))) percentage_downloaded = int((event["downloaded_bytes"] / self.total_bytes) * 100) if percentage_downloaded > self.percentage_downloaded: self.percentage_downloaded = percentage_downloaded DownloadHandler.static_self.updateDownloadTileEvent.emit(DDBDownloadTile(self)) else: if not "downloaded_bytes" in event: self.logger.warning("downloaded_bytes not in: {}".format(event)) if "_percent_str" in event: self.progress_bar.setFormat(event["_percent_str"])
def failed_download(self, e): """ How to handle a failed download. Called by PyQtSignal connected to the download listener. :return: """ human_readable_error = self.humanize_dl_error(e) self.logger.error("Failed download: {}".format(self.video)) self.failed = True self.status_value.setText("FAILED: {}".format(human_readable_error)) self.eta_value.setText("") self.speed_value.setText("Was {}".format(self.speed_value.text())) self.finished_date = datetime.utcnow() self.set_started_finished_on_label() self.download_progress_listener.threading_event.clear() self.progress_bar.fail() DownloadViewListener.static_self.updateDownloadTile.emit(DDBDownloadTile(self))
def clear_finished_downloads(self): """ Clears all finished downloads from the list and updated DB. :return: """ widgets_to_delete = [] for widget in self.widgets: if widget.finished: widget.cleared = True DownloadViewListener.static_self.updateDownloadTile.emit( DDBDownloadTile(widget)) widgets_to_delete.append(widget) while widgets_to_delete: widget = widgets_to_delete.pop() self.logger.info("Removing widget for video: {} - {}".format( widget.video.title, widget.__dict__)) sip.delete(widget) self.widgets.remove(widget)
def load_db_download_tiles(self): db_result = db_session.query(DBDownloadTile).filter( DBDownloadTile.cleared == false()).all() detached_db_result = DDBDownloadTile.list_detach(db_result) use_youtube_dl = read_config('Youtube-dl', 'use_youtube_dl') download_finished_signals = [ static_listeners.STATIC_GRID_VIEW_LISTENER.downloadFinished ] for tile in detached_db_result: if use_youtube_dl and not tile.finished: self.logger.info( "Starting paused in progress download for: {}".format( tile.video.__dict__)) tile.progress_listener = \ DownloadHandler.download_using_youtube_dl(tile.video, youtube_dl_finished_listener=download_finished_signals, wait=True) self.dbDownloadTiles.emit(detached_db_result)
def finished_download(self): self.finished = True self.progress_bar.setValue(1000) self.progress_bar.setFormat("100.0%") self.status_value.setText("Finished") DownloadHandler.static_self.updateDownloadTile.emit(DDBDownloadTile(self))