summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.hgignore10
-rw-r--r--module/gui/ConnectionManager.py225
-rw-r--r--module/gui/MainWindow.py95
-rw-r--r--module/gui/PWInputWindow.py47
-rw-r--r--module/gui/Queue.py252
-rw-r--r--module/gui/XMLParser.py70
-rw-r--r--module/gui/__init__.py1
-rw-r--r--module/gui/connector.py146
-rw-r--r--pyLoadGui.py734
9 files changed, 853 insertions, 727 deletions
diff --git a/.hgignore b/.hgignore
index 511709ef0..44507b09a 100644
--- a/.hgignore
+++ b/.hgignore
@@ -10,4 +10,12 @@ syntax: glob
*.pydevproject
Downloads/*
Logs/*
-Plugins/DLC.py \ No newline at end of file
+Plugins/DLC.py
+failed_links.txt
+guiconfig.xml
+links.txt
+module/links.pkl
+module/cookies.txt
+ssl.crt
+ssl.key
+cert.pem
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 <http://www.gnu.org/licenses/>.
+
+ @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 <http://www.gnu.org/licenses/>.
+
+ @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 <http://www.gnu.org/licenses/>.
+
+ @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 <http://www.gnu.org/licenses/>.
+
+ @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 <http://www.gnu.org/licenses/>.
+
+ @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 <http://www.gnu.org/licenses/>.
+
+ @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()
diff --git a/pyLoadGui.py b/pyLoadGui.py
index 844a96ef2..f8ba3efd3 100644
--- a/pyLoadGui.py
+++ b/pyLoadGui.py
@@ -19,21 +19,22 @@
@version: v0.3
"""
-SERVER_VERSION = "0.3"
-
import sys
-import os
from time import sleep, time
from PyQt4.QtCore import *
from PyQt4.QtGui import *
-from PyQt4.QtXml import *
-
-from xmlrpclib import ServerProxy
from uuid import uuid4 as uuid
+from module.gui.ConnectionManager import *
+from module.gui.connector import *
+from module.gui.MainWindow import *
+from module.gui.PWInputWindow import *
+from module.gui.Queue import *
+from module.gui.XMLParser import *
+
class main(QObject):
def __init__(self):
"""
@@ -41,7 +42,7 @@ class main(QObject):
"""
QObject.__init__(self)
self.app = QApplication(sys.argv)
- self.mainWindow = mainWindow()
+ self.mainWindow = MainWindow()
self.pwWindow = PWInputWindow()
self.connWindow = ConnectionManager()
self.connector = connector()
@@ -281,725 +282,6 @@ class main(QObject):
def update(self):
self.parent.refreshServerStatus()
-#############################################
-############## Connector Stuff ##############
-#############################################
-
-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()
-
-##########################################
-############## Window Stuff ##############
-##########################################
-
-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"])
-
-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)
-
-class PWInputWindow(QWidget):
- def __init__(self):
- QWidget.__init__(self)
- self.input = QLineEdit()
- 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"))
-
-#########################################
-############## Queue Stuff ##############
-#########################################
-
-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)
-
-#########################################
-############## Other Stuff ##############
-#########################################
-
-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
-
if __name__ == "__main__":
app = main()
app.loop()