add server manager based off code by AliAbdul
authorMoritz Venn <ritzmo@users.schwerkraft.elitedvb.net>
Sun, 20 Sep 2009 11:23:24 +0000 (11:23 +0000)
committerMoritz Venn <ritzmo@users.schwerkraft.elitedvb.net>
Sun, 20 Sep 2009 11:23:24 +0000 (11:23 +0000)
ftpbrowser/src/FTPBrowser.py
ftpbrowser/src/FTPServerManager.py [new file with mode: 0644]
ftpbrowser/src/plugin.py

index 282bcd0..93a5c0a 100644 (file)
@@ -15,7 +15,7 @@ from Screens.HelpMenu import HelpableScreen
 from Screens.MessageBox import MessageBox
 from Screens.ChoiceBox import ChoiceBox
 from Screens.InfoBarGenerics import InfoBarNotifications
-from NTIVirtualKeyBoard import NTIVirtualKeyBoard
+from FTPServerManager import FTPServerManager
 
 # GUI (Components)
 from Components.ActionMap import ActionMap, HelpableActionMap
@@ -30,51 +30,10 @@ from twisted.internet.protocol import Protocol, ClientCreator
 from twisted.protocols.ftp import FTPClient, FTPFileListProtocol
 from twisted.protocols.basic import FileSender
 
-# For new and improved _parse
-from urlparse import urlparse, urlunparse
-
 # System
 from os import path as os_path
 from time import time
 
-# Config
-from Components.config import config
-
-def _parse(url, defaultPort = None):
-       url = url.strip()
-       parsed = urlparse(url)
-       scheme = parsed[0]
-       path = urlunparse(('','')+parsed[2:])
-
-       if defaultPort is None:
-               if scheme == 'https':
-                       defaultPort = 443
-               elif scheme == 'ftp':
-                       defaultPort = 21
-               else:
-                       defaultPort = 80
-
-       host, port = parsed[1], defaultPort
-
-       if '@' in host:
-               username, host = host.split('@')
-               if ':' in username:
-                       username, password = username.split(':')
-               else:
-                       password = ""
-       else:
-               username = ""
-               password = ""
-
-       if ':' in host:
-               host, port = host.split(':')
-               port = int(port)
-
-       if path == "":
-               path = "/"
-
-       return scheme, host, port, path, username, password
-
 def FTPFileEntryComponent(file, directory):
        isDir = True if file['filetype'] == 'd' else False
        name = file['filename']
@@ -207,7 +166,7 @@ class FTPBrowser(Screen, Protocol, InfoBarNotifications, HelpableScreen):
                self["key_yellow"] = Button("")
                self["key_blue"] = Button("")
 
-               self.URI = "ftp://"
+               self.server = None
 
                self["ftpbrowserBaseActions"] = HelpableActionMap(self, "ftpbrowserBaseActions",
                        {
@@ -239,50 +198,17 @@ class FTPBrowser(Screen, Protocol, InfoBarNotifications, HelpableScreen):
                self["local"].refresh()
 
                if not self.ftpclient:
-                       self.connect(self.URI)
+                       self.connect(self.server)
                # XXX: Actually everything else should be taken care of... recheck this!
 
-       def menuCallback(self, ret):
-               ret and ret[1]()
+       def managerCallback(self, uri):
+               if uri:
+                       self.connect(uri)
 
        def menu(self):
                self.session.openWithCallback(
-                       self.menuCallback,
-                       ChoiceBox,
-                       title = _("What do you want to do?"),
-                       list = (
-                               (_("Connect to server from history"), self.connectHistory),
-                               (_("Connect to new server"), self.connectNew),
-                       )
-               )
-
-       def connectHistory(self):
-               options = [(x, x) for x in config.plugins.ftpbrowser.history.value]
-
-               if options:
-                       self.session.openWithCallback(
-                               self.connectWrapper,
-                               ChoiceBox,
-                               title = _("Select server to connect to"),
-                               list = options
-                       )
-               else:
-                       self.session.open(
-                               MessageBox,
-                               _("No history"),
-                               type = MessageBox.TYPE_INFO
-                       )
-
-       def inputCallback(self, res):
-               if res:
-                       self.connect(res)
-
-       def connectNew(self):
-               self.session.openWithCallback(
-                       self.inputCallback,
-                       NTIVirtualKeyBoard,
-                       title = _("Enter URI of FTP Server:"),
-                       text = self.URI,
+                       self.managerCallback,
+                       FTPServerManager,
                )
 
        def setLocal(self):
@@ -485,8 +411,6 @@ class FTPBrowser(Screen, Protocol, InfoBarNotifications, HelpableScreen):
                        self.close()
 
        def cancel(self):
-               config.plugins.ftpbrowser.save()
-
                if self.file is not None:
                        self.session.openWithCallback(
                                self.cancelQuestion,
@@ -527,31 +451,27 @@ class FTPBrowser(Screen, Protocol, InfoBarNotifications, HelpableScreen):
                if ret:
                        self.connect(ret[1])
 
-       def connect(self, address):
+       def connect(self, server):
                self.disconnect()
 
-               self.URI = address
+               self.server = server
 
-               scheme, host, port, path, username, password = _parse(address)
-               if not host:
+               if not server:
                        return
 
-               # Maintain history
-               history = config.plugins.ftpbrowser.history.value
-               if address not in history:
-                       history.insert(0, address)
-                       if len(history) > 10:
-                               history.pop(10)
-               else:
-                       history.remove(address)
-                       history.insert(0, address)
-
+               username = server.getUsername()
                if not username:
                        username = 'anonymous'
                        password = 'my@email.com'
+               else:
+                       password = server.getPassword()
 
+               host = server.getAddress()
+               passive = server.getPassive()
+               port = server.getPort()
                timeout = 30 # TODO: make configurable
-               passive = True # TODO: make configurable
+
+               # XXX: we might want to add a guard so we don't try to connect to another host while a previous attempt is not timed out
 
                creator = ClientCreator(reactor, FTPClient, username, password, passive = passive)
                creator.connectTCP(host, port, timeout).addCallback(self.controlConnectionMade).addErrback(self.connectionFailed)
@@ -562,13 +482,12 @@ class FTPBrowser(Screen, Protocol, InfoBarNotifications, HelpableScreen):
                self["remote"].ftpclient = ftpclient
                self["remoteText"].setText(_("Remote"))
 
-               scheme, host, port, path, username, password = _parse(self.URI)
-               self["remote"].changeDir(path)
+               self["remote"].changeDir(self.server.getPath())
 
        def connectionFailed(self, *args):
                print "[FTPBrowser] connection failed", args
 
-               self.URI = "ftp://"
+               self.server = None
                self["remoteText"].setText(_("Remote (not connected)"))
                self.session.open(
                                MessageBox,
diff --git a/ftpbrowser/src/FTPServerManager.py b/ftpbrowser/src/FTPServerManager.py
new file mode 100644 (file)
index 0000000..c9cf89f
--- /dev/null
@@ -0,0 +1,311 @@
+# GUI (Screens)
+from Components.ConfigList import ConfigListScreen
+from Screens.MessageBox import MessageBox
+from Screens.Screen import Screen
+from NTIVirtualKeyBoard import NTIVirtualKeyBoard
+
+# GUI (Components)
+from Components.MenuList import MenuList
+from Components.ActionMap import ActionMap
+from Components.Label import Label
+
+# Config
+from Components.config import config, ConfigInteger, ConfigSubsection, \
+               ConfigText, ConfigPassword, ConfigYesNo, getConfigListEntry
+
+# For new and improved _parse
+from urlparse import urlparse, urlunparse
+
+def _parse(url, defaultPort = None):
+       url = url.strip()
+       parsed = urlparse(url)
+       scheme = parsed[0]
+       path = urlunparse(('','')+parsed[2:])
+
+       if defaultPort is None:
+               if scheme == 'https':
+                       defaultPort = 443
+               elif scheme == 'ftp':
+                       defaultPort = 21
+               else:
+                       defaultPort = 80
+
+       host, port = parsed[1], defaultPort
+
+       if '@' in host:
+               username, host = host.split('@')
+               if ':' in username:
+                       username, password = username.split(':')
+               else:
+                       password = ""
+       else:
+               username = ""
+               password = ""
+
+       if ':' in host:
+               host, port = host.split(':')
+               port = int(port)
+
+       if path == "":
+               path = "/"
+
+       return scheme, host, port, path, username, password
+
+class FTPServer:
+       def __init__(self, cfg):
+               self.cfg = cfg
+
+       def getCfg(self):
+               return self.cfg
+
+       def getName(self):
+               return self.cfg.name.value
+
+       def getAddress(self):
+               return self.cfg.address.value
+
+       def getUsername(self):
+               return self.cfg.username.value
+
+       def getPassword(self):
+               return self.cfg.password.value
+
+       def getPort(self):
+               return self.cfg.port.value
+
+       def getPassive(self):
+               return self.cfg.passive.value
+
+       def getPath(self):
+               # TODO: implement
+               return '/'
+
+       def getURI(self):
+               if self.getUsername() != "":
+                       uri = "ftp://%s:%s@%s:%d%s" % (self.getUsername(), self.getPassword(), self.getAddress(), self.getPort(), self.getPath())
+               else:
+                       uri = "ftp://%s:%d%s" % (self.getAddress(), self.getPort(), self.getPath())
+               return uri
+
+       def save(self):
+               self.cfg.save()
+
+       def cancel(self):
+               self.cfg.cancel()
+
+def ftpserverFromURI(uri, name = ""):
+       scheme, host, port, path, username, password = _parse(uri, defaultPort = 21)
+       
+       newServer = ConfigSubsection()
+       config.plugins.ftpbrowser.server.append(newServer)
+       newServer.name = ConfigText(fixed_size = False)
+       newServer.name.value = name or host
+       newServer.address = ConfigText(fixed_size = False)
+       newServer.address.value = host
+       newServer.username = ConfigText(fixed_size = False)
+       newServer.username.value = username
+       newServer.password = ConfigPassword()
+       newServer.password.value = password
+       newServer.port = ConfigInteger(0, (0, 65535))
+       newServer.port.value = port
+       newServer.passive = ConfigYesNo(False)
+
+       newServer.save()
+       config.plugins.ftpbrowser.servercount.value += 1
+       config.plugins.ftpbrowser.servercount.save()
+
+       return newServer
+
+class FTPServerEditor(ConfigListScreen, Screen):
+       skin = """
+               <screen position="center,center" size="560,180" title="FTP Server Editor">
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
+                       <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="config" position="10,50" size="550,130" scrollbarMode="showOnDemand" />
+               </screen>"""
+
+       def __init__(self, session, server):
+               Screen.__init__(self, session)
+
+               self.server = server
+
+               self["key_red"] = Label(_("Exit"))
+               self["key_green"] = Label(_("OK"))
+               self["key_yellow"] = Label("")
+               self["key_blue"] = Label(_("Enter URI"))
+
+               ConfigListScreen.__init__(self, [
+                       getConfigListEntry(_("Name:"), server.cfg.name),
+                       getConfigListEntry(_("Address:"), server.cfg.address),
+                       getConfigListEntry(_("Username:"), server.cfg.username),
+                       getConfigListEntry(_("Password:"), server.cfg.password),
+                       getConfigListEntry(_("Port:"), server.cfg.port)
+               ])
+               
+               self["actions"] = ActionMap(["SetupActions", "ColorActions"],
+                       {
+                               "save": self.keySave,
+                               "cancel": self.keyCancel,
+                               "blue": self.getURI,
+                       }, -2)
+
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle(_("FTP Server Editor"))
+
+       def gotURI(self, res):
+               if res:
+                       cfg = self.server.cfg
+
+                       # _parse gets confused without a scheme
+                       if not res.startswith("ftp://"):
+                               res = "ftp://" + res
+                       scheme, host, port, path, username, password = _parse(res, defaultPort = 21)
+
+                       cfg.address.value = host
+                       cfg.username.value = username
+                       cfg.password.value = password
+                       cfg.port.value = port
+
+       def getURI(self):
+               self.session.openWithCallback(
+                       self.gotURI,
+                       NTIVirtualKeyBoard,
+                       title = _("Enter URI of FTP Server:"),
+                       text = self.server.getURI(),
+               )
+
+       def keySave(self):
+               self.saveAll()
+               self.close(True)
+
+class FTPServerManager(Screen):
+       skin = """
+               <screen position="center,center" size="560,420" title="FTP Server Manager" >
+                       <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
+                       <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
+                       <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
+                       <widget name="list" position="0,50" size="560,360" scrollbarMode="showOnDemand" />
+               </screen>"""
+
+       def __init__(self, session):
+               Screen.__init__(self, session)
+               self.session = session
+               self.changed = False
+               
+               self["key_red"] = Label(_("Delete"))
+               self["key_green"] = Label(_("Add"))
+               self["key_yellow"] = Label(_("Edit"))
+               self["key_blue"] = Label(_("Save"))
+               self["list"] = MenuList([])
+               
+               self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
+                       {
+                               "cancel": self.exit,
+                               "ok": self.okClicked,
+                               "red": self.delete,
+                               "green": self.add,
+                               "yellow": self.edit,
+                               "blue": self.save
+                       }, -1)
+               
+               self.onLayoutFinish.extend((
+                       self.updateServerList,
+                       self.layoutFinished,
+               ))
+
+       def layoutFinished(self):
+               self.setTitle(_("FTP Server Manager"))
+
+       def updateServerList(self):
+               list = [server.name.value for server in config.plugins.ftpbrowser.server]
+               self["list"].setList(list)
+
+       def exit(self, server=None):
+               if self.changed:
+                       self.save(False)
+               self.close(server)
+
+       def okClicked(self):
+               idx = self["list"].getSelectedIndex()
+               ftpserverconfig = config.plugins.ftpbrowser
+               Len = ftpserverconfig.servercount.value
+
+               if Len and idx < Len:
+                       server = FTPServer(ftpserverconfig.server[idx])
+                       self.exit(server)
+
+       def delete(self):
+               self.session.openWithCallback(
+                       self.deleteConfirm,
+                       MessageBox,
+                       _("Really delete this entry?\nIt cannot be recovered!")
+               )
+
+       def deleteConfirm(self, ret):
+               if not ret:
+                       return
+
+               idx = self["list"].getSelectedIndex()
+               ftpserverconfig = config.plugins.ftpbrowser
+               Len = ftpserverconfig.servercount.value
+
+               if Len and idx < Len:
+                       del ftpserverconfig.server[idx]
+                       ftpserverconfig.servercount.value -= 1
+                       self.updateServerList()
+                       self.changed = True
+
+       def add(self):
+               newServer = ConfigSubsection()
+               config.plugins.ftpbrowser.server.append(newServer)
+               newServer.name = ConfigText("Name", fixed_size = False)
+               newServer.address = ConfigText("192.168.2.12", fixed_size = False)
+               newServer.username = ConfigText("root", fixed_size = False)
+               newServer.password = ConfigPassword("dreambox")
+               newServer.port = ConfigInteger(21, (1, 65535))
+               newServer.passive = ConfigYesNo(False)
+               config.plugins.ftpbrowser.servercount.value += 1
+               config.plugins.ftpbrowser.servercount.save()
+
+               self.updateServerList()
+               self.changed = True
+
+       def edit(self):
+               idx = self["list"].getSelectedIndex()
+               ftpserverconfig = config.plugins.ftpbrowser
+               Len = ftpserverconfig.servercount.value
+
+               if Len and idx < Len:
+                       self.session.openWithCallback(
+                               self.editCallback,
+                               FTPServerEditor,
+                               FTPServer(ftpserverconfig.server[idx])
+                       )
+
+       def editCallback(self, ret = False):
+               if ret:
+                       self.updateServerList()
+                       self.changed = True
+
+       def save(self, showMessageBox=True):
+               config.plugins.ftpbrowser.save()
+               if showMessageBox:
+                       self.session.open(
+                               MessageBox,
+                               _("Configuration saved."),
+                               type = MessageBox.TYPE_INFO
+                       )
+
index f74c6f4..9a598ce 100644 (file)
@@ -6,10 +6,27 @@
 from . import _
 
 # Config
-from Components.config import config, ConfigSet, ConfigSubsection, ConfigText
+from Components.config import config, ConfigInteger, ConfigSubList, \
+               ConfigSubsection, ConfigText, ConfigPassword, ConfigYesNo
 
 config.plugins.ftpbrowser = ConfigSubsection()
-config.plugins.ftpbrowser.history = ConfigSet(choices = [])
+config.plugins.ftpbrowser.server = ConfigSubList()
+config.plugins.ftpbrowser.servercount = ConfigInteger(0)
+i = 0
+append = config.plugins.ftpbrowser.server.append
+while i < config.plugins.ftpbrowser.servercount.value:
+       newServer = ConfigSubsection()
+       append(newServer)
+       newServer.name = ConfigText("Name", fixed_size=False)
+       newServer.address = ConfigText("192.168.2.12", fixed_size=False)
+       newServer.username = ConfigText("root", fixed_size=False)
+       newServer.password = ConfigPassword("dreambox")
+       newServer.port = ConfigInteger(21, (1, 65535))
+       newServer.passive = ConfigYesNo(False)
+       i += 1
+       del newServer
+
+del append, i
 
 from FTPBrowser import FTPBrowser