diff options
Diffstat (limited to 'pyLoadQtGui.py')
-rw-r--r-- | pyLoadQtGui.py | 397 |
1 files changed, 362 insertions, 35 deletions
diff --git a/pyLoadQtGui.py b/pyLoadQtGui.py index 94fd33aa5..ad4fd1d0b 100644 --- a/pyLoadQtGui.py +++ b/pyLoadQtGui.py @@ -103,12 +103,22 @@ class main(QObject): sub.setData(0, Qt.DisplayRole, QVariant(info["filename"])) sub.setData(1, Qt.DisplayRole, QVariant(info["status_type"])) self.mainWindow.tabs["queue"]["treewidget"].addTopLevelItem(item) - """ + model = QueueModel(self.connector) model.setView(self.mainWindow.tabs["queue"]["view"]) self.mainWindow.tabs["queue"]["view"].setModel(model) self.mainWindow.tabs["queue"]["view"].setup() model.startLoop() + """ + self.mainWindow.tabs["queue"]["view"].setColumnCount(3) + self.mainWindow.tabs["queue"]["view"].setHeaderLabels(["Name", "Status", "Fortschritt"]) + self.mainWindow.tabs["queue"]["view"].setColumnWidth(0, 300) + self.mainWindow.tabs["queue"]["view"].setColumnWidth(1, 100) + self.mainWindow.tabs["queue"]["view"].setColumnWidth(2, 100) + #delegate = QueueProgressBarDelegate(self) + #self.mainWindow.tabs["queue"]["view"].setItemDelegateForColumn(2, delegate) + self.queue = Queue(self.mainWindow.tabs["queue"]["view"], self.connector) + self.queue.start() class connector(QThread): def __init__(self): @@ -116,7 +126,7 @@ class connector(QThread): init thread """ QThread.__init__(self) - self.lock = QMutex() + self.mutex = QMutex() self.running = True self.proxy = None @@ -148,43 +158,71 @@ class connector(QThread): """ grab links from collector and return the ids """ - return self.proxy.get_collector_files() + self.mutex.lock() + try: + return self.proxy.get_collector_files() + finally: + self.mutex.unlock() def getPackageCollector(self): """ grab packages from collector and return the data """ - return self.proxy.get_collector_packages() + self.mutex.lock() + try: + return self.proxy.get_collector_packages() + finally: + self.mutex.unlock() def getLinkInfo(self, id): """ grab file info for the given id and return it """ - return self.proxy.get_file_info(id) + self.mutex.lock() + try: + return self.proxy.get_file_info(id) + finally: + self.mutex.unlock() def getPackageInfo(self, id): """ grab package info for the given id and return it """ - return self.proxy.get_package_data(id) + self.mutex.lock() + try: + return self.proxy.get_package_data(id) + finally: + self.mutex.unlock() def getPackageQueue(self): """ grab queue return the data """ - return self.proxy.get_queue() + self.mutex.lock() + try: + return self.proxy.get_queue() + finally: + self.mutex.unlock() def getPackageFiles(self, id): """ grab package files and return ids """ - return self.proxy.get_package_files(id) + self.mutex.lock() + try: + return self.proxy.get_package_files(id) + finally: + self.mutex.unlock() def getDownloadQueue(self): """ grab files that are currently downloading and return info """ - return self.proxy.status_downloads() + self.mutex.lock() + try: + return self.proxy.status_downloads() + finally: + self.mutex.unlock() class mainWindow(QMainWindow): def __init__(self): @@ -244,7 +282,7 @@ class mainWindow(QMainWindow): #queue self.tabs["queue"]["l"] = QGridLayout() self.tabs["queue"]["w"].setLayout(self.tabs["queue"]["l"]) - self.tabs["queue"]["view"] = QueueView() + self.tabs["queue"]["view"] = QTreeWidget() self.tabs["queue"]["l"].addWidget(self.tabs["queue"]["view"]) #collector_packages @@ -259,46 +297,292 @@ class mainWindow(QMainWindow): self.tabs["collector_links"]["listwidget"] = QListWidget() self.tabs["collector_links"]["l"].addWidget(self.tabs["collector_links"]["listwidget"]) +class Queue(QThread): + def __init__(self, view, connector): + QThread.__init__(self) + self.view = view + self.connector = connector + self.statusMap = { + "finished": 0, + "checking": 1, + "waiting": 2, + "reconnected": 3, + "downloading": 4, + "failed": 5, + "aborted": 6, + } + self.statusMapReverse = dict((v,k) for k, v in self.statusMap.iteritems()) + self.queue = [] + self.interval = 2 + self.running = True + self.mutex = QMutex() + + def run(self): + while self.running: + self.update() + sleep(self.interval) + + def update(self): + locker = QMutexLocker(self.mutex) + packs = self.connector.getPackageQueue() + downloading = self.connector.getDownloadQueue() + for data in packs: + pack = self.getPack(data["id"]) + if not pack: + pack = self.QueuePack(self) + pack.setData(data) + self.addPack(data["id"], pack) + files = self.connector.getPackageFiles(data["id"]) + for fid in files: + info = self.connector.getLinkInfo(fid) + child = pack.getChild(fid) + if not child: + child = self.QueueFile(self, pack) + child.setData(info) + pack.addChild(fid, child) + + def addPack(self, pid, newPack): + pos = None + try: + for k, pack in enumerate(self.queue): + if pack.getData()["id"] == pid: + pos = k + break + if pos == None: + raise Exception() + self.queue[pos] = newPack + except: + self.queue.append(newPack) + pos = self.queue.index(newPack) + item = self.view.topLevelItem(pos) + if not item: + item = QTreeWidgetItem() + self.view.insertTopLevelItem(pos, item) + item.setData(0, Qt.DisplayRole, QVariant(newPack.getData()["package_name"])) + status = -1 + for child in newPack.getChildren(): + if self.statusMap.has_key(child.data["status_type"]) and self.statusMap[child.data["status_type"]] > status: + status = self.statusMap[child.data["status_type"]] + if status >= 0: + item.setData(1, Qt.DisplayRole, QVariant(self.statusMapReverse[status])) + item.setData(0, Qt.UserRole, QVariant(pid)) + + def getPack(self, pid): + for k, pack in enumerate(self.queue): + if pack.getData()["id"] == pid: + return pack + return None + + class QueuePack(): + def __init__(self, queue): + self.queue = queue + self.data = [] + self.children = [] + + def addChild(self, cid, newChild): + pos = None + try: + for k, child in enumerate(self.getChildren()): + if child.getData()["id"] == cid: + pos = k + break + if pos == None: + raise Exception() + self.children[pos] = newChild + except: + self.children.append(newChild) + pos = self.children.index(newChild) + ppos = self.queue.queue.index(self) + parent = self.queue.view.topLevelItem(ppos) + item = parent.child(pos) + if not item: + item = QTreeWidgetItem() + parent.insertChild(pos, item) + item.setData(0, Qt.DisplayRole, QVariant(newChild.getData()["filename"])) + item.setData(1, Qt.DisplayRole, QVariant(newChild.getData()["status_type"])) + item.setData(0, Qt.UserRole, QVariant(cid)) + + def getChildren(self): + return self.children + + def getChild(self, cid): + try: + return self.children[cid] + except: + return None + + def hasChildren(self, data): + return (len(self.children) > 0) + + def setData(self, data): + self.data = data + + def getData(self): + return self.data + + class QueueFile(): + def __init__(self, queue, pack): + self.queue = queue + self.pack = pack + + def getData(self): + return self.data + + def setData(self, data): + self.data = data + + def getPack(self): + return self.pack + + """ + def data(self, index, role=Qt.DisplayRole): + locker = QMutexLocker(self.mutex) + if not index.isValid(): + return QVariant() + if role == Qt.DisplayRole: + q = self.nodeFromIndex(index) + if index.column() == 0: + if isinstance(q, QueuePack): + return QVariant(q.data["package_name"]) + else: + return QVariant(q.data["filename"]) + elif index.column() == 1: + if isinstance(q, QueueFile): + return QVariant(q.data["status_type"]) + else: + status = 0 + for child in q.getChildren(): + if self.statusMap.has_key(child.data["status_type"]) and self.statusMap[child.data["status_type"]] > status: + status = self.statusMap[child.data["status_type"]] + return QVariant(self.statusMapReverse[status]) + return QVariant() + + + packs = self.connector.getPackageQueue() + for data in packs: + item = QTreeWidgetItem() + item.setData(0, Qt.UserRole, QVariant(data)) + item.setData(0, Qt.DisplayRole, QVariant(data["package_name"])) + files = self.connector.getPackageFiles(data["id"]) + for id in files: + info = self.connector.getLinkInfo(id) + sub = QTreeWidgetItem(item) + sub.setData(0, Qt.DisplayRole, QVariant(info["filename"])) + sub.setData(1, Qt.DisplayRole, QVariant(info["status_type"])) + self.mainWindow.tabs["queue"]["treewidget"].addTopLevelItem(item) + + + self.mutex.lock() + packs = self.connector.getPackageQueue() + self.downloading = self.connector.getDownloadQueue() + previous = None + for data in packs: + pos = self._inQueue(data["id"]) + if not type(pos) == int: + pack = QueuePack(data) + else: + pack = QueuePack(data) + #self.mutex.lock() + self.queue[pos] = pack + #self.mutex.unlock() + if not type(pos) == int: + self.mutex.unlock() + self._insertPack(pack, previous) + self.mutex.lock() + files = self.connector.getPackageFiles(data["id"]) + pos = self._inQueue(data["id"]) + for fid in files: + info = self.connector.getLinkInfo(fid) + qFile = QueueFile(info, pack) + if type(pos) == int: + self.mutex.unlock() + index = self.index(pos, 0) + pack.addChild(qFile, self, index) + self.mutex.lock() + previous = pack.getID() + self.mutex.unlock() + + + + + + + class QueueFile(): def __init__(self, data, pack): + self.mutex = QMutex() + self.mutex.lock() self.pack = pack + self.mutex.unlock() self.update(data) def update(self, data): + self.mutex.lock() self.data = data + self.mutex.unlock() def getID(self): - return self.data["id"] + self.mutex.lock() + id = self.data["id"] + self.mutex.unlock() + return id class QueuePack(): def __init__(self, data): + self.mutex = QMutex() + self.mutex.lock() self.data = data self.children = [] + self.mutex.unlock() def update(self, data): + self.mutex.lock() self.data = data + self.mutex.unlock() def addChild(self, NewQFile, model, index): + self.mutex.lock() for k, QFile in enumerate(self.children): if QFile.getID() == NewQFile.getID(): QFile.update(NewQFile.data) - #model.emit(SIGNAL("dataChanged(const QModelIndex topLeft, const QModelIndex bottomRight)"), model.index(k, 0, index), model.index(k, 2, index)) + #model.emit(SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), model.index(k, 0, index), model.index(k, 2, index)) return + self.mutex.unlock() model.beginInsertRows(index, len(self.children), len(self.children)+1) + self.mutex.lock() self.children.append(NewQFile) + self.mutex.unlock() model.endInsertRows() def getChildren(self): - return self.children + self.mutex.lock() + children = self.children + self.mutex.unlock() + return children def getID(self): - return self.data["id"] + self.mutex.lock() + id = self.data["id"] + self.mutex.unlock() + return id + +class MyLock(QMutex): + def __init__(self): + QMutex.__init__(self) + + def lock(self): + QMutex.lock(self) + print "locked" + + def unlock(self): + QMutex.unlock(self) + print "unlocked" class QueueModel(QAbstractItemModel): def __init__(self, connector): QAbstractItemModel.__init__(self) - self.mutex = QMutex() - self.mutex.lock() + self.mutex = MyLock() + #self.mutex.lock() self.connector = connector self.queue = [] self.downloading = [] @@ -315,15 +599,20 @@ class QueueModel(QAbstractItemModel): self.cols = 3 self.interval = 1 self.view = None - self.mutex.unlock() + #self.mutex.unlock() self.update() self.loop = self.Loop(self) + self.connect(self, SIGNAL("updateData()"), self.update) def setView(self, view): + self.mutex.lock() self.view = view + self.mutex.unlock() def _update(self): + self.mutex.lock() packs = self.connector.getPackageQueue() + self.downloading = self.connector.getDownloadQueue() previous = None for data in packs: pos = self._inQueue(data["id"]) @@ -331,24 +620,38 @@ class QueueModel(QAbstractItemModel): pack = QueuePack(data) else: pack = QueuePack(data) + #self.mutex.lock() self.queue[pos] = pack + #self.mutex.unlock() if not type(pos) == int: + self.mutex.unlock() self._insertPack(pack, previous) + self.mutex.lock() files = self.connector.getPackageFiles(data["id"]) pos = self._inQueue(data["id"]) for fid in files: info = self.connector.getLinkInfo(fid) qFile = QueueFile(info, pack) if type(pos) == int: - pack.addChild(qFile, self, self.index(pos, 0)) + self.mutex.unlock() + index = self.index(pos, 0) + pack.addChild(qFile, self, index) + self.mutex.lock() previous = pack.getID() + self.mutex.unlock() def update(self): - locker = QMutexLocker(self.mutex) + #locker = QMutexLocker(self.mutex) + print "updating" + #self.mutex.lock() + #locker.unlock() self._update() - self.downloading = self.connector.getDownloadQueue() + self.emit(SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), self.index(0, 0), self.index(self.rowCount()-1, 2)) + #locker.relock() + #self.mutex.unlock() #if self.view: # self.view.emit(SIGNAL("update()")) + print "done" def startLoop(self): self.loop.start() @@ -360,25 +663,35 @@ class QueueModel(QAbstractItemModel): return False def _insertPack(self, newpack, prevID): + self.mutex.lock() ck = 0 for k, pack in enumerate(self.queue): ck = k if pack.getID() == prevID: break + self.mutex.unlock() + #self.mutex.unlock() self.beginInsertRows(QModelIndex(),ck+1, ck+2) + self.mutex.lock() self.queue.insert(ck+1, newpack) + self.mutex.unlock() self.endInsertRows() + #self.mutex.lock() def index(self, row, column, parent=QModelIndex()): + self.mutex.lock() if parent == QModelIndex(): pointer = self.queue[row] index = self.createIndex(row, column, pointer) elif parent.isValid(): q = self.nodeFromIndex(parent) + #self.mutex.lock() pointer = q.getChildren()[row] + #self.mutex.unlock() index = self.createIndex(row, column, pointer) else: index = QModelIndex() + self.mutex.unlock() return index def nodeFromIndex(self, index): @@ -388,6 +701,7 @@ class QueueModel(QAbstractItemModel): return None def parent(self, index): + locker = QMutexLocker(self.mutex) if index == QModelIndex(): return QModelIndex() if index.isValid(): @@ -402,9 +716,11 @@ class QueueModel(QAbstractItemModel): return QModelIndex() def rowCount(self, parent=QModelIndex()): + locker = QMutexLocker(self.mutex) if parent == QModelIndex(): #return package count - return len(self.queue) + qlen = len(self.queue) + return qlen else: if parent.isValid(): #index is valid @@ -412,7 +728,8 @@ class QueueModel(QAbstractItemModel): if isinstance(q, QueuePack): #index points to a package #return len of children - return len(q.getChildren()) + clen = len(q.getChildren()) + return clen else: #index is invalid return False @@ -420,9 +737,12 @@ class QueueModel(QAbstractItemModel): return 0 def columnCount(self, parent=QModelIndex()): + #self.mutex.lock() return self.cols + #self.mutex.unlock() def data(self, index, role=Qt.DisplayRole): + locker = QMutexLocker(self.mutex) if not index.isValid(): return QVariant() if role == Qt.DisplayRole: @@ -444,8 +764,11 @@ class QueueModel(QAbstractItemModel): return QVariant() def hasChildren(self, parent=QModelIndex()): + self.mutex.lock() if not parent.isValid(): + self.mutex.unlock() return True + self.mutex.unlock() return (self.rowCount(parent) > 0) def canFetchMore(self, parent): @@ -462,6 +785,7 @@ class QueueModel(QAbstractItemModel): return QVariant() def getProgress(self, index): + locker = QMutexLocker(self.mutex) q = self.nodeFromIndex(index) if isinstance(q, QueueFile): for d in self.downloading: @@ -492,15 +816,17 @@ class QueueModel(QAbstractItemModel): return None class Loop(QThread): - def __init__(self, module): + def __init__(self, model): QThread.__init__(self) - self.module = module + self.model = model self.running = True def run(self): while self.running: - sleep(self.module.interval) - self.module.update() + sleep(self.model.interval) + #self.model.update() + #print "emit" + self.model.emit(SIGNAL("updateData()")) class QueueView(QTreeView): def __init__(self): @@ -512,6 +838,7 @@ class QueueView(QTreeView): self.setColumnWidth(2, 100) delegate = QueueProgressBarDelegate(self) self.setItemDelegateForColumn(2, delegate) + """ class QueueProgressBarDelegate(QItemDelegate): def __init__(self, parent): @@ -524,16 +851,16 @@ class QueueProgressBarDelegate(QItemDelegate): if progress == None: QItemDelegate.paint(self, painter, option, index) return - opts = QStyleOptionProgressBarV2()
- opts.maximum = 100
- opts.minimum = 0
- opts.progress = progress
- opts.rect = option.rect
- opts.rect.setRight(option.rect.right()-1)
- opts.rect.setHeight(option.rect.height()-1)
- opts.textVisible = True
+ opts = QStyleOptionProgressBarV2() + opts.maximum = 100 + opts.minimum = 0 + opts.progress = progress + opts.rect = option.rect + opts.rect.setRight(option.rect.right()-1) + opts.rect.setHeight(option.rect.height()-1) + opts.textVisible = True opts.textAlignment = Qt.AlignCenter - opts.text = QString.number(opts.progress) + "%"
+ opts.text = QString.number(opts.progress) + "%" QApplication.style().drawControl(QStyle.CE_ProgressBar, opts, painter) return QItemDelegate.paint(painter, option, index) |