520fc0451b12d2f5bcd31dd6683f095349db590e
[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.title = ""
39                 else:
40                         self.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.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.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", ".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                         pass
159
160         def baseName(self, str):
161                 name = str.split('/')[-1]
162                 if name.endswith(".ts") is True:
163                         return name[:-3]
164                 else:
165                         return name
166
167         def rejoinName(self, dir, name):
168                 name = name.strip()
169                 if name.endswith(".ts") is True:
170                         return dir + name[:-3]
171                 else:
172                         return dir + name
173
174 class MovieRetitleBackgroundMover:
175         def __init__(self):
176                 self.container = eConsoleAppContainer()
177                 self.container.appClosed.append(self.moveNextSuffBG)
178                 self.currid = 0;
179                 self.queue = []
180                 self.running = False
181                 self.messageQueue = []
182                 self.messageTimer = eTimer()
183                 self.messageTimer.callback.append(self.tryLaunchMessage)
184
185         def message(self, session, id, cb, txt):
186                 global global_message_block
187                 done = False
188                 if global_message_block and global_message_block == id:
189                         self.messageQueue = [(session, id, txt)] + self.messageQueue
190                 else:
191                         i = 0
192                         for ele in self.messageQueue:
193                                 if ele[1] == id:
194                                         self.messageQueue[i] = (session, id, txt)
195                                         done = True
196                                         break
197                                 i += 1
198                         if not done:
199                                 self.messageQueue.append((session, id, txt))
200                 self.tryLaunchMessage(callback = cb)
201
202         def tryLaunchMessage(self, dummy=0, callback = None):
203                 global global_message_block
204                 self.messageTimer.stop()
205                 if not self.messageQueue:
206                         if callback:
207                                 callback()
208                 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]):
209                         self.messageTimer.stop()
210                         session = self.messageQueue[0][0]
211                         id = self.messageQueue[0][1]
212                         mess = self.messageQueue[0][2]
213                         self.messageQueue = self.messageQueue[1:]
214                         if global_message_block == id:
215                                 closeprev = session.current_dialog
216                         else:
217                                 closeprev = None
218                         global_message_block = id
219                         try:
220                                 session.openWithCallback(lambda x: self.tryLaunchMessageCallback(callback, closeprev), MessageBox, mess, MessageBox.TYPE_INFO)
221                         except:
222                                 global_message_block = False
223                                 self.tryLaunchMessage()
224                 else:
225                         self.messageTimer.start(1500, True)
226                         if callback:
227                                 callback()
228
229         def tryLaunchMessageCallback(self, callback, closeprev):
230                 global global_message_block
231                 global_message_block = False
232                 if closeprev:
233                         closeprev.close(True)
234                 self.tryLaunchMessage(callback = callback)
235
236         def enqueue(self, cb, session, fr, to):
237                 self.currid += 1
238                 mess = _("The movie is moved in the background from %s to %s.") % (os_path.dirname(fr), os_path.dirname(to))
239                 self.message(session, self.currid, cb, mess)
240                 self.queue.append((session, self.currid, fr, to))
241                 if not self.running:
242                         self.running = True
243                         self.runNext()
244                         return True
245                 else:
246                         return False
247
248         def runNext(self):
249                 if not self.queue:
250                         self.running = False
251                 else:
252                         self.moveMovieFilesBackground(self.queue[0])
253
254         def runDone(self, retval):
255                 ele = self.queue[0]
256                 self.queue = self.queue[1:]
257                 self.runNext()
258
259         def moveMovieFilesBackground(self, ele):
260                 self.ele = ele
261                 self.sufflst = (".ts.meta", ".ts.cuts", ".ts.ap", ".eit", ".ts")
262                 self.sufflst2 = self.sufflst
263                 self.moveNextSuffBG(0)
264
265         def moveNextSuffBG(self, retval):
266                 if self.sufflst and not retval:
267                         fr = self.ele[2] + self.sufflst[0]
268                         to = self.ele[3] + self.sufflst[0]
269                         self.sufflst = self.sufflst[1:]
270                         print "Moving %s to %s" % (fr, to)
271                         if os_path.exists(fr):
272                                 self.container.execute("/bin/cp", "/bin/cp", fr, to)
273                         else:
274                                 self.moveNextSuffBG(0)
275                 elif retval:
276                         for suff in self.sufflst2:
277                                 if os_path.exists(self.ele[3] + suff) and os_path.exists(self.ele[2] + suff):
278                                         os_unlink(self.ele[3] + suff)
279                         mess = _("Failed to move the movie %s to %s in the background") % (self.ele[2], self.ele[3])
280                         self.message(self.ele[0], self.ele[1], None, mess)
281                         self.runDone(1)
282                 else:
283                         for suff in self.sufflst2:
284                                 if os_path.exists(self.ele[2] + suff) and os_path.exists(self.ele[3] + suff):
285                                         os_unlink(self.ele[2] + suff)
286                         mess = _("Successfully moved the movie %s") % (self.ele[2])
287                         self.message(self.ele[0], self.ele[1], None, mess)
288                         self.runDone(0)
289
290 global_background_mover = MovieRetitleBackgroundMover()
291
292 global_message_block = False
293