1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4 from Screens.LocationBox import MovieLocationBox
6 from Components.config import *
7 from Components.ActionMap import ActionMap, NumberActionMap
8 from Components.ConfigList import ConfigList, ConfigListScreen
9 from Components.Button import Button
10 from Components.Label import Label
11 from Components.Pixmap import Pixmap
12 from enigma import eTimer, eServiceReference, eServiceCenter, iServiceInformation, eConsoleAppContainer
15 def main(session, service, **kwargs):
16 session.open(MovieRetitle, service, session.current_dialog, **kwargs)
18 def Plugins(**kwargs):
19 return PluginDescriptor(name="MovieRetitle", description=_("Change name..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main)
22 class MovieRetitle(Screen, ConfigListScreen):
24 <screen name="TitleDescrInput" position="100,150" size="500,200" title="Name and Description Input">
25 <widget name="config" position="10,10" size="480,120" />
26 <widget name="ok" position="70,140" size="140,40" pixmap="skin_default/buttons/green.png" alphatest="on" />
27 <widget name="oktext" position="70,140" size="140,40" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
28 <widget name="cancel" position="290,140" size="140,40" pixmap="skin_default/buttons/red.png" alphatest="on" />
29 <widget name="canceltext" position="290,140" size="140,40" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
32 def __init__(self, session, service, parent, args = 0):
33 Screen.__init__(self, session)
34 self.session = session
35 self.service = service
36 self.parentscreen = parent
37 Screen.__init__(self, session)
38 serviceHandler = eServiceCenter.getInstance()
39 info = serviceHandler.info(self.service)
40 self.path = self.service.getPath()
41 if self.path.endswith(".ts") is True:
42 self.path = self.path[:-3]
43 self.dir = self.dirName(self.path)
44 self.file = self.baseName(self.path)
45 self.name = info.getName(self.service)
46 if self.file == self.baseName(self.name):
49 self.title = self.name
50 self.descr = info.getInfoString(self.service, iServiceInformation.sDescription)
52 self["oktext"] = Label(_("OK"))
53 self["canceltext"] = Label(_("Cancel"))
55 self["cancel"] = Pixmap()
57 self.input_file = ConfigText(default = self.file, fixed_size = False, visible_width = 42)
58 self.input_title = ConfigText(default = self.title, fixed_size = False, visible_width = 42)
59 self.input_descr = ConfigText(default = self.descr, fixed_size = False, visible_width = 42)
60 tmp = config.movielist.videodirs.value
61 if not self.dir in tmp:
63 self.input_dir = ConfigSelection(choices = tmp, default = self.dir)
65 self["actions"] = NumberActionMap(["SetupActions"],
67 "ok": self.keySelectOrGo,
69 "cancel": self.keyCancel,
73 ConfigListScreen.__init__(self, self.list)
74 self.createSetup(self["config"])
76 def createSetup(self, configlist):
78 self.list.append(getConfigListEntry(_("Filename"), self.input_file))
79 self.list.append(getConfigListEntry(_("Title"), self.input_title))
80 self.list.append(getConfigListEntry(_("Description"), self.input_descr))
81 self.list.append(getConfigListEntry(_("Location"), self.input_dir))
82 configlist.list = self.list
83 configlist.l.setList(self.list)
85 def pathSelected(self, res):
87 if config.movielist.videodirs.value != self.input_dir.choices:
88 self.input_dir.setChoices(config.movielist.videodirs.value, default=res)
89 self.input_dir.value = res
91 def keySelectOrGo(self):
92 if self["config"].getCurrent() == self.list[3]:
93 self.session.openWithCallback(
96 _("Choose target folder"),
103 if self.input_title.value != self.title or self.input_descr.value != self.descr:
104 self.setTitleDescr(self.path, self.input_title.value, self.input_descr.value)
105 if self.input_file.value != self.file or self.input_dir.value != self.dir:
106 self.maybeMoveMovieFiles(self.path, self.rejoinName(self.input_dir.value, self.input_file.value))
113 def setTitleDescr(self, file, title, descr):
114 if os.path.exists(file + ".ts.meta"):
115 metafile = open(file + ".ts.meta", "r")
116 sid = metafile.readline()
117 oldtitle = metafile.readline().rstrip()
118 olddescr = metafile.readline().rstrip()
119 rest = metafile.read()
121 if not title and title != "":
123 if not descr and descr != "":
125 metafile = open(file + ".ts.meta", "w")
126 metafile.write("%s%s\n%s\n%s" %(sid, title, descr, rest))
129 def maybeMoveMovieFiles(self, fr, to):
130 if os.path.exists(to+".ts"):
133 self.session.openWithCallback(self.confirmedReplace, MessageBox, _("Target file %s.ts already exist.\nDo you want to replace it?") % (to), MessageBox.TYPE_YESNO)
134 elif os.path.isdir(os.path.dirname(to)):
135 self.moveMovieFiles(fr, to)
137 self.session.openWithCallback(self.exitDialog, MessageBox, _("The target directory is not found. The file is not renamed."), MessageBox.TYPE_ERROR)
139 def confirmedReplace(self, answer):
141 self.moveMovieFiles(self.inter_fr, self.inter_to)
143 def moveMovieFiles(self, fr, to):
145 os.rename(fr + ".ts", to + ".ts")
147 print "Moving in background"
148 global_background_mover.enqueue(self.exitDialog, self.session, fr, to)
150 print "Moving in foreground"
151 for suff in [".ts.meta", ".ts.cuts", ".ts.ap", ".eit"]:
152 if os.path.exists(fr + suff):
153 os.rename(fr + suff, to + suff)
156 def exitDialog(self, dummy=None):
158 # This will try to get back to an updated movie list.
159 # A proper way to do this should be provided in enigma2.
161 self.parentscreen.csel.reloadList()
162 self.parentscreen.close()
163 except AttributeError:
166 def baseName(self, str):
167 name = str.split('/')[-1]
168 if name.endswith(".ts") is True:
173 def dirName(self, str):
174 return '/'.join(str.split('/')[:-1]) + '/'
176 def rejoinName(self, dir, name):
178 if name.endswith(".ts") is True:
179 return dir + name[:-3]
183 class MovieRetitleBackgroundMover:
185 self.container = eConsoleAppContainer()
186 self.container.appClosed.get().append(self.moveNextSuffBG)
190 self.messageQueue = []
191 self.messageTimer = eTimer()
192 self.messageTimer.callback.append(self.tryLaunchMessage)
194 def message(self, session, id, cb, txt):
195 global global_message_block
197 if global_message_block and global_message_block == id:
198 self.messageQueue = [(session, id, txt)] + self.messageQueue
201 for ele in self.messageQueue:
203 self.messageQueue[i] = (session, id, txt)
208 self.messageQueue.append((session, id, txt))
209 self.tryLaunchMessage(callback = cb)
211 def tryLaunchMessage(self, dummy=0, callback = None):
212 global global_message_block
213 self.messageTimer.stop()
214 if not self.messageQueue:
217 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]):
218 self.messageTimer.stop()
219 session = self.messageQueue[0][0]
220 id = self.messageQueue[0][1]
221 mess = self.messageQueue[0][2]
222 self.messageQueue = self.messageQueue[1:]
223 if global_message_block == id:
224 closeprev = session.current_dialog
227 global_message_block = id
229 session.openWithCallback(lambda x: self.tryLaunchMessageCallback(callback, closeprev), MessageBox, mess, MessageBox.TYPE_INFO)
231 global_message_block = False
232 self.tryLaunchMessage()
234 self.messageTimer.start(1500, True)
238 def tryLaunchMessageCallback(self, callback, closeprev):
239 global global_message_block
240 global_message_block = False
242 closeprev.close(True)
243 self.tryLaunchMessage(callback = callback)
245 def enqueue(self, cb, session, fr, to):
247 mess = _("The movie is moved in the background from %s to %s.") % (os.path.dirname(fr), os.path.dirname(to))
248 self.message(session, self.currid, cb, mess)
249 self.queue.append((session, self.currid, fr, to))
261 self.moveMovieFilesBackground(self.queue[0])
263 def runDone(self, retval):
265 self.queue = self.queue[1:]
268 def moveMovieFilesBackground(self, ele):
270 self.sufflst = [".ts.meta", ".ts.cuts", ".ts.ap", ".eit", ".ts"]
271 self.sufflst2 = self.sufflst
272 self.moveNextSuffBG(0)
274 def moveNextSuffBG(self, retval):
275 if self.sufflst and not retval:
276 fr = self.ele[2] + self.sufflst[0]
277 to = self.ele[3] + self.sufflst[0]
278 self.sufflst = self.sufflst[1:]
279 print "Moving %s to %s" % (fr, to)
280 if os.path.exists(fr):
281 self.container.execute("/bin/cp", ["/bin/cp", fr, to])
283 self.moveNextSuffBG(0)
285 for suff in self.sufflst2:
286 if os.path.exists(self.ele[3] + suff) and os.path.exists(self.ele[2] + suff):
287 os.unlink(self.ele[3] + suff)
288 mess = "Failed to move the movie %s to %s in the background" % (self.ele[2], self.ele[3])
289 self.message(self.ele[0], self.ele[1], None, mess)
292 for suff in self.sufflst2:
293 if os.path.exists(self.ele[2] + suff) and os.path.exists(self.ele[3] + suff):
294 os.unlink(self.ele[2] + suff)
295 mess = "Successfully moved the movie %s" % (self.ele[2])
296 self.message(self.ele[0], self.ele[1], None, mess)
299 global_background_mover = MovieRetitleBackgroundMover()
301 global_message_block = False