From 20f7c0e65607f2fb8607ed0e5e96181a36be76ca Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 21 Dec 2009 14:24:51 +0100 Subject: new update threads, link dock works now --- module/gui/Collector.py | 210 ++++++++++++++++++++++++++++++++++++++++++++++ module/gui/LinkDock.py | 53 ++++++++++++ module/gui/MainWindow.py | 15 ++-- module/gui/PackageDock.py | 49 +++++++++++ module/gui/connector.py | 10 +++ pyLoadCore.py | 6 +- pyLoadGui.py | 49 +++++------ 7 files changed, 356 insertions(+), 36 deletions(-) create mode 100644 module/gui/Collector.py create mode 100644 module/gui/LinkDock.py create mode 100644 module/gui/PackageDock.py diff --git a/module/gui/Collector.py b/module/gui/Collector.py new file mode 100644 index 000000000..0dbccab1f --- /dev/null +++ b/module/gui/Collector.py @@ -0,0 +1,210 @@ +# -*- coding: utf-8 -*- +""" + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . + + @author: mkaay +""" + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +from time import sleep + +class PackageCollector(QThread): + def __init__(self, view, connector): + QThread.__init__(self) + self.view = view + self.connector = connector + self.collector = [] + self.interval = 2 + self.running = True + self.mutex = QMutex() + + def run(self): + while self.running: + self.update() + sleep(self.interval) + + def stop(self): + self.running = False + + def update(self): + locker = QMutexLocker(self.mutex) + packs = self.connector.getPackageCollector() + for data in packs: + pack = self.getPack(data["id"]) + if not pack: + pack = self.PackageCollectorPack(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.PackageCollectorFile(self, pack) + child.setData(info) + pack.addChild(fid, child) + + def addPack(self, pid, newPack): + pos = None + try: + for k, pack in enumerate(self.collector): + if pack.getData()["id"] == pid: + pos = k + break + if pos == None: + raise Exception() + self.collector[pos] = newPack + except: + self.collector.append(newPack) + pos = self.collector.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"])) + item.setData(0, Qt.UserRole, QVariant(pid)) + + def getPack(self, pid): + for k, pack in enumerate(self.collector): + if pack.getData()["id"] == pid: + return pack + return None + + class PackageCollectorPack(): + def __init__(self, collector): + self.collector = collector + 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) + status = "%s (%s)" % (newChild.getData()["status_type"], newChild.getData()["plugin"]) + item.setData(0, Qt.DisplayRole, QVariant(newChild.getData()["filename"])) + 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 PackageCollectorFile(): + def __init__(self, collector, pack): + self.collector = collector + self.pack = pack + + def getData(self): + return self.data + + def setData(self, data): + self.data = data + + def getPack(self): + return self.pack + +class LinkCollector(QThread): + def __init__(self, view, connector): + QThread.__init__(self) + self.view = view + self.connector = connector + self.collector = [] + self.interval = 2 + self.running = True + self.mutex = QMutex() + + def run(self): + while self.running: + self.update() + sleep(self.interval) + + def stop(self): + self.running = False + + def update(self): + locker = QMutexLocker(self.mutex) + ids = self.connector.getLinkCollector() + for id in ids: + data = self.connector.getLinkInfo(id) + file = self.getFile(id) + if not file: + file = self.LinkCollectorFile(self) + file.setData(data) + self.addFile(id, file) + + def addFile(self, pid, newFile): + pos = None + try: + for k, file in enumerate(self.collector): + if file.getData()["id"] == pid: + pos = k + break + if pos == None: + raise Exception() + self.collector[pos] = newFile + except: + self.collector.append(newFile) + pos = self.collector.index(newFile) + item = self.view.topLevelItem(pos) + if not item: + item = QTreeWidgetItem() + self.view.insertTopLevelItem(pos, item) + item.setData(0, Qt.DisplayRole, QVariant(newFile.getData()["filename"])) + item.setData(0, Qt.UserRole, QVariant(pid)) + + def getFile(self, pid): + for k, file in enumerate(self.collector): + if file.getData()["id"] == pid: + return file + return None + + class LinkCollectorFile(): + def __init__(self, collector): + self.collector = collector + + def getData(self): + return self.data + + def setData(self, data): + self.data = data diff --git a/module/gui/LinkDock.py b/module/gui/LinkDock.py new file mode 100644 index 000000000..01a0cc193 --- /dev/null +++ b/module/gui/LinkDock.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . + + @author: mkaay +""" + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +class NewLinkDock(QDockWidget): + def __init__(self): + QDockWidget.__init__(self, "New Links") + self.widget = NewLinkWindow(self) + self.setWidget(self.widget) + self.setAllowedAreas(Qt.RightDockWidgetArea|Qt.LeftDockWidgetArea) + self.hide() + + def slotDone(self): + text = str(self.widget.box.toPlainText()) + lines = text.splitlines() + self.emit(SIGNAL("done"), lines) + self.widget.box.clear() + self.hide() + +class NewLinkWindow(QWidget): + def __init__(self, dock): + QWidget.__init__(self) + self.dock = dock + self.setLayout(QVBoxLayout()) + layout = self.layout() + + boxLabel = QLabel("Paste URLs here:") + self.box = QTextEdit() + + save = QPushButton("Add") + + layout.addWidget(boxLabel) + layout.addWidget(self.box) + layout.addWidget(save) + + self.connect(save, SIGNAL("clicked()"), self.dock.slotDone) diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 9c972dea1..ccca6b697 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -33,10 +33,12 @@ class MainWindow(QMainWindow): self.setWindowIcon(QIcon("icons/logo.png")) self.resize(750,500) + #init docks self.newPackDock = NewPackageDock() self.addDockWidget(Qt.RightDockWidgetArea, self.newPackDock) self.newLinkDock = NewLinkDock() self.addDockWidget(Qt.RightDockWidgetArea, self.newLinkDock) + self.connect(self.newLinkDock, SIGNAL("done"), self.slotAddLinks) #central widget, layout self.masterlayout = QVBoxLayout() @@ -104,8 +106,8 @@ class MainWindow(QMainWindow): packageAction = self.addMenu.addAction("Package") linkAction = self.addMenu.addAction("Links") self.connect(self.actions["add"], SIGNAL("triggered()"), self.slotAdd) - self.connect(packageAction, SIGNAL("triggered()"), self.slotAddPackage) - self.connect(linkAction, SIGNAL("triggered()"), self.slotAddLinks) + self.connect(packageAction, SIGNAL("triggered()"), self.slotShowAddPackage) + self.connect(linkAction, SIGNAL("triggered()"), self.slotShowAddLinks) def init_tabs(self): """ @@ -125,7 +127,7 @@ class MainWindow(QMainWindow): self.tabs["collector"]["l"] = QGridLayout() self.tabs["collector"]["w"].setLayout(self.tabs["collector"]["l"]) self.tabs["collector"]["package_view"] = QTreeWidget() - self.tabs["collector"]["link_view"] = QListWidget() + self.tabs["collector"]["link_view"] = QTreeWidget() groupPackage.layout().addWidget(self.tabs["collector"]["package_view"]) groupLinks.layout().addWidget(self.tabs["collector"]["link_view"]) self.tabs["collector"]["l"].addWidget(groupPackage, 0, 0) @@ -140,13 +142,16 @@ class MainWindow(QMainWindow): def slotAdd(self): self.addMenu.exec_(QCursor.pos()) - def slotAddPackage(self): + def slotShowAddPackage(self): self.tabw.setCurrentIndex(1) self.newPackDock.show() - def slotAddLinks(self): + def slotShowAddLinks(self): self.tabw.setCurrentIndex(1) self.newLinkDock.show() def slotShowConnector(self): self.emit(SIGNAL("connector")) + + def slotAddLinks(self, links): + self.emit(SIGNAL("addLinks"), links) diff --git a/module/gui/PackageDock.py b/module/gui/PackageDock.py new file mode 100644 index 000000000..c97e9d645 --- /dev/null +++ b/module/gui/PackageDock.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +""" + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, + or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . + + @author: mkaay +""" + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +class NewPackageDock(QDockWidget): + def __init__(self): + QDockWidget.__init__(self, "New Package") + self.widget = NewPackageWindow(self) + self.setWidget(self.widget) + self.setAllowedAreas(Qt.RightDockWidgetArea|Qt.LeftDockWidgetArea) + self.hide() + +class NewPackageWindow(QWidget): + def __init__(self, dock): + QWidget.__init__(self) + self.dock = dock + self.setLayout(QGridLayout()) + layout = self.layout() + + nameLabel = QLabel("Name") + nameInput = QLineEdit() + + linksLabel = QLabel("Links in this Package") + linkView = QListWidget() + + save = QPushButton("Create") + + layout.addWidget(nameLabel, 0, 0) + layout.addWidget(nameInput, 0, 1) + layout.addWidget(linksLabel, 1, 0, 1, 2) + layout.addWidget(linkView, 2, 0, 1, 2) + layout.addWidget(save, 3, 0, 1, 2) diff --git a/module/gui/connector.py b/module/gui/connector.py index e4fd4770c..3627545ba 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -144,3 +144,13 @@ class connector(QThread): return self.proxy.status_server() finally: self.mutex.unlock() + + def addURLs(self, links): + """ + add links to collector + """ + self.mutex.lock() + try: + self.proxy.add_urls(links) + finally: + self.mutex.unlock() diff --git a/pyLoadCore.py b/pyLoadCore.py index 2a9cbbc59..4df3f852e 100755 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -394,8 +394,10 @@ class ServerMethods(): return CURRENT_VERSION def add_urls(self, links): - for link in links: - self.core.file_list.collector.addLink(link) + for link in links: + link = link.strip() + if link.startswith("http") or exists(link): + self.core.file_list.collector.addLink(link) self.core.file_list.save() def add_package(self, name, links): diff --git a/pyLoadGui.py b/pyLoadGui.py index 77fe54ca0..2afd63033 100755 --- a/pyLoadGui.py +++ b/pyLoadGui.py @@ -33,6 +33,7 @@ from module.gui.connector import * from module.gui.MainWindow import * from module.gui.PWInputWindow import * from module.gui.Queue import * +from module.gui.Collector import * from module.gui.XMLParser import * class main(QObject): @@ -62,7 +63,8 @@ class main(QObject): sleep(1) self.mainWindow.show() self.initQueue() - self.testStuff() + self.initPackageCollector() + self.initLinkCollector() self.mainloop.start() def stopMain(self): @@ -85,6 +87,7 @@ class main(QObject): self.connect(self.pwWindow, SIGNAL("ok"), self.slotPasswordTyped) self.connect(self.pwWindow, SIGNAL("cancel"), self.quit) self.connect(self.mainWindow, SIGNAL("connector"), self.slotShowConnector) + self.connect(self.mainWindow, SIGNAL("addLinks"), self.slotAddLinks) def slotShowConnector(self): self.stopMain() @@ -105,33 +108,19 @@ class main(QObject): """ QMessageBox(QMessageBox.Warning, "Error", msg) - def testStuff(self): - """ - only for testing ;) - """ - #test for link collector - self.mainWindow.tabs["collector"]["package_view"].setColumnCount(1) - self.mainWindow.tabs["collector"]["package_view"].setHeaderLabels(["Name"]) - ids = self.connector.getLinkCollector() - for id in ids: - data = self.connector.getLinkInfo(id) - item = QListWidgetItem() - item.setData(Qt.UserRole, QVariant(data)) - item.setData(Qt.DisplayRole, QVariant(data["url"])) - self.mainWindow.tabs["collector_links"]["listwidget"].addItem(item) - - #test for package collector - packs = self.connector.getPackageCollector() - 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"])) - self.mainWindow.tabs["collector_packages"]["treewidget"].addTopLevelItem(item) + def initPackageCollector(self): + view = self.mainWindow.tabs["collector"]["package_view"] + view.setColumnCount(1) + view.setHeaderLabels(["Name"]) + self.packageCollector = PackageCollector(view, self.connector) + self.packageCollector.start() + + def initLinkCollector(self): + view = self.mainWindow.tabs["collector"]["link_view"] + view.setColumnCount(1) + view.setHeaderLabels(["Name"]) + self.linkCollector = LinkCollector(view, self.connector) + self.linkCollector.start() def initQueue(self): view = self.mainWindow.tabs["queue"]["view"] @@ -143,7 +132,6 @@ class main(QObject): self.queue = Queue(view, self.connector) delegate = QueueProgressBarDelegate(view, self.queue) view.setItemDelegateForColumn(2, delegate) - #view.setup(self.queue) self.queue.start() def refreshServerStatus(self): @@ -278,6 +266,9 @@ class main(QObject): conns = self.getConnections() self.connWindow.emit(SIGNAL("setConnections(connections)"), conns) + def slotAddLinks(self, links): + self.connector.addURLs(links) + class Loop(QThread): def __init__(self, parent): QThread.__init__(self) -- cgit v1.2.3