add support for custom localizations and german translation
[enigma2-plugins.git] / movieretitle / src / plugin.py
1 # for localized messages
2 from . import _
3
4 from Plugins.Plugin import PluginDescriptor
5 from Screens.Screen import Screen
6 from Screens.MessageBox import MessageBox
7 from Screens.LocationBox import MovieLocationBox
8 import Screens.Standby
9 from Components.config import config, ConfigText, ConfigSelection, getConfigListEntry
10 from Components.ActionMap import ActionMap, NumberActionMap
11 from Components.ConfigList import ConfigList, ConfigListScreen
12 from Components.Label import Label
13 from enigma import eTimer, eServiceReference, eServiceCenter, iServiceInformation, eConsoleAppContainer
14 import os
15
16 def main(session, service, **kwargs):
17         session.open(MovieRetitle, service, session.current_dialog, **kwargs)
18
19 def Plugins(**kwargs):
20         return PluginDescriptor(name="MovieRetitle", description=_("Change name..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main)
21
22
23 class MovieRetitle(Screen, ConfigListScreen):
24         skin = """
25         <screen name="TitleDescrInput" position="100,150" size="500,200" title="Name and Description Input">
26                 <widget name="config" position="10,10" size="480,120" />
27                 <ePixmap position="70,140" size="140,40" pixmap="skin_default/buttons/green.png" alphatest="on" />
28                 <widget name="oktext" position="70,140" size="140,40" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
29                 <ePixmap position="290,140" size="140,40" pixmap="skin_default/buttons/red.png" alphatest="on" />
30                 <widget name="canceltext" position="290,140" size="140,40" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
31         </screen>"""
32
33         def __init__(self, session, service, parent, args = 0):
34                 Screen.__init__(self, session, parent = parent)
35                 serviceHandler = eServiceCenter.getInstance()
36                 info = serviceHandler.info(service)
37                 path = service.getPath()
38                 if path.endswith(".ts") is True:
39                         path = path[:-3]
40                 self.path = path
41                 self.dir = '/'.join(path.split('/')[:-1]) + '/'
42                 self.file = self.baseName(path)
43                 self.name = info.getName(service)
44                 if self.file == self.baseName(self.name):
45                         self.title = ""
46                 else:
47                         self.title = self.name
48                 self.descr = info.getInfoString(service, iServiceInformation.sDescription)
49
50                 self["oktext"] = Label(_("OK"))
51                 self["canceltext"] = Label(_("Cancel"))
52
53                 self.input_file = ConfigText(default = self.file, fixed_size = False, visible_width = 42)
54                 self.input_title = ConfigText(default = self.title, fixed_size = False, visible_width = 42)
55                 self.input_descr = ConfigText(default = self.descr, fixed_size = False, visible_width = 42)
56                 tmp = config.movielist.videodirs.value
57                 if not self.dir in tmp:
58                         tmp.append(self.dir)
59                 self.input_dir = ConfigSelection(choices = tmp, default = self.dir)
60
61                 self["actions"] = NumberActionMap(["SetupActions"],
62                 {
63                         "ok": self.keySelectOrGo,
64                         "save": self.keyGo,
65                         "cancel": self.keyCancel,
66                 }, -2)
67
68                 self.locationEl = getConfigListEntry(_("Location"), self.input_dir)
69                 l = [
70                         getConfigListEntry(_("Filename"), self.input_file),
71                         getConfigListEntry(_("Title"), self.input_title),
72                         getConfigListEntry(_("Description"), self.input_descr),
73                         self.locationEl
74                 ]
75
76                 ConfigListScreen.__init__(self, l)
77
78         def pathSelected(self, res):
79                 if res is not None:
80                         videodirs = config.movielist.videodirs.value
81                         if videodirs != self.input_dir.choices:
82                                 self.input_dir.setChoices(videodirs, default=res)
83                         self.input_dir.value = res
84
85         def keySelectOrGo(self):
86                 cur = self["config"].getCurrent()
87                 if cur is self.locationEl:
88                         self.session.openWithCallback(
89                                 self.pathSelected,
90                                 MovieLocationBox,
91                                 _("Choose target folder"),
92                                 self.input_dir.value,
93                         )
94                 else:
95                         self.keyGo()
96
97         def keyGo(self):
98                 if self.input_title.value != self.title or self.input_descr.value != self.descr:
99                         self.setTitleDescr(self.path, self.input_title.value, self.input_descr.value)
100                 if self.input_file.value != self.file or self.input_dir.value != self.dir:
101                         self.maybeMoveMovieFiles(self.path, self.rejoinName(self.input_dir.value, self.input_file.value))
102                 else:
103                         self.exitDialog()
104
105         def keyCancel(self):
106                 self.close()
107
108         def setTitleDescr(self, file, title, descr):
109                 if os.path.exists(file + ".ts.meta"):
110                         metafile = open(file + ".ts.meta", "r")
111                         sid = metafile.readline()
112                         oldtitle = metafile.readline().rstrip()
113                         olddescr = metafile.readline().rstrip()
114                         rest = metafile.read()
115                         metafile.close()
116                         if not title and title != "":
117                                 title = oldtitle
118                         if not descr and descr != "":
119                                 descr = olddescr
120                         metafile = open(file + ".ts.meta", "w")
121                         metafile.write("%s%s\n%s\n%s" %(sid, title, descr, rest))
122                         metafile.close()
123
124         def maybeMoveMovieFiles(self, fr, to):
125                 if os.path.exists(to+".ts"):
126                         self.inter_fr = fr
127                         self.inter_to = to
128                         self.session.openWithCallback(self.confirmedReplace, MessageBox, _("Target file %s.ts already exist.\nDo you want to replace it?") % (to), MessageBox.TYPE_YESNO)
129                 elif os.path.isdir(os.path.dirname(to)):
130                         self.moveMovieFiles(fr, to)
131                 else:
132                         self.session.openWithCallback(self.exitDialog, MessageBox, _("The target directory is not found. The file is not renamed."), MessageBox.TYPE_ERROR)
133
134         def confirmedReplace(self, answer):
135                 if answer == True:
136                         self.moveMovieFiles(self.inter_fr, self.inter_to)
137
138         def moveMovieFiles(self, fr, to):
139                 try:
140                         os.rename(fr + ".ts", to + ".ts")
141                 except OSError:
142                         print "Moving in background"
143                         global_background_mover.enqueue(self.exitDialog, self.session, fr, to)
144                 else:
145                         print "Moving in foreground"
146                         for suff in (".ts.meta", ".ts.cuts", ".ts.ap", ".eit"):
147                                 if os.path.exists(fr + suff):
148                                         os.rename(fr + suff, to + suff)
149                         self.exitDialog()
150
151         def exitDialog(self, dummy=None):
152                 self.close()
153                 # This will try to get back to an updated movie list.
154                 # A proper way to do this should be provided in enigma2.
155                 try:
156                         parent = self.parent
157                         parent.csel.reloadList()
158                         parent.close()
159                 except AttributeError:
160                         pass
161
162         def baseName(self, str):
163                 name = str.split('/')[-1]
164                 if name.endswith(".ts") is True:
165                         return name[:-3]
166                 else:
167                         return name
168
169         def rejoinName(self, dir, name):
170                 name = name.strip()
171                 if name.endswith(".ts") is True:
172                         return dir + name[:-3]
173                 else:
174                         return dir + name
175
176 class MovieRetitleBackgroundMover:
177         def __init__(self):
178                 self.container = eConsoleAppContainer()
179                 self.container.appClosed.append(self.moveNextSuffBG)
180                 self.currid = 0;
181                 self.queue = []
182                 self.running = False
183                 self.messageQueue = []
184                 self.messageTimer = eTimer()
185                 self.messageTimer.callback.append(self.tryLaunchMessage)
186
187         def message(self, session, id, cb, txt):
188                 global global_message_block
189                 done = False
190                 if global_message_block and global_message_block == id:
191                         self.messageQueue = [(session, id, txt)] + self.messageQueue
192                 else:
193                         i = 0
194                         for ele in self.messageQueue:
195                                 if ele[1] == id:
196                                         self.messageQueue[i] = (session, id, txt)
197                                         done = True
198                                         break
199                                 i += 1
200                         if not done:
201                                 self.messageQueue.append((session, id, txt))
202                 self.tryLaunchMessage(callback = cb)
203
204         def tryLaunchMessage(self, dummy=0, callback = None):
205                 global global_message_block
206                 self.messageTimer.stop()
207                 if not self.messageQueue:
208                         if callback:
209                                 callback()
210                 elif not Screens.Standby.inStandby and self.messageQueue[0][0].in_exec and (not global_message_block or global_message_block == self.messageQueue[0][1]):
211                         self.messageTimer.stop()
212                         session = self.messageQueue[0][0]
213                         id = self.messageQueue[0][1]
214                         mess = self.messageQueue[0][2]
215                         self.messageQueue = self.messageQueue[1:]
216                         if global_message_block == id:
217                                 closeprev = session.current_dialog
218                         else:
219                                 closeprev = None
220                         global_message_block = id
221                         try:
222                                 session.openWithCallback(lambda x: self.tryLaunchMessageCallback(callback, closeprev), MessageBox, mess, MessageBox.TYPE_INFO)
223                         except:
224                                 global_message_block = False
225                                 self.tryLaunchMessage()
226                 else:
227                         self.messageTimer.start(1500, True)
228                         if callback:
229                                 callback()
230
231         def tryLaunchMessageCallback(self, callback, closeprev):
232                 global global_message_block
233                 global_message_block = False
234                 if closeprev:
235                         closeprev.close(True)
236                 self.tryLaunchMessage(callback = callback)
237
238         def enqueue(self, cb, session, fr, to):
239                 self.currid += 1
240                 mess = _("The movie is moved in the background from %s to %s.") % (os.path.dirname(fr), os.path.dirname(to))
241                 self.message(session, self.currid, cb, mess)
242                 self.queue.append((session, self.currid, fr, to))
243                 if not self.running:
244                         self.running = True
245                         self.runNext()
246                         return True
247                 else:
248                         return False
249
250         def runNext(self):
251                 if not self.queue:
252                         self.running = False
253                 else:
254                         self.moveMovieFilesBackground(self.queue[0])
255
256         def runDone(self, retval):
257                 ele = self.queue[0]
258                 self.queue = self.queue[1:]
259                 self.runNext()
260
261         def moveMovieFilesBackground(self, ele):
262                 self.ele = ele
263                 self.sufflst = (".ts.meta", ".ts.cuts", ".ts.ap", ".eit", ".ts")
264                 self.sufflst2 = self.sufflst
265                 self.moveNextSuffBG(0)
266
267         def moveNextSuffBG(self, retval):
268                 if self.sufflst and not retval:
269                         fr = self.ele[2] + self.sufflst[0]
270                         to = self.ele[3] + self.sufflst[0]
271                         self.sufflst = self.sufflst[1:]
272                         print "Moving %s to %s" % (fr, to)
273                         if os.path.exists(fr):
274                                 self.container.execute("/bin/cp", "/bin/cp", fr, to)
275                         else:
276                                 self.moveNextSuffBG(0)
277                 elif retval:
278                         for suff in self.sufflst2:
279                                 if os.path.exists(self.ele[3] + suff) and os.path.exists(self.ele[2] + suff):
280                                         os.unlink(self.ele[3] + suff)
281                         mess = _("Failed to move the movie %s to %s in the background") % (self.ele[2], self.ele[3])
282                         self.message(self.ele[0], self.ele[1], None, mess)
283                         self.runDone(1)
284                 else:
285                         for suff in self.sufflst2:
286                                 if os.path.exists(self.ele[2] + suff) and os.path.exists(self.ele[3] + suff):
287                                         os.unlink(self.ele[2] + suff)
288                         mess = _("Successfully moved the movie %s") % (self.ele[2])
289                         self.message(self.ele[0], self.ele[1], None, mess)
290                         self.runDone(0)
291
292 global_background_mover = MovieRetitleBackgroundMover()
293
294 global_message_block = False
295