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