-from Tools.Directories import resolveFilename, fileExists, SCOPE_FONTS, SCOPE_PLUGINS, SCOPE_SKIN
+from Tools.Directories import fileExists
+
class DVDProject:
def __init__(self):
self.titles = [ ]
self.target = None
- self.name = _("Dreambox DVD record")
- self.vmgm = resolveFilename(SCOPE_PLUGINS,"Extensions/DVDBurn/dreamvmgm.mpg")
- self.menuaudio = resolveFilename(SCOPE_PLUGINS,"Extensions/DVDBurn/silence.mp2")
- self.menubg = resolveFilename(SCOPE_SKIN, "dreamdvd_02.jpg")
- # tuples with R, G, B values
- self.color_button = ( 0x08, 0x00, 0x00 )
- self.color_highlight = ( 0x00, 0xC0, 0xC0 )
- self.color_headline = ( 0x00, 0x00, 0x80 )
- self.font_face = resolveFilename(SCOPE_FONTS, "nmsbd.ttf")
- # tuple with three pixel values ( headline, title, subtitle )
- self.font_size = ( 48, 28, 16 )
- # please supply even numbers for all dimensions
- self.space_left = 30
- self.space_top = 120
- self.space_rows = 36
def addService(self, service):
import DVDTitle
title.addService(service)
self.titles.append(title)
return title
-
+
def saveProject(self, path):
import xml.dom.minidom
from Tools.XMLTools import elementsWithTag, mergeText, stringToXML
list = []
list.append('<?xml version="1.0" encoding="utf-8" ?>\n')
list.append('<DreamDVDBurnerProject>\n')
- list.append('\t<config')
+ list.append('\t<project')
list.append(' name="' + self.name + '"')
list.append(' vmgm="' + self.vmgm + '"')
list.append(' />\n')
list.append('\t<menu')
+ list.append('\tuse="' + str(self.menu) + '"\n')
list.append('\tbg="' + self.menubg + '"\n')
list.append('\t\taudio="' + self.menuaudio + '"\n')
list.append('\t\tcolor_button="' + str(self.color_button) + '"\n')
list.append('\t\tspace_top="' + str(self.space_top) + '"\n')
list.append('\t\tspace_rows="' + str(self.space_rows) + '"')
list.append(' />\n')
- list.append('\t<titles>\n')
+ list.append('\t<titles')
+ list.append(' link="' + str(self.linktitles) + '"')
+ list.append(' />\n')
for title in self.titles:
list.append('\t\t<path>')
list.append(stringToXML(title.source.getPath()))
file = open(filename, "w")
for x in list:
file.write(x)
- file.close()
\ No newline at end of file
+ file.close()
+
+ def loadProject(self, filename):
+ import xml.dom.minidom
+ print "[loadProject]", filename
+ try:
+ if not fileExists(filename):
+ self.error = "file not found!"
+ raise AttributeError
+ else:
+ self.error = ""
+ file = open(filename, "r")
+ data = file.read().decode("utf-8").replace('&',"&").encode("ascii",'xmlcharrefreplace')
+ file.close()
+ projectfiledom = xml.dom.minidom.parseString(data)
+ for project in projectfiledom.childNodes[0].childNodes:
+ if project.nodeType == xml.dom.minidom.Element.nodeType:
+ if project.tagName == 'project':
+ self.name = project.getAttribute("name").encode("utf-8")
+ self.vmgm = project.getAttribute("vmgm").encode("utf-8")
+ if project.tagName == 'menu':
+ self.menu = eval(project.getAttribute("use"))
+ self.menubg = project.getAttribute("bg").encode("utf-8")
+ self.menuaudio = project.getAttribute("audio").encode("utf-8")
+ # tuples with R, G, B values
+ self.color_button = eval(project.getAttribute("color_button"))
+ self.color_highlight = eval(project.getAttribute("color_highlight"))
+ self.color_headline = eval(project.getAttribute("color_headline"))
+ self.font_face = project.getAttribute("font_face").encode("utf-8")
+ # tuple with three pixel sizes ( headline, title, subtitle )
+ self.font_size = eval(project.getAttribute("font_size"))
+ # please supply even numbers for all dimensions
+ self.space_left = int(project.getAttribute("space_left"))
+ self.space_top = int(project.getAttribute("space_top"))
+ self.space_rows = int(project.getAttribute("space_rows"))
+ if project.tagName == 'titles':
+ self.linktitles = eval(project.getAttribute("link"))
+ if not fileExists(self.vmgm):
+ self.error += "\nvmgm '%s' not found" % self.vmgm
+ if not fileExists(self.menubg):
+ self.error += "\nmenu background '%s' not found" % self.menubg
+ if not fileExists(self.menuaudio):
+ self.error += "\nmenu audio '%s' not found" % self.menuaudio
+ if not fileExists(self.font_face):
+ self.error += "\nmenu font '%s' not found" % self.font_face
+ print "len(self.error):", len(self.error)
+ if len(self.error):
+ raise AttributeError
+ except:
+ print "len(self.error):, error", len(self.error), len(self.error)
+ self.error = ("error parsing project xml file '%s'" % filename) + self.error
+ return False
+ return True
task.ERROR_SIZE: ("Content does not fit on DVD!"),
task.ERROR_WRITE_FAILED: ("Write failed!"),
task.ERROR_DVDROM: ("No (supported) DVDROM found!"),
+ task.ERROR_ISOFS: ("Medium is not empty!"),
task.ERROR_UNKNOWN: ("An unknown error occured!")
}[task.error]
class BurnTask(Task):
- ERROR_MEDIA, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_UNKNOWN = range(5)
+ ERROR_MEDIA, ERROR_SIZE, ERROR_WRITE_FAILED, ERROR_DVDROM, ERROR_ISOFS, ERROR_UNKNOWN = range(6)
def __init__(self, job):
Task.__init__(self, job, "burn")
else:
self.error = self.ERROR_UNKNOWN
print "BurnTask: unknown error %s" % line
+ elif line.startswith("FATAL:"):
+ if line.find("already carries isofs!"):
+ self.error = self.ERROR_ISOFS
+ else:
+ self.error = self.ERROR_UNKNOWN
+ print "BurnTask: unknown error %s" % line
class RemoveDVDFolder(Task):
def __init__(self, job):
def CreateAuthoringXML(job):
nr_titles = len(job.project.titles)
titles_per_menu = getTitlesPerMenu(nr_titles)
- authorxml = """<?xml version="1.0" encoding="utf-8"?>
-<dvdauthor dest="%s">
- <vmgm>
- <menus>
- <pgc>
- <vob file="%s" />
- <post> jump titleset 1 menu; </post>
- </pgc>
- </menus>
- </vmgm>
- <titleset>
- <menus>
- <video aspect="4:3"/>"""% (job.workspace+"/dvd", job.project.vmgm)
- for menu_count in range(1 , job.nr_menus+1):
- if menu_count == 1:
- authorxml += """
- <pgc entry="root">"""
- else:
- authorxml += """
- <pgc>"""
- menu_start_title = (menu_count-1)*titles_per_menu + 1
- menu_end_title = (menu_count)*titles_per_menu + 1
- if menu_end_title > nr_titles:
- menu_end_title = nr_titles+1
- for i in range( menu_start_title , menu_end_title ):
- authorxml += """
- <button name="button%s">jump title %d;</button>""" % (str(i).zfill(2), i)
-
- if menu_count > 1:
- authorxml += """
- <button name="button_prev">jump menu %d;</button>""" % (menu_count-1)
-
- if menu_count < job.nr_menus:
- authorxml += """
- <button name="button_next">jump menu %d;</button>""" % (menu_count+1)
-
- menuoutputfilename = job.workspace+"/dvdmenu"+str(menu_count)+".mpg"
- authorxml += """
- <vob file="%s" pause="inf"/>
- </pgc>""" % menuoutputfilename
- authorxml += """
- </menus>
- <titles>"""
+ authorxml = []
+ authorxml.append('<?xml version="1.0" encoding="utf-8"?>\n')
+ authorxml.append(' <dvdauthor dest="' + (job.workspace+"/dvd") + '">\n')
+ authorxml.append(' <vmgm>\n')
+ authorxml.append(' <menus>\n')
+ authorxml.append(' <pgc>\n')
+ authorxml.append(' <vob file="' + job.project.vmgm + '" />\n', )
+ if job.project.menu:
+ authorxml.append(' <post> jump titleset 1 menu; </post>\n')
+ else:
+ authorxml.append(' <post> jump title 1; </post>\n')
+ authorxml.append(' </pgc>\n')
+ authorxml.append(' </menus>\n')
+ authorxml.append(' </vmgm>\n')
+ authorxml.append(' <titleset>\n')
+ if job.project.menu:
+ authorxml.append(' <menus>\n')
+ authorxml.append(' <video aspect="4:3"/>\n')
+ for menu_count in range(1 , job.nr_menus+1):
+ if menu_count == 1:
+ authorxml.append(' <pgc entry="root">\n')
+ else:
+ authorxml.append(' <pgc>\n')
+ menu_start_title = (menu_count-1)*titles_per_menu + 1
+ menu_end_title = (menu_count)*titles_per_menu + 1
+ if menu_end_title > nr_titles:
+ menu_end_title = nr_titles+1
+ for i in range( menu_start_title , menu_end_title ):
+ authorxml.append(' <button name="button' + (str(i).zfill(2)) + '"> jump title ' + str(i) +'; </button>\n')
+ if menu_count > 1:
+ authorxml.append(' <button name="button_prev"> jump menu ' + str(menu_count-1) + '; </button>\n')
+ if menu_count < job.nr_menus:
+ authorxml.append(' <button name="button_next"> jump menu ' + str(menu_count+1) + '; </button>\n')
+ menuoutputfilename = job.workspace+"/dvdmenu"+str(menu_count)+".mpg"
+ authorxml.append(' <vob file="' + menuoutputfilename + '" pause="inf"/>\n')
+ authorxml.append(' </pgc>\n')
+ authorxml.append(' </menus>\n')
+ authorxml.append(' <titles>\n')
for i in range( nr_titles ):
chapters = ','.join(["%d:%02d:%02d.%03d" % (p / (90000 * 3600), p % (90000 * 3600) / (90000 * 60), p % (90000 * 60) / 90000, (p % 90000) / 90) for p in job.project.titles[i].chaptermarks])
-
title_no = i+1
title_filename = job.workspace + "/dvd_title_%d.mpg" % (title_no)
-
if job.menupreview:
LinkTS(job, job.project.vmgm, title_filename)
else:
MakeFifoNode(job, title_no)
- vob_tag = """file="%s" chapters="%s" />""" % (title_filename, chapters)
-
- if title_no < nr_titles:
+ if job.project.linktitles and title_no < nr_titles:
post_tag = "jump title %d;" % ( title_no+1 )
- else:
+ elif job.project.menu:
post_tag = "call vmgm menu 1;"
- authorxml += """
- <pgc>
- <vob %s
- <post> %s </post>
- </pgc>""" % (vob_tag, post_tag)
-
- authorxml += """
- </titles>
- </titleset>
-</dvdauthor>
-"""
+ else: post_tag = ""
+
+ authorxml.append(' <pgc>\n')
+ authorxml.append(' <vob file="' + title_filename + '" chapters="' + chapters + '" />\n')
+ authorxml.append(' <post> ' + post_tag + ' </post>\n')
+ authorxml.append(' </pgc>\n')
+
+ authorxml.append(' </titles>\n')
+ authorxml.append(' </titleset>\n')
+ authorxml.append(' </dvdauthor>\n')
f = open(job.workspace+"/dvdauthor.xml", "w")
- f.write(authorxml)
+ for x in authorxml:
+ f.write(x)
f.close()
class DVDJob(Job):
from time import strftime
from Tools.Directories import SCOPE_HDD, resolveFilename, createDir
new_workspace = resolveFilename(SCOPE_HDD) + "tmp/" + strftime("%Y%m%d%H%M%S")
- createDir(new_workspace)
+ createDir(new_workspace, True)
self.workspace = new_workspace
self.project.workspace = self.workspace
self.menupreview = menupreview
self.conduct()
def conduct(self):
- CreateMenus(self)
+ if self.project.menu or self.menupreview:
+ CreateMenus(self)
CreateAuthoringXML(self)
totalsize = 50*1024*1024 # require an extra safety 50 MB
from Plugins.Extensions.CutListEditor.plugin import CutListEditor
-
class TitleCutter(CutListEditor):
def __init__(self, session, title):
CutListEditor.__init__(self, session, title.source)
from Screens.ChoiceBox import ChoiceBox
from Screens.InputBox import InputBox
from Screens.MessageBox import MessageBox
+from Screens.HelpMenu import HelpableScreen
from Components.ActionMap import HelpableActionMap, ActionMap
from Components.Sources.List import List
from Components.Sources.StaticText import StaticText
from Components.Sources.Progress import Progress
from Components.FileList import FileList
from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT
+from Tools.Directories import resolveFilename, SCOPE_PLAYLIST
class WaitBox(MessageBox):
def __init__(self, session, callback):
- MessageBox.__init__(self, session, text=_("Preparing... Please wait"), type = MessageBox.TYPE_INFO)
+ MessageBox.__init__(self, session, text=_("please wait, loading picture..."), type = MessageBox.TYPE_INFO)
self.skinName = "MessageBox"
self.CB = callback
self.onShown.append(self.runCB)
-
+
def ok(self):
pass
self.delayTimer.callback.append(self.CB)
self.delayTimer.start(10,1)
-class FileBrowser(Screen):
+class FileBrowser(Screen, HelpableScreen):
skin = """
<screen name="FileBrowser" position="100,100" size="520,376" title="DVD File Browser" >
<widget name="filelist" position="0,0" size="520,376" scrollbarMode="showOnDemand" />
</screen>"""
def __init__(self, session, currDir = None, projectBrowser = False):
Screen.__init__(self, session)
+ HelpableScreen.__init__(self)
self.projectBrowser = projectBrowser
if not currDir:
currDir = "/"
if self.filelist.canDescent():
self.filelist.descent()
else:
- ret = self["filelist"].getCurrentDirectory() + '/' + self["filelist"].getFilename()
+ ret = self["filelist"].getCurrentDirectory() + self["filelist"].getFilename()
self.close(ret,self.projectBrowser)
def exit(self):
"addTitle": (self.addTitle, _("Add a new title"), _("Add title")),
"editTitle": (self.editTitle, _("Edit chapters of current title"), _("Edit title")),
"removeCurrentTitle": (self.removeCurrentTitle, _("Remove currently selected title"), _("Remove title")),
- "saveProject": (self.saveProject, _("Save current project to disk"), _("Save")),
+ "saveProject": (self.saveProject, _("Save current collection to disk"), _("Save")),
"burnProject": (self.burnProject, _("Burn DVD"), _("Burn DVD")),
})
menu.append((_("Edit chapters of current title"), "edittitle"));
menu.append((_("Set collection name"), "setname"));
menu.append((_("Set menu background"), "setbackground"));
- menu.append((_("Save current project to disk"), "save"));
- menu.append((_("Load saved project from disk"), "load"));
+ menu.append((_("Save current collection to disk"), "save"));
+ menu.append((_("Load saved collection from disk"), "load"));
menu.append((_("Preview menu"), "previewMenu"));
menu.append((_("Burn DVD"), "burn"));
self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
def newProject(self):
self.project = DVDProject.DVDProject()
- self.project.titles = [ ]
- self.project.session = self.session
- self.updateCollectionName()
+ if self.loadProject():
+ self.project.session = self.session
+ self.updateCollectionName()
def updateCollectionName(self):
self["title_label"].text = _("Table of content for collection") + " \"" + self.project.name + "\":"
self.updateTitleList()
def saveProject(self):
- from Tools.Directories import resolveFilename, SCOPE_PLAYLIST
self.project.saveProject(resolveFilename(SCOPE_PLAYLIST))
+ def loadProject(self, filename=None):
+ if not filename:
+ filename = resolveFilename(SCOPE_PLAYLIST)+"DreamboxDVDtemplate.ddvdp.xml"
+ if self.project.loadProject(filename):
+ return True
+ else:
+ try:
+ self.session.open(MessageBox,self.project.error,MessageBox.TYPE_ERROR)
+ except:
+ self["title_label"].text = self.project.error
+ print self.project.error
+ return False
+
def burnProject(self):
self.project.waitboxref = self.project.session.open(WaitBox,self.burnProjectCB)
def showFileBrowser(self, projectBrowser=False):
if projectBrowser:
- currDir = "/home/root"
+ currDir = resolveFilename(SCOPE_PLAYLIST)
else:
currDir = self.project.menubg
if len(currDir) > 1:
self.session.openWithCallback(self.FileBrowserClosed, FileBrowser, currDir, projectBrowser)
def FileBrowserClosed(self, path, projectBrowser=False):
- print "FileBrowserClosed", path, projectBrowser
if projectBrowser:
- print "would load project", path
+ self.loadProject(path)
else:
self.project.menubg = path