- get rid of custom title source and use builtin Title,
[enigma2-plugins.git] / ftpbrowser / src / FTPServerManager.py
1 # for localized messages
2 from . import _
3
4 # GUI (Screens)
5 from Components.ConfigList import ConfigListScreen
6 from Screens.MessageBox import MessageBox
7 from Screens.Screen import Screen
8 from NTIVirtualKeyBoard import NTIVirtualKeyBoard
9
10 # GUI (Summary)
11 from Screens.Setup import SetupSummary
12
13 # GUI (Components)
14 from Components.ActionMap import ActionMap
15 from Components.Sources.List import List
16 from Components.Sources.StaticText import StaticText
17
18 # Config
19 from Components.config import config, ConfigInteger, ConfigSubsection, \
20                 ConfigText, ConfigPassword, ConfigYesNo, getConfigListEntry
21
22 # For new and improved _parse
23 from urlparse import urlparse, urlunparse
24
25 def _parse(url, defaultPort = None):
26         url = url.strip()
27         parsed = urlparse(url)
28         scheme = parsed[0]
29         path = urlunparse(('','')+parsed[2:])
30
31         if defaultPort is None:
32                 if scheme == 'https':
33                         defaultPort = 443
34                 elif scheme == 'ftp':
35                         defaultPort = 21
36                 else:
37                         defaultPort = 80
38
39         host, port = parsed[1], defaultPort
40
41         if '@' in host:
42                 username, host = host.split('@')
43                 if ':' in username:
44                         username, password = username.split(':')
45                 else:
46                         password = ""
47         else:
48                 username = ""
49                 password = ""
50
51         if ':' in host:
52                 host, port = host.split(':')
53                 port = int(port)
54
55         if path == "":
56                 path = "/"
57
58         return scheme, host, port, path, username, password
59
60 class FTPServer:
61         def __init__(self, cfg):
62                 self.cfg = cfg
63
64         def getCfg(self):
65                 return self.cfg
66
67         def getName(self):
68                 return self.cfg.name.value
69
70         def getAddress(self):
71                 return self.cfg.address.value
72
73         def getUsername(self):
74                 return self.cfg.username.value
75
76         def getPassword(self):
77                 return self.cfg.password.value
78
79         def getPort(self):
80                 return self.cfg.port.value
81
82         def getPassive(self):
83                 return self.cfg.passive.value
84
85         def getPath(self):
86                 # TODO: implement
87                 return '/'
88
89         def getURI(self):
90                 if self.getUsername() != "":
91                         uri = "ftp://%s:%s@%s:%d%s" % (self.getUsername(), self.getPassword(), self.getAddress(), self.getPort(), self.getPath())
92                 else:
93                         uri = "ftp://%s:%d%s" % (self.getAddress(), self.getPort(), self.getPath())
94                 return uri
95
96         def save(self):
97                 self.cfg.save()
98
99         def cancel(self):
100                 self.cfg.cancel()
101
102 def ftpserverFromURI(uri, name = "", save = True):
103         scheme, host, port, path, username, password = _parse(uri, defaultPort = 21)
104         
105         newServer = ConfigSubsection()
106         if save:
107                 config.plugins.ftpbrowser.server.append(newServer)
108         newServer.name = ConfigText(fixed_size = False)
109         newServer.name.value = name or host
110         newServer.address = ConfigText(fixed_size = False)
111         newServer.address.value = host
112         newServer.username = ConfigText(fixed_size = False)
113         newServer.username.value = username
114         newServer.password = ConfigPassword()
115         newServer.password.value = password
116         newServer.port = ConfigInteger(0, (0, 65535))
117         newServer.port.value = port
118         newServer.passive = ConfigYesNo(False)
119
120         if save:
121                 newServer.save()
122                 config.plugins.ftpbrowser.servercount.value += 1
123                 config.plugins.ftpbrowser.servercount.save()
124
125         return FTPServer(newServer)
126
127 class FTPServerEditor(ConfigListScreen, Screen):
128         skin = """
129                 <screen position="center,center" size="560,180" title="FTP Server Editor">
130                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
131                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
132                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
133                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
134                         <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
135                         <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
136                         <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
137                         <widget source="key_blue" render="Label"  position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
138                         <widget name="config" position="10,50" size="550,130" scrollbarMode="showOnDemand" />
139                 </screen>"""
140
141         def __init__(self, session, server):
142                 Screen.__init__(self, session)
143
144                 self.onChangedEntry = []
145                 self.setup_title = _("FTP Server Editor")
146                 self.server = server
147
148                 self["key_red"] = StaticText(_("Exit"))
149                 self["key_green"] = StaticText(_("OK"))
150                 self["key_yellow"] = StaticText("")
151                 self["key_blue"] = StaticText(_("Enter URI"))
152
153                 ConfigListScreen.__init__(self, [
154                         getConfigListEntry(_("Name:"), server.cfg.name),
155                         getConfigListEntry(_("Address:"), server.cfg.address),
156                         getConfigListEntry(_("Username:"), server.cfg.username),
157                         getConfigListEntry(_("Password:"), server.cfg.password),
158                         getConfigListEntry(_("Port:"), server.cfg.port)
159                 ])
160                 
161                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
162                         {
163                                 "save": self.keySave,
164                                 "cancel": self.keyCancel,
165                                 "blue": self.getURI,
166                         }, -2)
167
168                 self.onLayoutFinish.append(self.layoutFinished)
169
170         def layoutFinished(self):
171                 self.setTitle(_("FTP Server Editor"))
172
173         def changed(self):
174                 for x in self.onChangedEntry:
175                         try:
176                                 x()
177                         except Exception:
178                                 pass
179
180         def getCurrentEntry(self):
181                 return self["config"].getCurrent()[0]
182
183         def getCurrentValue(self):
184                 return str(self["config"].getCurrent()[1].getText())
185
186         def createSummary(self):
187                 return SetupSummary
188
189         def gotURI(self, res):
190                 if res:
191                         cfg = self.server.cfg
192
193                         # _parse gets confused without a scheme
194                         if not res.startswith("ftp://"):
195                                 res = "ftp://" + res
196                         scheme, host, port, path, username, password = _parse(res, defaultPort = 21)
197
198                         cfg.address.value = host
199                         cfg.username.value = username
200                         cfg.password.value = password
201                         cfg.port.value = port
202
203         def getURI(self):
204                 self.session.openWithCallback(
205                         self.gotURI,
206                         NTIVirtualKeyBoard,
207                         title = _("Enter URI of FTP Server:"),
208                         text = self.server.getURI(),
209                 )
210
211         def keySave(self):
212                 self.saveAll()
213                 self.close(True)
214
215 class FTPServerManagerSummary(Screen):
216         skin = """
217         <screen position="0,0" size="132,64">
218                 <widget source="parent.Title" render="Label" position="6,4" size="120,21" font="Regular;18" />
219                 <widget source="parent.list" render="Label" position="6,25" size="120,21" font="Regular;16">
220                         <convert type="StringListSelection" />
221                 </widget>
222                 <widget source="global.CurrentTime" render="Label" position="56,46" size="82,18" font="Regular;16" >
223                         <convert type="ClockToText">WithSeconds</convert>
224                 </widget>
225         </screen>"""
226
227 class FTPServerManager(Screen):
228         skin = """
229                 <screen position="center,center" size="560,420" title="FTP Server Manager" >
230                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
231                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
232                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
233                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
234                         <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
235                         <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
236                         <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
237                         <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
238                         <widget source="list" render="Listbox" position="0,50" size="560,360" scrollbarMode="showAlways">
239                                 <convert type="TemplatedMultiContent">
240                                         {"template": [
241                                                         MultiContentEntryText(pos=(1,1), size=(540,22), text = 0, font = 0, flags = RT_HALIGN_LEFT|RT_VALIGN_CENTER),
242                                                 ],
243                                           "fonts": [gFont("Regular", 20)],
244                                           "itemHeight": 24
245                                          }
246                                 </convert>
247                         </widget>
248                 </screen>"""
249
250         def __init__(self, session):
251                 Screen.__init__(self, session)
252                 self.changed = False
253
254                 self["key_red"] = StaticText(_("Delete"))
255                 self["key_green"] = StaticText(_("Add"))
256                 self["key_yellow"] = StaticText(_("Edit"))
257                 self["key_blue"] = StaticText(_("Save"))
258                 self["list"] = List([])
259                 
260                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
261                         {
262                                 "cancel": self.exit,
263                                 "ok": self.okClicked,
264                                 "red": self.delete,
265                                 "green": self.add,
266                                 "yellow": self.edit,
267                                 "blue": self.save
268                         }, -1)
269                 
270                 self.onLayoutFinish.extend((
271                         self.updateServerList,
272                         self.layoutFinished,
273                 ))
274
275         def createSummary(self):
276                 return FTPServerManagerSummary
277
278         def layoutFinished(self):
279                 self.setTitle(_("FTP Server Manager"))
280
281         def updateServerList(self):
282                 list = [(server.name.value,) for server in config.plugins.ftpbrowser.server]
283                 self["list"].setList(list)
284
285         def exit(self, server=None):
286                 if self.changed:
287                         self.save(False)
288                 self.close(server)
289
290         def okClicked(self):
291                 idx = self["list"].index
292                 if idx is None:
293                         return
294
295                 ftpserverconfig = config.plugins.ftpbrowser
296                 Len = ftpserverconfig.servercount.value
297
298                 if Len and idx < Len:
299                         server = FTPServer(ftpserverconfig.server[idx])
300                         self.exit(server)
301
302         def delete(self):
303                 idx = self["list"].index
304                 if idx is None:
305                         return
306
307                 self.session.openWithCallback(
308                         self.deleteConfirm,
309                         MessageBox,
310                         _("Really delete this entry?\nIt cannot be recovered!")
311                 )
312
313         def deleteConfirm(self, ret):
314                 if not ret:
315                         return
316
317                 idx = self["list"].index
318                 ftpserverconfig = config.plugins.ftpbrowser
319                 Len = ftpserverconfig.servercount.value
320
321                 if Len and idx < Len:
322                         del ftpserverconfig.server[idx]
323                         ftpserverconfig.servercount.value -= 1
324                         self.updateServerList()
325                         self.changed = True
326
327         def add(self):
328                 newServer = ConfigSubsection()
329                 config.plugins.ftpbrowser.server.append(newServer)
330                 newServer.name = ConfigText("Name", fixed_size = False)
331                 newServer.address = ConfigText("192.168.2.12", fixed_size = False)
332                 newServer.username = ConfigText("root", fixed_size = False)
333                 newServer.password = ConfigPassword("dreambox")
334                 newServer.port = ConfigInteger(21, (1, 65535))
335                 newServer.passive = ConfigYesNo(False)
336                 config.plugins.ftpbrowser.servercount.value += 1
337                 config.plugins.ftpbrowser.servercount.save()
338
339                 self.updateServerList()
340                 self.changed = True
341
342         def edit(self):
343                 idx = self["list"].index
344                 ftpserverconfig = config.plugins.ftpbrowser
345                 Len = ftpserverconfig.servercount.value
346
347                 if idx is not None and Len and idx < Len:
348                         self.session.openWithCallback(
349                                 self.editCallback,
350                                 FTPServerEditor,
351                                 FTPServer(ftpserverconfig.server[idx])
352                         )
353
354         def editCallback(self, ret = False):
355                 if ret:
356                         self.updateServerList()
357                         self.changed = True
358
359         def save(self, showMessageBox=True):
360                 config.plugins.ftpbrowser.save()
361                 if showMessageBox:
362                         self.session.open(
363                                 MessageBox,
364                                 _("Configuration saved."),
365                                 type = MessageBox.TYPE_INFO
366                         )
367