1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Screen import Screen
3 from Screens.MessageBox import MessageBox
4 from Screens.ChoiceBox import ChoiceBox
5 from Screens.LocationBox import MovieLocationBox
7 from Components.config import *
8 from Components.ActionMap import ActionMap, NumberActionMap
9 from Components.ConfigList import ConfigList, ConfigListScreen
10 from Components.Button import Button
11 from Components.Label import Label
12 from Components.Pixmap import Pixmap
13 from enigma import eTimer, eServiceReference, eServiceCenter, iServiceInformation, eConsoleAppContainer
14 from os import access, chmod, X_OK
16 mcut_path = "/usr/lib/enigma2/python/Plugins/Extensions/MovieCut/bin/mcut"
17 # Hack to make sure it is executable
18 if not access(mcut_path, X_OK):
21 def main(session, service, **kwargs):
22 session.open(MovieCut, service, **kwargs)
24 def Plugins(**kwargs):
25 return PluginDescriptor(name="MovieCut", description=_("Execute cuts..."), where = PluginDescriptor.WHERE_MOVIELIST, fnc=main)
28 class MovieCut(ChoiceBox):
29 def __init__(self, session, service):
30 self.service = service
31 serviceHandler = eServiceCenter.getInstance()
32 path = self.service.getPath()
33 info = serviceHandler.info(self.service)
37 self.name = info.getName(self.service)
39 tlist.append((_("Don't cut"), "CALLFUNC", self.confirmed0))
40 tlist.append((_("Replace the original movie with the cut movie"), "CALLFUNC", self.confirmed1))
41 tlist.append((_("Place the cut movie in a new file ending with \" cut\""), "CALLFUNC", self.confirmed2))
42 tlist.append((_("Advanced cut specification..."), "CALLFUNC", self.confirmed3))
43 ChoiceBox.__init__(self, session, _("How would you like to cut \"%s\"?") % (self.name), list = tlist, selection = 0)
44 self.skinName = "ChoiceBox"
46 def confirmed0(self, arg):
49 def confirmed1(self, arg):
50 MovieCutSpawn(self.session, self, [mcut_path, "-r", self.service.getPath()], self.name)
52 def confirmed2(self, arg):
53 MovieCutSpawn(self.session, self, [mcut_path, self.service.getPath()], self.name)
55 def confirmed3(self, arg):
56 serviceHandler = eServiceCenter.getInstance()
57 info = serviceHandler.info(self.service)
58 self.path = self.service.getPath()
59 self.name = info.getName(self.service)
60 self.descr = info.getInfoString(self.service, iServiceInformation.sDescription)
61 self.session.openWithCallback(self.advcutConfirmed, AdvancedCutInput, self.name, self.path, self.descr)
63 def advcutConfirmed(self, ret):
64 if len(ret) <= 1 or not ret[0]:
70 clist.append(self.service.getPath())
72 clist += ["-o", ret[2]]
74 clist += ["-n", ret[3]]
76 clist += ["-d", ret[4]]
80 MovieCutSpawn(self.session, self, clist, self.name)
82 class AdvancedCutInput(Screen, ConfigListScreen):
84 <screen name="AdvancedCutInput" position="80,100" size="550,320" title="Cut Parameter Input">
85 <widget name="config" position="5,10" size="530,250" />
86 <widget name="ok" position="90,265" size="140,40" pixmap="skin_default/buttons/green.png" alphatest="on" />
87 <widget name="oktext" position="90,265" size="140,40" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
88 <widget name="cancel" position="320,265" size="140,40" pixmap="skin_default/buttons/red.png" alphatest="on" />
89 <widget name="canceltext" position="320,265" size="140,40" valign="center" halign="center" zPosition="2" font="Regular;20" transparent="1" />
92 def __init__(self, session, name, path, descr):
93 self.skin = AdvancedCutInput.skin
94 Screen.__init__(self, session)
96 self["oktext"] = Label(_("OK"))
97 self["canceltext"] = Label(_("Cancel"))
99 self["cancel"] = Pixmap()
101 if self.baseName(path) == self.baseName(name):
105 self.dir = self.dirName(path)
106 self.file = self.baseName(path) + " cut"
108 self.input_replace = ConfigSelection(choices = [("no", _("No")), ("yes", _("Yes"))], default = "no")
109 self.input_file = ConfigText(default = self.file, fixed_size = False, visible_width = 45)
110 self.input_title = ConfigText(default = self.title, fixed_size = False, visible_width = 45)
111 self.input_descr = ConfigText(default = self.descr, fixed_size = False, visible_width = 45)
112 tmp = config.movielist.videodirs.value
113 if not self.dir in tmp:
115 self.input_dir = ConfigSelection(choices = tmp, default = self.dir)
116 self.input_manual = ConfigSelection(choices = [("no", _("Cutlist")), ("yes", _("Manual specification"))], default = "no")
117 self.input_space = ConfigNothing()
118 self.input_manualcuts = ConfigText(default = "", fixed_size = False)
119 self.input_manualcuts.setUseableChars(" 0123456789:.")
120 self["actions"] = NumberActionMap(["SetupActions"],
122 "ok": self.keySelectOrGo,
124 "cancel": self.keyCancel,
128 ConfigListScreen.__init__(self, self.list)
129 self.entry_replace = getConfigListEntry(_("Replace original:"), self.input_replace)
130 self.entry_file = getConfigListEntry(_("New filename:"), self.input_file)
131 self.entry_title = getConfigListEntry(_("New title:"), self.input_title)
132 self.entry_descr = getConfigListEntry(_("New description:"), self.input_descr)
133 self.entry_dir = getConfigListEntry(_("New location:"), self.input_dir)
134 self.entry_manual = getConfigListEntry(_("Cut source:"), self.input_manual)
135 self.entry_space = getConfigListEntry(_("Cuts (an IN OUT IN OUT ... sequence of hour:min:sec)"), self.input_space)
136 self.entry_manualcuts = getConfigListEntry(":", self.input_manualcuts)
137 self.createSetup(self["config"])
139 def createSetup(self, configlist):
141 self.list.append(self.entry_replace)
142 if self.input_replace.value == "no":
143 self.list.append(self.entry_file)
144 self.list.append(self.entry_dir)
145 self.list.append(self.entry_title)
146 self.list.append(self.entry_descr)
147 self.list.append(self.entry_manual)
148 if self.input_manual.value == "yes":
149 self.list.append(self.entry_space)
150 self.list.append(self.entry_manualcuts)
151 configlist.list = self.list
152 configlist.l.setList(self.list)
155 ConfigListScreen.keyLeft(self)
156 cc = self["config"].getCurrent()
157 if cc is self.entry_replace or cc is self.entry_manual:
158 self.createSetup(self["config"])
161 ConfigListScreen.keyRight(self)
162 cc = self["config"].getCurrent()
163 if cc is self.entry_replace or cc is self.entry_manual:
164 self.createSetup(self["config"])
166 def pathSelected(self, res):
168 if config.movielist.videodirs.value != self.input_dir.choices:
169 self.input_dir.setChoices(config.movielist.videodirs.value, default=res)
170 self.input_dir.value = res
172 def keySelectOrGo(self):
173 if self["config"].getCurrent() == self.entry_dir:
174 self.session.openWithCallback(
177 _("Choose target folder"),
178 self.input_dir.value,
184 if self.input_replace.value == "yes":
187 path = self.rejoinName(self.input_dir.value, self.input_file.value)
188 if self.input_manual.value == "no":
191 cuts = self.input_manualcuts.value.split(' ')
194 self.close((True, self.input_replace.value, path, self.input_title.value, self.input_descr.value, cuts))
199 def baseName(self, str):
200 name = str.split('/')[-1]
201 if name.endswith(".ts") is True:
206 def dirName(self, str):
207 return '/'.join(str.split('/')[:-1]) + '/'
209 def rejoinName(self, dir, name):
211 if name.endswith(".ts") is True:
212 return dir + name[:-3]
218 self.container = eConsoleAppContainer()
219 self.container.appClosed.append(self.runDone)
223 def enqueue(self, cb, cmd):
224 self.queue.append((cb, cmd))
236 self.container.execute(*self.queue[0][1])
238 def runDone(self, retval):
239 cb = self.queue[0][0]
240 self.queue = self.queue[1:]
244 global_mcut_errors = [_("The movie \"%s\" is successfully cut"),
245 _("Cutting failed for movie \"%s\"")+":\n"+_("Bad arguments"),
246 _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open input .ts file"),
247 _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open input .cuts file"),
248 _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open input .ap file"),
249 _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open output .ts file"),
250 _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open output .cuts file"),
251 _("Cutting failed for movie \"%s\"")+":\n"+_("Couldn't open output .ap file"),
252 _("Cutting failed for movie \"%s\"")+":\n"+_("Empty .ap file"),
253 _("Cutting failed for movie \"%s\"")+":\n"+_("No cuts specified"),
254 _("Cutting failed for movie \"%s\"")+":\n"+_("Read/write error (disk full?)"),
255 _("Cutting was aborted for movie \"%s\"")]
257 global_mcut_queue = MovieCutQueue()
259 global_mcut_block = False
262 def __init__(self, session, parent, clist, name):
263 global global_mcut_queue
264 global global_mcut_block
265 self.session = session
268 self.clist = [clist[0]] + clist
271 self.waitTimer = eTimer()
272 self.waitTimer.callback.append(self.doWaitAck)
273 if global_mcut_queue.enqueue(self.doAck, self.clist):
274 mess = _("The movie \"%s\" is cut in the background.") % (self.name)
276 mess = _("Another movie is currently cut.\nThe movie \"%s\" will be cut in the background after it.") % (self.name)
277 global_mcut_block = True
278 self.dialog = self.session.openWithCallback(self.endc, MessageBox, mess, MessageBox.TYPE_INFO)
280 def doAck(self, retval):
281 global global_mcut_errors
282 # if WIFEXITED(retval):
283 # self.mess = global_mcut_errors[WEXITSTATUS(retval)] % (self.name)
285 # self.mess = global_mcut_errors[-1] % (self.name)
286 self.mess = global_mcut_errors[retval] % (self.name)
290 global global_mcut_block
291 if Screens.Standby.inStandby or not self.session.in_exec or (global_mcut_block and not self.dialog):
292 self.waitTimer.start(2000, True)
294 global_mcut_block = True
295 self.session.openWithCallback(self.endw, MessageBox, self.mess, MessageBox.TYPE_INFO)
297 def endw(self, arg = 0):
298 global global_mcut_block
299 global_mcut_block = False
300 if self.session.current_dialog == self.dialog:
301 self.session.current_dialog.close(True)
304 def endc(self, arg = 0):
305 global global_mcut_block
306 global_mcut_block = False
309 # self.session.current_dialog.close()