diff options
Diffstat (limited to 'pyLoadGui.py')
-rwxr-xr-x | pyLoadGui.py | 914 |
1 files changed, 595 insertions, 319 deletions
diff --git a/pyLoadGui.py b/pyLoadGui.py index 806c4437c..9e04cc003 100755 --- a/pyLoadGui.py +++ b/pyLoadGui.py @@ -1,336 +1,612 @@ #!/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 +""" + +import sys + +from time import sleep, time + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +from uuid import uuid4 as uuid +import re +from os.path import basename + +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.Collector import * +from module.gui.XMLParser import * + +class main(QObject): + def __init__(self): + """ + main setup + """ + QObject.__init__(self) + self.app = QApplication(sys.argv) + self.init(True) + + def init(self, first=False): + """ + set main things up + """ + self.mainWindow = MainWindow() + self.pwWindow = PWInputWindow() + self.connWindow = ConnectionManager() + self.connector = connector() + self.mainloop = self.Loop(self) + self.connectSignals() + self.parser = XMLParser("module/config/gui.xml", "module/config/gui_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] - try: - s = self.itemDataMap[index][col] - except: - s = "" - return s - - def OnGetItemAttr(self, item): + self.checkClipboard = False + default = self.refreshConnections() + self.connData = None + self.captchaProcessing = False + if not first: + self.connWindow.show() + else: + self.connWindow.edit.setData(default) + data = self.connWindow.edit.getData() + self.slotConnect(data) + + def startMain(self): + """ + start all refresh threads and show main window + """ + if not self.connector.canConnect(): + self.init() + return + self.connector.start() + sleep(1) + self.restoreMainWindow() + self.mainWindow.show() + self.initQueue() + self.initPackageCollector() + self.initLinkCollector() + self.mainloop.start() + self.clipboard = self.app.clipboard() + self.connect(self.clipboard, SIGNAL('dataChanged()'), self.slotClipboardChange) + self.connect(self.mainWindow, SIGNAL("pauseItemUpdate"), self.packageCollector.pauseItemUpdate) + self.mainWindow.actions["clipboard"].setChecked(self.checkClipboard) + + def stopMain(self): + """ + stop all refresh threads and hide main window + """ + self.disconnect(self.clipboard, SIGNAL('dataChanged()'), self.slotClipboardChange) + self.disconnect(self.mainWindow, SIGNAL("pauseItemUpdate"), self.packageCollector.pauseItemUpdate) + self.mainloop.stop() + self.connector.stop() + self.mainWindow.saveWindow() + self.mainWindow.hide() + self.queue.stop() + self.linkCollector.stop() + self.packageCollector.stop() + self.mainloop.wait() + self.connector.wait() + self.queue.wait() + self.linkCollector.wait() + self.packageCollector.wait() + + 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) + self.connect(self.mainWindow, SIGNAL("connector"), self.slotShowConnector) + self.connect(self.mainWindow, SIGNAL("addLinks"), self.slotAddLinks) + self.connect(self.mainWindow, SIGNAL("addPackage"), self.slotAddPackage) + self.connect(self.mainWindow, SIGNAL("setDownloadStatus"), self.slotSetDownloadStatus) + self.connect(self.mainWindow, SIGNAL("saveMainWindow"), self.slotSaveMainWindow) + self.connect(self.mainWindow, SIGNAL("pushPackageToQueue"), self.slotPushPackageToQueue) + self.connect(self.mainWindow, SIGNAL("restartDownload"), self.slotRestartDownload) + self.connect(self.mainWindow, SIGNAL("removeDownload"), self.slotRemoveDownload) + self.connect(self.mainWindow, SIGNAL("addContainer"), self.slotAddContainer) + self.connect(self.mainWindow, SIGNAL("stopAllDownloads"), self.slotStopAllDownloads) + self.connect(self.mainWindow, SIGNAL("setClipboardStatus"), self.slotSetClipboardStatus) + self.connect(self.mainWindow, SIGNAL("changePackageName"), self.slotChangePackageName) + self.connect(self.mainWindow, SIGNAL("pullOutPackage"), self.slotPullOutPackage) + self.connect(self.mainWindow.captchaDock, SIGNAL("done"), self.slotCaptchaDone) + + def slotShowConnector(self): + """ + emitted from main window (menu) + hide the main window and show connection manager + (to switch to other core) + """ + self.stopMain() + self.init() + + def quit(self): + """ + quit gui + """ + self.app.quit() + + def loop(self): + """ + start application loop + """ + sys.exit(self.app.exec_()) + + def slotErrorBox(self, msg): + """ + display a nice error box + """ + msgb = QMessageBox(QMessageBox.Warning, "Error", msg) + msgb.exec_() + + def initPackageCollector(self): + """ + init the package collector view + * columns + * selection + * refresh thread + * drag'n'drop + """ + view = self.mainWindow.tabs["collector"]["package_view"] + view.setColumnCount(1) + view.setHeaderLabels(["Name"]) + view.setSelectionBehavior(QAbstractItemView.SelectRows) + view.setSelectionMode(QAbstractItemView.ExtendedSelection) + def dropEvent(klass, event): + event.setDropAction(Qt.CopyAction) + event.accept() + view = event.source() + if view == klass: + items = view.selectedItems() + for item in items: + if not hasattr(item.parent(), "getPackData"): + continue + target = view.itemAt(event.pos()) + if not hasattr(target, "getPackData"): + target = target.parent() + klass.emit(SIGNAL("droppedToPack"), target.getPackData()["id"], item.getFileData()["id"]) + event.accept() + return + items = view.selectedItems() + for item in items: + row = view.indexOfTopLevelItem(item) + view.takeTopLevelItem(row) + def dragEvent(klass, event): + view = event.source() + dragOkay = False + items = view.selectedItems() + for item in items: + if hasattr(item, "_data"): + if item._data["id"] == "fixed" or item.parent()._data["id"] == "fixed": + dragOkay = True + else: + dragOkay = True + if dragOkay: + event.accept() + else: + event.ignore() + view.dropEvent = dropEvent + view.dragEnterEvent = dragEvent + view.setDragEnabled(True) + view.setDragDropMode(QAbstractItemView.DragDrop) + view.setDropIndicatorShown(True) + view.setDragDropOverwriteMode(True) + self.connect(view, SIGNAL("droppedToPack"), self.slotAddFileToPackage) + self.packageCollector = PackageCollector(view, self.connector) + self.packageCollector.start() + + def initLinkCollector(self): + """ + init the link collector + * refresh thread + """ + self.linkCollector = LinkCollector(self.mainWindow.tabs["collector"]["package_view"], self.packageCollector.linkCollector, self.connector) + self.linkCollector.start() + + def initQueue(self): + """ + init the queue view + * columns + * refresh thread + * progressbar + """ + view = self.mainWindow.tabs["queue"]["view"] + view.setColumnCount(4) + view.setHeaderLabels(["Name", "Plugin", "Status", "Fortschritt"]) + view.setColumnWidth(0, 300) + view.setColumnWidth(1, 100) + view.setColumnWidth(2, 200) + view.setColumnWidth(3, 100) + self.queue = Queue(view, self.connector) + delegate = QueueProgressBarDelegate(view, self.queue) + view.setItemDelegateForColumn(3, delegate) + self.queue.start() + + def refreshServerStatus(self): + """ + refresh server status and overall speed in the status bar + """ + 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.actions["toggle_status"].setChecked(not status["pause"]) + self.mainWindow.serverStatus.setText(text) + + def refreshLog(self): + """ + update log window + """ + offset = self.mainWindow.tabs["log"]["text"].logOffset + lines = self.connector.getLog(offset) + if not lines: + return + self.mainWindow.tabs["log"]["text"].logOffset += len(lines) + for line in lines: + self.mainWindow.tabs["log"]["text"].emit(SIGNAL("append(QString)"), line) + cursor = self.mainWindow.tabs["log"]["text"].textCursor() + cursor.movePosition(QTextCursor.End, QTextCursor.MoveAnchor) + self.mainWindow.tabs["log"]["text"].setTextCursor(cursor) + + def updateAvailable(self): + """ + update notification + """ + status = self.connector.updateAvailable() + if status: + self.mainWindow.statusbar.emit(SIGNAL("showMsg"), "Update Available") + else: + self.mainWindow.statusbar.emit(SIGNAL("showMsg"), "") + + def getConnections(self): + """ + parse all connections in the config file + """ + 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): + """ + save connection to config file + """ + 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", str(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): + """ + remove connection from config file + """ + 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): + """ + slot: connect button in connectionmanager + show password window if remote connection or start connecting + """ + self.connWindow.hide() + self.connData = data + if data["type"] == "local": + self.slotPasswordTyped("") + else: + self.pwWindow.show() + + def slotPasswordTyped(self, pw): + """ + connect to a core + if connection is local, parse the core config file for data + set up connector, show main window + """ + data = self.connData + data["password"] = pw + if not data["type"] == "remote": + coreparser = XMLParser("module/config/core.xml", "module/config/core_default.xml") + sections = coreparser.parseNode(coreparser.root, "dict") + conf = coreparser.parseNode(sections["remote"], "dict") + ssl = coreparser.parseNode(sections["ssl"], "dict") + data["port"] = conf["port"].text() + data["user"] = conf["username"].text() + data["password"] = conf["password"].text() + data["host"] = "127.0.0.1" + if str(ssl["activated"].text()).lower() == "true": + data["ssl"] = True + else: + data["ssl"] = False + 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(str(server_url)) + self.startMain() + + def refreshConnections(self): + """ + reload connetions and display them + """ + self.parser.loadData() + conns = self.getConnections() + self.connWindow.emit(SIGNAL("setConnections(connections)"), conns) + for conn in conns: + if conn["default"]: + return conn 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) - -class _Host_Dialog(wx.Dialog): - def __init__(self, parent, id, title): - wx.Dialog.__init__(self, parent, id, title, size=(250, 170)) - - 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)) - - - fgs = wx.FlexGridSizer(3, 2, 9, 25) + + def slotAddLinks(self, links): + """ + emitted from main window + add urls to the collector + """ + self.connector.addURLs(links) + + def slotSetDownloadStatus(self, status): + """ + toolbar start/pause slot + """ + self.connector.setPause(not status) + + def slotAddPackage(self, name, ids): + """ + emitted from main window + add package to the collector + """ + packid = self.connector.newPackage(str(name)) + for fileid in ids: + self.connector.addFileToPackage(fileid, packid) + self.mainWindow.lastAddedID = packid + + def slotAddFileToPackage(self, pid, fid): + """ + emitted from collector view after a drop action + """ + self.connector.addFileToPackage(fid, pid) + + def slotAddContainer(self, path): + """ + emitted from main window + add container + """ + filename = basename(path) + type = "".join(filename.split(".")[-1]) + fh = open(path, "r") + content = fh.read() + fh.close() + self.connector.uploadContainer(filename, type, content) + + def slotSaveMainWindow(self, state, geo): + """ + save the window geometry and toolbar/dock position to config file + """ + mainWindowNode = self.parser.xml.elementsByTagName("mainWindow").item(0) + if mainWindowNode.isNull(): + mainWindowNode = self.parser.xml.createElement("mainWindow") + self.parser.root.appendChild(mainWindowNode) + stateNode = mainWindowNode.toElement().elementsByTagName("state").item(0) + geoNode = mainWindowNode.toElement().elementsByTagName("geometry").item(0) + newStateNode = self.parser.xml.createTextNode(state) + newGeoNode = self.parser.xml.createTextNode(geo) - 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)]) + stateNode.removeChild(stateNode.firstChild()) + geoNode.removeChild(geoNode.firstChild()) + stateNode.appendChild(newStateNode) + geoNode.appendChild(newGeoNode) - fgs.AddGrowableCol(1, 1) + self.parser.saveData() + + def restoreMainWindow(self): + """ + load and restore main window geometry and toolbar/dock position from config + """ + mainWindowNode = self.parser.xml.elementsByTagName("mainWindow").item(0) + if mainWindowNode.isNull(): + return + nodes = self.parser.parseNode(mainWindowNode, "dict") - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add(fgs, 1, wx.ALL | wx.EXPAND, 15) + state = str(nodes["state"].text()) + geo = str(nodes["geometry"].text()) + self.mainWindow.restoreWindow(state, geo) + self.mainWindow.captchaDock.hide() + + def slotPushPackageToQueue(self, id): + """ + emitted from main window + push the collector package to queue + """ + self.connector.pushPackageToQueue(id) + + def slotRestartDownload(self, id, isPack): + """ + emitted from main window + restart download + """ + if isPack: + self.connector.restartPackage(id) + else: + self.connector.restartFile(id) + + def slotRemoveDownload(self, id, isPack): + """ + emitted from main window + remove download + """ + if isPack: + self.connector.removePackage(id) + else: + self.connector.removeFile(id) + + def slotStopAllDownloads(self): + """ + emitted from main window + stop all running downloads + """ + self.connector.stopAllDownloads() + + def slotClipboardChange(self): + """ + called if clipboard changes + """ + if self.checkClipboard: + text = self.clipboard.text() + pattern = re.compile(r"(http|https)://[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(([0-9]{1,5})?/.*)?") + matches = pattern.finditer(text) + for match in matches: + self.slotAddLinks([str(match.group(0))]) + + def slotSetClipboardStatus(self, status): + """ + set clipboard checking + """ + self.checkClipboard = status + + def slotChangePackageName(self, pid, name): + """ + package name edit finished + """ + self.connector.setPackageName(pid, str(name)) + + def slotPullOutPackage(self, pid, isPack): + """ + pull package out of the queue + """ + if isPack: + self.connector.pullOutPackage(pid) + + def checkCaptcha(self): + if self.connector.captchaWaiting() and self.mainWindow.captchaDock.isFree(): + cid, img, imgType = self.connector.getCaptcha() + self.mainWindow.captchaDock.emit(SIGNAL("setTask"), cid, str(img), imgType) + + def slotCaptchaDone(self, cid, result): + self.connector.setCaptchaResult(str(cid), str(result)) + + class Loop(QThread): + """ + main loop (not application loop) + """ - self.SetSizer(hbox) + def __init__(self, parent): + QThread.__init__(self) + self.parent = parent + self.running = True -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) + def run(self): + while self.running: + sleep(1) + self.update() - # 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) + def update(self): + """ + methods to call + """ + self.parent.refreshServerStatus() + self.parent.refreshLog() + self.parent.updateAvailable() + self.parent.checkCaptcha() + def stop(self): + self.running = False - def exit_button_clicked(self, event): - self.Close() - - 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) - - 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) - - -def format_time(seconds): - seconds = int(seconds) - hours, seconds = divmod(seconds, 3600) - minutes, seconds = divmod(seconds, 60) - return "%.2i:%.2i:%.2i" % (hours, minutes, seconds) - +if __name__ == "__main__": + app = main() + app.loop() -app = wx.App() -Pyload_Main_Gui(None, -1) -app.MainLoop() |