summaryrefslogtreecommitdiffstats
path: root/pyLoadGui.py
diff options
context:
space:
mode:
authorGravatar mkaay <mkaay@mkaay.de> 2009-12-17 17:26:59 +0100
committerGravatar mkaay <mkaay@mkaay.de> 2009-12-17 17:26:59 +0100
commitedf9060676ba864118d87518abb697a96ab1d5ad (patch)
treec8d9e9acaeec4c5f247e231cb64954c4d63e2a2c /pyLoadGui.py
parentgui config file (diff)
downloadpyload-edf9060676ba864118d87518abb697a96ab1d5ad.tar.xz
renamed gui
Diffstat (limited to 'pyLoadGui.py')
-rw-r--r--[-rwxr-xr-x]pyLoadGui.py1295
1 files changed, 982 insertions, 313 deletions
diff --git a/pyLoadGui.py b/pyLoadGui.py
index 806c4437c..844a96ef2 100755..100644
--- a/pyLoadGui.py
+++ b/pyLoadGui.py
@@ -1,336 +1,1005 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-#
-#Copyright (C) 2009 KingZero
-#
-#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/>.
-#
-###
-import socket
-import subprocess
-from os import sep
-from os.path import abspath, dirname
-from time import sleep
+"""
+ 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.
-import wxversion
-wxversion.select('2.8')
+ 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.
-import wx
-import wx.lib.newevent
-import wx.lib.sized_controls as sized_control
-from module.remote.ClientSocket import SocketThread
-
-(DataArrived, EVT_DATA_ARRIVED) = wx.lib.newevent.NewEvent()
-
-class _Download_Dialog(sized_control.SizedDialog):
- def __init__(self, parent, id):
- sized_control.SizedDialog.__init__(self, parent, id, "Downloads hinzufügen",
- style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
-
- pane = self.GetContentsPane()
-
- self.links = wx.TextCtrl(pane, -1, style=wx.TE_MULTILINE, size=(500, 200))
- self.links.SetSizerProps(expand=True, proportion=1)
-
- self.SetButtonSizer(self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL))
-
- self.Fit()
- self.SetMinSize(self.GetSize())
-
- #Clipboard
- self.data = wx.TextDataObject()
- if wx.TheClipboard.Open():
- wx.TheClipboard.GetData(self.data)
- for link in self.data.GetText().split('\n'):
- if link.startswith("http"):
- self.links.write(link + "\n")
- wx.TheClipboard.Close()
-
-class Download_Liste(wx.ListCtrl):
- def __init__(self, parent):
- wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.LC_VIRTUAL)
-
- # columns
- self.InsertColumn(0, 'Name', width=300)
- self.InsertColumn(1, 'Status', width=120)
- self.InsertColumn(2, 'Größe')
- self.InsertColumn(3, 'Übertragen', width=100)
- self.InsertColumn(4, 'Prozent', width=60)
- self.InsertColumn(5, 'Dauer', width=100)
- self.InsertColumn(7, 'Geschwindigkeit', width=120)
-
-
- self.itemDataMap = {}
- self.itemIndexMap = []
- self.SetItemCount(len(self.itemIndexMap))
-
- def reload(self, links, data):
-
- self.itemIndexMap = data['order']
-
- self.create_data(links, data)
+ 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
+ @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
+
+class main(QObject):
+ def __init__(self):
+ """
+ main setup
+ """
+ QObject.__init__(self)
+ self.app = QApplication(sys.argv)
+ self.mainWindow = mainWindow()
+ self.pwWindow = PWInputWindow()
+ self.connWindow = ConnectionManager()
+ self.connector = connector()
+ self.mainloop = self.Loop(self)
+ self.connectSignals()
+ self.parser = XMLParser("guiconfig.xml", "guiconfig_default.xml")
- self.SetItemCount(len(self.itemIndexMap))
- self.Refresh()
-
- def create_data(self, links, data):
-
- self.itemDataMap = {}
-
- for key, value in data.iteritems():
- if key != 'version' and key != 'order':
- self.itemDataMap[key] = [value.url]
-
- for link in links:
- self.itemDataMap[link['id']][0] = link['name']
- self.itemDataMap[link['id']].append(link['status'])
- self.itemDataMap[link['id']].append(str(link['size']) + " kb")
- self.itemDataMap[link['id']].append(str(link['size'] - link['kbleft']) + " kb")
- self.itemDataMap[link['id']].append(str(link['percent']) + " %")
- self.itemDataMap[link['id']].append(format_time(link['eta']))
- self.itemDataMap[link['id']].append(str(int(link['speed'])) + " kb/s")
-
- # virtual methods
- def OnGetItemText(self, item, col):
- index = self.itemIndexMap[item]
+ self.refreshConnections()
+ self.connData = None
+ self.connWindow.show()
+
+ def startMain(self):
+ self.connector.start()
+ sleep(1)
+ self.mainWindow.show()
+ self.testStuff()
+ self.mainloop.start()
+
+ def connectSignals(self):
+ """
+ signal and slot stuff, yay!
+ """
+ self.connect(self.connector, SIGNAL("error_box"), self.slotErrorBox)
+ self.connect(self.connWindow, SIGNAL("saveConnection"), self.slotSaveConnection)
+ self.connect(self.connWindow, SIGNAL("removeConnection"), self.slotRemoveConnection)
+ self.connect(self.connWindow, SIGNAL("connect"), self.slotConnect)
+ self.connect(self.pwWindow, SIGNAL("ok"), self.slotPasswordTyped)
+ self.connect(self.pwWindow, SIGNAL("cancel"), self.quit)
+
+ def quit(self):
+ self.app.quit()
+
+ def loop(self):
+ """
+ start exec loop
+ """
+ sys.exit(self.app.exec_())
+
+ def slotErrorBox(self, msg):
+ """
+ display a nice error box
+ """
+ QMessageBox(QMessageBox.Warning, "Error", msg)
+
+ def testStuff(self):
+ """
+ only for testing ;)
+ """
+ #test for link collector
+ ids = self.connector.getLinkCollector()
+ for id in ids:
+ data = self.connector.getLinkInfo(id)
+ item = QListWidgetItem()
+ item.setData(Qt.UserRole, QVariant(data))
+ item.setData(Qt.DisplayRole, QVariant(data["url"]))
+ self.mainWindow.tabs["collector_links"]["listwidget"].addItem(item)
+
+ #test for package collector
+ packs = self.connector.getPackageCollector()
+ for data in packs:
+ item = QTreeWidgetItem()
+ item.setData(0, Qt.UserRole, QVariant(data))
+ item.setData(0, Qt.DisplayRole, QVariant(data["package_name"]))
+ files = self.connector.getPackageFiles(data["id"])
+ for id in files:
+ info = self.connector.getLinkInfo(id)
+ sub = QTreeWidgetItem(item)
+ sub.setData(0, Qt.DisplayRole, QVariant(info["filename"]))
+ self.mainWindow.tabs["collector_packages"]["treewidget"].addTopLevelItem(item)
+
+ #test for queue
+ """
+ packs = self.connector.getPackageQueue()
+ for data in packs:
+ item = QTreeWidgetItem()
+ item.setData(0, Qt.UserRole, QVariant(data))
+ item.setData(0, Qt.DisplayRole, QVariant(data["package_name"]))
+ files = self.connector.getPackageFiles(data["id"])
+ for id in files:
+ info = self.connector.getLinkInfo(id)
+ sub = QTreeWidgetItem(item)
+ sub.setData(0, Qt.DisplayRole, QVariant(info["filename"]))
+ sub.setData(1, Qt.DisplayRole, QVariant(info["status_type"]))
+ self.mainWindow.tabs["queue"]["treewidget"].addTopLevelItem(item)
+
+ model = QueueModel(self.connector)
+ model.setView(self.mainWindow.tabs["queue"]["view"])
+ self.mainWindow.tabs["queue"]["view"].setModel(model)
+ self.mainWindow.tabs["queue"]["view"].setup()
+ model.startLoop()
+ """
+ view = self.mainWindow.tabs["queue"]["view"]
+ view.setColumnCount(3)
+ view.setHeaderLabels(["Name", "Status", "Fortschritt"])
+ view.setColumnWidth(0, 300)
+ view.setColumnWidth(1, 200)
+ view.setColumnWidth(2, 100)
+ self.queue = Queue(view, self.connector)
+ delegate = QueueProgressBarDelegate(view, self.queue)
+ view.setItemDelegateForColumn(2, delegate)
+ #view.setup(self.queue)
+ self.queue.start()
+
+ def refreshServerStatus(self):
+ status = self.connector.getServerStatus()
+ if status["pause"]:
+ status["status"] = "Paused"
+ else:
+ status["status"] = "Running"
+ status["speed"] = int(status["speed"])
+ text = "Status: %(status)s | Speed: %(speed)s kb/s" % status
+ self.mainWindow.serverStatus.setText(text)
+
+ def getConnections(self):
+ connectionsNode = self.parser.xml.elementsByTagName("connections").item(0)
+ if connectionsNode.isNull():
+ raise Exception("null")
+ connections = self.parser.parseNode(connectionsNode)
+ ret = []
+ for conn in connections:
+ data = {}
+ data["type"] = conn.attribute("type", "remote")
+ data["default"] = conn.attribute("default", "False")
+ data["id"] = conn.attribute("id", uuid().hex)
+ if data["default"] == "True":
+ data["default"] = True
+ else:
+ data["default"] = False
+ subs = self.parser.parseNode(conn, "dict")
+ if not subs.has_key("name"):
+ data["name"] = "Unnamed"
+ else:
+ data["name"] = subs["name"].text()
+ if data["type"] == "remote":
+ if not subs.has_key("server"):
+ continue
+ else:
+ data["host"] = subs["server"].text()
+ data["ssl"] = subs["server"].attribute("ssl", "False")
+ if data["ssl"] == "True":
+ data["ssl"] = True
+ else:
+ data["ssl"] = False
+ data["user"] = subs["server"].attribute("user", "admin")
+ data["port"] = int(subs["server"].attribute("port", "7227"))
+ ret.append(data)
+ return ret
+
+ def slotSaveConnection(self, data):
+ connectionsNode = self.parser.xml.elementsByTagName("connections").item(0)
+ if connectionsNode.isNull():
+ raise Exception("null")
+ connections = self.parser.parseNode(connectionsNode)
+ connNode = self.parser.xml.createElement("connection")
+ connNode.setAttribute("default", data["default"])
+ connNode.setAttribute("type", data["type"])
+ connNode.setAttribute("id", data["id"])
+ nameNode = self.parser.xml.createElement("name")
+ nameText = self.parser.xml.createTextNode(data["name"])
+ nameNode.appendChild(nameText)
+ connNode.appendChild(nameNode)
+ if data["type"] == "remote":
+ serverNode = self.parser.xml.createElement("server")
+ serverNode.setAttribute("ssl", data["ssl"])
+ serverNode.setAttribute("user", data["user"])
+ serverNode.setAttribute("port", data["port"])
+ hostText = self.parser.xml.createTextNode(data["host"])
+ serverNode.appendChild(hostText)
+ connNode.appendChild(serverNode)
+ found = False
+ for c in connections:
+ cid = c.attribute("id", "None")
+ if str(cid) == str(data["id"]):
+ found = c
+ break
+ if found:
+ connectionsNode.replaceChild(connNode, found)
+ else:
+ connectionsNode.appendChild(connNode)
+ self.parser.saveData()
+ self.refreshConnections()
+
+ def slotRemoveConnection(self, data):
+ connectionsNode = self.parser.xml.elementsByTagName("connections").item(0)
+ if connectionsNode.isNull():
+ raise Exception("null")
+ connections = self.parser.parseNode(connectionsNode)
+ found = False
+ for c in connections:
+ cid = c.attribute("id", "None")
+ if str(cid) == str(data["id"]):
+ found = c
+ break
+ if found:
+ connectionsNode.removeChild(found)
+ self.parser.saveData()
+ self.refreshConnections()
+
+ def slotConnect(self, data):
+ self.connWindow.hide()
+ self.connData = data
+ if data["type"] == "local":
+ self.slotPasswordTyped("")
+ self.pwWindow.show()
+
+ def slotPasswordTyped(self, pw):
+ data = self.connData
+ data["password"] = pw
+ if data["type"] == "remote":
+ if data["ssl"]:
+ data["ssl"] = "s"
+ else:
+ data["ssl"] = ""
+ server_url = "http%(ssl)s://%(user)s:%(password)s@%(host)s:%(port)s/" % data
+ self.connector.setAddr(server_url)
+ self.startMain()
+ else:
+ print "comming soon ;)"
+ self.quit()
+
+ def refreshConnections(self):
+ self.parser.loadData()
+ conns = self.getConnections()
+ self.connWindow.emit(SIGNAL("setConnections(connections)"), conns)
+
+ class Loop(QThread):
+ def __init__(self, parent):
+ QThread.__init__(self)
+ self.parent = parent
+ self.running = True
+
+ def run(self):
+ while self.running:
+ sleep(1)
+ self.update()
+
+ 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:
- s = self.itemDataMap[index][col]
- except:
- s = ""
- return s
-
- def OnGetItemAttr(self, item):
- return None
-
-class _Upper_Panel(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent)
- sizer = wx.BoxSizer(wx.HORIZONTAL)
- self.parent = parent
-
- self.list = Download_Liste(self)
-
- sizer.Add(self.list, 1, wx.EXPAND)
- self.SetSizer(sizer)
-
- def refresh(self, links, data):
- self.list.reload(links, data)
-
- def get_selected_ids(self, deselect=False):
- """return ids and deselect items"""
- item = self.list.GetFirstSelected()
- if deselect: self.list.Select(item, on=0)
-
- if item == -1:
- return False
-
- links = []
- links.append(self.parent.data['order'][item])
-
- while self.list.GetNextSelected(item) != -1:
- item = self.list.GetNextSelected(item)
- if deselect: self.list.Select(item, on=0)
- links.append(self.parent.data['order'][item])
-
- return links
-
-class _Lower_Panel(wx.Panel):
- def __init__(self, parent):
- wx.Panel.__init__(self, parent)
- self.SetBackgroundColour(wx.BLACK)
+ 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)
-class _Host_Dialog(wx.Dialog):
- def __init__(self, parent, id, title):
- wx.Dialog.__init__(self, parent, id, title, size=(250, 170))
+ #central widget, layout
+ self.masterlayout = QVBoxLayout()
+ lw = QWidget()
+ lw.setLayout(self.masterlayout)
+ self.setCentralWidget(lw)
- self.host = wx.TextCtrl(self, -1, '127.0.0.1')
- host_name = wx.StaticText(self, -1, 'Host:')
- self.port = wx.TextCtrl(self, -1, '7272')
- port_name = wx.StaticText(self, -1, 'Port:')
- self.password = wx.TextCtrl(self, -1, 'pwhere')
- password_name = wx.StaticText(self, -1, 'Password:')
- button_ok = wx.Button(self, wx.ID_OK, 'Ok', size=(90, 28))
- button_cancel = wx.Button(self, wx.ID_CANCEL, 'Close', size=(90, 28))
+ #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")
- fgs = wx.FlexGridSizer(3, 2, 9, 25)
+ #menu actions
+ self.mactions = {}
+ self.mactions["exit"] = QAction("Exit", self.menus["file"])
+ self.mactions["manager"] = QAction("Connection manager", self.menus["connections"])
- fgs.AddMany([(host_name), (self.host, 0, wx.EXPAND), (port_name), (self.port, 1, wx.EXPAND), (password_name), (self.password, 1, wx.EXPAND), (button_ok, 1, wx.EXPAND), (button_cancel, 1, wx.EXPAND)])
+ #add menu actions
+ self.menus["file"].addAction(self.mactions["exit"])
+ self.menus["connections"].addAction(self.mactions["manager"])
- fgs.AddGrowableCol(1, 1)
+ #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")
- hbox = wx.BoxSizer(wx.HORIZONTAL)
- hbox.Add(fgs, 1, wx.ALL | wx.EXPAND, 15)
+ #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"])
- self.SetSizer(hbox)
+ #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"])
-class Pyload_Main_Gui(wx.Frame):
- def __init__(self, parent, id, title="pyLoad"):
-
- wx.Frame.__init__(self, parent, id, title, size=(910, 500))
-
- app_path = dirname(abspath(__file__)) + sep
-
- # vars
- self.links = []
- self.data = {}
-
- # Menubar
- menubar = wx.MenuBar()
- menu_file = wx.Menu()
- submenu_exit = menu_file.Append(-1, 'Schliessen', 'pyLoad beenden')
- menubar.Append(menu_file, '&Datei')
- menu_pyload = wx.Menu()
- self.submenu_pyload_connect = menu_pyload.Append(-1, 'Connect', 'Connect to pyLoad')
- self.submenu_pyload_disconnect = menu_pyload.Append(-1, 'Disconnect', 'Disconnect')
- self.submenu_pyload_shutdown = menu_pyload.Append(-1, 'Shutdown', 'Shutdown pyLoad Core')
- menubar.Append(menu_pyload, '&pyLoad')
- self.SetMenuBar(menubar)
-
- # Statusbar
- self.CreateStatusBar()
-
- # icon
- icon1 = wx.Icon(app_path + '/icons/pyload.ico', wx.BITMAP_TYPE_ICO)
- self.SetIcon(icon1)
-
- # Toolbar
- toolbar = self.CreateToolBar()
- toolbar.SetToolBitmapSize((32, 32))
- add = toolbar.AddLabelTool(2, '', wx.Bitmap(app_path + '/icons/add.png'))
- delete = toolbar.AddLabelTool(3, '', wx.Bitmap(app_path + '/icons/del.png'))
- start = toolbar.AddLabelTool(4, '', wx.Bitmap(app_path + '/icons/start.png'))
- pause = toolbar.AddLabelTool(5, '', wx.Bitmap(app_path + '/icons/pause.png'))
- stop = toolbar.AddLabelTool(6, '', wx.Bitmap(app_path + '/icons/stop.png'))
- up = toolbar.AddLabelTool(7, '', wx.Bitmap(app_path + '/icons/up.png'))
- down = toolbar.AddLabelTool(8, '', wx.Bitmap(app_path + '/icons/down.png'))
- config = toolbar.AddLabelTool(9, '', wx.Bitmap(app_path + '/icons/setup.png'))
- toolbar.Realize()
-
- #splitter = wx.SplitterWindow(self)
- self.panel_up = _Upper_Panel(self)
- #panel_down = _Lower_Panel(splitter)
- #splitter.SplitHorizontally(panel_up, panel_down, 300)
-
- # Binds
- self.Bind(wx.EVT_MENU, self.exit_button_clicked, submenu_exit)
- self.Bind(wx.EVT_MENU, self.connect, self.submenu_pyload_connect)
- self.Bind(wx.EVT_MENU, self.disconnect, self.submenu_pyload_disconnect)
- self.Bind(wx.EVT_MENU, self.shutdown, self.submenu_pyload_shutdown)
- self.Bind(wx.EVT_TOOL, self.add_button_clicked, add)
- self.Bind(wx.EVT_TOOL, self.delete_button_clicked, delete)
- self.Bind(wx.EVT_TOOL, self.up_button_clicked, up)
- self.Bind(wx.EVT_TOOL, self.down_button_clicked, down)
- self.Bind(EVT_DATA_ARRIVED, self.onUpdate)
-
- self.Centre()
- self.Show(True)
+ #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)
-
- def exit_button_clicked(self, event):
- self.Close()
+ 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 connect(self, event):
- socket_host = _Host_Dialog(self, -1, 'Connect to:')
- res_socket = socket_host.ShowModal()
- if (res_socket == wx.ID_OK):
- try:
- self.thread = SocketThread(socket_host.host.GetValue(), int(socket_host.port.GetValue()), socket_host.password.GetValue(), self)
- self.SetStatusText('Connected to: %s:%s' % (socket_host.host.GetValue(), socket_host.port.GetValue()))
- except socket.error:
- if (socket_host.host.GetValue() in ['localhost', '127.0.0.1']):
- if (wx.MessageDialog(None, 'Do you want to start pyLoadCore locally?', 'Start pyLoad', wx.OK | wx.CANCEL).ShowModal() == wx.ID_OK):
- cmd = ['python', 'pyLoadCore.py']
- subprocess.Popen(cmd)
- sleep(2)
- self.thread = SocketThread(socket_host.host.GetValue(), int(socket_host.port.GetValue()), socket_host.password.GetValue(), self)
- self.SetStatusText('Connected to: %s:%s' % (socket_host.host.GetValue(), socket_host.port.GetValue()))
- else:
- wx.MessageDialog(None, 'Cant connect to: %s:%s' % (socket_host.host.GetValue(), socket_host.port.GetValue()), 'Error', wx.OK | wx.ICON_ERROR).ShowModal()
- else:
- wx.MessageDialog(None, 'Cant connect to: %s:%s' % (socket_host.host.GetValue(), socket_host.port.GetValue()), 'Error', wx.OK | wx.ICON_ERROR).ShowModal()
-
- self.thread.push_exec("get_links")
-
- def disconnect(self, event):
- self.thread.socket.close_when_done()
- self.SetStatusText('')
-
- def shutdown(self, event):
- self.thread.push_exec("kill")
-
- def add_button_clicked(self, event):
- #test
- #self.thread.push_exec("get_downloads")
-
- add_download = _Download_Dialog(None, -1)
- result = add_download.ShowModal()
- add_download.Destroy()
- downloads = add_download.links.GetValue().split()
- self.thread.push_exec('add_links', [downloads])
-
- def delete_button_clicked(self, event):
-
- links = self.panel_up.get_selected_ids(True)
-
- self.thread.push_exec('remove_links', [links])
-
- def up_button_clicked(self, event):
-
- links = self.panel_up.get_selected_ids()
- self.thread.push_exec('move_links_up', [links])
-
-
- def down_button_clicked(self, event):
-
- links = self.panel_up.get_selected_ids()
-
- self.thread.push_exec('move_links_down', [links])
-
- def show_links(self, links):
- for link in links:
- #wx.MessageDialog(self, str(link), 'info', style=wx.OK).ShowModal()
- print str(link)
-
- def data_arrived(self, rep):
- evt = DataArrived(obj=rep)
- wx.PostEvent(self, evt)
-
- def onUpdate(self, evt):
-
- if evt.obj.function == "get_downloads":
- pass
- #self.show_links(evt.obj.response)
-
- if evt.obj.command == "update":
- self.links = evt.obj.data
- self.panel_up.refresh(self.links, self.data)
+ 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)
- if evt.obj.command == "file_list" or evt.obj.function == "get_links":
- self.data = evt.obj.data
- self.panel_up.refresh(self.links, self.data)
-
+ 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
-def format_time(seconds):
- seconds = int(seconds)
- hours, seconds = divmod(seconds, 3600)
- minutes, seconds = divmod(seconds, 60)
- return "%.2i:%.2i:%.2i" % (hours, minutes, seconds)
+ 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
-app = wx.App()
-Pyload_Main_Gui(None, -1)
-app.MainLoop()
+if __name__ == "__main__":
+ app = main()
+ app.loop()