Example #1
0
	def __init__(self, main_window, qsettings_object):
		QueueModel.__init__(self, main_window, qsettings_object, "downloads.xml")
		self.pool = DownloadPool(callback=self.handleProgress)
		main_window.aboutToQuit.connect(self.pool.shutdown)
Example #2
0
class DownloadModel(QueueModel):
	def __init__(self, main_window, qsettings_object):
		QueueModel.__init__(self, main_window, qsettings_object, "downloads.xml")
		self.pool = DownloadPool(callback=self.handleProgress)
		main_window.aboutToQuit.connect(self.pool.shutdown)

	def _init_internal_dict(self):
		# this variant of ElementTreeModel has additional dicts to manage:
		self.progress_bars = {}  # progressbar for each item and package
		self.option_elements = {}  # selected option element for easy access
		QueueModel._init_internal_dict(self)

	def _add_to_internal_dict(self, element, parent, num_row):
		QueueModel._add_to_internal_dict(self, element, parent, num_row)
		if element.tag == "item":
			# TODO: check if file exists and if so, initialize percentage
			progressbar = QProgressBar()
			progressbar.setValue(0)
			self.progress_bars[element] = progressbar
			selected_extension = element.get("selected")
			if selected_extension is None:
				element.attrib["status"] = "Error: No Extension selected"
				return
			selected_format = element.find("format[@extension='%s']" % selected_extension)
			if selected_format is None:
				element.attrib["status"] = "Error: No Quality selected"
				return
			selected_quality = selected_format.get("selected")
			option = element.find("format[@extension='%s']/option[@quality='%s']" % (selected_extension, selected_quality))
			self.option_elements[element] = option
			# fill remaining filename template, extension and quality shall not change within DownloadModel
			mapping = dict(title=element.get("title"), url=element.get("url"), host=element.get("host"),
										 extension=selected_extension, quality=selected_quality)
			element.attrib["filename"] = fill_filename_template(element.attrib["filename"], mapping)

	def data(self, index, role):
		if index.isValid() and role in (Qt.DisplayRole, Qt.EditRole):
			# handle extension, quality and progress differently here
			element = index.internalPointer()
			num_col = index.column()
			if element.tag == 'item':
				if num_col == 8:
					return element.attrib.get("selected")
				elif num_col == 9:
					# data() is called VERY often, even when the column ain't visible -> avoid xpath queries here
					option = self.option_elements[element]
					return option.attrib.get("quality")
			return QueueModel.data(self, index, role)

	def start(self):
		for item in self._root.findall("item[@status='Queued']"):
			item.attrib["status"] = "Progressing"  # TODO: self.dataChanged.emit(index, index)
			option = self.option_elements[item]
			# self.pool.apply_async(func=download, args=args)
			self.pool.add_task(item.get("url"), item.get("path"), item.get("filename"),
												 option.get("download_url"), option.get("player_url"),
												 option.get("plugin_specific"))

	def pause(self):
		pass

	def handleProgress(self, url, result_dict, failed, finished):
		item = self._root.find("item[@url='%s']" % url)
		if item is None:
			# TODO: item might have gotten deleted in the GUI, send abort signal!
			return
		progressbar = self.progress_bars[item]
		print(result_dict)
		if result_dict["status"] == "downloading":
			# TODO: Bandwidth
			percentage = result_dict.get("downloaded_bytes", 0) / result_dict.get("total_bytes", 1) * 100
			progressbar.setValue(percentage)
		elif result_dict["status"] == "finished":
			item.attrib["status"] = "Ready"  # TODO: datachanged()
			progressbar.setValue(100)