2 ## DVD Backup plugin for enigma2 by AliAbdul
3 ## using the great open source dvdbackup by Olaf Beck
5 from Components.ActionMap import ActionMap
6 from Components.config import config, ConfigSubsection, ConfigText, ConfigYesNo, getConfigListEntry
7 from Components.ConfigList import ConfigListScreen
8 from Components.Console import Console as eConsole
9 from Components.Label import Label
10 from Components.Language import language
\r
11 from Components.MenuList import MenuList
\r
12 from Components.MultiContent import MultiContentEntryText, MultiContentEntryProgress
13 from Components.Scanner import Scanner, ScanPath
\r
14 from enigma import eListboxPythonMultiContent, eTimer, gFont, RT_HALIGN_CENTER
15 from fcntl import ioctl
16 from Plugins.Plugin import PluginDescriptor
17 from Screens.Console import Console as ConsoleScreen
18 from Screens.LocationBox import LocationBox
19 from Screens.MessageBox import MessageBox
20 from Screens.Screen import Screen
21 from Screens.VirtualKeyBoard import VirtualKeyBoard
23 from Tools.BoundFunction import boundFunction
24 from Tools.Directories import fileExists, resolveFilename, SCOPE_LANGUAGE, SCOPE_PLUGINS
25 import gettext, os, stat
27 #################################################
30 lang = language.getLanguage()
31 os.environ["LANGUAGE"] = lang[:2]
32 gettext.bindtextdomain("enigma2", resolveFilename(SCOPE_LANGUAGE))
33 gettext.textdomain("enigma2")
34 gettext.bindtextdomain("DVDBackup", "%s%s" % (resolveFilename(SCOPE_PLUGINS), "Extensions/DVDBackup/locale/"))
37 t = gettext.dgettext("DVDBackup", txt)
39 t = gettext.gettext(txt)
43 language.addCallback(localeInit)
45 #################################################
47 config.plugins.DVDBackup = ConfigSubsection()
48 config.plugins.DVDBackup.device = ConfigText(default="/dev/sr0", fixed_size=False)
49 config.plugins.DVDBackup.directory = ConfigText(default="/hdd/movie", fixed_size=False)
50 config.plugins.DVDBackup.name = ConfigText(default=_("Name of DVD"), fixed_size=False)
51 config.plugins.DVDBackup.log = ConfigYesNo(default=True)
52 config.plugins.DVDBackup.create_iso = ConfigYesNo(default=False)
54 #################################################
60 SESSION.open(MessageBox, msg, type=MessageBox.TYPE_ERROR, timeout=10)
62 #################################################
67 ioctl_flag = int(0x5307)
68 ioctl(cd.fileno(), ioctl_flag)
69 ioctl_flag = int(0x5329)
70 ioctl(cd.fileno(), ioctl_flag)
71 ioctl_flag = int(0x5309)
72 ioctl(cd.fileno(), ioctl_flag)
77 #################################################
80 def __init__(self, name, size):
83 self.name = ("%s/%s/%s"%(config.plugins.DVDBackup.directory.value, config.plugins.DVDBackup.name.value, name)).replace("//", "/")
87 def checkProgress(self):
88 if self.name != "mkisofs":
89 if fileExists(self.name):
90 if self.progress < 100:
91 file_stats = os.stat(self.name)
92 self.progress = 100.0 * file_stats[stat.ST_SIZE] / self.size
96 #################################################
102 self.startTime = None
107 self.startTime = time()
114 self.console = eConsole()
115 self.console.ePopen("dvdbackup --info -i %s"%config.plugins.DVDBackup.device.value, self.gotInfo)
117 def gotInfo(self, result, retval, extra_args):
118 if result and result.__contains__("File Structure DVD") and result.__contains__("Main feature:"):
119 result = result[result.index("File Structure DVD"): result.index("Main feature:")]
120 lines = result.split("\n")
123 tmp = line.split("\t")
129 if size.__contains__("."):
130 size = size[:size.index(".")]
131 if not name.__contains__("VTS_00_0."):
132 self.files.append(DVDBackupFile(name, int(size)))
133 if len(self.files) > 0:
135 self.console = eConsole()
136 if config.plugins.DVDBackup.log.value:
137 log = " 2>> /tmp/dvdbackup.log"
140 cmd = 'dvdbackup -M -v -i %s -o "%s" -n "%s"%s'%(config.plugins.DVDBackup.device.value, config.plugins.DVDBackup.directory.value, config.plugins.DVDBackup.name.value, log)
141 self.console.ePopen(cmd, self.dvdbackupFinished)
143 message(_("Could not find any file to backup!"))
146 message(_("Could not read the DVD informations!"))
147 print "[DVD Backup]",result
150 def dvdbackupFinished(self, result, retval, extra_args):
152 message(_("Error while backup of DVD!"))
153 print "[DVD Backup]", retval, result
156 if config.plugins.DVDBackup.create_iso.value:
157 path = ("%s/%s"%(config.plugins.DVDBackup.directory.value, config.plugins.DVDBackup.name.value)).replace("//", "/")
159 self.console = eConsole()
160 self.mkisofs = DVDBackupFile("mkisofs", 0)
161 self.files.append(self.mkisofs)
162 cmd = 'mkisofs -dvd-video -udf -o "%s.iso" "%s"'%(path, path)
163 self.console.ePopen(cmd, self.mkisofsCallback)
164 self.console.appContainers[cmd].dataAvail.append(boundFunction(self.mkisofsProgress, cmd))
168 def mkisofsProgress(self, name, data):
169 if data.__contains__("%"):
170 for x in data.split("\n"):
171 if x.__contains__("%"):
173 if x.__contains__("."):
175 x = x.replace(" ", "")
177 self.mkisofs.progress = int(x)
179 def mkisofsCallback(self, result, retval, extra_args):
181 message(_("Error while backup of DVD!"))
182 print "[DVD Backup]", result
185 self.mkisofs.progress = 100
186 SESSION.openWithCallback(self.mkisofsCallback2, MessageBox, _("mkisofs job done.\nDelete DVD directory?"))
188 def mkisofsCallback2(self, yesno):
190 cmd = ("rm -R %s/%s"%(config.plugins.DVDBackup.directory.value, config.plugins.DVDBackup.name.value)).replace("//", "/")
196 seconds = int(time() - self.startTime)
201 SESSION.openWithCallback(self.eject, MessageBox, "%s\n%s %d:%02d\n\n%s"%(_("Backup of DVD finished."), _("Duration:"), minutes, seconds, _("Eject DVD?")))
203 def eject(self, yesno):
205 eject(config.plugins.DVDBackup.device.value)
208 dvdbackup = DVDBackup()
210 #################################################
212 class DVDBackupList(MenuList):
\r
213 def __init__(self):
\r
214 MenuList.__init__(self, [], False, eListboxPythonMultiContent)
\r
215 self.l.setItemHeight(25)
\r
216 self.l.setFont(0, gFont("Regular", 20))
\r
218 #################################################
\r
220 def DVDBackupListEntry(file):
\r
222 res.append(MultiContentEntryText(pos=(0, 0), size=(180, 25), font=0, text=file.name.split("/")[-1]))
\r
223 res.append(MultiContentEntryText(pos=(200, 0), size=(120, 25), font=0, text="%d %s"%((file.size / 1024) / 1024, "MB"), flags=RT_HALIGN_CENTER))
\r
224 res.append(MultiContentEntryProgress(pos=(340, 9), size=(100, 7), percent=file.progress, borderWidth=1))
\r
225 res.append(MultiContentEntryText(pos=(460, 0), size=(60, 25), font=0, text="%d%s"%(file.progress, "%"), flags=RT_HALIGN_CENTER))
\r
228 #################################################
230 class DVDBackupProgress(Screen):
232 <screen position="center,center" size="560,450" title="DVD Backup">
\r
233 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
234 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
\r
235 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
\r
236 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
\r
237 <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
238 <widget name="list" position="0,45" size="560,400" scrollbarMode="showOnDemand" />
241 def __init__(self, session):
242 Screen.__init__(self, session)
244 self.refreshTimer = eTimer()
245 self.refreshTimer.callback.append(self.refreshList)
250 self["key_red"] = Label(_("Abort"))
251 self["list"] = DVDBackupList()
253 self["actions"] = ActionMap(["ColorActions", "OkCancelActions"],
259 self.onLayoutFinish.append(self.refreshList)
262 if self.working == False:
263 self.refreshTimer.stop()
266 def refreshList(self):
270 for file in dvdbackup.files:
272 if file.progress == 0:
273 tostart.append(DVDBackupListEntry(file))
274 elif file.progress == 100:
275 finished.append(DVDBackupListEntry(file))
277 list.append(DVDBackupListEntry(file))
282 self["list"].setList(list)
283 self.refreshTimer.start(3000, 1)
286 if self.working == False and dvdbackup.working:
289 self.console = eConsole()
291 for file in dvdbackup.files:
292 if file.name == "mkisofs":
294 self.console.ePopen("killall -9 %s"%tool, self.abortCallback)
296 def abortCallback(self, result, retval, extra_args):
299 #################################################
301 class DVDBackupScreen(ConfigListScreen, Screen):
303 <screen position="center,center" size="560,175" title="DVD Backup">
\r
304 <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
\r
305 <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
\r
306 <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
\r
307 <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
\r
308 <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
\r
309 <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
\r
310 <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
\r
311 <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
\r
312 <widget name="config" position="0,45" size="560,125" scrollbarMode="showOnDemand" />
315 def __init__(self, session, device=None):
316 Screen.__init__(self, session)
319 self.session = session
322 self["key_red"] = Label(_("Progress"))
323 self["key_green"] = Label(_("Backup"))
324 self["key_yellow"] = Label(_("Keyboard"))
325 self["key_blue"] = Label(_("Location"))
328 config.plugins.DVDBackup.device.value = device
330 ConfigListScreen.__init__(self, [
\r
331 getConfigListEntry(_("Device:"), config.plugins.DVDBackup.device),
\r
332 getConfigListEntry(_("Directory:"), config.plugins.DVDBackup.directory),
\r
333 getConfigListEntry(_("Name:"), config.plugins.DVDBackup.name),
\r
334 getConfigListEntry(_("Log:"), config.plugins.DVDBackup.log),
335 getConfigListEntry(_("Create iso:"), config.plugins.DVDBackup.create_iso)])
337 self["actions"] = ActionMap(["ColorActions", "OkCancelActions"],
339 "red": self.progress,
340 "green": self.backup,
341 "yellow": self.keyboard,
342 "blue": self.location,
346 self["config"].onSelectionChanged.append(self.checkConfig)
347 self.onLayoutFinish.append(self.getName)
350 if self.working == False:
351 self.session.open(DVDBackupProgress)
354 if self.working == False:
\r
355 for x in self["config"].list:
\r
358 self.session.openWithCallback(self.close, DVDBackupProgress)
361 if self.working == False:
\r
362 for x in self["config"].list:
\r
366 def checkConfig(self):
367 current = self["config"].getCurrent()
368 key = current and current[1]
369 if isinstance(key, ConfigText):
370 self["key_yellow"].show()
372 self["key_yellow"].hide()
375 if self.working == False:
376 current = self["config"].getCurrent()
377 self.toChange = current and current[1]
378 if isinstance(self.toChange, ConfigText):
379 self.session.openWithCallback(self.keyBoardCallback, VirtualKeyBoard, current and current[0], self.toChange.value)
381 def keyBoardCallback(self, callback=None):
383 self.toChange.value = callback
384 self["config"].setList(self["config"].getList())
389 self.console = eConsole()
390 self.console.ePopen("dvdbackup --info -i %s"%config.plugins.DVDBackup.device.value, self.gotInfo)
393 self.session.openWithCallback(self.locationCallback, LocationBox)
395 def locationCallback(self, callback):
397 config.plugins.DVDBackup.directory.value = callback
398 self["config"].setList(self["config"].getList())
400 def gotInfo(self, result, retval, extra_args):
401 config.plugins.DVDBackup.name.value = _("Name of DVD")
403 lines = result.split("\n")
405 if line.startswith("DVD-Video information of the DVD with title "):
406 idx = line.index("title ")
407 config.plugins.DVDBackup.name.value = line[idx+6:]
409 self["config"].setList(self["config"].getList())
412 #################################################
414 def main(session, **kwargs):
417 if dvdbackup.working:
418 session.open(DVDBackupProgress)
420 if not fileExists("/usr/bin/dvdbackup"):
421 session.openWithCallback(open_main, ConsoleScreen, title=_("Installing..."), cmdlist=["ipkg install http://www.lt-forums.org/ali/downloads/dvdbackup_0.4.1-r0_mipsel.ipk"])
423 session.open(DVDBackupScreen)
425 def open_main(callback=None):
426 if not fileExists("/usr/bin/dvdbackup"):
427 message(_("Could not install needed dvdbackup package!"))
429 SESSION.open(DVDBackupScreen)
431 def filescan_open(list, session, **kwargs):
432 if len(list) == 1 and list[0].mimetype == "video/x-dvd":
433 splitted = list[0].path.split('/')
434 if len(splitted) > 2:
435 if splitted[1] == 'autofs':
436 session.open(DVDBackupScreen, device="/dev/%s"%(splitted[2]))
439 def filescan(**kwargs):
440 class LocalScanner(Scanner):
441 def checkFile(self, file):
442 return fileExists(file.path)
443 return [LocalScanner(mimetypes=["video/x-dvd"], paths_to_scan=[ScanPath(path="video_ts", with_subdirs=False)], name="DVD", description=_("DVD Backup"), openfnc=filescan_open)]
445 def Plugins(**kwargs):
446 return [PluginDescriptor(name=_("DVD Backup"), description=_("Backup your Video-DVD to your harddisk"), where=[PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU], icon="DVDBackup.png", fnc=main),
447 PluginDescriptor(where=PluginDescriptor.WHERE_FILESCAN, fnc=filescan)]