From ddd93d0e571edbe1a62f928436ea79818466e940 Mon Sep 17 00:00:00 2001 From: mkaay Date: Thu, 17 Dec 2009 17:47:41 +0100 Subject: splited gui file, extended .hgignore --- module/gui/ConnectionManager.py | 225 +++++++++++++++++++++++++++++++++++ module/gui/MainWindow.py | 95 +++++++++++++++ module/gui/PWInputWindow.py | 47 ++++++++ module/gui/Queue.py | 252 ++++++++++++++++++++++++++++++++++++++++ module/gui/XMLParser.py | 70 +++++++++++ module/gui/__init__.py | 1 + module/gui/connector.py | 146 +++++++++++++++++++++++ 7 files changed, 836 insertions(+) create mode 100644 module/gui/ConnectionManager.py create mode 100644 module/gui/MainWindow.py create mode 100644 module/gui/PWInputWindow.py create mode 100644 module/gui/Queue.py create mode 100644 module/gui/XMLParser.py create mode 100644 module/gui/__init__.py create mode 100644 module/gui/connector.py (limited to 'module/gui') diff --git a/module/gui/ConnectionManager.py b/module/gui/ConnectionManager.py new file mode 100644 index 000000000..a7f2aaf38 --- /dev/null +++ b/module/gui/ConnectionManager.py @@ -0,0 +1,225 @@ +# -*- 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 ConnectionManager(QWidget): + def __init__(self): + QWidget.__init__(self) + + mainLayout = QHBoxLayout() + buttonLayout = QVBoxLayout() + + connList = QListWidget() + + new = QPushButton("New") + edit = QPushButton("Edit") + remove = QPushButton("Remove") + connect = QPushButton("Connect") + + mainLayout.addWidget(connList) + mainLayout.addLayout(buttonLayout) + + buttonLayout.addWidget(new) + buttonLayout.addWidget(edit) + buttonLayout.addWidget(remove) + buttonLayout.addStretch() + buttonLayout.addWidget(connect) + + self.setLayout(mainLayout) + + self.new = new + self.connectb = connect + self.remove = remove + self.editb = edit + self.connList = connList + self.edit = self.EditWindow() + self.connectSignals() + + def connectSignals(self): + self.connect(self, SIGNAL("setConnections(connections)"), self.setConnections) + self.connect(self.new, SIGNAL("clicked()"), self.slotNew) + self.connect(self.editb, SIGNAL("clicked()"), self.slotEdit) + self.connect(self.remove, SIGNAL("clicked()"), self.slotRemove) + self.connect(self.connectb, SIGNAL("clicked()"), self.slotConnect) + self.connect(self.edit, SIGNAL("save"), self.slotSave) + + def setConnections(self, connections): + self.connList.clear() + for conn in connections: + item = QListWidgetItem() + item.setData(Qt.DisplayRole, QVariant(conn["name"])) + item.setData(Qt.UserRole, QVariant(conn)) + self.connList.addItem(item) + if conn["default"]: + self.connList.setCurrentItem(item) + + def slotNew(self): + data = {"id":uuid().hex, "type":"remote", "default":False, "name":"", "host":"", "ssl":False, "port":"7227", "user":"admin"} + self.edit.setData(data) + self.edit.show() + + def slotEdit(self): + item = self.connList.currentItem() + data = item.data(Qt.UserRole).toPyObject() + tmp = {} + for k, d in data.items(): + tmp[str(k)] = d + data = tmp + self.edit.setData(data) + self.edit.show() + + def slotRemove(self): + item = self.connList.currentItem() + data = item.data(Qt.UserRole).toPyObject() + tmp = {} + for k, d in data.items(): + tmp[str(k)] = d + data = tmp + self.emit(SIGNAL("removeConnection"), data) + + def slotConnect(self): + item = self.connList.currentItem() + data = item.data(Qt.UserRole).toPyObject() + tmp = {} + for k, d in data.items(): + tmp[str(k)] = d + data = tmp + self.emit(SIGNAL("connect"), data) + + def slotSave(self, data): + self.emit(SIGNAL("saveConnection"), data) + + class EditWindow(QWidget): + def __init__(self): + QWidget.__init__(self) + + grid = QGridLayout() + + nameLabel = QLabel("Name:") + hostLabel = QLabel("Host:") + sslLabel = QLabel("SSL:") + localLabel = QLabel("Local:") + userLabel = QLabel("User:") + portLabel = QLabel("Port:") + + name = QLineEdit() + host = QLineEdit() + ssl = QCheckBox() + local = QCheckBox() + user = QLineEdit() + port = QSpinBox() + port.setRange(1,10000) + + save = QPushButton("Save") + cancel = QPushButton("Cancel") + + grid.addWidget(nameLabel, 0, 0) + grid.addWidget(name, 0, 1) + grid.addWidget(localLabel, 1, 0) + grid.addWidget(local, 1, 1) + grid.addWidget(hostLabel, 2, 0) + grid.addWidget(host, 2, 1) + grid.addWidget(sslLabel, 4, 0) + grid.addWidget(ssl, 4, 1) + grid.addWidget(userLabel, 5, 0) + grid.addWidget(user, 5, 1) + grid.addWidget(portLabel, 3, 0) + grid.addWidget(port, 3, 1) + grid.addWidget(cancel, 6, 0) + grid.addWidget(save, 6, 1) + + self.setLayout(grid) + self.controls = {} + self.controls["name"] = name + self.controls["host"] = host + self.controls["ssl"] = ssl + self.controls["local"] = local + self.controls["user"] = user + self.controls["port"] = port + self.controls["save"] = save + self.controls["cancel"] = cancel + + self.connect(cancel, SIGNAL("clicked()"), self.hide) + self.connect(save, SIGNAL("clicked()"), self.slotDone) + self.connect(local, SIGNAL("stateChanged(int)"), self.slotLocalChanged) + + self.id = None + self.default = None + + def setData(self, data): + self.id = data["id"] + self.default = data["default"] + self.controls["name"].setText(data["name"]) + if data["type"] == "local": + data["local"] = True + else: + data["local"] = False + self.controls["local"].setChecked(data["local"]) + if not data["local"]: + self.controls["ssl"].setChecked(data["ssl"]) + self.controls["user"].setText(data["user"]) + self.controls["port"].setValue(int(data["port"])) + self.controls["host"].setText(data["host"]) + self.controls["ssl"].setDisabled(False) + self.controls["user"].setDisabled(False) + self.controls["port"].setDisabled(False) + self.controls["host"].setDisabled(False) + else: + self.controls["ssl"].setChecked(False) + self.controls["user"].setText("") + self.controls["port"].setValue(1) + self.controls["host"].setText("") + self.controls["ssl"].setDisabled(True) + self.controls["user"].setDisabled(True) + self.controls["port"].setDisabled(True) + self.controls["host"].setDisabled(True) + + def slotLocalChanged(self, val): + if val == 2: + self.controls["ssl"].setDisabled(True) + self.controls["user"].setDisabled(True) + self.controls["port"].setDisabled(True) + self.controls["host"].setDisabled(True) + elif val == 0: + self.controls["ssl"].setDisabled(False) + self.controls["user"].setDisabled(False) + self.controls["port"].setDisabled(False) + self.controls["host"].setDisabled(False) + + def getData(self): + d = {} + d["id"] = self.id + d["default"] = self.default + d["name"] = self.controls["name"].text() + d["local"] = self.controls["local"].isChecked() + d["ssl"] = str(self.controls["ssl"].isChecked()) + d["user"] = self.controls["user"].text() + d["host"] = self.controls["host"].text() + d["port"] = self.controls["port"].value() + if d["local"]: + d["type"] = "local" + else: + d["type"] = "remote" + return d + + def slotDone(self): + data = self.getData() + self.hide() + self.emit(SIGNAL("save"), data) diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py new file mode 100644 index 000000000..fad98d9da --- /dev/null +++ b/module/gui/MainWindow.py @@ -0,0 +1,95 @@ +# -*- 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 MainWindow(QMainWindow): + def __init__(self): + """ + set up main window + """ + QMainWindow.__init__(self) + #window stuff + self.setWindowTitle("pyLoad Client") + self.setWindowIcon(QIcon("icons/logo.png")) + self.resize(750,500) + + #central widget, layout + self.masterlayout = QVBoxLayout() + lw = QWidget() + lw.setLayout(self.masterlayout) + self.setCentralWidget(lw) + + #set menubar and statusbar + self.menubar = self.menuBar() + self.statusbar = self.statusBar() + self.serverStatus = QLabel("Status: Not Connected") + self.statusbar.addPermanentWidget(self.serverStatus) + + #menu + self.menus = {} + self.menus["file"] = self.menubar.addMenu("&File") + self.menus["connections"] = self.menubar.addMenu("&Connections") + + #menu actions + self.mactions = {} + self.mactions["exit"] = QAction("Exit", self.menus["file"]) + self.mactions["manager"] = QAction("Connection manager", self.menus["connections"]) + + #add menu actions + self.menus["file"].addAction(self.mactions["exit"]) + self.menus["connections"].addAction(self.mactions["manager"]) + + #tabs + self.tabw = QTabWidget() + self.tabs = {} + self.tabs["queue"] = {"w":QWidget()} + self.tabs["collector_packages"] = {"w":QWidget()} + self.tabs["collector_links"] = {"w":QWidget()} + self.tabw.addTab(self.tabs["queue"]["w"], "Queue") + self.tabw.addTab(self.tabs["collector_packages"]["w"], "Package collector") + self.tabw.addTab(self.tabs["collector_links"]["w"], "Link collector") + + #init tabs + self.init_tabs() + + #layout + self.masterlayout.addWidget(self.tabw) + + def init_tabs(self): + """ + create tabs + """ + #queue + self.tabs["queue"]["l"] = QGridLayout() + self.tabs["queue"]["w"].setLayout(self.tabs["queue"]["l"]) + self.tabs["queue"]["view"] = QTreeWidget() + self.tabs["queue"]["l"].addWidget(self.tabs["queue"]["view"]) + + #collector_packages + self.tabs["collector_packages"]["l"] = QGridLayout() + self.tabs["collector_packages"]["w"].setLayout(self.tabs["collector_packages"]["l"]) + self.tabs["collector_packages"]["treewidget"] = QTreeWidget() + self.tabs["collector_packages"]["l"].addWidget(self.tabs["collector_packages"]["treewidget"]) + + #collector_links + self.tabs["collector_links"]["l"] = QGridLayout() + self.tabs["collector_links"]["w"].setLayout(self.tabs["collector_links"]["l"]) + self.tabs["collector_links"]["listwidget"] = QListWidget() + self.tabs["collector_links"]["l"].addWidget(self.tabs["collector_links"]["listwidget"]) diff --git a/module/gui/PWInputWindow.py b/module/gui/PWInputWindow.py new file mode 100644 index 000000000..4fc834c4f --- /dev/null +++ b/module/gui/PWInputWindow.py @@ -0,0 +1,47 @@ +# -*- 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 PWInputWindow(QWidget): + def __init__(self): + QWidget.__init__(self) + self.input = QLineEdit() + self.input.setEchoMode(QLineEdit.Password) + label = QLabel("Password:") + ok = QPushButton("OK") + cancel = QPushButton("Cancel") + grid = QGridLayout() + grid.addWidget(label, 0, 0, 1, 2) + grid.addWidget(self.input, 1, 0, 1, 2) + grid.addWidget(cancel, 2, 0) + grid.addWidget(ok, 2, 1) + self.setLayout(grid) + + self.connect(ok, SIGNAL("clicked()"), self.slotOK) + self.connect(cancel, SIGNAL("clicked()"), self.slotCancel) + self.connect(self.input, SIGNAL("returnPressed()"), self.slotOK) + + def slotOK(self): + self.hide() + self.emit(SIGNAL("ok"), self.input.text()) + + def slotCancel(self): + self.hide() + self.emit(SIGNAL("cancel")) diff --git a/module/gui/Queue.py b/module/gui/Queue.py new file mode 100644 index 000000000..7e63e6180 --- /dev/null +++ b/module/gui/Queue.py @@ -0,0 +1,252 @@ +# -*- 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 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_raw = self.connector.getDownloadQueue() + downloading = {} + for d in downloading: + did = d["id"] + del d["id"] + del d["name"] + del d["status"] + downloading[did] = d + 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) + try: + info["downloading"] = downloading[data["id"]] + except: + info["downloading"] = None + 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)) + item.setData(2, Qt.UserRole, QVariant(newPack)) + + def getPack(self, pid): + for k, pack in enumerate(self.queue): + if pack.getData()["id"] == pid: + return pack + return None + + def getProgress(self, q): + locker = QMutexLocker(self.mutex) + if isinstance(q, self.QueueFile): + data = q.getData() + if data["downloading"]: + return int(data["downloading"]["percent"]) + if data["status_type"] == "finished" or \ + data["status_type"] == "failed" or \ + data["status_type"] == "aborted": + return 100 + elif isinstance(q, self.QueuePack): + children = q.getChildren() + count = len(children) + perc_sum = 0 + for child in children: + val = 0 + data = child.getData() + if data["downloading"]: + val = int(data["downloading"]["percent"]) + elif child.data["status_type"] == "finished" or \ + child.data["status_type"] == "failed" or \ + child.data["status_type"] == "aborted": + val = 100 + perc_sum += val + if count == 0: + return 0 + return perc_sum/count + return 0 + + def getSpeed(self, q): + locker = QMutexLocker(self.mutex) + if isinstance(q, self.QueueFile): + data = q.getData() + if data["downloading"]: + return int(data["downloading"]["speed"]) + elif isinstance(q, self.QueuePack): + children = q.getChildren() + count = len(children) + speed_sum = 0 + for child in children: + val = 0 + data = child.getData() + running = False + if data["downloading"]: + val = int(data["downloading"]["speed"]) + running = True + speed_sum += val + if count == 0 or not running: + return None + return speed_sum + 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) + status = "%s (%s)" % (newChild.getData()["status_type"], newChild.getData()["plugin"]) + item.setData(0, Qt.DisplayRole, QVariant(newChild.getData()["filename"])) + item.setData(1, Qt.DisplayRole, QVariant(status)) + item.setData(0, Qt.UserRole, QVariant(cid)) + item.setData(2, Qt.UserRole, QVariant(newChild)) + + 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 + +class QueueProgressBarDelegate(QItemDelegate): + def __init__(self, parent, queue): + QItemDelegate.__init__(self, parent) + self.queue = queue + + def paint(self, painter, option, index): + if index.column() == 2: + qe = index.data(Qt.UserRole).toPyObject() + progress = self.queue.getProgress(qe) + 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 + speed = self.queue.getSpeed(qe) + if speed == None: + opts.text = QString.number(opts.progress) + "%" + else: + opts.text = QString("%s kb/s - %s" % (speed, opts.progress)) + "%" + QApplication.style().drawControl(QStyle.CE_ProgressBar, opts, painter) + return + QItemDelegate.paint(self, painter, option, index) diff --git a/module/gui/XMLParser.py b/module/gui/XMLParser.py new file mode 100644 index 000000000..0e3b4e59f --- /dev/null +++ b/module/gui/XMLParser.py @@ -0,0 +1,70 @@ +# -*- 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 PyQt4.QtXml import * + +import os + +class XMLParser(): + def __init__(self, data, dfile=""): + self.mutex = QMutex() + self.mutex.lock() + self.xml = QDomDocument() + self.file = data + self.dfile = dfile + self.mutex.unlock() + self.loadData() + self.root = self.xml.documentElement() + + def loadData(self): + self.mutex.lock() + f = self.file + if not os.path.exists(f): + f = self.dfile + with open(f, 'r') as fh: + content = fh.read() + self.xml.setContent(content) + self.mutex.unlock() + + def saveData(self): + self.mutex.lock() + content = self.xml.toString() + with open(self.file, 'w') as fh: + fh.write(content) + self.mutex.unlock() + return content + + def parseNode(self, node, ret_type="list"): + if ret_type == "dict": + childNodes = {} + else: + childNodes = [] + child = node.firstChild() + while True: + n = child.toElement() + if n.isNull(): + break + else: + if ret_type == "dict": + childNodes[str(n.tagName())] = n + else: + childNodes.append(n) + child = child.nextSibling() + return childNodes diff --git a/module/gui/__init__.py b/module/gui/__init__.py new file mode 100644 index 000000000..8d1c8b69c --- /dev/null +++ b/module/gui/__init__.py @@ -0,0 +1 @@ + diff --git a/module/gui/connector.py b/module/gui/connector.py new file mode 100644 index 000000000..e4fd4770c --- /dev/null +++ b/module/gui/connector.py @@ -0,0 +1,146 @@ +# -*- 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 +""" + +SERVER_VERSION = "0.3" + +from time import sleep + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +from xmlrpclib import ServerProxy + +class connector(QThread): + def __init__(self): + """ + init thread + """ + QThread.__init__(self) + self.mutex = QMutex() + self.running = True + self.proxy = None + self.addr = None + + def setAddr(self, addr): + self.mutex.lock() + self.addr = addr + self.mutex.unlock() + + def run(self): + """ + start thread + (called from thread.start()) + """ + self.connectProxy(self.addr) + while self.running: + sleep(1) + + def stop(self): + """ + stop thread + """ + self.running = False + + def connectProxy(self, addr): + """ + connect to remote server + """ + self.proxy = ServerProxy(addr, allow_none=True) + server_version = self.proxy.get_server_version() + if not server_version == SERVER_VERSION: + self.emit(SIGNAL("error_box"), "server is version %s client accepts version %s" % (server_version, SERVER_VERSION)) + + def getLinkCollector(self): + """ + grab links from collector and return the ids + """ + 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 + """ + 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 + """ + 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 + """ + self.mutex.lock() + try: + return self.proxy.get_package_data(id) + finally: + self.mutex.unlock() + + def getPackageQueue(self): + """ + grab queue return the data + """ + self.mutex.lock() + try: + return self.proxy.get_queue() + finally: + self.mutex.unlock() + + def getPackageFiles(self, id): + """ + grab package files and return ids + """ + 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 + """ + self.mutex.lock() + try: + return self.proxy.status_downloads() + finally: + self.mutex.unlock() + + def getServerStatus(self): + """ + return server status + """ + self.mutex.lock() + try: + return self.proxy.status_server() + finally: + self.mutex.unlock() -- cgit v1.2.3 From d63ba825e039fbfd78d87b07efb7fdff0fdebeeb Mon Sep 17 00:00:00 2001 From: mkaay Date: Thu, 17 Dec 2009 18:47:06 +0100 Subject: fixed QueueManager --- module/gui/ConnectionManager.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'module/gui') diff --git a/module/gui/ConnectionManager.py b/module/gui/ConnectionManager.py index a7f2aaf38..c997eee19 100644 --- a/module/gui/ConnectionManager.py +++ b/module/gui/ConnectionManager.py @@ -19,6 +19,8 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * +from uuid import uuid4 as uuid + class ConnectionManager(QWidget): def __init__(self): QWidget.__init__(self) -- cgit v1.2.3 From e17c410d4c0fcd6c9c59368e1472cdc524617dc1 Mon Sep 17 00:00:00 2001 From: mkaay Date: Thu, 17 Dec 2009 21:53:59 +0100 Subject: fixed with statement (python2.5) --- module/gui/XMLParser.py | 1 + 1 file changed, 1 insertion(+) (limited to 'module/gui') diff --git a/module/gui/XMLParser.py b/module/gui/XMLParser.py index 0e3b4e59f..5e3b7bf65 100644 --- a/module/gui/XMLParser.py +++ b/module/gui/XMLParser.py @@ -15,6 +15,7 @@ @author: mkaay """ +from __future__ import with_statement from PyQt4.QtCore import * from PyQt4.QtGui import * -- cgit v1.2.3 From 5a9540d6ee0c81fadf1895df457d3e4a169ca240 Mon Sep 17 00:00:00 2001 From: mkaay Date: Sun, 20 Dec 2009 17:13:01 +0100 Subject: gui toolbar with dummy actions --- module/gui/MainWindow.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index fad98d9da..5878d18d4 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -56,6 +56,10 @@ class MainWindow(QMainWindow): self.menus["file"].addAction(self.mactions["exit"]) self.menus["connections"].addAction(self.mactions["manager"]) + #toolbar + self.actions = {} + self.init_toolbar() + #tabs self.tabw = QTabWidget() self.tabs = {} @@ -72,6 +76,24 @@ class MainWindow(QMainWindow): #layout self.masterlayout.addWidget(self.tabw) + def init_toolbar(self): + self.toolbar = self.addToolBar("main") + self.toolbar.setIconSize(QSize(40,40)) + self.actions["toggle_status"] = self.toolbar.addAction("Toggle Pause/Resume") + pricon = QIcon() + pricon.addFile("icons/gui/toolbar_start.png", QSize(), QIcon.Normal, QIcon.Off) + pricon.addFile("icons/gui/toolbar_pause.png", QSize(), QIcon.Normal, QIcon.On) + self.actions["toggle_status"].setIcon(pricon) + self.actions["toggle_status"].setCheckable(True) + self.actions["status_stop"] = self.toolbar.addAction(QIcon("icons/gui/toolbar_stop.png"), "Stop") + self.toolbar.addSeparator() + self.actions["add"] = self.toolbar.addAction(QIcon("icons/gui/toolbar_add.png"), "Add") + #self.toolbar.addAction(QIcon("icons/gui/toolbar_remove.png"), "Remove") + + self.connect(self.actions["toggle_status"], SIGNAL("toggled(bool)"), self.slotToggleStatus) + self.connect(self.actions["status_stop"], SIGNAL("triggered()"), self.slotStatusStop) + self.connect(self.actions["add"], SIGNAL("triggered()"), self.slotAdd) + def init_tabs(self): """ create tabs @@ -93,3 +115,12 @@ class MainWindow(QMainWindow): self.tabs["collector_links"]["w"].setLayout(self.tabs["collector_links"]["l"]) self.tabs["collector_links"]["listwidget"] = QListWidget() self.tabs["collector_links"]["l"].addWidget(self.tabs["collector_links"]["listwidget"]) + + def slotToggleStatus(self, status): + print "toggle status", status + + def slotStatusStop(self): + print "stop!" + + def slotAdd(self): + print "add" -- cgit v1.2.3 From ab5d907f48a8879f717e0c6482695ef1afe280a0 Mon Sep 17 00:00:00 2001 From: mkaay Date: Sun, 20 Dec 2009 18:25:19 +0100 Subject: gui can return to connection manager, new collector --- module/gui/MainWindow.py | 35 ++++++++++++++++++++--------------- module/gui/Queue.py | 3 +++ 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 5878d18d4..f9d2d0fb8 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -64,17 +64,17 @@ class MainWindow(QMainWindow): self.tabw = QTabWidget() self.tabs = {} self.tabs["queue"] = {"w":QWidget()} - self.tabs["collector_packages"] = {"w":QWidget()} - self.tabs["collector_links"] = {"w":QWidget()} + self.tabs["collector"] = {"w":QWidget()} self.tabw.addTab(self.tabs["queue"]["w"], "Queue") - self.tabw.addTab(self.tabs["collector_packages"]["w"], "Package collector") - self.tabw.addTab(self.tabs["collector_links"]["w"], "Link collector") + self.tabw.addTab(self.tabs["collector"]["w"], "Collector") #init tabs self.init_tabs() #layout self.masterlayout.addWidget(self.tabw) + + self.connect(self.mactions["manager"], SIGNAL("triggered()"), self.slotShowConnector) def init_toolbar(self): self.toolbar = self.addToolBar("main") @@ -104,17 +104,19 @@ class MainWindow(QMainWindow): self.tabs["queue"]["view"] = QTreeWidget() self.tabs["queue"]["l"].addWidget(self.tabs["queue"]["view"]) - #collector_packages - self.tabs["collector_packages"]["l"] = QGridLayout() - self.tabs["collector_packages"]["w"].setLayout(self.tabs["collector_packages"]["l"]) - self.tabs["collector_packages"]["treewidget"] = QTreeWidget() - self.tabs["collector_packages"]["l"].addWidget(self.tabs["collector_packages"]["treewidget"]) - - #collector_links - self.tabs["collector_links"]["l"] = QGridLayout() - self.tabs["collector_links"]["w"].setLayout(self.tabs["collector_links"]["l"]) - self.tabs["collector_links"]["listwidget"] = QListWidget() - self.tabs["collector_links"]["l"].addWidget(self.tabs["collector_links"]["listwidget"]) + #collector + groupPackage = QGroupBox("Packages") + groupLinks = QGroupBox("Links") + groupPackage.setLayout(QVBoxLayout()) + groupLinks.setLayout(QVBoxLayout()) + 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() + groupPackage.layout().addWidget(self.tabs["collector"]["package_view"]) + groupLinks.layout().addWidget(self.tabs["collector"]["link_view"]) + self.tabs["collector"]["l"].addWidget(groupPackage, 0, 0) + self.tabs["collector"]["l"].addWidget(groupLinks, 0, 1) def slotToggleStatus(self, status): print "toggle status", status @@ -124,3 +126,6 @@ class MainWindow(QMainWindow): def slotAdd(self): print "add" + + def slotShowConnector(self): + self.emit(SIGNAL("connector")) diff --git a/module/gui/Queue.py b/module/gui/Queue.py index 7e63e6180..52f11fd8c 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -46,6 +46,9 @@ class Queue(QThread): self.update() sleep(self.interval) + def stop(self): + self.running = False + def update(self): locker = QMutexLocker(self.mutex) packs = self.connector.getPackageQueue() -- cgit v1.2.3 From 9f342ea3f73148154054515c4a3d3fa8ab35bf51 Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 21 Dec 2009 00:41:08 +0100 Subject: GUI: new docks --- module/gui/MainWindow.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index f9d2d0fb8..9c972dea1 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -19,6 +19,9 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * +from module.gui.PackageDock import * +from module.gui.LinkDock import * + class MainWindow(QMainWindow): def __init__(self): """ @@ -30,6 +33,11 @@ class MainWindow(QMainWindow): self.setWindowIcon(QIcon("icons/logo.png")) self.resize(750,500) + self.newPackDock = NewPackageDock() + self.addDockWidget(Qt.RightDockWidgetArea, self.newPackDock) + self.newLinkDock = NewLinkDock() + self.addDockWidget(Qt.RightDockWidgetArea, self.newLinkDock) + #central widget, layout self.masterlayout = QVBoxLayout() lw = QWidget() @@ -92,7 +100,12 @@ class MainWindow(QMainWindow): self.connect(self.actions["toggle_status"], SIGNAL("toggled(bool)"), self.slotToggleStatus) self.connect(self.actions["status_stop"], SIGNAL("triggered()"), self.slotStatusStop) + self.addMenu = QMenu() + 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) def init_tabs(self): """ @@ -125,7 +138,15 @@ class MainWindow(QMainWindow): print "stop!" def slotAdd(self): - print "add" + self.addMenu.exec_(QCursor.pos()) + + def slotAddPackage(self): + self.tabw.setCurrentIndex(1) + self.newPackDock.show() + + def slotAddLinks(self): + self.tabw.setCurrentIndex(1) + self.newLinkDock.show() def slotShowConnector(self): self.emit(SIGNAL("connector")) -- cgit v1.2.3 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 +++ 5 files changed, 332 insertions(+), 5 deletions(-) create mode 100644 module/gui/Collector.py create mode 100644 module/gui/LinkDock.py create mode 100644 module/gui/PackageDock.py (limited to 'module/gui') 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() -- cgit v1.2.3 From 4c98db9a0eb0ca1ca70c4886b907e79682bfad82 Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 21 Dec 2009 14:41:23 +0100 Subject: pause/start button works --- module/gui/MainWindow.py | 3 ++- module/gui/connector.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index ccca6b697..6d68f4d7a 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -85,6 +85,7 @@ class MainWindow(QMainWindow): self.masterlayout.addWidget(self.tabw) self.connect(self.mactions["manager"], SIGNAL("triggered()"), self.slotShowConnector) + self.connect(self.mactions["exit"], SIGNAL("triggered()"), self.close) def init_toolbar(self): self.toolbar = self.addToolBar("main") @@ -134,7 +135,7 @@ class MainWindow(QMainWindow): self.tabs["collector"]["l"].addWidget(groupLinks, 0, 1) def slotToggleStatus(self, status): - print "toggle status", status + self.emit(SIGNAL("setDownloadStatus"), status) def slotStatusStop(self): print "stop!" diff --git a/module/gui/connector.py b/module/gui/connector.py index 3627545ba..32da29bba 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -154,3 +154,26 @@ class connector(QThread): self.proxy.add_urls(links) finally: self.mutex.unlock() + + def togglePause(self): + """ + toogle pause + """ + self.mutex.lock() + try: + return self.proxy.toggle_pause() + finally: + self.mutex.unlock() + + def setPause(self, pause): + """ + set pause + """ + self.mutex.lock() + try: + if pause: + self.proxy.pause_server() + else: + self.proxy.unpause_server() + finally: + self.mutex.unlock() -- cgit v1.2.3 From ff7fa4a0d1aa1c09e563d2086704aa7e2acea716 Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 21 Dec 2009 17:07:16 +0100 Subject: package creation works --- module/gui/Collector.py | 21 +++++++++++++++++++-- module/gui/MainWindow.py | 4 ++++ module/gui/PackageDock.py | 28 +++++++++++++++++++++++++++- module/gui/connector.py | 20 ++++++++++++++++++++ 4 files changed, 70 insertions(+), 3 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 0dbccab1f..28cac097b 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -102,8 +102,8 @@ class PackageCollector(QThread): except: self.children.append(newChild) pos = self.children.index(newChild) - ppos = self.queue.queue.index(self) - parent = self.queue.view.topLevelItem(ppos) + ppos = self.collector.collector.index(self) + parent = self.collector.view.topLevelItem(ppos) item = parent.child(pos) if not item: item = QTreeWidgetItem() @@ -172,6 +172,7 @@ class LinkCollector(QThread): file = self.LinkCollectorFile(self) file.setData(data) self.addFile(id, file) + self.clear(ids) def addFile(self, pid, newFile): pos = None @@ -192,12 +193,28 @@ class LinkCollector(QThread): self.view.insertTopLevelItem(pos, item) item.setData(0, Qt.DisplayRole, QVariant(newFile.getData()["filename"])) item.setData(0, Qt.UserRole, QVariant(pid)) + flags = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled + item.setFlags(flags) def getFile(self, pid): for k, file in enumerate(self.collector): if file.getData()["id"] == pid: return file return None + + def clear(self, ids): + toremove = [] + for k, file in enumerate(self.collector): + id = file.getData()["id"] + if not id in ids: + toremove.append(k) + if not toremove: + return + toremove.sort() + toremove.reverse() + for pos in toremove: + del self.collector[k] + self.view.takeTopLevelItem(k) class LinkCollectorFile(): def __init__(self, collector): diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 6d68f4d7a..63ffb86a0 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -39,6 +39,7 @@ class MainWindow(QMainWindow): self.newLinkDock = NewLinkDock() self.addDockWidget(Qt.RightDockWidgetArea, self.newLinkDock) self.connect(self.newLinkDock, SIGNAL("done"), self.slotAddLinks) + self.connect(self.newPackDock, SIGNAL("done"), self.slotAddPackage) #central widget, layout self.masterlayout = QVBoxLayout() @@ -156,3 +157,6 @@ class MainWindow(QMainWindow): def slotAddLinks(self, links): self.emit(SIGNAL("addLinks"), links) + + def slotAddPackage(self, name, ids): + self.emit(SIGNAL("addPackage"), name, ids) diff --git a/module/gui/PackageDock.py b/module/gui/PackageDock.py index c97e9d645..7367efda4 100644 --- a/module/gui/PackageDock.py +++ b/module/gui/PackageDock.py @@ -26,6 +26,18 @@ class NewPackageDock(QDockWidget): self.setWidget(self.widget) self.setAllowedAreas(Qt.RightDockWidgetArea|Qt.LeftDockWidgetArea) self.hide() + + def slotDone(self): + view = self.widget.view + count = view.topLevelItemCount() + ids = [] + for i in range(count): + item = view.topLevelItem(i) + if item: + ids.append(item.data(0, Qt.UserRole).toInt()[0]) + self.emit(SIGNAL("done"), self.widget.nameInput.text(), ids) + view.clear() + self.hide() class NewPackageWindow(QWidget): def __init__(self, dock): @@ -38,7 +50,19 @@ class NewPackageWindow(QWidget): nameInput = QLineEdit() linksLabel = QLabel("Links in this Package") - linkView = QListWidget() + linkView = QTreeWidget() + linkView.setSelectionBehavior(QAbstractItemView.SelectRows) + linkView.setSelectionMode(QAbstractItemView.SingleSelection) + linkView.setColumnCount(1) + linkView.setHeaderLabels(["Name"]) + linkView.setDragEnabled(True) + linkView.setDragDropMode(QAbstractItemView.DragDrop) + linkView.setDropIndicatorShown(True) + linkView.setAcceptDrops(True) + linkView.setDragDropOverwriteMode(True) + + self.view = linkView + self.nameInput = nameInput save = QPushButton("Create") @@ -47,3 +71,5 @@ class NewPackageWindow(QWidget): layout.addWidget(linksLabel, 1, 0, 1, 2) layout.addWidget(linkView, 2, 0, 1, 2) layout.addWidget(save, 3, 0, 1, 2) + + self.connect(save, SIGNAL("clicked()"), self.dock.slotDone) diff --git a/module/gui/connector.py b/module/gui/connector.py index 32da29bba..e7a151c5e 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -177,3 +177,23 @@ class connector(QThread): self.proxy.unpause_server() finally: self.mutex.unlock() + + def newPackage(self, name): + """ + create a new package and return id + """ + self.mutex.lock() + try: + return self.proxy.new_package(name) + finally: + self.mutex.unlock() + + def addFileToPackage(self, fileid, packid): + """ + add a file from collector to package + """ + self.mutex.lock() + try: + self.proxy.move_file_2_package(fileid, packid) + finally: + self.mutex.unlock() -- cgit v1.2.3 From 59eaacc4228707f715be147350adb0a670de6985 Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 21 Dec 2009 17:57:17 +0100 Subject: save window state --- module/gui/LinkDock.py | 1 + module/gui/MainWindow.py | 27 ++++++++++++++++++++++++++- module/gui/PackageDock.py | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) (limited to 'module/gui') diff --git a/module/gui/LinkDock.py b/module/gui/LinkDock.py index 01a0cc193..99429d04b 100644 --- a/module/gui/LinkDock.py +++ b/module/gui/LinkDock.py @@ -22,6 +22,7 @@ from PyQt4.QtGui import * class NewLinkDock(QDockWidget): def __init__(self): QDockWidget.__init__(self, "New Links") + self.setObjectName("New Links Dock") self.widget = NewLinkWindow(self) self.setWidget(self.widget) self.setAllowedAreas(Qt.RightDockWidgetArea|Qt.LeftDockWidgetArea) diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 63ffb86a0..4f92f68a9 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -33,6 +33,9 @@ class MainWindow(QMainWindow): self.setWindowIcon(QIcon("icons/logo.png")) self.resize(750,500) + #layout version + self.version = 1 + #init docks self.newPackDock = NewPackageDock() self.addDockWidget(Qt.RightDockWidgetArea, self.newPackDock) @@ -89,7 +92,8 @@ class MainWindow(QMainWindow): self.connect(self.mactions["exit"], SIGNAL("triggered()"), self.close) def init_toolbar(self): - self.toolbar = self.addToolBar("main") + self.toolbar = self.addToolBar("Main Toolbar") + self.toolbar.setObjectName("Main Toolbar") self.toolbar.setIconSize(QSize(40,40)) self.actions["toggle_status"] = self.toolbar.addAction("Toggle Pause/Resume") pricon = QIcon() @@ -160,3 +164,24 @@ class MainWindow(QMainWindow): def slotAddPackage(self, name, ids): self.emit(SIGNAL("addPackage"), name, ids) + + def closeEvent(self, event): + state_raw = self.saveState(self.version) + geo_raw = self.saveGeometry() + + state = str(state_raw.toBase64()) + geo = str(geo_raw.toBase64()) + + self.emit(SIGNAL("saveMainWindow"), state, geo) + event.accept() + + def restoreWindow(self, state, geo): + state = QByteArray(state) + geo = QByteArray(geo) + + state_raw = QByteArray.fromBase64(state) + geo_raw = QByteArray.fromBase64(geo) + + self.restoreState(state_raw, self.version) + self.restoreGeometry(geo_raw) + diff --git a/module/gui/PackageDock.py b/module/gui/PackageDock.py index 7367efda4..b90e3533d 100644 --- a/module/gui/PackageDock.py +++ b/module/gui/PackageDock.py @@ -22,6 +22,7 @@ from PyQt4.QtGui import * class NewPackageDock(QDockWidget): def __init__(self): QDockWidget.__init__(self, "New Package") + self.setObjectName("New Package Dock") self.widget = NewPackageWindow(self) self.setWidget(self.widget) self.setAllowedAreas(Qt.RightDockWidgetArea|Qt.LeftDockWidgetArea) -- cgit v1.2.3 From ed36dd5988907019cc9cc5b98265f00a52462c85 Mon Sep 17 00:00:00 2001 From: mkaay Date: Tue, 22 Dec 2009 17:07:35 +0100 Subject: more docstrings, small design changes --- module/gui/Collector.py | 34 +++++++++++++++ module/gui/MainWindow.py | 107 ++++++++++++++++++++++++++++++++++++++++++++++- module/gui/Queue.py | 79 ++++++++++++++++++++++++++-------- module/gui/connector.py | 13 ++++++ 4 files changed, 214 insertions(+), 19 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 28cac097b..1d622b006 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -42,7 +42,9 @@ class PackageCollector(QThread): def update(self): locker = QMutexLocker(self.mutex) packs = self.connector.getPackageCollector() + ids = [] for data in packs: + ids.append(data["id"]) pack = self.getPack(data["id"]) if not pack: pack = self.PackageCollectorPack(self) @@ -56,6 +58,8 @@ class PackageCollector(QThread): child = self.PackageCollectorFile(self, pack) child.setData(info) pack.addChild(fid, child) + #pack.clear(files) + self.clear(ids) def addPack(self, pid, newPack): pos = None @@ -83,6 +87,18 @@ class PackageCollector(QThread): return pack return None + def clear(self, ids): + toremove = [] + for k, pack in enumerate(self.collector): + id = pack.getData()["id"] + if not id in ids: + toremove.append(k) + if not toremove: + return + self.collector = [] + #self.view.clear() + self.view.emit(SIGNAL("clear")) + class PackageCollectorPack(): def __init__(self, collector): self.collector = collector @@ -111,6 +127,8 @@ class PackageCollector(QThread): 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)) + flags = Qt.ItemIsEnabled + item.setFlags(flags) def getChildren(self): return self.children @@ -129,6 +147,22 @@ class PackageCollector(QThread): def getData(self): return self.data + + def clear(self, ids): + toremove = [] + for k, file in enumerate(self.getChildren()): + id = file.getData()["id"] + if not id in ids: + toremove.append(k) + if not toremove: + return + ppos = self.collector.collector.index(self) + parent = self.collector.view.topLevelItem(ppos) + toremove.sort() + toremove.reverse() + for pos in toremove: + del self.children[k] + parent.takeChild(k) class PackageCollectorFile(): def __init__(self, collector, pack): diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 4f92f68a9..f72ad97de 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -31,7 +31,7 @@ class MainWindow(QMainWindow): #window stuff self.setWindowTitle("pyLoad Client") self.setWindowIcon(QIcon("icons/logo.png")) - self.resize(750,500) + self.resize(850,500) #layout version self.version = 1 @@ -85,13 +85,24 @@ class MainWindow(QMainWindow): #init tabs self.init_tabs() + #context menus + self.init_context() + #layout self.masterlayout.addWidget(self.tabw) + #signals.. self.connect(self.mactions["manager"], SIGNAL("triggered()"), self.slotShowConnector) self.connect(self.mactions["exit"], SIGNAL("triggered()"), self.close) + + self.connect(self.tabs["queue"]["view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotQueueContextMenu) + self.connect(self.tabs["collector"]["package_view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotPackageCollectorContextMenu) + self.connect(self.tabs["collector"]["link_view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotLinkCollectorContextMenu) def init_toolbar(self): + """ + create toolbar + """ self.toolbar = self.addToolBar("Main Toolbar") self.toolbar.setObjectName("Main Toolbar") self.toolbar.setIconSize(QSize(40,40)) @@ -130,42 +141,102 @@ class MainWindow(QMainWindow): groupLinks = QGroupBox("Links") groupPackage.setLayout(QVBoxLayout()) groupLinks.setLayout(QVBoxLayout()) + toQueue = QPushButton("Push selected packages to queue") self.tabs["collector"]["l"] = QGridLayout() self.tabs["collector"]["w"].setLayout(self.tabs["collector"]["l"]) self.tabs["collector"]["package_view"] = QTreeWidget() + self.connect(self.tabs["collector"]["package_view"], SIGNAL("clear"), self.tabs["collector"]["package_view"].clear) self.tabs["collector"]["link_view"] = QTreeWidget() groupPackage.layout().addWidget(self.tabs["collector"]["package_view"]) + groupPackage.layout().addWidget(toQueue) groupLinks.layout().addWidget(self.tabs["collector"]["link_view"]) self.tabs["collector"]["l"].addWidget(groupPackage, 0, 0) self.tabs["collector"]["l"].addWidget(groupLinks, 0, 1) + self.connect(toQueue, SIGNAL("clicked()"), self.slotPushPackageToQueue) + + def init_context(self): + """ + create context menus + """ + self.queueContext = QMenu() + self.queueContext.buttons = {} + self.queueContext.buttons["remove"] = QAction("Remove", self.queueContext) + self.queueContext.addAction(self.queueContext.buttons["remove"]) def slotToggleStatus(self, status): + """ + pause/start toggle (toolbar) + """ self.emit(SIGNAL("setDownloadStatus"), status) def slotStatusStop(self): + """ + stop button (toolbar) + + dummy + """ print "stop!" def slotAdd(self): + """ + add button (toolbar) + show context menu (choice: links/package) + """ self.addMenu.exec_(QCursor.pos()) def slotShowAddPackage(self): + """ + action from add-menu + show new-package dock + """ self.tabw.setCurrentIndex(1) self.newPackDock.show() def slotShowAddLinks(self): + """ + action from add-menu + show new-links dock + """ self.tabw.setCurrentIndex(1) self.newLinkDock.show() def slotShowConnector(self): + """ + connectionmanager action triggered + let main to the stuff + """ self.emit(SIGNAL("connector")) def slotAddLinks(self, links): + """ + new links + let main to the stuff + """ self.emit(SIGNAL("addLinks"), links) def slotAddPackage(self, name, ids): + """ + new package + let main to the stuff + """ self.emit(SIGNAL("addPackage"), name, ids) - def closeEvent(self, event): + def slotPushPackageToQueue(self): + """ + push collector pack to queue + get child ids + let main to the rest + """ + items = self.tabs["collector"]["package_view"].selectedItems() + for item in items: + id = item.data(0, Qt.UserRole).toPyObject() + self.emit(SIGNAL("pushPackageToQueue"), id) + + def saveWindow(self): + """ + get window state/geometry + pass data to main + """ state_raw = self.saveState(self.version) geo_raw = self.saveGeometry() @@ -173,9 +244,19 @@ class MainWindow(QMainWindow): geo = str(geo_raw.toBase64()) self.emit(SIGNAL("saveMainWindow"), state, geo) + + def closeEvent(self, event): + """ + somebody wants to close me! + let me first save my state + """ + self.saveWindow() event.accept() def restoreWindow(self, state, geo): + """ + restore window state/geometry + """ state = QByteArray(state) geo = QByteArray(geo) @@ -184,4 +265,26 @@ class MainWindow(QMainWindow): self.restoreState(state_raw, self.version) self.restoreGeometry(geo_raw) + + def slotQueueContextMenu(self, pos): + """ + custom context menu in queue view requested + """ + globalPos = self.tabs["queue"]["view"].mapToGlobal(pos) + i = self.tabs["queue"]["view"].itemAt(pos) + i.setSelected(True) + self.addFav.setData(QVariant(i)) + self.showContext.exec_(globalPos) + + def slotPackageCollectorContextMenu(self, pos): + """ + custom context menu in package collector view requested + """ + pass + + def slotLinkCollectorContextMenu(self, pos): + """ + custom context menu in link collector view requested + """ + pass diff --git a/module/gui/Queue.py b/module/gui/Queue.py index 52f11fd8c..c9a3e858b 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -19,7 +19,7 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * -from time import sleep +from time import sleep, time class Queue(QThread): def __init__(self, view, connector): @@ -37,8 +37,9 @@ class Queue(QThread): } self.statusMapReverse = dict((v,k) for k, v in self.statusMap.iteritems()) self.queue = [] - self.interval = 2 + self.interval = 1 self.running = True + self.wait_dict = {} self.mutex = QMutex() def run(self): @@ -54,7 +55,7 @@ class Queue(QThread): packs = self.connector.getPackageQueue() downloading_raw = self.connector.getDownloadQueue() downloading = {} - for d in downloading: + for d in downloading_raw: did = d["id"] del d["id"] del d["name"] @@ -73,7 +74,7 @@ class Queue(QThread): if not child: child = self.QueueFile(self, pack) try: - info["downloading"] = downloading[data["id"]] + info["downloading"] = downloading[info["id"]] except: info["downloading"] = None child.setData(info) @@ -98,13 +99,22 @@ class Queue(QThread): self.view.insertTopLevelItem(pos, item) item.setData(0, Qt.DisplayRole, QVariant(newPack.getData()["package_name"])) status = -1 + speed = self.getSpeed(newPack) + plugins = [] 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 not child.data["plugin"] in plugins: + plugins.append(child.data["plugin"]) if status >= 0: - item.setData(1, Qt.DisplayRole, QVariant(self.statusMapReverse[status])) + if speed == None: + statustxt = self.statusMapReverse[status] + else: + statustxt = "%s (%s KB/s)" % (self.statusMapReverse[status], speed) + item.setData(2, Qt.DisplayRole, QVariant(statustxt)) + item.setData(1, Qt.DisplayRole, QVariant(", ".join(plugins))) item.setData(0, Qt.UserRole, QVariant(pid)) - item.setData(2, Qt.UserRole, QVariant(newPack)) + item.setData(3, Qt.UserRole, QVariant(newPack)) def getPack(self, pid): for k, pack in enumerate(self.queue): @@ -112,6 +122,27 @@ class Queue(QThread): return pack return None + def getWaitingProgress(self, q): + locker = QMutexLocker(self.mutex) + if isinstance(q, self.QueueFile): + data = q.getData() + if data["status_type"] == "waiting" and data["downloading"]: + until = float(data["downloading"]["wait_until"]) + try: + since, until_old = self.wait_dict[data["id"]] + if not until == until_old: + raise Exception + except: + since = time() + self.wait_dict[data["id"]] = since, until + since = float(since) + max_wait = float(until-since) + rest = int(until-time()) + res = 100/max_wait + perc = rest*res + return perc, rest + return None + def getProgress(self, q): locker = QMutexLocker(self.mutex) if isinstance(q, self.QueueFile): @@ -142,7 +173,7 @@ class Queue(QThread): return 0 def getSpeed(self, q): - locker = QMutexLocker(self.mutex) + #locker = QMutexLocker(self.mutex) if isinstance(q, self.QueueFile): data = q.getData() if data["downloading"]: @@ -151,15 +182,18 @@ class Queue(QThread): children = q.getChildren() count = len(children) speed_sum = 0 + all_waiting = True for child in children: val = 0 data = child.getData() running = False if data["downloading"]: + if not data["status_type"] == "waiting": + all_waiting = False val = int(data["downloading"]["speed"]) running = True speed_sum += val - if count == 0 or not running: + if count == 0 or not running or all_waiting: return None return speed_sum return None @@ -189,11 +223,16 @@ class Queue(QThread): if not item: item = QTreeWidgetItem() parent.insertChild(pos, item) - status = "%s (%s)" % (newChild.getData()["status_type"], newChild.getData()["plugin"]) + speed = self.queue.getSpeed(newChild) + if speed == None: + status = newChild.getData()["status_type"] + else: + status = "%s (%s KB/s)" % (newChild.getData()["status_type"], speed) item.setData(0, Qt.DisplayRole, QVariant(newChild.getData()["filename"])) - item.setData(1, Qt.DisplayRole, QVariant(status)) + item.setData(2, Qt.DisplayRole, QVariant(status)) + item.setData(1, Qt.DisplayRole, QVariant(newChild.getData()["plugin"])) item.setData(0, Qt.UserRole, QVariant(cid)) - item.setData(2, Qt.UserRole, QVariant(newChild)) + item.setData(3, Qt.UserRole, QVariant(newChild)) def getChildren(self): return self.children @@ -217,6 +256,7 @@ class Queue(QThread): def __init__(self, queue, pack): self.queue = queue self.pack = pack + self.wait_since = None def getData(self): return self.data @@ -233,9 +273,15 @@ class QueueProgressBarDelegate(QItemDelegate): self.queue = queue def paint(self, painter, option, index): - if index.column() == 2: + if index.column() == 3: qe = index.data(Qt.UserRole).toPyObject() - progress = self.queue.getProgress(qe) + w = self.queue.getWaitingProgress(qe) + wait = None + if w: + progress = w[0] + wait = w[1] + else: + progress = self.queue.getProgress(qe) opts = QStyleOptionProgressBarV2() opts.maximum = 100 opts.minimum = 0 @@ -245,11 +291,10 @@ class QueueProgressBarDelegate(QItemDelegate): opts.rect.setHeight(option.rect.height()-1) opts.textVisible = True opts.textAlignment = Qt.AlignCenter - speed = self.queue.getSpeed(qe) - if speed == None: - opts.text = QString.number(opts.progress) + "%" + if not wait == None: + opts.text = QString("waiting %d seconds" % (wait,)) else: - opts.text = QString("%s kb/s - %s" % (speed, opts.progress)) + "%" + opts.text = QString.number(opts.progress) + "%" QApplication.style().drawControl(QStyle.CE_ProgressBar, opts, painter) return QItemDelegate.paint(self, painter, option, index) diff --git a/module/gui/connector.py b/module/gui/connector.py index e7a151c5e..2a1ce511e 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -37,6 +37,9 @@ class connector(QThread): self.addr = None def setAddr(self, addr): + """ + set new address + """ self.mutex.lock() self.addr = addr self.mutex.unlock() @@ -197,3 +200,13 @@ class connector(QThread): self.proxy.move_file_2_package(fileid, packid) finally: self.mutex.unlock() + + def pushPackageToQueue(self, packid): + """ + push a package to queue + """ + self.mutex.lock() + try: + self.proxy.push_package_2_queue(packid) + finally: + self.mutex.unlock() -- cgit v1.2.3 From a5ff0482ede8bd7bd932482887f2f7cdae5039d9 Mon Sep 17 00:00:00 2001 From: mkaay Date: Wed, 23 Dec 2009 00:04:36 +0100 Subject: core: downloadlimit is not far away ;) gui: restart download action --- module/gui/MainWindow.py | 19 +++++++++++++++++-- module/gui/connector.py | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index f72ad97de..837125263 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -153,6 +153,9 @@ class MainWindow(QMainWindow): self.tabs["collector"]["l"].addWidget(groupPackage, 0, 0) self.tabs["collector"]["l"].addWidget(groupLinks, 0, 1) self.connect(toQueue, SIGNAL("clicked()"), self.slotPushPackageToQueue) + self.tabs["collector"]["package_view"].setContextMenuPolicy(Qt.CustomContextMenu) + self.tabs["collector"]["link_view"].setContextMenuPolicy(Qt.CustomContextMenu) + self.tabs["queue"]["view"].setContextMenuPolicy(Qt.CustomContextMenu) def init_context(self): """ @@ -160,8 +163,12 @@ class MainWindow(QMainWindow): """ self.queueContext = QMenu() self.queueContext.buttons = {} + self.queueContext.item = (None, None) self.queueContext.buttons["remove"] = QAction("Remove", self.queueContext) + self.queueContext.buttons["restart"] = QAction("Restart", self.queueContext) self.queueContext.addAction(self.queueContext.buttons["remove"]) + self.queueContext.addAction(self.queueContext.buttons["restart"]) + self.connect(self.queueContext.buttons["restart"], SIGNAL("triggered()"), self.slotRestartDownload) def slotToggleStatus(self, status): """ @@ -273,8 +280,8 @@ class MainWindow(QMainWindow): globalPos = self.tabs["queue"]["view"].mapToGlobal(pos) i = self.tabs["queue"]["view"].itemAt(pos) i.setSelected(True) - self.addFav.setData(QVariant(i)) - self.showContext.exec_(globalPos) + self.queueContext.item = (i.data(0, Qt.UserRole).toPyObject(), i.parent() == None) + self.queueContext.exec_(globalPos) def slotPackageCollectorContextMenu(self, pos): """ @@ -287,4 +294,12 @@ class MainWindow(QMainWindow): custom context menu in link collector view requested """ pass + + def slotRestartDownload(self): + """ + restart download action is triggered + """ + id, isTopLevel = self.queueContext.item + if not id == None: + self.emit(SIGNAL("restartDownload"), id, isTopLevel) diff --git a/module/gui/connector.py b/module/gui/connector.py index 2a1ce511e..75781ebb1 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -210,3 +210,23 @@ class connector(QThread): self.proxy.push_package_2_queue(packid) finally: self.mutex.unlock() + + def restartPackage(self, packid): + """ + restart a package + """ + self.mutex.lock() + try: + self.proxy.restart_package(packid) + finally: + self.mutex.unlock() + + def restartFile(self, fileid): + """ + restart a file + """ + self.mutex.lock() + try: + self.proxy.restart_file(fileid) + finally: + self.mutex.unlock() -- cgit v1.2.3 From ea04c11ce1fb52895449a56e862eff5448ea456a Mon Sep 17 00:00:00 2001 From: mkaay Date: Thu, 24 Dec 2009 01:28:08 +0100 Subject: downloads are now aborted correctly, gui: remove downloads, new icons --- module/gui/Collector.py | 55 ++++++++++++++++++++---------------------------- module/gui/MainWindow.py | 20 +++++++++++++++--- module/gui/Queue.py | 30 ++++++++++++++++++++++++-- module/gui/connector.py | 20 ++++++++++++++++++ 4 files changed, 88 insertions(+), 37 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 1d622b006..1f89670ce 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -58,7 +58,7 @@ class PackageCollector(QThread): child = self.PackageCollectorFile(self, pack) child.setData(info) pack.addChild(fid, child) - #pack.clear(files) + pack.clear(files) self.clear(ids) def addPack(self, pid, newPack): @@ -88,15 +88,14 @@ class PackageCollector(QThread): return None def clear(self, ids): - toremove = [] - for k, pack in enumerate(self.collector): - id = pack.getData()["id"] - if not id in ids: - toremove.append(k) - if not toremove: + clear = False + for pack in self.collector: + if not pack.getData()["id"] in ids: + clear = True + break + if not clear: return self.collector = [] - #self.view.clear() self.view.emit(SIGNAL("clear")) class PackageCollectorPack(): @@ -149,20 +148,15 @@ class PackageCollector(QThread): return self.data def clear(self, ids): - toremove = [] - for k, file in enumerate(self.getChildren()): - id = file.getData()["id"] - if not id in ids: - toremove.append(k) - if not toremove: + clear = False + for file in self.getChildren(): + if not file.getData()["id"] in ids: + clear = True + break + if not clear: return - ppos = self.collector.collector.index(self) - parent = self.collector.view.topLevelItem(ppos) - toremove.sort() - toremove.reverse() - for pos in toremove: - del self.children[k] - parent.takeChild(k) + self.collector.collector = [] + self.collector.view.emit(SIGNAL("clear")) class PackageCollectorFile(): def __init__(self, collector, pack): @@ -237,18 +231,15 @@ class LinkCollector(QThread): return None def clear(self, ids): - toremove = [] - for k, file in enumerate(self.collector): - id = file.getData()["id"] - if not id in ids: - toremove.append(k) - if not toremove: + clear = False + for pack in self.collector: + if not pack.getData()["id"] in ids: + clear = True + break + if not clear: return - toremove.sort() - toremove.reverse() - for pos in toremove: - del self.collector[k] - self.view.takeTopLevelItem(k) + self.collector = [] + self.view.emit(SIGNAL("clear")) class LinkCollectorFile(): def __init__(self, collector): diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 837125263..53de8cd54 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -147,6 +147,7 @@ class MainWindow(QMainWindow): self.tabs["collector"]["package_view"] = QTreeWidget() self.connect(self.tabs["collector"]["package_view"], SIGNAL("clear"), self.tabs["collector"]["package_view"].clear) self.tabs["collector"]["link_view"] = QTreeWidget() + self.connect(self.tabs["collector"]["link_view"], SIGNAL("clear"), self.tabs["collector"]["link_view"].clear) groupPackage.layout().addWidget(self.tabs["collector"]["package_view"]) groupPackage.layout().addWidget(toQueue) groupLinks.layout().addWidget(self.tabs["collector"]["link_view"]) @@ -164,10 +165,11 @@ class MainWindow(QMainWindow): self.queueContext = QMenu() self.queueContext.buttons = {} self.queueContext.item = (None, None) - self.queueContext.buttons["remove"] = QAction("Remove", self.queueContext) - self.queueContext.buttons["restart"] = QAction("Restart", self.queueContext) + self.queueContext.buttons["remove"] = QAction(QIcon("icons/gui/remove_small.png"), "Remove", self.queueContext) + self.queueContext.buttons["restart"] = QAction(QIcon("icons/gui/refresh_small.png"), "Restart", self.queueContext) self.queueContext.addAction(self.queueContext.buttons["remove"]) self.queueContext.addAction(self.queueContext.buttons["restart"]) + self.connect(self.queueContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) self.connect(self.queueContext.buttons["restart"], SIGNAL("triggered()"), self.slotRestartDownload) def slotToggleStatus(self, status): @@ -279,9 +281,13 @@ class MainWindow(QMainWindow): """ globalPos = self.tabs["queue"]["view"].mapToGlobal(pos) i = self.tabs["queue"]["view"].itemAt(pos) + if not i: + return i.setSelected(True) self.queueContext.item = (i.data(0, Qt.UserRole).toPyObject(), i.parent() == None) - self.queueContext.exec_(globalPos) + menuPos = QCursor.pos() + menuPos.setX(menuPos.x()+2) + self.queueContext.exec_(menuPos) def slotPackageCollectorContextMenu(self, pos): """ @@ -302,4 +308,12 @@ class MainWindow(QMainWindow): id, isTopLevel = self.queueContext.item if not id == None: self.emit(SIGNAL("restartDownload"), id, isTopLevel) + + def slotRemoveDownload(self): + """ + remove download action is triggered + """ + id, isTopLevel = self.queueContext.item + if not id == None: + self.emit(SIGNAL("removeDownload"), id, isTopLevel) diff --git a/module/gui/Queue.py b/module/gui/Queue.py index c9a3e858b..35e1163b9 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -61,8 +61,10 @@ class Queue(QThread): del d["name"] del d["status"] downloading[did] = d + ids = [] for data in packs: pack = self.getPack(data["id"]) + ids.append(data["id"]) if not pack: pack = self.QueuePack(self) pack.setData(data) @@ -73,12 +75,15 @@ class Queue(QThread): child = pack.getChild(fid) if not child: child = self.QueueFile(self, pack) + info["downloading"] = None try: info["downloading"] = downloading[info["id"]] except: - info["downloading"] = None + pass child.setData(info) pack.addChild(fid, child) + pack.clear(files) + self.clear(ids) def addPack(self, pid, newPack): pos = None @@ -122,6 +127,17 @@ class Queue(QThread): return pack return None + def clear(self, ids): + clear = False + for pack in self.queue: + if not pack.getData()["id"] in ids: + clear = True + break + if not clear: + return + self.queue = [] + self.view.emit(SIGNAL("clear")) + def getWaitingProgress(self, q): locker = QMutexLocker(self.mutex) if isinstance(q, self.QueueFile): @@ -173,7 +189,6 @@ class Queue(QThread): return 0 def getSpeed(self, q): - #locker = QMutexLocker(self.mutex) if isinstance(q, self.QueueFile): data = q.getData() if data["downloading"]: @@ -251,6 +266,17 @@ class Queue(QThread): def getData(self): return self.data + + def clear(self, ids): + clear = False + for file in self.getChildren(): + if not file.getData()["id"] in ids: + clear = True + break + if not clear: + return + self.queue.queue = [] + self.queue.view.emit(SIGNAL("clear")) class QueueFile(): def __init__(self, queue, pack): diff --git a/module/gui/connector.py b/module/gui/connector.py index 75781ebb1..4d3af0d61 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -230,3 +230,23 @@ class connector(QThread): self.proxy.restart_file(fileid) finally: self.mutex.unlock() + + def removePackage(self, packid): + """ + remove a package + """ + self.mutex.lock() + try: + self.proxy.del_packages([packid,]) + finally: + self.mutex.unlock() + + def removeFile(self, fileid): + """ + remove a file + """ + self.mutex.lock() + try: + self.proxy.del_links([fileid,]) + finally: + self.mutex.unlock() -- cgit v1.2.3 From 504b313112be6a82d6eee418ae059646ecfc4b30 Mon Sep 17 00:00:00 2001 From: mkaay Date: Sat, 26 Dec 2009 20:18:11 +0100 Subject: fixed ddl-music, cleaned up, new status (starting), some more fixes --- module/gui/Queue.py | 15 ++++++++++++-- module/gui/connector.py | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Queue.py b/module/gui/Queue.py index 35e1163b9..f542c9a6b 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -198,10 +198,10 @@ class Queue(QThread): count = len(children) speed_sum = 0 all_waiting = True + running = False for child in children: val = 0 data = child.getData() - running = False if data["downloading"]: if not data["status_type"] == "waiting": all_waiting = False @@ -239,7 +239,7 @@ class Queue(QThread): item = QTreeWidgetItem() parent.insertChild(pos, item) speed = self.queue.getSpeed(newChild) - if speed == None: + if speed == None or newChild.getData()["status_type"] == "starting": status = newChild.getData()["status_type"] else: status = "%s (%s KB/s)" % (newChild.getData()["status_type"], speed) @@ -269,12 +269,23 @@ class Queue(QThread): def clear(self, ids): clear = False + children = {} for file in self.getChildren(): if not file.getData()["id"] in ids: clear = True break + try: + children[file.getData()["id"]] + clear = True + except: + children[file.getData()["id"]] = True + if not clear: return + ppos = self.queue.queue.index(self) + parent = self.queue.view.topLevelItem(ppos) + parent.takeChildren() + self.children = [] self.queue.queue = [] self.queue.view.emit(SIGNAL("clear")) diff --git a/module/gui/connector.py b/module/gui/connector.py index 4d3af0d61..4ac635200 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -35,6 +35,8 @@ class connector(QThread): self.running = True self.proxy = None self.addr = None + self.errorQueue = [] + self.connect(self, SIGNAL("proxy_error"), self._proxyError) def setAddr(self, addr): """ @@ -52,6 +54,7 @@ class connector(QThread): self.connectProxy(self.addr) while self.running: sleep(1) + self.getError() def stop(self): """ @@ -68,6 +71,21 @@ class connector(QThread): if not server_version == SERVER_VERSION: self.emit(SIGNAL("error_box"), "server is version %s client accepts version %s" % (server_version, SERVER_VERSION)) + def _proxyError(self, func): + """ + formats proxy error msg + """ + msg = "proxy error in '%s'" % (func,) + self.errorQueue.append(msg) + + def getError(self): + self.mutex.lock() + if len(self.errorQueue) > 0: + err = self.errorQueue.pop() + print err + self.emit(SIGNAL("error_box"), err) + self.mutex.unlock() + def getLinkCollector(self): """ grab links from collector and return the ids @@ -75,6 +93,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_collector_files() + except: + self.emit(SIGNAL("proxy_error"), "getLinkCollector") finally: self.mutex.unlock() @@ -85,6 +105,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_collector_packages() + except: + self.emit(SIGNAL("proxy_error"), "getPackageCollector") finally: self.mutex.unlock() @@ -95,6 +117,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_file_info(id) + except: + self.emit(SIGNAL("proxy_error"), "getLinkInfo") finally: self.mutex.unlock() @@ -105,6 +129,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_package_data(id) + except: + self.emit(SIGNAL("proxy_error"), "getPackageInfo") finally: self.mutex.unlock() @@ -115,6 +141,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_queue() + except: + self.emit(SIGNAL("proxy_error"), "getPackageQueue") finally: self.mutex.unlock() @@ -125,6 +153,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_package_files(id) + except: + self.emit(SIGNAL("proxy_error"), "getPackageFiles") finally: self.mutex.unlock() @@ -135,6 +165,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.status_downloads() + except: + self.emit(SIGNAL("proxy_error"), "getDownloadQueue") finally: self.mutex.unlock() @@ -145,6 +177,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.status_server() + except: + self.emit(SIGNAL("proxy_error"), "getServerStatus") finally: self.mutex.unlock() @@ -155,6 +189,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.add_urls(links) + except: + self.emit(SIGNAL("proxy_error"), "addURLs") finally: self.mutex.unlock() @@ -165,6 +201,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.toggle_pause() + except: + self.emit(SIGNAL("proxy_error"), "togglePause") finally: self.mutex.unlock() @@ -178,6 +216,8 @@ class connector(QThread): self.proxy.pause_server() else: self.proxy.unpause_server() + except: + self.emit(SIGNAL("proxy_error"), "setPause") finally: self.mutex.unlock() @@ -188,6 +228,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.new_package(name) + except: + self.emit(SIGNAL("proxy_error"), "newPackage") finally: self.mutex.unlock() @@ -198,6 +240,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.move_file_2_package(fileid, packid) + except: + self.emit(SIGNAL("proxy_error"), "addFileToPackage") finally: self.mutex.unlock() @@ -208,6 +252,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.push_package_2_queue(packid) + except: + self.emit(SIGNAL("proxy_error"), "pushPackageToQueue") finally: self.mutex.unlock() @@ -218,6 +264,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.restart_package(packid) + except: + self.emit(SIGNAL("proxy_error"), "restartPackage") finally: self.mutex.unlock() @@ -228,6 +276,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.restart_file(fileid) + except: + self.emit(SIGNAL("proxy_error"), "restartFile") finally: self.mutex.unlock() @@ -238,6 +288,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.del_packages([packid,]) + except: + self.emit(SIGNAL("proxy_error"), "removePackage") finally: self.mutex.unlock() @@ -248,5 +300,7 @@ class connector(QThread): self.mutex.lock() try: self.proxy.del_links([fileid,]) + except: + self.emit(SIGNAL("proxy_error"), "removeFile") finally: self.mutex.unlock() -- cgit v1.2.3 From 8888b714d748398e99f7425fa861f4e165579da6 Mon Sep 17 00:00:00 2001 From: mkaay Date: Sat, 26 Dec 2009 20:46:36 +0100 Subject: fixed view update --- module/gui/Collector.py | 32 ++++++++++++++++++++++---------- module/gui/Queue.py | 20 ++++++++++---------- 2 files changed, 32 insertions(+), 20 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 1f89670ce..bf0e50349 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -29,6 +29,7 @@ class PackageCollector(QThread): self.collector = [] self.interval = 2 self.running = True + self.rootItem = self.view.invisibleRootItem() self.mutex = QMutex() def run(self): @@ -43,6 +44,9 @@ class PackageCollector(QThread): locker = QMutexLocker(self.mutex) packs = self.connector.getPackageCollector() ids = [] + for data in packs: + ids.append(data["id"]) + self.clear(ids) for data in packs: ids.append(data["id"]) pack = self.getPack(data["id"]) @@ -51,6 +55,7 @@ class PackageCollector(QThread): pack.setData(data) self.addPack(data["id"], pack) files = self.connector.getPackageFiles(data["id"]) + pack.clear(files) for fid in files: info = self.connector.getLinkInfo(fid) child = pack.getChild(fid) @@ -58,8 +63,6 @@ class PackageCollector(QThread): child = self.PackageCollectorFile(self, pack) child.setData(info) pack.addChild(fid, child) - pack.clear(files) - self.clear(ids) def addPack(self, pid, newPack): pos = None @@ -74,10 +77,10 @@ class PackageCollector(QThread): except: self.collector.append(newPack) pos = self.collector.index(newPack) - item = self.view.topLevelItem(pos) + item = self.rootItem.child(pos) if not item: item = QTreeWidgetItem() - self.view.insertTopLevelItem(pos, item) + self.rootItem.insertChild(pos, item) item.setData(0, Qt.DisplayRole, QVariant(newPack.getData()["package_name"])) item.setData(0, Qt.UserRole, QVariant(pid)) @@ -95,8 +98,8 @@ class PackageCollector(QThread): break if not clear: return - self.collector = [] - self.view.emit(SIGNAL("clear")) + self.queue = [] + self.rootItem.takeChildren() class PackageCollectorPack(): def __init__(self, collector): @@ -118,7 +121,7 @@ class PackageCollector(QThread): self.children.append(newChild) pos = self.children.index(newChild) ppos = self.collector.collector.index(self) - parent = self.collector.view.topLevelItem(ppos) + parent = self.collector.rootItem.child(ppos) item = parent.child(pos) if not item: item = QTreeWidgetItem() @@ -149,14 +152,23 @@ class PackageCollector(QThread): def clear(self, ids): clear = False + children = {} for file in self.getChildren(): if not file.getData()["id"] in ids: clear = True break + try: + children[file.getData()["id"]] + clear = True + except: + children[file.getData()["id"]] = True + if not clear: return - self.collector.collector = [] - self.collector.view.emit(SIGNAL("clear")) + ppos = self.collector.collector.index(self) + parent = self.collector.rootItem.child(ppos) + parent.takeChildren() + self.children = [] class PackageCollectorFile(): def __init__(self, collector, pack): @@ -193,6 +205,7 @@ class LinkCollector(QThread): def update(self): locker = QMutexLocker(self.mutex) ids = self.connector.getLinkCollector() + self.clear(ids) for id in ids: data = self.connector.getLinkInfo(id) file = self.getFile(id) @@ -200,7 +213,6 @@ class LinkCollector(QThread): file = self.LinkCollectorFile(self) file.setData(data) self.addFile(id, file) - self.clear(ids) def addFile(self, pid, newFile): pos = None diff --git a/module/gui/Queue.py b/module/gui/Queue.py index f542c9a6b..0def31bf6 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -40,6 +40,7 @@ class Queue(QThread): self.interval = 1 self.running = True self.wait_dict = {} + self.rootItem = self.view.invisibleRootItem() self.mutex = QMutex() def run(self): @@ -63,13 +64,16 @@ class Queue(QThread): downloading[did] = d ids = [] for data in packs: - pack = self.getPack(data["id"]) ids.append(data["id"]) + self.clear(ids) + 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"]) + pack.clear(files) for fid in files: info = self.connector.getLinkInfo(fid) child = pack.getChild(fid) @@ -82,8 +86,6 @@ class Queue(QThread): pass child.setData(info) pack.addChild(fid, child) - pack.clear(files) - self.clear(ids) def addPack(self, pid, newPack): pos = None @@ -98,10 +100,10 @@ class Queue(QThread): except: self.queue.append(newPack) pos = self.queue.index(newPack) - item = self.view.topLevelItem(pos) + item = self.rootItem.child(pos) if not item: item = QTreeWidgetItem() - self.view.insertTopLevelItem(pos, item) + self.rootItem.insertChild(pos, item) item.setData(0, Qt.DisplayRole, QVariant(newPack.getData()["package_name"])) status = -1 speed = self.getSpeed(newPack) @@ -136,7 +138,7 @@ class Queue(QThread): if not clear: return self.queue = [] - self.view.emit(SIGNAL("clear")) + self.rootItem.takeChildren() def getWaitingProgress(self, q): locker = QMutexLocker(self.mutex) @@ -233,7 +235,7 @@ class Queue(QThread): self.children.append(newChild) pos = self.children.index(newChild) ppos = self.queue.queue.index(self) - parent = self.queue.view.topLevelItem(ppos) + parent = self.queue.rootItem.child(ppos) item = parent.child(pos) if not item: item = QTreeWidgetItem() @@ -283,11 +285,9 @@ class Queue(QThread): if not clear: return ppos = self.queue.queue.index(self) - parent = self.queue.view.topLevelItem(ppos) + parent = self.queue.rootItem.child(ppos) parent.takeChildren() self.children = [] - self.queue.queue = [] - self.queue.view.emit(SIGNAL("clear")) class QueueFile(): def __init__(self, queue, pack): -- cgit v1.2.3 From b5d1c47ac2590fe4314d7e96d58443c30463746c Mon Sep 17 00:00:00 2001 From: mkaay Date: Sat, 26 Dec 2009 22:35:20 +0100 Subject: gui contaoner upload, closes #39 --- module/gui/MainWindow.py | 11 +++++++++++ module/gui/connector.py | 13 +++++++++++++ 2 files changed, 24 insertions(+) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 53de8cd54..744518adb 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -122,9 +122,11 @@ class MainWindow(QMainWindow): self.addMenu = QMenu() packageAction = self.addMenu.addAction("Package") linkAction = self.addMenu.addAction("Links") + containerAction = self.addMenu.addAction("Container") self.connect(self.actions["add"], SIGNAL("triggered()"), self.slotAdd) self.connect(packageAction, SIGNAL("triggered()"), self.slotShowAddPackage) self.connect(linkAction, SIGNAL("triggered()"), self.slotShowAddLinks) + self.connect(containerAction, SIGNAL("triggered()"), self.slotShowAddContainer) def init_tabs(self): """ @@ -230,6 +232,15 @@ class MainWindow(QMainWindow): """ self.emit(SIGNAL("addPackage"), name, ids) + def slotShowAddContainer(self): + """ + action from add-menu + show file selector, emit upload + """ + fileNames = QFileDialog.getOpenFileNames(self, "Container Öffnen", "", "All Container Types (*.dlc *.ccf *.rsdf *.txt);;DLC (*.dlc);;CCF (*.ccf);;RSDF (*.rsdf);;Text Files (*.txt)") + for name in fileNames: + self.emit(SIGNAL("addContainer"), str(name)) + def slotPushPackageToQueue(self): """ push collector pack to queue diff --git a/module/gui/connector.py b/module/gui/connector.py index 4ac635200..e52cf42ff 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -304,3 +304,16 @@ class connector(QThread): self.emit(SIGNAL("proxy_error"), "removeFile") finally: self.mutex.unlock() + + def uploadContainer(self, filename, type, content): + """ + upload a container + """ + self.mutex.lock() + try: + self.proxy.upload_container(filename, type, content) + except: + self.emit(SIGNAL("proxy_error"), "uploadContainer") + finally: + self.mutex.unlock() + -- cgit v1.2.3 From 757f025247d77b085b6168d5f625d2bbfa7c4c0d Mon Sep 17 00:00:00 2001 From: mkaay Date: Sun, 27 Dec 2009 14:45:22 +0100 Subject: stop button works, closes #59 --- module/gui/MainWindow.py | 24 +++++++++++++++++++++--- module/gui/connector.py | 24 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 744518adb..74bf00b51 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -79,8 +79,13 @@ class MainWindow(QMainWindow): self.tabs = {} self.tabs["queue"] = {"w":QWidget()} self.tabs["collector"] = {"w":QWidget()} + self.tabs["settings"] = {"w":QWidget()} + self.tabs["log"] = {"w":QWidget()} self.tabw.addTab(self.tabs["queue"]["w"], "Queue") self.tabw.addTab(self.tabs["collector"]["w"], "Collector") + self.tabw.addTab(self.tabs["settings"]["w"], "Settings") + self.tabw.addTab(self.tabs["log"]["w"], "Log") + self.tabw.setTabEnabled(2, False) #init tabs self.init_tabs() @@ -159,6 +164,21 @@ class MainWindow(QMainWindow): self.tabs["collector"]["package_view"].setContextMenuPolicy(Qt.CustomContextMenu) self.tabs["collector"]["link_view"].setContextMenuPolicy(Qt.CustomContextMenu) self.tabs["queue"]["view"].setContextMenuPolicy(Qt.CustomContextMenu) + + #settings + self.tabs["settings"]["l"] = QGridLayout() + self.tabs["settings"]["w"].setLayout(self.tabs["settings"]["l"]) + #self.tabs["settings"]["view"] = QTreeWidget() + #self.tabs["settings"]["l"].addWidget(self.tabs["settings"]["view"]) + + #log + self.tabs["log"]["l"] = QGridLayout() + self.tabs["log"]["w"].setLayout(self.tabs["log"]["l"]) + self.tabs["log"]["text"] = QTextEdit() + self.tabs["log"]["text"].logOffset = 0 + self.tabs["log"]["text"].setReadOnly(True) + self.connect(self.tabs["log"]["text"], SIGNAL("append(QString)"), self.tabs["log"]["text"].append) + self.tabs["log"]["l"].addWidget(self.tabs["log"]["text"]) def init_context(self): """ @@ -183,10 +203,8 @@ class MainWindow(QMainWindow): def slotStatusStop(self): """ stop button (toolbar) - - dummy """ - print "stop!" + self.emit(SIGNAL("stopAllDownloads")) def slotAdd(self): """ diff --git a/module/gui/connector.py b/module/gui/connector.py index e52cf42ff..64c05ba8c 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -316,4 +316,28 @@ class connector(QThread): self.emit(SIGNAL("proxy_error"), "uploadContainer") finally: self.mutex.unlock() + + def getLog(self, offset): + """ + get log + """ + self.mutex.lock() + try: + return self.proxy.get_log(offset) + except: + self.emit(SIGNAL("proxy_error"), "getLog") + finally: + self.mutex.unlock() + + def stopAllDownloads(self): + """ + get log + """ + self.mutex.lock() + try: + self.proxy.stop_downloads() + except: + self.emit(SIGNAL("proxy_error"), "stopAllDownloads") + finally: + self.mutex.unlock() -- cgit v1.2.3 From ff7d4f1a13db0f4a9d6c427dcccbb0d1faf6c577 Mon Sep 17 00:00:00 2001 From: mkaay Date: Sun, 27 Dec 2009 15:26:33 +0100 Subject: closes #51 --- module/gui/MainWindow.py | 1 + module/gui/connector.py | 100 ++++++++++++++++++++++++++--------------------- 2 files changed, 57 insertions(+), 44 deletions(-) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 74bf00b51..06df7447c 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -53,6 +53,7 @@ class MainWindow(QMainWindow): #set menubar and statusbar self.menubar = self.menuBar() self.statusbar = self.statusBar() + self.connect(self.statusbar, SIGNAL("showMsg"), self.statusbar.showMessage) self.serverStatus = QLabel("Status: Not Connected") self.statusbar.addPermanentWidget(self.serverStatus) diff --git a/module/gui/connector.py b/module/gui/connector.py index 64c05ba8c..8458d74b9 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -71,11 +71,11 @@ class connector(QThread): if not server_version == SERVER_VERSION: self.emit(SIGNAL("error_box"), "server is version %s client accepts version %s" % (server_version, SERVER_VERSION)) - def _proxyError(self, func): + def _proxyError(self, func, e): """ formats proxy error msg """ - msg = "proxy error in '%s'" % (func,) + msg = "proxy error in '%s':\n%s" % (func, e) self.errorQueue.append(msg) def getError(self): @@ -93,8 +93,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_collector_files() - except: - self.emit(SIGNAL("proxy_error"), "getLinkCollector") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getLinkCollector", e) finally: self.mutex.unlock() @@ -105,8 +105,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_collector_packages() - except: - self.emit(SIGNAL("proxy_error"), "getPackageCollector") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getPackageCollector", e) finally: self.mutex.unlock() @@ -117,8 +117,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_file_info(id) - except: - self.emit(SIGNAL("proxy_error"), "getLinkInfo") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getLinkInfo", e) finally: self.mutex.unlock() @@ -129,8 +129,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_package_data(id) - except: - self.emit(SIGNAL("proxy_error"), "getPackageInfo") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getPackageInfo", e) finally: self.mutex.unlock() @@ -141,8 +141,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_queue() - except: - self.emit(SIGNAL("proxy_error"), "getPackageQueue") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getPackageQueue", e) finally: self.mutex.unlock() @@ -153,8 +153,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_package_files(id) - except: - self.emit(SIGNAL("proxy_error"), "getPackageFiles") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getPackageFiles", e) finally: self.mutex.unlock() @@ -165,8 +165,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.status_downloads() - except: - self.emit(SIGNAL("proxy_error"), "getDownloadQueue") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getDownloadQueue", e) finally: self.mutex.unlock() @@ -177,8 +177,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.status_server() - except: - self.emit(SIGNAL("proxy_error"), "getServerStatus") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getServerStatus", e) finally: self.mutex.unlock() @@ -189,8 +189,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.add_urls(links) - except: - self.emit(SIGNAL("proxy_error"), "addURLs") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "addURLs", e) finally: self.mutex.unlock() @@ -201,8 +201,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.toggle_pause() - except: - self.emit(SIGNAL("proxy_error"), "togglePause") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "togglePause", e) finally: self.mutex.unlock() @@ -216,8 +216,8 @@ class connector(QThread): self.proxy.pause_server() else: self.proxy.unpause_server() - except: - self.emit(SIGNAL("proxy_error"), "setPause") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "setPause", e) finally: self.mutex.unlock() @@ -228,8 +228,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.new_package(name) - except: - self.emit(SIGNAL("proxy_error"), "newPackage") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "newPackage", e) finally: self.mutex.unlock() @@ -240,8 +240,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.move_file_2_package(fileid, packid) - except: - self.emit(SIGNAL("proxy_error"), "addFileToPackage") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "addFileToPackage", e) finally: self.mutex.unlock() @@ -252,8 +252,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.push_package_2_queue(packid) - except: - self.emit(SIGNAL("proxy_error"), "pushPackageToQueue") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "pushPackageToQueue", e) finally: self.mutex.unlock() @@ -264,8 +264,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.restart_package(packid) - except: - self.emit(SIGNAL("proxy_error"), "restartPackage") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "restartPackage", e) finally: self.mutex.unlock() @@ -276,8 +276,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.restart_file(fileid) - except: - self.emit(SIGNAL("proxy_error"), "restartFile") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "restartFile", e) finally: self.mutex.unlock() @@ -288,8 +288,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.del_packages([packid,]) - except: - self.emit(SIGNAL("proxy_error"), "removePackage") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "removePackage", e) finally: self.mutex.unlock() @@ -300,8 +300,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.del_links([fileid,]) - except: - self.emit(SIGNAL("proxy_error"), "removeFile") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "removeFile", e) finally: self.mutex.unlock() @@ -312,8 +312,8 @@ class connector(QThread): self.mutex.lock() try: self.proxy.upload_container(filename, type, content) - except: - self.emit(SIGNAL("proxy_error"), "uploadContainer") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "uploadContainer", e) finally: self.mutex.unlock() @@ -324,8 +324,8 @@ class connector(QThread): self.mutex.lock() try: return self.proxy.get_log(offset) - except: - self.emit(SIGNAL("proxy_error"), "getLog") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getLog", e) finally: self.mutex.unlock() @@ -336,8 +336,20 @@ class connector(QThread): self.mutex.lock() try: self.proxy.stop_downloads() - except: - self.emit(SIGNAL("proxy_error"), "stopAllDownloads") + except Exception, e: + self.emit(SIGNAL("proxy_error"), "stopAllDownloads", e) + finally: + self.mutex.unlock() + + def updateAvailable(self): + """ + update available + """ + self.mutex.lock() + try: + return self.proxy.update_available() + except Exception, e: + self.emit(SIGNAL("proxy_error"), "updateAvailable", e) finally: self.mutex.unlock() -- cgit v1.2.3 From 090c9d2abdac07025fe6d7351e376e85aabc0891 Mon Sep 17 00:00:00 2001 From: mkaay Date: Sun, 27 Dec 2009 22:16:51 +0100 Subject: fixed uploaded.to and netload.in, gui clipboard check --- module/gui/MainWindow.py | 35 ++++++++++++++++++++++++++++++++--- module/gui/connector.py | 1 + 2 files changed, 33 insertions(+), 3 deletions(-) (limited to 'module/gui') diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 06df7447c..1e769110b 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -121,9 +121,12 @@ class MainWindow(QMainWindow): self.actions["status_stop"] = self.toolbar.addAction(QIcon("icons/gui/toolbar_stop.png"), "Stop") self.toolbar.addSeparator() self.actions["add"] = self.toolbar.addAction(QIcon("icons/gui/toolbar_add.png"), "Add") - #self.toolbar.addAction(QIcon("icons/gui/toolbar_remove.png"), "Remove") + self.toolbar.addSeparator() + self.actions["clipboard"] = self.toolbar.addAction(QIcon("icons/gui/clipboard.png"), "Check Clipboard") + self.actions["clipboard"].setCheckable(True) self.connect(self.actions["toggle_status"], SIGNAL("toggled(bool)"), self.slotToggleStatus) + self.connect(self.actions["clipboard"], SIGNAL("toggled(bool)"), self.slotToggleClipboard) self.connect(self.actions["status_stop"], SIGNAL("triggered()"), self.slotStatusStop) self.addMenu = QMenu() packageAction = self.addMenu.addAction("Package") @@ -185,6 +188,8 @@ class MainWindow(QMainWindow): """ create context menus """ + self.activeMenu = None + #queue self.queueContext = QMenu() self.queueContext.buttons = {} self.queueContext.item = (None, None) @@ -194,6 +199,14 @@ class MainWindow(QMainWindow): self.queueContext.addAction(self.queueContext.buttons["restart"]) self.connect(self.queueContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) self.connect(self.queueContext.buttons["restart"], SIGNAL("triggered()"), self.slotRestartDownload) + + #package collector + self.packageCollectorContext = QMenu() + self.packageCollectorContext.buttons = {} + self.packageCollectorContext.item = (None, None) + self.packageCollectorContext.buttons["remove"] = QAction(QIcon("icons/gui/remove_small.png"), "Remove", self.packageCollectorContext) + self.packageCollectorContext.addAction(self.packageCollectorContext.buttons["remove"]) + self.connect(self.packageCollectorContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) def slotToggleStatus(self, status): """ @@ -317,13 +330,23 @@ class MainWindow(QMainWindow): self.queueContext.item = (i.data(0, Qt.UserRole).toPyObject(), i.parent() == None) menuPos = QCursor.pos() menuPos.setX(menuPos.x()+2) + self.activeMenu = self.queueContext self.queueContext.exec_(menuPos) def slotPackageCollectorContextMenu(self, pos): """ custom context menu in package collector view requested """ - pass + globalPos = self.tabs["collector"]["package_view"].mapToGlobal(pos) + i = self.tabs["collector"]["package_view"].itemAt(pos) + if not i: + return + i.setSelected(True) + self.packageCollectorContext.item = (i.data(0, Qt.UserRole).toPyObject(), i.parent() == None) + menuPos = QCursor.pos() + menuPos.setX(menuPos.x()+2) + self.activeMenu = self.packageCollectorContext + self.packageCollectorContext.exec_(menuPos) def slotLinkCollectorContextMenu(self, pos): """ @@ -343,7 +366,13 @@ class MainWindow(QMainWindow): """ remove download action is triggered """ - id, isTopLevel = self.queueContext.item + id, isTopLevel = self.activeMenu.item if not id == None: self.emit(SIGNAL("removeDownload"), id, isTopLevel) + + def slotToggleClipboard(self, status): + """ + check clipboard (toolbar) + """ + self.emit(SIGNAL("setClipboardStatus"), status) diff --git a/module/gui/connector.py b/module/gui/connector.py index 8458d74b9..3f594d68e 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -335,6 +335,7 @@ class connector(QThread): """ self.mutex.lock() try: + self.proxy.pause_server() self.proxy.stop_downloads() except Exception, e: self.emit(SIGNAL("proxy_error"), "stopAllDownloads", e) -- cgit v1.2.3 From ce2a8294b5aefe4497c88f24c817084868b8b1eb Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 28 Dec 2009 15:32:06 +0100 Subject: gui now stable --- module/gui/Collector.py | 184 +++++++++++++++++++--------------------- module/gui/MainWindow.py | 6 +- module/gui/Queue.py | 217 ++++++++++++++++++++++++++--------------------- 3 files changed, 210 insertions(+), 197 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index bf0e50349..c2d167291 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -21,6 +21,8 @@ from PyQt4.QtGui import * from time import sleep +from module.gui.Queue import ItemIterator + class PackageCollector(QThread): def __init__(self, view, connector): QThread.__init__(self) @@ -52,7 +54,7 @@ class PackageCollector(QThread): pack = self.getPack(data["id"]) if not pack: pack = self.PackageCollectorPack(self) - pack.setData(data) + pack.setPackData(data) self.addPack(data["id"], pack) files = self.connector.getPackageFiles(data["id"]) pack.clear(files) @@ -61,125 +63,115 @@ class PackageCollector(QThread): child = pack.getChild(fid) if not child: child = self.PackageCollectorFile(self, pack) - child.setData(info) - pack.addChild(fid, child) + child.setFileData(info) + pack.addPackChild(fid, child) def addPack(self, pid, newPack): pos = None try: - for k, pack in enumerate(self.collector): - if pack.getData()["id"] == pid: - pos = k + for pack in ItemIterator(self.rootItem): + if pack.getPackData()["id"] == pid: + pos = self.rootItem.indexOfChild(pack) break if pos == None: raise Exception() - self.collector[pos] = newPack + item = self.rootItem.child(pos) + item.setPackData(newPack.getPackData()) except: - self.collector.append(newPack) - pos = self.collector.index(newPack) - item = self.rootItem.child(pos) - if not item: - item = QTreeWidgetItem() - self.rootItem.insertChild(pos, item) - item.setData(0, Qt.DisplayRole, QVariant(newPack.getData()["package_name"])) + self.rootItem.addChild(newPack) + item = newPack + item.setData(0, Qt.DisplayRole, QVariant(item.getPackData()["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: + for k, pack in enumerate(ItemIterator(self.rootItem)): + if pack.getPackData()["id"] == pid: return pack return None def clear(self, ids): clear = False - for pack in self.collector: - if not pack.getData()["id"] in ids: + for pack in ItemIterator(self.rootItem): + if not pack.getPackData()["id"] in ids: clear = True break if not clear: return - self.queue = [] self.rootItem.takeChildren() - class PackageCollectorPack(): + class PackageCollectorPack(QTreeWidgetItem): def __init__(self, collector): + QTreeWidgetItem.__init__(self) self.collector = collector - self.data = [] - self.children = [] + self._data = {} - def addChild(self, cid, newChild): + def addPackChild(self, cid, newChild): pos = None try: - for k, child in enumerate(self.getChildren()): + for child in ItemIterator(self): if child.getData()["id"] == cid: - pos = k + pos = self.indexOfChild(child) break if pos == None: raise Exception() - self.children[pos] = newChild + item = self.child(pos) + item.setFileData(newChild.getFileData()) except: - self.children.append(newChild) - pos = self.children.index(newChild) - ppos = self.collector.collector.index(self) - parent = self.collector.rootItem.child(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"])) + self.addChild(newChild) + item = newChild + item.setData(0, Qt.DisplayRole, QVariant(item.getFileData()["filename"])) item.setData(0, Qt.UserRole, QVariant(cid)) - flags = Qt.ItemIsEnabled - item.setFlags(flags) - def getChildren(self): - return self.children + def setPackData(self, data): + self._data = data - def getChild(self, cid): - try: - return self.children[cid] - except: - return None - - def hasChildren(self, data): - return (len(self.children) > 0) + def getPackData(self): + return self._data - def setData(self, data): - self.data = data + def getChildren(self): + ret = [] + for item in ItemIterator(self): + ret.append(item) + return ret - def getData(self): - return self.data + def getChild(self, cid): + for item in ItemIterator(self): + if item.getFileData()["id"] == cid: + return item + return None def clear(self, ids): clear = False - children = {} - for file in self.getChildren(): - if not file.getData()["id"] in ids: - clear = True - break - try: - children[file.getData()["id"]] - clear = True - except: - children[file.getData()["id"]] = True - - if not clear: + remove = [] + children = [] + for k, file in enumerate(self.getChildren()): + if not file.getFileData()["id"] in ids: + remove.append(file.getFileData()["id"]) + if file.getFileData()["id"] in children and not file.getFileData()["id"] in remove: + remove.append(file.getFileData()["id"]) + continue + children.append(file.getFileData()["id"]) + if not remove: return - ppos = self.collector.collector.index(self) - parent = self.collector.rootItem.child(ppos) - parent.takeChildren() - self.children = [] + remove.sort() + remove.reverse() + parent = self + for k in remove: + parent.takeChild(k) - class PackageCollectorFile(): + class PackageCollectorFile(QTreeWidgetItem): def __init__(self, collector, pack): + QTreeWidgetItem.__init__(self) self.collector = collector self.pack = pack + self._data = {} + self.wait_since = None - def getData(self): - return self.data + def getFileData(self): + return self._data - def setData(self, data): - self.data = data + def setFileData(self, data): + self._data = data def getPack(self): return self.pack @@ -189,9 +181,9 @@ class LinkCollector(QThread): QThread.__init__(self) self.view = view self.connector = connector - self.collector = [] self.interval = 2 self.running = True + self.rootItem = self.view.invisibleRootItem() self.mutex = QMutex() def run(self): @@ -211,54 +203,52 @@ class LinkCollector(QThread): file = self.getFile(id) if not file: file = self.LinkCollectorFile(self) - file.setData(data) + file.setFileData(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 + for pack in ItemIterator(self.rootItem): + if file.getFileData()["id"] == pid: + pos = self.rootItem.indexOfChild(file) break if pos == None: raise Exception() - self.collector[pos] = newFile + item = self.rootItem.child(pos) + item.setFileData(newFile.getPackData()) 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"])) + self.rootItem.addChild(newFile) + item = newFile + item.setData(0, Qt.DisplayRole, QVariant(newFile.getFileData()["filename"])) item.setData(0, Qt.UserRole, QVariant(pid)) flags = Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsEnabled item.setFlags(flags) def getFile(self, pid): - for k, file in enumerate(self.collector): - if file.getData()["id"] == pid: + for file in ItemIterator(self.rootItem): + if file.getFileData()["id"] == pid: return file return None def clear(self, ids): clear = False - for pack in self.collector: - if not pack.getData()["id"] in ids: + for file in ItemIterator(self.rootItem): + if not file.getFileData()["id"] in ids: clear = True break if not clear: return - self.collector = [] - self.view.emit(SIGNAL("clear")) + self.rootItem.takeChildren() - class LinkCollectorFile(): + class LinkCollectorFile(QTreeWidgetItem): def __init__(self, collector): + QTreeWidgetItem.__init__(self) self.collector = collector + self._data = {} - def getData(self): - return self.data + def getFileData(self): + return self._data - def setData(self, data): - self.data = data + def setFileData(self, data): + self._data = data diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 1e769110b..76f60a5bd 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -281,7 +281,11 @@ class MainWindow(QMainWindow): """ items = self.tabs["collector"]["package_view"].selectedItems() for item in items: - id = item.data(0, Qt.UserRole).toPyObject() + try: + id = item.getFileData()["id"] + id = item.parent().getPackData()["id"] + except: + id = item.getPackData()["id"] self.emit(SIGNAL("pushPackageToQueue"), id) def saveWindow(self): diff --git a/module/gui/Queue.py b/module/gui/Queue.py index 0def31bf6..c0f43c740 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -28,15 +28,16 @@ class Queue(QThread): self.connector = connector self.statusMap = { "finished": 0, - "checking": 1, - "waiting": 2, - "reconnected": 3, - "downloading": 4, - "failed": 5, - "aborted": 6, + "queued": 1, + "checking": 2, + "waiting": 3, + "reconnected": 4, + "starting": 5, + "downloading": 6, + "failed": 7, + "aborted": 8, } self.statusMapReverse = dict((v,k) for k, v in self.statusMap.iteritems()) - self.queue = [] self.interval = 1 self.running = True self.wait_dict = {} @@ -70,10 +71,10 @@ class Queue(QThread): pack = self.getPack(data["id"]) if not pack: pack = self.QueuePack(self) - pack.setData(data) - self.addPack(data["id"], pack) + pack.setPackData(data) files = self.connector.getPackageFiles(data["id"]) pack.clear(files) + self.addPack(data["id"], pack) for fid in files: info = self.connector.getLinkInfo(fid) child = pack.getChild(fid) @@ -84,35 +85,36 @@ class Queue(QThread): info["downloading"] = downloading[info["id"]] except: pass - child.setData(info) - pack.addChild(fid, child) + if not info["status_type"]: + info["status_type"] = "queued" + child.setFileData(info) + pack.addPackChild(fid, child) + self.addPack(data["id"], pack) def addPack(self, pid, newPack): pos = None try: - for k, pack in enumerate(self.queue): - if pack.getData()["id"] == pid: - pos = k + for pack in QueueIterator(self.rootItem): + if pack.getPackData()["id"] == pid: + pos = self.rootItem.indexOfChild(pack) break if pos == None: raise Exception() - self.queue[pos] = newPack + item = self.rootItem.child(pos) + item.setPackData(newPack.getPackData()) except: - self.queue.append(newPack) - pos = self.queue.index(newPack) - item = self.rootItem.child(pos) - if not item: - item = QTreeWidgetItem() - self.rootItem.insertChild(pos, item) - item.setData(0, Qt.DisplayRole, QVariant(newPack.getData()["package_name"])) + self.rootItem.addChild(newPack) + item = newPack + item.setData(0, Qt.DisplayRole, QVariant(item.getPackData()["package_name"])) status = -1 - speed = self.getSpeed(newPack) + speed = self.getSpeed(item) plugins = [] - 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 not child.data["plugin"] in plugins: - plugins.append(child.data["plugin"]) + for child in item.getChildren(): + data = child.getFileData() + if self.statusMap.has_key(data["status_type"]) and self.statusMap[data["status_type"]] > status: + status = self.statusMap[data["status_type"]] + if not data["plugin"] in plugins: + plugins.append(data["plugin"]) if status >= 0: if speed == None: statustxt = self.statusMapReverse[status] @@ -121,29 +123,28 @@ class Queue(QThread): item.setData(2, Qt.DisplayRole, QVariant(statustxt)) item.setData(1, Qt.DisplayRole, QVariant(", ".join(plugins))) item.setData(0, Qt.UserRole, QVariant(pid)) - item.setData(3, Qt.UserRole, QVariant(newPack)) + item.setData(3, Qt.UserRole, QVariant(item)) def getPack(self, pid): - for k, pack in enumerate(self.queue): - if pack.getData()["id"] == pid: + for k, pack in enumerate(ItemIterator(self.rootItem)): + if pack.getPackData()["id"] == pid: return pack return None def clear(self, ids): clear = False - for pack in self.queue: - if not pack.getData()["id"] in ids: + for pack in ItemIterator(self.rootItem): + if not pack.getPackData()["id"] in ids: clear = True break if not clear: return - self.queue = [] self.rootItem.takeChildren() def getWaitingProgress(self, q): locker = QMutexLocker(self.mutex) if isinstance(q, self.QueueFile): - data = q.getData() + data = q.getFileData() if data["status_type"] == "waiting" and data["downloading"]: until = float(data["downloading"]["wait_until"]) try: @@ -164,7 +165,7 @@ class Queue(QThread): def getProgress(self, q): locker = QMutexLocker(self.mutex) if isinstance(q, self.QueueFile): - data = q.getData() + data = q.getFileData() if data["downloading"]: return int(data["downloading"]["percent"]) if data["status_type"] == "finished" or \ @@ -177,12 +178,12 @@ class Queue(QThread): perc_sum = 0 for child in children: val = 0 - data = child.getData() + data = child.getFileData() if data["downloading"]: val = int(data["downloading"]["percent"]) - elif child.data["status_type"] == "finished" or \ - child.data["status_type"] == "failed" or \ - child.data["status_type"] == "aborted": + elif data["status_type"] == "finished" or \ + data["status_type"] == "failed" or \ + data["status_type"] == "aborted": val = 100 perc_sum += val if count == 0: @@ -192,7 +193,7 @@ class Queue(QThread): def getSpeed(self, q): if isinstance(q, self.QueueFile): - data = q.getData() + data = q.getFileData() if data["downloading"]: return int(data["downloading"]["speed"]) elif isinstance(q, self.QueuePack): @@ -203,7 +204,7 @@ class Queue(QThread): running = False for child in children: val = 0 - data = child.getData() + data = child.getFileData() if data["downloading"]: if not data["status_type"] == "waiting": all_waiting = False @@ -215,91 +216,87 @@ class Queue(QThread): return speed_sum return None - class QueuePack(): + class QueuePack(QTreeWidgetItem): def __init__(self, queue): + QTreeWidgetItem.__init__(self) self.queue = queue - self.data = [] - self.children = [] + self._data = {} - def addChild(self, cid, newChild): + def addPackChild(self, cid, newChild): pos = None try: - for k, child in enumerate(self.getChildren()): + for child in ItemIterator(self): if child.getData()["id"] == cid: - pos = k + pos = self.indexOfChild(child) break if pos == None: raise Exception() - self.children[pos] = newChild + item = self.child(pos) + item.setFileData(newChild.getFileData()) except: - self.children.append(newChild) - pos = self.children.index(newChild) - ppos = self.queue.queue.index(self) - parent = self.queue.rootItem.child(ppos) - item = parent.child(pos) - if not item: - item = QTreeWidgetItem() - parent.insertChild(pos, item) - speed = self.queue.getSpeed(newChild) - if speed == None or newChild.getData()["status_type"] == "starting": - status = newChild.getData()["status_type"] + self.addChild(newChild) + item = newChild + speed = self.queue.getSpeed(item) + if speed == None or item.getFileData()["status_type"] == "starting": + status = item.getFileData()["status_type"] else: - status = "%s (%s KB/s)" % (newChild.getData()["status_type"], speed) - item.setData(0, Qt.DisplayRole, QVariant(newChild.getData()["filename"])) + status = "%s (%s KB/s)" % (item.getFileData()["status_type"], speed) + item.setData(0, Qt.DisplayRole, QVariant(item.getFileData()["filename"])) item.setData(2, Qt.DisplayRole, QVariant(status)) - item.setData(1, Qt.DisplayRole, QVariant(newChild.getData()["plugin"])) + item.setData(1, Qt.DisplayRole, QVariant(item.getFileData()["plugin"])) item.setData(0, Qt.UserRole, QVariant(cid)) - item.setData(3, Qt.UserRole, QVariant(newChild)) - - def getChildren(self): - return self.children + item.setData(3, Qt.UserRole, QVariant(item)) - def getChild(self, cid): - try: - return self.children[cid] - except: - return None + def setPackData(self, data): + self._data = data - def hasChildren(self, data): - return (len(self.children) > 0) + def getPackData(self): + return self._data - def setData(self, data): - self.data = data + def getChildren(self): + ret = [] + for item in ItemIterator(self): + ret.append(item) + return ret - def getData(self): - return self.data + def getChild(self, cid): + for item in ItemIterator(self): + if item.getFileData()["id"] == cid: + return item + return None def clear(self, ids): clear = False - children = {} - for file in self.getChildren(): - if not file.getData()["id"] in ids: - clear = True - break - try: - children[file.getData()["id"]] - clear = True - except: - children[file.getData()["id"]] = True - - if not clear: + remove = [] + children = [] + for k, file in enumerate(self.getChildren()): + if not file.getFileData()["id"] in ids: + remove.append(file.getFileData()["id"]) + if file.getFileData()["id"] in children and not file.getFileData()["id"] in remove: + remove.append(file.getFileData()["id"]) + continue + children.append(file.getFileData()["id"]) + if not remove: return - ppos = self.queue.queue.index(self) - parent = self.queue.rootItem.child(ppos) - parent.takeChildren() - self.children = [] + remove.sort() + remove.reverse() + parent = self + for k in remove: + parent.takeChild(k) - class QueueFile(): + class QueueFile(QTreeWidgetItem): def __init__(self, queue, pack): + QTreeWidgetItem.__init__(self) self.queue = queue self.pack = pack + self._data = {} self.wait_since = None - def getData(self): - return self.data + def getFileData(self): + return self._data - def setData(self, data): - self.data = data + def setFileData(self, data): + self._data = data def getPack(self): return self.pack @@ -335,3 +332,25 @@ class QueueProgressBarDelegate(QItemDelegate): QApplication.style().drawControl(QStyle.CE_ProgressBar, opts, painter) return QItemDelegate.paint(self, painter, option, index) + +class ItemIterator(): + def __init__(self, item): + self.item = item + self.current = -1 + + def __iadd__(self, val): + self.current += val + + def value(self): + return self.item.child(self.current) + + def next(self): + self.__iadd__(1) + value = self.value() + if value: + return self.value() + else: + raise StopIteration + + def __iter__(self): + return self -- cgit v1.2.3 From da359f8c770bac754234e0f899058b25126cd476 Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 28 Dec 2009 19:51:37 +0100 Subject: gui: easier package management --- module/gui/Collector.py | 26 +++++++++++++++++------- module/gui/MainWindow.py | 50 ++++++++++++++++++++++++----------------------- module/gui/PackageDock.py | 2 +- module/gui/Queue.py | 10 +++++++--- 4 files changed, 53 insertions(+), 35 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index c2d167291..07a5203e9 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -33,6 +33,12 @@ class PackageCollector(QThread): self.running = True self.rootItem = self.view.invisibleRootItem() self.mutex = QMutex() + item = self.PackageCollectorPack(self) + item.setPackData({"id":"fixed"}) + item.setData(0, Qt.DisplayRole, QVariant("Single Links")) + item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) + self.rootItem.addChild(item) + self.linkCollector = item def run(self): while self.running: @@ -78,10 +84,11 @@ class PackageCollector(QThread): item = self.rootItem.child(pos) item.setPackData(newPack.getPackData()) except: - self.rootItem.addChild(newPack) + self.rootItem.insertChild(self.rootItem.childCount()-1, newPack) item = newPack item.setData(0, Qt.DisplayRole, QVariant(item.getPackData()["package_name"])) item.setData(0, Qt.UserRole, QVariant(pid)) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) def getPack(self, pid): for k, pack in enumerate(ItemIterator(self.rootItem)): @@ -91,13 +98,17 @@ class PackageCollector(QThread): def clear(self, ids): clear = False - for pack in ItemIterator(self.rootItem): - if not pack.getPackData()["id"] in ids: + remove = [] + for k, pack in enumerate(ItemIterator(self.rootItem)): + if not pack.getPackData()["id"] in ids and not pack.getPackData()["id"] == "fixed": clear = True - break + remove.append(k) if not clear: return - self.rootItem.takeChildren() + remove.sort() + remove.reverse() + for k in remove: + self.rootItem.takeChild(k) class PackageCollectorPack(QTreeWidgetItem): def __init__(self, collector): @@ -121,6 +132,7 @@ class PackageCollector(QThread): item = newChild item.setData(0, Qt.DisplayRole, QVariant(item.getFileData()["filename"])) item.setData(0, Qt.UserRole, QVariant(cid)) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) def setPackData(self, data): self._data = data @@ -177,13 +189,13 @@ class PackageCollector(QThread): return self.pack class LinkCollector(QThread): - def __init__(self, view, connector): + def __init__(self, view, root, connector): QThread.__init__(self) self.view = view self.connector = connector self.interval = 2 self.running = True - self.rootItem = self.view.invisibleRootItem() + self.rootItem = root self.mutex = QMutex() def run(self): diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 76f60a5bd..610d8e840 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -102,8 +102,9 @@ class MainWindow(QMainWindow): self.connect(self.mactions["exit"], SIGNAL("triggered()"), self.close) self.connect(self.tabs["queue"]["view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotQueueContextMenu) - self.connect(self.tabs["collector"]["package_view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotPackageCollectorContextMenu) - self.connect(self.tabs["collector"]["link_view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotLinkCollectorContextMenu) + self.connect(self.tabs["collector"]["package_view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotcollectorContextMenu) + + self.lastAddedID = None def init_toolbar(self): """ @@ -149,31 +150,21 @@ class MainWindow(QMainWindow): #collector groupPackage = QGroupBox("Packages") - groupLinks = QGroupBox("Links") groupPackage.setLayout(QVBoxLayout()) - groupLinks.setLayout(QVBoxLayout()) toQueue = QPushButton("Push selected packages to queue") self.tabs["collector"]["l"] = QGridLayout() self.tabs["collector"]["w"].setLayout(self.tabs["collector"]["l"]) self.tabs["collector"]["package_view"] = QTreeWidget() - self.connect(self.tabs["collector"]["package_view"], SIGNAL("clear"), self.tabs["collector"]["package_view"].clear) - self.tabs["collector"]["link_view"] = QTreeWidget() - self.connect(self.tabs["collector"]["link_view"], SIGNAL("clear"), self.tabs["collector"]["link_view"].clear) groupPackage.layout().addWidget(self.tabs["collector"]["package_view"]) groupPackage.layout().addWidget(toQueue) - groupLinks.layout().addWidget(self.tabs["collector"]["link_view"]) self.tabs["collector"]["l"].addWidget(groupPackage, 0, 0) - self.tabs["collector"]["l"].addWidget(groupLinks, 0, 1) self.connect(toQueue, SIGNAL("clicked()"), self.slotPushPackageToQueue) self.tabs["collector"]["package_view"].setContextMenuPolicy(Qt.CustomContextMenu) - self.tabs["collector"]["link_view"].setContextMenuPolicy(Qt.CustomContextMenu) self.tabs["queue"]["view"].setContextMenuPolicy(Qt.CustomContextMenu) #settings self.tabs["settings"]["l"] = QGridLayout() self.tabs["settings"]["w"].setLayout(self.tabs["settings"]["l"]) - #self.tabs["settings"]["view"] = QTreeWidget() - #self.tabs["settings"]["l"].addWidget(self.tabs["settings"]["view"]) #log self.tabs["log"]["l"] = QGridLayout() @@ -200,13 +191,16 @@ class MainWindow(QMainWindow): self.connect(self.queueContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) self.connect(self.queueContext.buttons["restart"], SIGNAL("triggered()"), self.slotRestartDownload) - #package collector - self.packageCollectorContext = QMenu() - self.packageCollectorContext.buttons = {} - self.packageCollectorContext.item = (None, None) - self.packageCollectorContext.buttons["remove"] = QAction(QIcon("icons/gui/remove_small.png"), "Remove", self.packageCollectorContext) - self.packageCollectorContext.addAction(self.packageCollectorContext.buttons["remove"]) - self.connect(self.packageCollectorContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) + #collector + self.collectorContext = QMenu() + self.collectorContext.buttons = {} + self.collectorContext.item = (None, None) + self.collectorContext.buttons["remove"] = QAction(QIcon("icons/gui/remove_small.png"), "Remove", self.collectorContext) + self.collectorContext.buttons["push"] = QAction(QIcon("icons/gui/push_small.png"), "Push to queue", self.collectorContext) + self.collectorContext.addAction(self.collectorContext.buttons["push"]) + self.collectorContext.addAction(self.collectorContext.buttons["remove"]) + self.connect(self.collectorContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) + self.connect(self.collectorContext.buttons["push"], SIGNAL("triggered()"), self.slotPushPackageToQueue) def slotToggleStatus(self, status): """ @@ -282,10 +276,18 @@ class MainWindow(QMainWindow): items = self.tabs["collector"]["package_view"].selectedItems() for item in items: try: - id = item.getFileData()["id"] + item.getFileData() id = item.parent().getPackData()["id"] + pack = item.parent() except: id = item.getPackData()["id"] + pack = item + if id == "fixed": + ids = [] + for child in pack.getChildren(): + ids.append(child.getFileData()["id"]) + self.emit(SIGNAL("addPackage"), "Single Links", ids) + id = self.lastAddedID self.emit(SIGNAL("pushPackageToQueue"), id) def saveWindow(self): @@ -337,7 +339,7 @@ class MainWindow(QMainWindow): self.activeMenu = self.queueContext self.queueContext.exec_(menuPos) - def slotPackageCollectorContextMenu(self, pos): + def slotcollectorContextMenu(self, pos): """ custom context menu in package collector view requested """ @@ -346,11 +348,11 @@ class MainWindow(QMainWindow): if not i: return i.setSelected(True) - self.packageCollectorContext.item = (i.data(0, Qt.UserRole).toPyObject(), i.parent() == None) + self.collectorContext.item = (i.data(0, Qt.UserRole).toPyObject(), i.parent() == None) menuPos = QCursor.pos() menuPos.setX(menuPos.x()+2) - self.activeMenu = self.packageCollectorContext - self.packageCollectorContext.exec_(menuPos) + self.activeMenu = self.collectorContext + self.collectorContext.exec_(menuPos) def slotLinkCollectorContextMenu(self, pos): """ diff --git a/module/gui/PackageDock.py b/module/gui/PackageDock.py index b90e3533d..c81798935 100644 --- a/module/gui/PackageDock.py +++ b/module/gui/PackageDock.py @@ -53,7 +53,7 @@ class NewPackageWindow(QWidget): linksLabel = QLabel("Links in this Package") linkView = QTreeWidget() linkView.setSelectionBehavior(QAbstractItemView.SelectRows) - linkView.setSelectionMode(QAbstractItemView.SingleSelection) + linkView.setSelectionMode(QAbstractItemView.ExtendedSelection) linkView.setColumnCount(1) linkView.setHeaderLabels(["Name"]) linkView.setDragEnabled(True) diff --git a/module/gui/Queue.py b/module/gui/Queue.py index c0f43c740..499cb5199 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -133,13 +133,17 @@ class Queue(QThread): def clear(self, ids): clear = False - for pack in ItemIterator(self.rootItem): + remove = [] + for k, pack in enumerate(ItemIterator(self.rootItem)): if not pack.getPackData()["id"] in ids: clear = True - break + remove.append(k) if not clear: return - self.rootItem.takeChildren() + remove.sort() + remove.reverse() + for k in remove: + self.rootItem.takeChild(k) def getWaitingProgress(self, q): locker = QMutexLocker(self.mutex) -- cgit v1.2.3 From c225a31e70e85c6e400a7ed4407a1fa53de29689 Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 28 Dec 2009 20:44:49 +0100 Subject: you can now drop single links directly into a package --- module/gui/Collector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 07a5203e9..1b1a6b654 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -88,7 +88,7 @@ class PackageCollector(QThread): item = newPack item.setData(0, Qt.DisplayRole, QVariant(item.getPackData()["package_name"])) item.setData(0, Qt.UserRole, QVariant(pid)) - item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled) def getPack(self, pid): for k, pack in enumerate(ItemIterator(self.rootItem)): -- cgit v1.2.3 From 86949a6240bc6d5a5fd5e5677925e0d945686d3e Mon Sep 17 00:00:00 2001 From: mkaay Date: Mon, 28 Dec 2009 22:21:35 +0100 Subject: package renaming in collector works --- module/gui/Collector.py | 23 ++++++++++++++++++----- module/gui/MainWindow.py | 25 +++++++++++++++++++++++-- module/gui/connector.py | 12 ++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 1b1a6b654..8b421001e 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -39,6 +39,7 @@ class PackageCollector(QThread): item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) self.rootItem.addChild(item) self.linkCollector = item + self.pauseIDs = [] def run(self): while self.running: @@ -56,6 +57,8 @@ class PackageCollector(QThread): ids.append(data["id"]) self.clear(ids) for data in packs: + if data["id"] in self.pauseIDs: + continue ids.append(data["id"]) pack = self.getPack(data["id"]) if not pack: @@ -88,7 +91,7 @@ class PackageCollector(QThread): item = newPack item.setData(0, Qt.DisplayRole, QVariant(item.getPackData()["package_name"])) item.setData(0, Qt.UserRole, QVariant(pid)) - item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled) + item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsEditable) def getPack(self, pid): for k, pack in enumerate(ItemIterator(self.rootItem)): @@ -110,6 +113,16 @@ class PackageCollector(QThread): for k in remove: self.rootItem.takeChild(k) + def pauseItemUpdate(self, pid, pause=True): + locker = QMutexLocker(self.mutex) + if pause and not pid in self.pauseIDs: + self.pauseIDs.append(int(pid)) + else: + try: + self.pauseIDs.remove(int(pid)) + except: + pass + class PackageCollectorPack(QTreeWidgetItem): def __init__(self, collector): QTreeWidgetItem.__init__(self) @@ -210,13 +223,13 @@ class LinkCollector(QThread): locker = QMutexLocker(self.mutex) ids = self.connector.getLinkCollector() self.clear(ids) - for id in ids: - data = self.connector.getLinkInfo(id) - file = self.getFile(id) + for fid in ids: + data = self.connector.getLinkInfo(fid) + file = self.getFile(fid) if not file: file = self.LinkCollectorFile(self) file.setFileData(data) - self.addFile(id, file) + self.addFile(fid, file) def addFile(self, pid, newFile): pos = None diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 610d8e840..5237436f0 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -102,7 +102,8 @@ class MainWindow(QMainWindow): self.connect(self.mactions["exit"], SIGNAL("triggered()"), self.close) self.connect(self.tabs["queue"]["view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotQueueContextMenu) - self.connect(self.tabs["collector"]["package_view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotcollectorContextMenu) + self.connect(self.tabs["collector"]["package_view"], SIGNAL('customContextMenuRequested(const QPoint &)'), self.slotCollectorContextMenu) + self.connect(self.tabs["collector"]["package_view"].itemDelegate(), SIGNAL("closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint)"), self.slotCloseItemEditor) self.lastAddedID = None @@ -197,10 +198,13 @@ class MainWindow(QMainWindow): self.collectorContext.item = (None, None) self.collectorContext.buttons["remove"] = QAction(QIcon("icons/gui/remove_small.png"), "Remove", self.collectorContext) self.collectorContext.buttons["push"] = QAction(QIcon("icons/gui/push_small.png"), "Push to queue", self.collectorContext) + self.collectorContext.buttons["edit"] = QAction(QIcon("icons/gui/edit_small.png"), "Edit Name", self.collectorContext) self.collectorContext.addAction(self.collectorContext.buttons["push"]) + self.collectorContext.addAction(self.collectorContext.buttons["edit"]) self.collectorContext.addAction(self.collectorContext.buttons["remove"]) self.connect(self.collectorContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) self.connect(self.collectorContext.buttons["push"], SIGNAL("triggered()"), self.slotPushPackageToQueue) + self.connect(self.collectorContext.buttons["edit"], SIGNAL("triggered()"), self.slotEditPackage) def slotToggleStatus(self, status): """ @@ -339,7 +343,7 @@ class MainWindow(QMainWindow): self.activeMenu = self.queueContext self.queueContext.exec_(menuPos) - def slotcollectorContextMenu(self, pos): + def slotCollectorContextMenu(self, pos): """ custom context menu in package collector view requested """ @@ -352,6 +356,10 @@ class MainWindow(QMainWindow): menuPos = QCursor.pos() menuPos.setX(menuPos.x()+2) self.activeMenu = self.collectorContext + if hasattr(i, "getPackData"): + self.collectorContext.buttons["edit"].setVisible(True) + else: + self.collectorContext.buttons["edit"].setVisible(False) self.collectorContext.exec_(menuPos) def slotLinkCollectorContextMenu(self, pos): @@ -381,4 +389,17 @@ class MainWindow(QMainWindow): check clipboard (toolbar) """ self.emit(SIGNAL("setClipboardStatus"), status) + + def slotEditPackage(self): + item = self.tabs["collector"]["package_view"].currentItem() + pid = self.tabs["collector"]["package_view"].currentItem().data(0, Qt.UserRole).toPyObject() + print type(pid) + self.emit(SIGNAL("pauseItemUpdate"), pid, True) + self.tabs["collector"]["package_view"].editItem(item, 0) + + def slotCloseItemEditor(self, editor, hint): + pid = self.tabs["collector"]["package_view"].currentItem().data(0, Qt.UserRole).toPyObject() + print type(pid) + self.emit(SIGNAL("changePackageName"), pid, editor.text()) + self.emit(SIGNAL("pauseItemUpdate"), pid, False) diff --git a/module/gui/connector.py b/module/gui/connector.py index 3f594d68e..8a2909c5e 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -353,4 +353,16 @@ class connector(QThread): self.emit(SIGNAL("proxy_error"), "updateAvailable", e) finally: self.mutex.unlock() + + def setPackageName(self, pid, name): + """ + set new package name + """ + self.mutex.lock() + try: + return self.proxy.set_package_name(pid, name) + except Exception, e: + self.emit(SIGNAL("proxy_error"), "setPackageName", e) + finally: + self.mutex.unlock() -- cgit v1.2.3 From fa9cce4987da585f5bf21274cfbe5f046f46f703 Mon Sep 17 00:00:00 2001 From: mkaay Date: Tue, 29 Dec 2009 16:50:13 +0100 Subject: : Bitte gib eine Versions-Meldung ein. Zeilen beginnend mit 'HG:' werden entfernt. --- module/gui/Collector.py | 9 +++++++++ module/gui/ConnectionManager.py | 42 +++++++++++++++++++++++++++++++---------- module/gui/MainWindow.py | 15 +++++++++++++++ module/gui/connector.py | 24 +++++++++++++++++++++-- 4 files changed, 78 insertions(+), 12 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 8b421001e..356ab36ec 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -112,6 +112,15 @@ class PackageCollector(QThread): remove.reverse() for k in remove: self.rootItem.takeChild(k) + for pack in ItemIterator(self.rootItem): + if pack.getPackData()["id"] == "fixed": + return + item = self.PackageCollectorPack(self) + item.setPackData({"id":"fixed"}) + item.setData(0, Qt.DisplayRole, QVariant("Single Links")) + item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) + self.rootItem.addChild(item) + self.linkCollector = item def pauseItemUpdate(self, pid, pause=True): locker = QMutexLocker(self.mutex) diff --git a/module/gui/ConnectionManager.py b/module/gui/ConnectionManager.py index c997eee19..57aed3a18 100644 --- a/module/gui/ConnectionManager.py +++ b/module/gui/ConnectionManager.py @@ -53,6 +53,8 @@ class ConnectionManager(QWidget): self.connList = connList self.edit = self.EditWindow() self.connectSignals() + + self.defaultStates = {} def connectSignals(self): self.connect(self, SIGNAL("setConnections(connections)"), self.setConnections) @@ -61,6 +63,7 @@ class ConnectionManager(QWidget): self.connect(self.remove, SIGNAL("clicked()"), self.slotRemove) self.connect(self.connectb, SIGNAL("clicked()"), self.slotConnect) self.connect(self.edit, SIGNAL("save"), self.slotSave) + self.connect(self.connList, SIGNAL("itemDoubleClicked(QListWidgetItem *)"), self.slotItemDoubleClicked) def setConnections(self, connections): self.connList.clear() @@ -70,6 +73,7 @@ class ConnectionManager(QWidget): item.setData(Qt.UserRole, QVariant(conn)) self.connList.addItem(item) if conn["default"]: + item.setData(Qt.DisplayRole, QVariant("%s (Default)" % conn["name"])) self.connList.setCurrentItem(item) def slotNew(self): @@ -80,34 +84,51 @@ class ConnectionManager(QWidget): def slotEdit(self): item = self.connList.currentItem() data = item.data(Qt.UserRole).toPyObject() - tmp = {} - for k, d in data.items(): - tmp[str(k)] = d - data = tmp + data = self.cleanDict(data) self.edit.setData(data) self.edit.show() def slotRemove(self): item = self.connList.currentItem() data = item.data(Qt.UserRole).toPyObject() - tmp = {} - for k, d in data.items(): - tmp[str(k)] = d - data = tmp + data = self.cleanDict(data) self.emit(SIGNAL("removeConnection"), data) def slotConnect(self): item = self.connList.currentItem() data = item.data(Qt.UserRole).toPyObject() + data = self.cleanDict(data) + self.emit(SIGNAL("connect"), data) + + def cleanDict(self, data): tmp = {} for k, d in data.items(): tmp[str(k)] = d - data = tmp - self.emit(SIGNAL("connect"), data) + return tmp def slotSave(self, data): self.emit(SIGNAL("saveConnection"), data) + def slotItemDoubleClicked(self, defaultItem): + data = defaultItem.data(Qt.UserRole).toPyObject() + self.setDefault(data, True) + did = self.cleanDict(data)["id"] + allItems = self.connList.findItems("*", Qt.MatchWildcard) + count = self.connList.count() + for i in range(count): + item = self.connList.item(i) + data = item.data(Qt.UserRole).toPyObject() + if self.cleanDict(data)["id"] == did: + continue + self.setDefault(data, False) + + def setDefault(self, data, state): + data = self.cleanDict(data) + self.edit.setData(data) + data = self.edit.getData() + data["default"] = state + self.edit.emit(SIGNAL("save"), data) + class EditWindow(QWidget): def __init__(self): QWidget.__init__(self) @@ -225,3 +246,4 @@ class ConnectionManager(QWidget): data = self.getData() self.hide() self.emit(SIGNAL("save"), data) + diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 5237436f0..6daa0aa55 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -187,10 +187,13 @@ class MainWindow(QMainWindow): self.queueContext.item = (None, None) self.queueContext.buttons["remove"] = QAction(QIcon("icons/gui/remove_small.png"), "Remove", self.queueContext) self.queueContext.buttons["restart"] = QAction(QIcon("icons/gui/refresh_small.png"), "Restart", self.queueContext) + self.queueContext.buttons["pull"] = QAction(QIcon("icons/gui/pull_small.png"), "Pull out", self.queueContext) + self.queueContext.addAction(self.queueContext.buttons["pull"]) self.queueContext.addAction(self.queueContext.buttons["remove"]) self.queueContext.addAction(self.queueContext.buttons["restart"]) self.connect(self.queueContext.buttons["remove"], SIGNAL("triggered()"), self.slotRemoveDownload) self.connect(self.queueContext.buttons["restart"], SIGNAL("triggered()"), self.slotRestartDownload) + self.connect(self.queueContext.buttons["pull"], SIGNAL("triggered()"), self.slotPullOutPackage) #collector self.collectorContext = QMenu() @@ -341,6 +344,10 @@ class MainWindow(QMainWindow): menuPos = QCursor.pos() menuPos.setX(menuPos.x()+2) self.activeMenu = self.queueContext + if hasattr(i, "getPackData"): + self.queueContext.buttons["pull"].setVisible(True) + else: + self.queueContext.buttons["pull"].setVisible(False) self.queueContext.exec_(menuPos) def slotCollectorContextMenu(self, pos): @@ -402,4 +409,12 @@ class MainWindow(QMainWindow): print type(pid) self.emit(SIGNAL("changePackageName"), pid, editor.text()) self.emit(SIGNAL("pauseItemUpdate"), pid, False) + + def slotPullOutPackage(self): + """ + pull package out of the queue + """ + id, isTopLevel = self.activeMenu.item + if not id == None: + self.emit(SIGNAL("pullOutPackage"), id, isTopLevel) diff --git a/module/gui/connector.py b/module/gui/connector.py index 8a2909c5e..2915cf568 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -51,11 +51,14 @@ class connector(QThread): start thread (called from thread.start()) """ - self.connectProxy(self.addr) + self.canConnect() while self.running: sleep(1) self.getError() + def canConnect(self): + return self.connectProxy(self.addr) + def stop(self): """ stop thread @@ -67,9 +70,14 @@ class connector(QThread): connect to remote server """ self.proxy = ServerProxy(addr, allow_none=True) - server_version = self.proxy.get_server_version() + try: + server_version = self.proxy.get_server_version() + except: + return False if not server_version == SERVER_VERSION: self.emit(SIGNAL("error_box"), "server is version %s client accepts version %s" % (server_version, SERVER_VERSION)) + return False + return True def _proxyError(self, func, e): """ @@ -365,4 +373,16 @@ class connector(QThread): self.emit(SIGNAL("proxy_error"), "setPackageName", e) finally: self.mutex.unlock() + + def slotPullOutPackage(self, pid): + """ + pull out package + """ + self.mutex.lock() + try: + return self.proxy.pull_out_package(pid) + except Exception, e: + self.emit(SIGNAL("proxy_error"), "slotPullOutPackage", e) + finally: + self.mutex.unlock() -- cgit v1.2.3 From c1516088e4e7f76dddd68ef71f58c6413862e31c Mon Sep 17 00:00:00 2001 From: mkaay Date: Wed, 30 Dec 2009 12:35:03 +0100 Subject: show captchas in gui, SerienjunkiesOrg plugin --- module/gui/CaptchaDock.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++ module/gui/MainWindow.py | 5 ++- module/gui/connector.py | 40 +++++++++++++++++++++-- 3 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 module/gui/CaptchaDock.py (limited to 'module/gui') diff --git a/module/gui/CaptchaDock.py b/module/gui/CaptchaDock.py new file mode 100644 index 000000000..193bac6fa --- /dev/null +++ b/module/gui/CaptchaDock.py @@ -0,0 +1,82 @@ +# -*- 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 CaptchaDock(QDockWidget): + def __init__(self): + QDockWidget.__init__(self, "Captcha") + self.setObjectName("Captcha Dock") + self.widget = CaptchaDockWidget(self) + self.setWidget(self.widget) + self.setAllowedAreas(Qt.BottomDockWidgetArea) + self.setFeatures(QDockWidget.NoDockWidgetFeatures) + self.hide() + self.processing = False + self.currentID = None + + def isFree(self): + return not self.processing + + def setTask(self, tid, img, imgType): + self.processing = True + data = QByteArray(img) + self.currentID = tid + self.widget.emit(SIGNAL("setImage"), data) + self.show() + +class CaptchaDockWidget(QWidget): + def __init__(self, dock): + QWidget.__init__(self) + self.dock = dock + self.setLayout(QHBoxLayout()) + layout = self.layout() + + imgLabel = QLabel() + captchaInput = QLineEdit() + okayButton = QPushButton("OK") + cancelButton = QPushButton("Cancel") + + layout.addWidget(imgLabel) + layout.addWidget(captchaInput) + layout.addWidget(okayButton) + layout.addWidget(cancelButton) + layout.addStretch() + + self.input = captchaInput + + self.connect(okayButton, SIGNAL("clicked()"), self.slotSubmit) + self.connect(captchaInput, SIGNAL("returnPressed()"), self.slotSubmit) + self.connect(self, SIGNAL("setImage"), self.setImg) + self.connect(self, SIGNAL("setPixmap(const QPixmap &)"), imgLabel, SLOT("setPixmap(const QPixmap &)")) + + def setImg(self, data): + pixmap = QPixmap() + pixmap.loadFromData(data) + self.emit(SIGNAL("setPixmap(const QPixmap &)"), pixmap) + + def slotSubmit(self): + text = self.input.text() + tid = self.dock.currentID + self.dock.currentID = None + self.dock.emit(SIGNAL("done"), tid, str(text)) + self.dock.hide() + self.dock.processing = False + diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 6daa0aa55..94ff63dda 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -21,6 +21,7 @@ from PyQt4.QtGui import * from module.gui.PackageDock import * from module.gui.LinkDock import * +from module.gui.CaptchaDock import CaptchaDock class MainWindow(QMainWindow): def __init__(self): @@ -34,7 +35,7 @@ class MainWindow(QMainWindow): self.resize(850,500) #layout version - self.version = 1 + self.version = 2 #init docks self.newPackDock = NewPackageDock() @@ -43,6 +44,8 @@ class MainWindow(QMainWindow): self.addDockWidget(Qt.RightDockWidgetArea, self.newLinkDock) self.connect(self.newLinkDock, SIGNAL("done"), self.slotAddLinks) self.connect(self.newPackDock, SIGNAL("done"), self.slotAddPackage) + self.captchaDock = CaptchaDock() + self.addDockWidget(Qt.BottomDockWidgetArea, self.captchaDock) #central widget, layout self.masterlayout = QVBoxLayout() diff --git a/module/gui/connector.py b/module/gui/connector.py index 2915cf568..432999161 100644 --- a/module/gui/connector.py +++ b/module/gui/connector.py @@ -374,7 +374,7 @@ class connector(QThread): finally: self.mutex.unlock() - def slotPullOutPackage(self, pid): + def pullOutPackage(self, pid): """ pull out package """ @@ -382,7 +382,43 @@ class connector(QThread): try: return self.proxy.pull_out_package(pid) except Exception, e: - self.emit(SIGNAL("proxy_error"), "slotPullOutPackage", e) + self.emit(SIGNAL("proxy_error"), "pullOutPackage", e) + finally: + self.mutex.unlock() + + def captchaWaiting(self): + """ + is the a captcha waiting? + """ + self.mutex.lock() + try: + return self.proxy.is_captcha_waiting() + except Exception, e: + self.emit(SIGNAL("proxy_error"), "captchaWaiting", e) + finally: + self.mutex.unlock() + + def getCaptcha(self): + """ + get captcha + """ + self.mutex.lock() + try: + return self.proxy.get_captcha_task() + except Exception, e: + self.emit(SIGNAL("proxy_error"), "getCaptcha", e) + finally: + self.mutex.unlock() + + def setCaptchaResult(self, cid, result): + """ + get captcha + """ + self.mutex.lock() + try: + return self.proxy.set_captcha_result(cid, result) + except Exception, e: + self.emit(SIGNAL("proxy_error"), "setCaptchaResult", e) finally: self.mutex.unlock() -- cgit v1.2.3 From 08f12b089eb6fade689134b8170aa2b81218ddf7 Mon Sep 17 00:00:00 2001 From: mkaay Date: Wed, 30 Dec 2009 12:50:10 +0100 Subject: signal slot stuff --- module/gui/CaptchaDock.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'module/gui') diff --git a/module/gui/CaptchaDock.py b/module/gui/CaptchaDock.py index 193bac6fa..3dc9441a4 100644 --- a/module/gui/CaptchaDock.py +++ b/module/gui/CaptchaDock.py @@ -31,6 +31,7 @@ class CaptchaDock(QDockWidget): self.hide() self.processing = False self.currentID = None + self.connect(self, SIGNAL("setTask"), self.setTask) def isFree(self): return not self.processing @@ -54,6 +55,7 @@ class CaptchaDockWidget(QWidget): okayButton = QPushButton("OK") cancelButton = QPushButton("Cancel") + layout.addStretch() layout.addWidget(imgLabel) layout.addWidget(captchaInput) layout.addWidget(okayButton) -- cgit v1.2.3 From 7c28259f92c2b3c608583ff128a5ae4134d4c48f Mon Sep 17 00:00:00 2001 From: mkaay Date: Wed, 30 Dec 2009 17:33:14 +0100 Subject: moved captcha stuff, extended serienjunkies, some other stuff --- module/gui/CaptchaDock.py | 1 + 1 file changed, 1 insertion(+) (limited to 'module/gui') diff --git a/module/gui/CaptchaDock.py b/module/gui/CaptchaDock.py index 3dc9441a4..8a7e8010e 100644 --- a/module/gui/CaptchaDock.py +++ b/module/gui/CaptchaDock.py @@ -41,6 +41,7 @@ class CaptchaDock(QDockWidget): data = QByteArray(img) self.currentID = tid self.widget.emit(SIGNAL("setImage"), data) + self.widget.input.setText("") self.show() class CaptchaDockWidget(QWidget): -- cgit v1.2.3 From 4f904bd9610795c36d9e896bdf44c263ff43f5fd Mon Sep 17 00:00:00 2001 From: mkaay Date: Fri, 1 Jan 2010 17:13:43 +0100 Subject: fixed SerienjunkiesOrg, no more segfault in gui? --- module/gui/Collector.py | 58 +++++++++++++++++++++++++++++++++++------------- module/gui/MainWindow.py | 2 -- module/gui/Queue.py | 38 +++++++++++++++++++++---------- 3 files changed, 68 insertions(+), 30 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 356ab36ec..112eb1cd5 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -23,14 +23,13 @@ from time import sleep from module.gui.Queue import ItemIterator -class PackageCollector(QThread): +class PackageCollector(QObject): def __init__(self, view, connector): - QThread.__init__(self) + QObject.__init__(self) self.view = view self.connector = connector self.collector = [] self.interval = 2 - self.running = True self.rootItem = self.view.invisibleRootItem() self.mutex = QMutex() item = self.PackageCollectorPack(self) @@ -40,14 +39,28 @@ class PackageCollector(QThread): self.rootItem.addChild(item) self.linkCollector = item self.pauseIDs = [] + self.updater = self.CollectorUpdater(self.interval) + self.connect(self.updater, SIGNAL("update()"), self.update) - def run(self): - while self.running: - self.update() - sleep(self.interval) + class CollectorUpdater(QThread): + def __init__(self, interval): + QThread.__init__(self) + self.interval = interval + self.running = True + + def run(self): + while self.running: + self.emit(SIGNAL("update()")) + self.sleep(self.interval) + + def start(self): + self.updater.start() + + def wait(self): + self.updater.wait() def stop(self): - self.running = False + self.updater.running = False def update(self): locker = QMutexLocker(self.mutex) @@ -210,23 +223,36 @@ class PackageCollector(QThread): def getPack(self): return self.pack -class LinkCollector(QThread): +class LinkCollector(QObject): def __init__(self, view, root, connector): - QThread.__init__(self) + QObject.__init__(self) self.view = view self.connector = connector self.interval = 2 - self.running = True self.rootItem = root self.mutex = QMutex() + self.updater = self.CollectorUpdater(self.interval) + self.connect(self.updater, SIGNAL("update()"), self.update) + + class CollectorUpdater(QThread): + def __init__(self, interval): + QThread.__init__(self) + self.interval = interval + self.running = True + + def run(self): + while self.running: + self.emit(SIGNAL("update()")) + self.sleep(self.interval) + + def start(self): + self.updater.start() - def run(self): - while self.running: - self.update() - sleep(self.interval) + def wait(self): + self.updater.wait() def stop(self): - self.running = False + self.updater.running = False def update(self): locker = QMutexLocker(self.mutex) diff --git a/module/gui/MainWindow.py b/module/gui/MainWindow.py index 94ff63dda..250b701e4 100644 --- a/module/gui/MainWindow.py +++ b/module/gui/MainWindow.py @@ -403,13 +403,11 @@ class MainWindow(QMainWindow): def slotEditPackage(self): item = self.tabs["collector"]["package_view"].currentItem() pid = self.tabs["collector"]["package_view"].currentItem().data(0, Qt.UserRole).toPyObject() - print type(pid) self.emit(SIGNAL("pauseItemUpdate"), pid, True) self.tabs["collector"]["package_view"].editItem(item, 0) def slotCloseItemEditor(self, editor, hint): pid = self.tabs["collector"]["package_view"].currentItem().data(0, Qt.UserRole).toPyObject() - print type(pid) self.emit(SIGNAL("changePackageName"), pid, editor.text()) self.emit(SIGNAL("pauseItemUpdate"), pid, False) diff --git a/module/gui/Queue.py b/module/gui/Queue.py index 499cb5199..ed1c0f0a1 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -21,9 +21,9 @@ from PyQt4.QtGui import * from time import sleep, time -class Queue(QThread): +class Queue(QObject): def __init__(self, view, connector): - QThread.__init__(self) + QObject.__init__(self) self.view = view self.connector = connector self.statusMap = { @@ -33,24 +33,38 @@ class Queue(QThread): "waiting": 3, "reconnected": 4, "starting": 5, - "downloading": 6, - "failed": 7, - "aborted": 8, + "failed": 6, + "aborted": 7, + "decrypting": 8, + "downloading": 9 } self.statusMapReverse = dict((v,k) for k, v in self.statusMap.iteritems()) self.interval = 1 - self.running = True self.wait_dict = {} self.rootItem = self.view.invisibleRootItem() self.mutex = QMutex() + self.updater = self.QueueUpdater(self.interval) + self.connect(self.updater, SIGNAL("update()"), self.update) - def run(self): - while self.running: - self.update() - sleep(self.interval) + class QueueUpdater(QThread): + def __init__(self, interval): + QThread.__init__(self) + self.interval = interval + self.running = True + + def run(self): + while self.running: + self.emit(SIGNAL("update()")) + self.sleep(self.interval) + + def start(self): + self.updater.start() + + def wait(self): + self.updater.wait() def stop(self): - self.running = False + self.updater.running = False def update(self): locker = QMutexLocker(self.mutex) @@ -241,7 +255,7 @@ class Queue(QThread): self.addChild(newChild) item = newChild speed = self.queue.getSpeed(item) - if speed == None or item.getFileData()["status_type"] == "starting": + if speed == None or item.getFileData()["status_type"] == "starting" or item.getFileData()["status_type"] == "decrypting": status = item.getFileData()["status_type"] else: status = "%s (%s KB/s)" % (item.getFileData()["status_type"], speed) -- cgit v1.2.3 From d2ea03a068c9cbc43750d672aab7f2574ccfd9b4 Mon Sep 17 00:00:00 2001 From: mkaay Date: Fri, 1 Jan 2010 20:54:44 +0100 Subject: fixed netload.in premium --- module/gui/Queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'module/gui') diff --git a/module/gui/Queue.py b/module/gui/Queue.py index ed1c0f0a1..be2170309 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -130,7 +130,7 @@ class Queue(QObject): if not data["plugin"] in plugins: plugins.append(data["plugin"]) if status >= 0: - if speed == None: + if speed == None or self.statusMapReverse[status] == "starting" or self.statusMapReverse[status] == "decrypting": statustxt = self.statusMapReverse[status] else: statustxt = "%s (%s KB/s)" % (self.statusMapReverse[status], speed) -- cgit v1.2.3 From 3d655ddbfbd96abecb9a9c9bebf6e43eb710ab12 Mon Sep 17 00:00:00 2001 From: RaNaN Date: Sun, 10 Jan 2010 16:20:31 +0100 Subject: fixed manage.py, addBox working, some code formatted and cleaned --- module/gui/Collector.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Collector.py b/module/gui/Collector.py index 112eb1cd5..0aad5d1ba 100644 --- a/module/gui/Collector.py +++ b/module/gui/Collector.py @@ -19,8 +19,6 @@ from PyQt4.QtCore import * from PyQt4.QtGui import * -from time import sleep - from module.gui.Queue import ItemIterator class PackageCollector(QObject): -- cgit v1.2.3 From bdb3deb371bbbcb5452e97ee560b793834d1a3f3 Mon Sep 17 00:00:00 2001 From: mkaay Date: Thu, 21 Jan 2010 19:39:27 +0100 Subject: fixed link deletion --- module/gui/Queue.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'module/gui') diff --git a/module/gui/Queue.py b/module/gui/Queue.py index be2170309..8681d3bb1 100644 --- a/module/gui/Queue.py +++ b/module/gui/Queue.py @@ -298,9 +298,8 @@ class Queue(QObject): return remove.sort() remove.reverse() - parent = self for k in remove: - parent.takeChild(k) + self.takeChild(k) class QueueFile(QTreeWidgetItem): def __init__(self, queue, pack): -- cgit v1.2.3