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