Ticket #10071: mythburn.py_fixes_1.3.2012_for_git_1.3.2012_unified.patch

File mythburn.py_fixes_1.3.2012_for_git_1.3.2012_unified.patch, 38.6 KB (added by t.brackertz@…, 9 years ago)

unified version

  • (a) mythburn_git_5.2.2012.py vs. (b) mythburn_gepatched_vor

    a b  
    11#!/usr/bin/env python
     2# -*- coding: utf-8 -*-
    23# mythburn.py
    34# The ported MythBurn scripts which feature:
    45
     
    3031# pyfribidi
    3132
    3233# Optional (alternate demuxer)
    33 # ProjectX - 0.90.4.00
     34# ProjectX - >=0.91
    3435
    3536#******************************************************************************
    3637#******************************************************************************
    3738#******************************************************************************
    3839
     40
     41# All strings in this file should be unicode, not byte string!! They get converted to utf-8 only
     42
     43
     44
     45
    3946# version of script - change after each update
    4047VERSION="0.1.20111228-1"
    4148
     
    256263
    257264def write(text, progress=True):
    258265    """Simple place to channel all text output through"""
     266
     267    text = text.encode("utf-8", "replace")
    259268    sys.stdout.write(text + "\n")
    260269    sys.stdout.flush()
    261270
     
    270279    """Display an error message and exit app"""
    271280    write("*"*60)
    272281    write("ERROR: " + msg)
     282    write("See mythburn.log for more information.")
    273283    write("*"*60)
    274284    write("")
    275285    saveSetting("MythArchiveLastRunResult", "Failed: " + quoteString(msg));
     
    304314# Try to work out how many cpus we have available
    305315
    306316def getCPUCount():
    307     """return the number of CPU's"""
     317    """return the number of CPUs"""
    308318    cpustat = open("/proc/cpuinfo")
    309319    cpudata = cpustat.readlines()
    310320    cpustat.close()
     
    338348    return os.path.exists( file )
    339349
    340350#############################################################
    341 # Escape quotes in a filename
     351# Escape quotes in a command line argument
    342352
    343 def quoteFilename(filename):
    344     filename = filename.replace('"', '\\"')
    345     filename = filename.replace('`', '\\`')
    346     return '"%s"' % filename
     353def quoteCmdArg(arg):
     354    arg = arg.replace('"', '\\"')
     355    arg = arg.replace('`', '\\`')
     356    return '"%s"' % arg
    347357
    348358#############################################################
    349359# Returns the text contents from a given XML element.
     
    415425                os.remove(os.path.join(root, name))
    416426
    417427#############################################################
     428# Romoves all the objects from a directory
     429
     430def deleteEverythingInFolder(folder):
     431    for root, dirs, files in os.walk(folder, topdown=False):
     432        for name in files:
     433                os.remove(os.path.join(root, name))
     434        for name in dirs:
     435                if os.path.islink(os.path.join(root, name)):
     436                    os.remove(os.path.join(root, name))
     437                else:
     438                    os.rmdir(os.path.join(root, name))
     439
     440#############################################################
    418441# Check to see if the user has cancelled the DVD creation process
    419442
    420443def checkCancelFlag():
     
    433456def runCommand(command):
    434457    checkCancelFlag()
    435458
    436     result = os.system(command)
     459    # mytharchivehelper needes this locale to work correctly
     460    try:
     461       oldlocale = os.environ["LC_ALL"]
     462    except:
     463       oldlocale = ""
     464    os.putenv("LC_ALL", "en_US.UTF-8")
     465    result = os.system(command.encode('utf-8'))
     466    os.putenv("LC_ALL", oldlocale)
    437467
    438468    if os.WIFEXITED(result):
    439469        result = os.WEXITSTATUS(result)
     
    464494
    465495    totalframes=int(musiclength * framespersecond)
    466496
    467     command = path_jpeg2yuv[0] + " -n %s -v0 -I p -f %s -j '%s' | %s -b 5000 -a %s -v 1 -f 8 -o '%s'" \
    468               % (totalframes, framespersecond, background, path_mpeg2enc[0], aspectratio, tempvideo)
     497    command = quoteCmdArg(path_jpeg2yuv[0]) + " -n %s -v0 -I p -f %s -j %s | %s -b 5000 -a %s -v 1 -f 8 -o %s" \
     498              % (totalframes, framespersecond, quoteCmdArg(background), quoteCmdArg(path_mpeg2enc[0]), aspectratio, quoteCmdArg(tempvideo))
    469499    result = runCommand(command)
    470500    if result<>0:
    471501        fatalError("Failed while running jpeg2yuv - %s" % command)
    472502
    473     command = path_mplex[0] + " -f 8 -v 0 -o '%s' '%s' '%s'" % (tempmovie, tempvideo, music)
     503    command = quoteCmdArg(path_mplex[0]) + " -f 8 -v 0 -o %s %s %s" % (quoteCmdArg(tempmovie), quoteCmdArg(tempvideo), quoteCmdArg(music))
    474504    result = runCommand(command)
    475505    if result<>0:
    476506        fatalError("Failed while running mplex - %s" % command)
    477507
    478508    if xmlfile != "":
    479         command = path_spumux[0] + " -m dvd -s 0 '%s' < '%s' > '%s'" % (xmlfile, tempmovie, finaloutput)
     509        command = quoteCmdArg(path_spumux[0]) + " -m dvd -s 0 %s < %s > %s" % (quoteCmdArg(xmlfile), quoteCmdArg(tempmovie), quoteCmdArg(finaloutput))
    480510        result = runCommand(command)
    481511        if result<>0:
    482512            fatalError("Failed while running spumux - %s" % command)
     
    14311461        data.thumblist = ','.join(thumblist)
    14321462
    14331463    for k,v in data.items():
    1434         print "Node = %s, Data = %s" % (k, v)
     1464        write( "Node = %s, Data = %s" % (k, v))
    14351465        node = infoDOM.createElement(k)
    1436         node.appendChild(infoDOM.createTextNode(str(v)))
     1466        # v may be either an integer. Therefore we have to
     1467        # convert it to an unicode-string
     1468        # If it is already a string it is not encoded as all
     1469        # strings in this script are unicode. As no
     1470        # encoding-argument is supplied to unicode() it does
     1471        # nothing in this case.
     1472        node.appendChild(infoDOM.createTextNode(unicode(v)))
    14371473        top_element.appendChild(node)
    14381474
    14391475    WriteXMLToFile (infoDOM, outputfile)
     
    14971533        if cpuCount > 1:
    14981534            cmd += "-threads %d " % cpuCount
    14991535
    1500         cmd += "-i '%s' -f ac3 -ab 192k -ar 48000 '%s'" % (sourcefile, destinationfile)
     1536        cmd += "-i %s -f ac3 -ab 192k -ar 48000 %s" % (quoteCmdArg(sourcefile), quoteCmdArg(destinationfile))
    15011537        result = runCommand(cmd)
    15021538
    15031539        if result != 0:
     
    15911627    # run spumux to add subtitles if they exist
    15921628    if os.path.exists(os.path.dirname(destination) + "/stream.d/spumux.xml"):
    15931629        write("Checking integrity of subtitle pngs")
    1594         command = os.path.join(scriptpath, "testsubtitlepngs.sh") + " %s/stream.d/spumux.xml" % (os.path.dirname(destination))
     1630        command = quoteCmdArg(os.path.join(scriptpath, "testsubtitlepngs.sh")) + " " + quoteCmdArg(os.path.dirname(destination) + "/stream.d/spumux.xml")
    15951631        result = runCommand(command)
    15961632        if result<>0:
    15971633            fatalError("Failed while running testsubtitlepngs.sh - %s" % command)
    15981634
    15991635        write("Running spumux to add subtitles")
    1600         command = path_spumux[0] + " -P %s/stream.d/spumux.xml <%s >%s" % (os.path.dirname(destination), destination, os.path.splitext(destination)[0] + "-sub.mpg")
     1636        command = quoteCmdArg(path_spumux[0]) + " -P %s <%s >%s" % (quoteCmdArg(os.path.dirname(destination) + "/stream.d/spumux.xml"), quoteCmdArg(destination), quoteCmdArg(os.path.splitext(destination)[0] + "-sub.mpg"))
    16011637        result = runCommand(command)
    16021638        if result<>0:
    16031639            nonfatalError("Failed while running spumux.\n"
     
    16151651
    16161652def getStreamInformation(filename, xmlFilename, lenMethod):
    16171653    """create a stream.xml file for filename"""
    1618     filename = quoteFilename(filename)
    1619     command = "mytharchivehelper -q -q --getfileinfo --infile %s --outfile %s --method %d" % (filename, xmlFilename, lenMethod)
     1654
     1655    command = "mytharchivehelper -q -q --getfileinfo --infile %s --outfile %s --method %d" % (quoteCmdArg(filename), quoteCmdArg(xmlFilename), lenMethod)
     1656
    16201657
    16211658    result = runCommand(command)
    16221659
     
    16261663
    16271664    # print out the streaminfo.xml file to the log
    16281665    infoDOM = xml.dom.minidom.parse(xmlFilename)
    1629     write("streaminfo.xml :-\n" + infoDOM.toprettyxml("    ", ""), False)
     1666    write(xmlFilename + ":-\n" + infoDOM.toprettyxml("    ", ""), False)
    16301667
    16311668#############################################################
    16321669# Gets the video width and height from a file's stream xml file
     
    16721709    if (localfile != ""):
    16731710        localfile = quoteFilename(localfile)
    16741711        if usecutlist == True:
    1675             command = "mythtranscode --mpeg2 --honorcutlist %s --infile %s --outfile %s" % (cutlist_s, localfile, destination)
     1712            command = "mythtranscode --mpeg2 --honorcutlist %s --infile %s --outfile %s" % (cutlist_s, quoteCmdArg(localfile), quoteCmdArg(destination))
    16761713        else:
    1677             command = "mythtranscode --mpeg2 -i %s -o %s" % (localfile, destination)
     1714            command = "mythtranscode --mpeg2 --infile %s --outfile %s" % (quoteCmdArg(localfile), quoteCmdArg(destination))
    16781715    else:
    16791716        if usecutlist == True:
    1680             command = "mythtranscode --mpeg2 --honorcutlist --chanid %s --starttime %s --outfile %s" % (chanid, starttime, destination)
     1717            command = "mythtranscode --mpeg2 --honorcutlist --chanid %s --starttime %s --outfile %s" % (chanid, starttime, quoteCmdArg(destination))
    16811718        else:
    1682             command = "mythtranscode --mpeg2 --chanid %s --starttime %s --outfile %s" % (chanid, starttime, destination)
     1719            command = "mythtranscode --mpeg2 --chanid %s --starttime %s --outfile %s" % (chanid, starttime, quoteCmdArg(destination))
    16831720
    16841721    result = runCommand(command)
    16851722
     
    17361773            write("Failed to generate Project-X cutlist.")
    17371774            return False
    17381775
    1739     pxbasename = os.path.splitext(os.path.basename(file))[0]
    1740 
    17411776    if os.path.exists(file) != True:
    17421777        write("Error: input file doesn't exist on local filesystem")
    17431778        return False
    17441779
    1745 
    1746     qdestdir = quoteFilename(folder)
    1747     qpxbasename = quoteFilename(pxbasename)
    1748     qfile = quoteFilename(file)
    1749     qcutlist = os.path.join(folder, "cutlist_x.txt")
    1750 
    1751     command = path_projectx[0] + " -id %s" % getStreamList(folder)
     1780    command = quoteCmdArg(path_projectx[0]) + " %s -id '%s' -set ExternPanel.appendPidToFileName=1 -out %s -name stream" % (quoteCmdArg(file), getStreamList(folder), quoteCmdArg(folder))
    17521781    if usecutlist == True:
    1753         command += " -cut %s -out %s -name %s %s" % (qcutlist, qdestdir, qpxbasename, qfile)
    1754     else:
    1755         command += " -out %s -name %s %s" % (qdestdir, qpxbasename, qfile)
    1756 
     1782        command += " -cut %s" % quoteCmdArg(os.path.join(folder, "cutlist_x.txt"))
    17571783    write(command)
    1758 
    17591784    result = runCommand(command)
    17601785
    17611786    if (result != 0):
     
    17651790
    17661791
    17671792    # workout which files we need and rename them
    1768     renameProjectXFiles(folder, pxbasename)
     1793    video, audio1, audio2 = selectStreams(folder)
     1794    if addSubtitles:
     1795        subtitles = selectSubtitleStream(folder)
     1796
     1797    videoID_hex = "0x%x" % video[VIDEO_ID]
     1798    if audio1[AUDIO_ID] != -1:
     1799        audio1ID_hex = "0x%x" % audio1[AUDIO_ID]
     1800    else:
     1801        audio1ID_hex = ""
     1802    if audio2[AUDIO_ID] != -1:
     1803        audio2ID_hex = "0x%x" % audio2[AUDIO_ID]
     1804    else:
     1805        audio2ID_hex = ""
     1806    if addSubtitles and subtitles[SUBTITLE_ID] != -1:
     1807        subtitlesID_hex = "0x%x" % subtitles[SUBTITLE_ID]
     1808    else:
     1809        subtitlesID_hex = ""
     1810
     1811
     1812    files = os.listdir(folder)
     1813    for file in files:
     1814        if file[0:9] == "stream{0x": # don't rename files that have already been renamed
     1815            PID = file[7:13]
     1816            SubID = file[19:23]
     1817            if PID == videoID_hex or SubID == videoID_hex:
     1818                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.mv2"))
     1819            elif PID == audio1ID_hex or SubID == audio1ID_hex:
     1820                os.rename(os.path.join(folder, file), os.path.join(folder, "stream0." + file[-3:]))
     1821            elif PID == audio2ID_hex or SubID == audio2ID_hex:
     1822                os.rename(os.path.join(folder, file), os.path.join(folder, "stream1." + file[-3:]))
     1823            elif PID == subtitlesID_hex or SubID == subtitlesID_hex:
     1824                if file[-3:] == "sup":
     1825                    os.rename(os.path.join(folder, file), os.path.join(folder, "stream.sup"))
     1826                else:
     1827                    os.rename(os.path.join(folder, file), os.path.join(folder, "stream.sup.IFO"))
     1828
     1829
     1830    # Fallback if assignment and renaming by ID failed
     1831   
     1832    files = os.listdir(folder)
     1833    for file in files:
     1834        if file[0:9] == "stream{0x": # don't rename files that have already been renamed
     1835            if not os.path.exists(os.path.join(folder, "stream.mv2")) and file[-3:] == "m2v":
     1836                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.mv2"))
     1837            elif not (os.path.exists(os.path.join(folder, "stream0.ac3")) or os.path.exists(os.path.join(folder, "stream0.mp2"))) and file[-3:] == "ac3":
     1838                os.rename(os.path.join(folder, file), os.path.join(folder, "stream0.ac3"))
     1839            elif not (os.path.exists(os.path.join(folder, "stream0.ac3")) or os.path.exists(os.path.join(folder, "stream0.mp2"))) and file[-3:] == "mp2":
     1840                os.rename(os.path.join(folder, file), os.path.join(folder, "stream0.mp2"))
     1841            elif not (os.path.exists(os.path.join(folder, "stream1.ac3")) or os.path.exists(os.path.join(folder, "stream1.mp2"))) and file[-3:] == "ac3":
     1842                os.rename(os.path.join(folder, file), os.path.join(folder, "stream1.ac3"))
     1843            elif not (os.path.exists(os.path.join(folder, "stream1.ac3")) or os.path.exists(os.path.join(folder, "stream1.mp2"))) and file[-3:] == "mp2":
     1844                os.rename(os.path.join(folder, file), os.path.join(folder, "stream1.mp2"))
     1845            elif not os.path.exists(os.path.join(folder, "stream.sup")) and file[-3:] == "sup":
     1846                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.sup"))
     1847            elif not os.path.exists(os.path.join(folder, "stream.sup.IFO")) and file[-3:] == "IFO":
     1848                os.rename(os.path.join(folder, file), os.path.join(folder, "stream.sup.IFO"))
     1849
    17691850
    17701851    # if we have some dvb subtitles and the user wants to add them to the DVD
    17711852    # convert them to pngs and create the spumux xml file
     
    17741855            os.path.exists(os.path.join(folder, "stream.sup.IFO"))):
    17751856            write("Found DVB subtitles converting to DVD subtitles")
    17761857            command = "mytharchivehelper -q -q --sup2dast "
    1777             command += " --infile %s --ifofile %s --delay 0" % (os.path.join(folder, "stream.sup"), os.path.join(folder, "stream.sup.IFO"))
     1858            command += " --infile %s --ifofile %s --delay 0" % (quoteCmdArg(os.path.join(folder, "stream.sup")), quoteCmdArg(os.path.join(folder, "stream.sup.IFO")))
    17781859
    17791860            result = runCommand(command)
    17801861
     
    17891870    return True
    17901871
    17911872#############################################################
    1792 # find the required stream files and rename them
    1793 
    1794 def renameProjectXFiles(folder, pxbasename):
    1795 
    1796     write("renameProjectXFiles start -----------------------------------------", False)
    1797     logf = open(os.path.join(folder, pxbasename + "_log.txt"))
    1798     logdata = logf.readlines()
    1799     logf.close()
    1800 
    1801     # find stream PIDs and Files
    1802     streamIds = []
    1803     streamFiles = []   
    1804     for line in logdata:
    1805          tokens = line.split()
    1806          if len(tokens) > 0:
    1807             if tokens[0] == "++>":
    1808               # From ProjectX/resources/pjxresources_en.properties:
    1809               if tokens[1] == "Mpg":
    1810                 if tokens[2] == "Video:":
    1811                   write("found MPEG video stream %s" % tokens[4], False)
    1812                   streamIds.append(int(tokens[4], 16))
    1813                 if tokens[2] == "Audio:":
    1814                   write("found MPEG audio stream %s" % tokens[4], False)
    1815                   streamIds.append(int(tokens[4], 16))
    1816               if tokens[1] == "AC3/DTS":
    1817                 write("found AC3/DTS audio stream %s" % tokens[4], False)
    1818                 streamIds.append(int(tokens[4], 16))             
    1819               if tokens[1] == "LPCM":
    1820                 write("found LPCM audio stream %s" % tokens[4], False)
    1821                 streamIds.append(int(tokens[4], 16))             
    1822               if tokens[1] == "Teletext:":
    1823                 write("found Teletext stream %s" % tokens[3], False)
    1824                 streamIds.append(int(tokens[3], 16))             
    1825               if tokens[1] == "Subpicture:":
    1826                 write("found Subpicture stream %s" % tokens[3], False)
    1827                 streamIds.append(int(tokens[3], 16))
    1828               if tokens[1] == "Generic_VBI:":
    1829                 write("found Generic_VBI stream %s" % tokens[3], False)
    1830                 streamIds.append(int(tokens[3], 16))                                           
    1831             if tokens[0] == "--->":
    1832               if tokens[1] == "new":
    1833                 if tokens[2] == "File:":
    1834                   write("found file for stream 0x%x, %s" % (streamIds[len(streamIds)-1], tokens[3]), False)
    1835                   streamFiles.append(tokens[3].replace("'","")) # let's hope the path never has a space in it
    1836             if tokens[0] == "-->":
    1837               if tokens[1] == "stream":
    1838                 if tokens[2] == "omitted":
    1839                   write("stream 0x%x omitted" % streamIds[len(streamIds)-1], False)
    1840                   streamFiles.append("")
    1841                  
    1842     write("streadmIds=%s" % streamIds)
    1843     write("streamFiles=%s" % streamFiles)
    1844 
    1845     # choose which streams we need
    1846     video, audio1, audio2 = selectStreams(folder)
    1847 
    1848     if getFileType(folder) == "mpeg":
    1849         videoID  = video[VIDEO_ID] & 255
    1850         audio1ID = audio1[AUDIO_ID] & 255
    1851         audio2ID = audio2[AUDIO_ID] & 255
    1852     else:
    1853         videoID  = video[VIDEO_ID]
    1854         audio1ID = audio1[AUDIO_ID]
    1855         audio2ID = audio2[AUDIO_ID]
    1856 
    1857     # sanity check - we should have a file for each ID
    1858     if len(streamIds) == len(streamFiles):
    1859         # loop thought the available streams looking for the ones we want
    1860         for stream in streamIds:
    1861             write("got stream: %d" % stream, False)
    1862             if stream == videoID:
    1863                 write("found video streamID", False)
    1864                 if os.path.exists(streamFiles[streamIds.index(stream)]):
    1865                     write("found video stream file", False)
    1866                     os.rename(streamFiles[streamIds.index(stream)], os.path.join(folder, "stream.mv2"))
    1867 
    1868             if stream == audio1ID:
    1869                 write("found audio1 streamID", False)
    1870                 if os.path.exists(streamFiles[streamIds.index(stream)]):
    1871                     write("found audio1 stream file", False)
    1872                     if audio1[AUDIO_CODEC] == "AC3":
    1873                         os.rename(streamFiles[streamIds.index(stream)], os.path.join(folder, "stream0.ac3"))
    1874                     else:
    1875                         os.rename(streamFiles[streamIds.index(stream)], os.path.join(folder, "stream0.mp2"))
    1876 
    1877             if stream == audio2ID:
    1878                 write("found audio2 streamID", False)
    1879                 if os.path.exists(streamFiles[streamIds.index(stream)]):
    1880                     write("found audio2 stream file", False)
    1881                     if audio2[AUDIO_CODEC] == "AC3":
    1882                         os.rename(streamFiles[streamIds.index(stream)], os.path.join(folder, "stream1.ac3"))
    1883                     else:
    1884                         os.rename(streamFiles[streamIds.index(stream)], os.path.join(folder, "stream1.mp2"))
    1885 
    1886     # final chance to find the correct stream files
    1887     if not os.path.exists(os.path.join(folder, "stream.mv2")):
    1888         if os.path.exists(os.path.join(folder, pxbasename + ".m2v")):
    1889             os.rename(os.path.join(folder, pxbasename + ".m2v"), os.path.join(folder, "stream.mv2"))
    1890 
    1891     if not os.path.exists(os.path.join(folder, "stream0.mp2")) or not os.path.exists(os.path.join(folder, "stream0.ac3")):
    1892         if os.path.exists(os.path.join(folder, pxbasename + ".mp2")):
    1893             os.rename(os.path.join(folder, pxbasename + ".mp2"), os.path.join(folder, "stream0.mp2"))
    1894         if os.path.exists(os.path.join(folder, pxbasename + ".ac3")):
    1895             os.rename(os.path.join(folder, pxbasename + ".ac3"), os.path.join(folder, "stream0.ac3"))
    1896 
    1897     if not os.path.exists(os.path.join(folder, "stream1.mp2")) or not os.path.exists(os.path.join(folder, "stream1.ac3")):
    1898         if os.path.exists(os.path.join(folder, pxbasename + "[1].mp2")):
    1899             os.rename(os.path.join(folder, pxbasename + "[1].mp2"), os.path.join(folder, "stream1.mp2"))
    1900         if os.path.exists(os.path.join(folder, pxbasename + "[1].ac3")):
    1901             os.rename(os.path.join(folder, pxbasename + "[1].ac3"), os.path.join(folder, "stream1.ac3"))
    1902 
    1903     # do we have any subtitle files
    1904     if os.path.exists(os.path.join(folder, pxbasename + ".sup")):
    1905         os.rename(os.path.join(folder, pxbasename + ".sup"), os.path.join(folder, "stream.sup"))
    1906 
    1907     if os.path.exists(os.path.join(folder, pxbasename + ".sup.IFO")):
    1908         os.rename(os.path.join(folder, pxbasename + ".sup.IFO"), os.path.join(folder, "stream.sup.IFO"))
    1909 
    1910     write("renameProjectXFiles end -----------------------------------------", False)
    1911 
    1912 #############################################################
    19131873# convert time stamp to pts
    19141874
    19151875def ts2pts(time):
     
    19801940        else:
    19811941            fr=framerateNTSC
    19821942
    1983         source = quoteFilename(source)
    1984 
    1985         command = "mytharchivehelper -q -q --createthumbnail --infile %s --thumblist '%s' --outfile %s" % (source, seconds, destination)
     1943        command = "mytharchivehelper -q -q --createthumbnail --infile %s --thumblist '%s' --outfile %s" % (quoteCmdArg(source), seconds, quoteCmdArg(destination))
    19861944        result = runCommand(command)
    19871945        if result <> 0:
    19881946            fatalError("Failed while running mytharchivehelper to get thumbnails.\n"
     
    20051963    write("Extracting thumbnail images from: %s - at %s" % (source, thumbList))
    20061964    write("Destination file %s" % destination)
    20071965
    2008     source = quoteFilename(source)
    2009 
    2010     command = "mytharchivehelper -q -q --createthumbnail --infile %s --thumblist '%s' --outfile %s" % (source, thumbList, destination)
     1966    command = "mytharchivehelper -q -q --createthumbnail --infile %s --thumblist '%s' --outfile %s" % (quoteCmdArg(source), thumbList, quoteCmdArg(destination))
     1967    write(command)
    20111968    result = runCommand(command)
    20121969    if result <> 0:
    20131970        fatalError("Failed while running mytharchivehelper to get thumbnails.\n"
     
    20361993
    20371994        # do some parameter substitution
    20381995        if value == "%inputfile":
    2039             value = quoteFilename(source)
     1996            value = quoteCmdArg(source)
    20401997        if value == "%outputfile":
    2041             value = quoteFilename(destvideofile)
     1998            value = quoteCmdArg(destvideofile)
    20421999        if value == "%aspect":
    20432000            value = aspectratio
    20442001
     
    20922049        passLog = os.path.join(getTempPath(), 'pass')
    20932050
    20942051        pass1 = string.replace(command, "%passno","1")
    2095         pass1 = string.replace(pass1, "%passlogfile", passLog)
     2052        pass1 = string.replace(pass1, "%passlogfile", quoteCmdArg(passLog))
    20962053        write("Pass 1 - " + pass1)
    20972054        result = runCommand(pass1)
    20982055
     
    22142171    if cpuCount > 1:
    22152172        command += "-threads %d " % cpuCount
    22162173
    2217     command += "-f s16le -ar %s -ac %s -i %s " % (samplerate, channels, os.path.join(folder, "audout"))
     2174    command += "-f s16le -ar %s -ac %s -i %s " % (samplerate, channels, quoteCmdArg(os.path.join(folder, "audout")))
    22182175    command += "-f rawvideo -pix_fmt yuv420p -s %s -aspect %s -r %s " % (videores, aspectratio, fps)
    2219     command += "-i %s " % os.path.join(folder, "vidout")
     2176    command += "-i %s " % quoteCmdArg(os.path.join(folder, "vidout"))
    22202177    command += "-aspect %s -r %s " % (aspectratio, fps)
    22212178    if (deinterlace == 1):
    22222179        command += "-deinterlace "
     
    22242181    command += "-s %s -b %s -vcodec mpeg2video " % (outvideores, outvideobitrate)
    22252182    command += "-qmin %s -qmax %s -qdiff %s " % (qmin, qmax, qdiff)
    22262183    command += "-ab %s -ar %s -acodec %s " % (outaudiobitrate, outaudiosamplerate, outaudiocodec)
    2227     command += "-f dvd %s" % quoteFilename(destvideofile)
     2184    command += "-f dvd %s" % quoteCmdArg(destvideofile)
    22282185
    22292186    #wait for mythtranscode to create the fifos
    22302187    tries = 30
     
    22612218def CreateDVDISO(title):
    22622219    write("Creating ISO image")
    22632220    checkCancelFlag()
    2264     command = path_mkisofs[0] + ' -dvd-video '
    2265     command += ' -V ' + quoteFilename(title)
    2266     command += ' -o ' + os.path.join(getTempPath(), 'mythburn.iso')
    2267     command += " " + os.path.join(getTempPath(),'dvd')
     2221    command = quoteCmdArg(path_mkisofs[0]) + ' -dvd-video '
     2222    command += ' -V ' + quoteCmdArg(title)
     2223    command += ' -o ' + quoteCmdArg(os.path.join(getTempPath(), 'mythburn.iso'))
     2224    command += " " + quoteCmdArg(os.path.join(getTempPath(),'dvd'))
    22682225
    22692226    result = runCommand(command)
    22702227
     
    22792236
    22802237def BurnDVDISO(title):
    22812238    write( "Burning ISO image to %s" % dvddrivepath)
    2282     checkCancelFlag()
    22832239
    2284     finished = False
    2285     tries = 0
    2286     while not finished and tries < 10:
     2240    #######################
     2241    # some helper functions
     2242    def drivestatus():
    22872243        f = os.open(dvddrivepath, os.O_RDONLY | os.O_NONBLOCK)
    2288         drivestatus = ioctl(f,CDROM.CDROM_DRIVE_STATUS, 0)
    2289         os.close(f);
     2244        status = ioctl(f,CDROM.CDROM_DRIVE_STATUS, 0)
     2245        os.close(f)
     2246        return status
     2247    def displayneededdisktype():
     2248        if mediatype == DVD_SL:
     2249          write("Please insert an empty single-layer disc (DVD+R or DVD-R).")
     2250        if mediatype == DVD_DL:
     2251          write("Please insert an empty double-layer disc (DVD+R DL or DVD-R DL).")
     2252        if mediatype == DVD_RW:
     2253          write("Please insert a rewritable disc (DVD+RW or DVD-RW).")
     2254    def tray(action):
     2255        runCommand("pumount " + quoteCmdArg(dvddrivepath));
     2256        waitForDrive()
     2257        try:
     2258            f = os.open(drivepath, os.O_RDONLY | os.O_NONBLOCK)
     2259            r = ioctl(f,action, 0)
     2260            os.close(f)
     2261            return True
     2262        except:
     2263            write("Failed to eject the disc!")
     2264            return False
     2265        finally:
     2266            os.close(f)               
     2267    def waitForDrive():
     2268        tries = 0
     2269        while drivestatus() == CDROM.CDS_DRIVE_NOT_READY:
     2270            checkCancelFlag()
     2271            write("Waiting for drive")
     2272            time.sleep(5)
     2273            tries += 1
     2274            if tries > 10:
     2275                # Try a hard reset if the device is still not ready
     2276                write("Try a hard-reset of the device")
     2277                tray(CDROM.CDROMRESET)
     2278                tries = 0
    22902279
    2291         if drivestatus == CDROM.CDS_DISC_OK or drivestatus == CDROM.CDS_NO_INFO:
     2280
     2281    ####################
     2282    # start working here
     2283
     2284
     2285    finished = False
     2286    while not finished:
     2287        # Maybe the user has no appropriate medium or something alike. Give her the chance to cancel.
     2288        checkCancelFlag()
     2289
     2290        # If drive needs some time (for example to close the tray) give it to it
     2291        waitForDrive()
     2292
     2293        if drivestatus() == CDROM.CDS_DISC_OK or drivestatus() == CDROM.CDS_NO_INFO:
    22922294
    22932295            # If the frontend has a previously burnt DVD+RW mounted,
    22942296            # growisofs will fail to burn it, so try to pumount it first...
    2295             runCommand("pumount " + dvddrivepath);
     2297            runCommand("pumount " + quoteCmdArg(dvddrivepath));
    22962298
    2297             if mediatype == DVD_RW and erasedvdrw == True:
    2298                 command = path_growisofs[0] + " -dvd-compat "
    2299                 if drivespeed != 0:
    2300                     command += "-speed=%d " % drivespeed
    2301                 command += " -use-the-force-luke -Z " + dvddrivepath
    2302                 command += " -dvd-video -V '" + title.replace("'", "'\\''") + "' "
    2303                 command += os.path.join(getTempPath(),'dvd')
    2304             else:
    2305                 command = path_growisofs[0] + " -dvd-compat "
    2306                 if drivespeed != 0:
    2307                     command += "-speed=%d " % drivespeed
    2308                 command += " -Z " + dvddrivepath + " -dvd-video -V '" + title.replace("'", "'\\''") + "' "
    2309                 command += os.path.join(getTempPath(),'dvd')
    23102299
     2300            command = quoteCmdArg(path_growisofs[0]) + " -dvd-compat"
     2301            if drivespeed != 0:
     2302                command += " -speed=%d" % drivespeed
     2303            if mediatype == DVD_RW and erasedvdrw == True:
     2304                command += " -use-the-force-luke"
     2305            command += " -Z " + quoteCmdArg(dvddrivepath) + " -dvd-video -V " + quoteCmdArg(title) + " " + quoteCmdArg(os.path.join(getTempPath(),'dvd'))
    23112306            write(command)
    23122307            write("Running growisofs to burn DVD")
    23132308
    23142309            result = runCommand(command)
    2315             if result != 0:
    2316                 write("-"*60)
    2317                 write("ERROR: Failed while running growisofs.")
    2318                 write("Result %d, Command was: %s" % (result, command))
    2319                 write("Please check the troubleshooting section of the README for ways to fix this error")
    2320                 write("-"*60)
    2321                 write("")
    2322                 sys.exit(1)
    2323             finished = True
    2324 
    2325             try:
    2326                 # eject the burned disc
    2327                 f = os.open(dvddrivepath, os.O_RDONLY | os.O_NONBLOCK)
    2328                 r = ioctl(f,CDROM.CDROMEJECT, 0)
    2329                 os.close(f)
    2330             except:
    2331                 write("Failed to eject the disc! "
    2332                       "Maybe the media monitor has mounted it")
     2310            if result == 0:
     2311                finished = True
     2312            else:
     2313                if result == 252:
     2314                    write("-"*60)
     2315                    write("You probably inserted a medium of wrong type.")
     2316                elif (result == 156):
     2317                    write("-"*60)
     2318                    write("You probably inserted a non-empty, corrupt or too small medium.")
     2319                elif (result == 144):
     2320                    write("-"*60)
     2321                    write("You inserted a non-empty medium.")
     2322                else:
     2323                    write("-"*60)
     2324                    write("ERROR: Failed while running growisofs.")
     2325                    write("Result %d, Command was: %s" % (result, command))
     2326                    write("Please check mythburn.log for further information")
     2327                    write("-"*60)
     2328                    write("")
     2329                    write("Going to try it again until canceled by user:")
     2330                    write("-"*60)
     2331                    write("")
     2332                displayneededdisktype()
    23332333
    2334         elif drivestatus == CDROM.CDS_TRAY_OPEN:
    2335             # Give the user 10secs to close the Tray
    2336             write("Waiting for tray to close.")
    2337             time.sleep(10)
    2338         elif drivestatus == CDROM.CDS_NO_DISC:
    2339             # Open the Tray, if there is one.
    2340             write("Opening tray to get it fed with a DVD.")
    2341             f = os.open(dvddrivepath, os.O_RDONLY | os.O_NONBLOCK)
    2342             ioctl(f,CDROM.CDROMEJECT, 0)
    2343             os.close(f);
    2344         elif drivestatus == CDROM.CDS_DRIVE_NOT_READY:
    2345             # Try a hard reset
    2346             write("Trying a hard-reset of the device")
    2347             f = os.open(dvddrivepath, os.O_RDONLY | os.O_NONBLOCK)
    2348             ioctl(f,CDROM.CDROMEJECT, 0)
    2349             os.close(f);
     2334            # eject the disc
     2335            tray(CDROM.CDROMEJECT)
    23502336
    2351         time.sleep(1)
    2352         tries += 1
    23532337
    2354     if not finished:
    2355         fatalError("Tried 10 times to get a good status from DVD drive - Giving up!")
     2338        elif drivestatus() == CDROM.CDS_TRAY_OPEN:
     2339            displayneededdisktype()
     2340            write("Waiting for tray to close.")
     2341            # Wait until user closes tray or cancels
     2342            while drivestatus() == CDROM.CDS_TRAY_OPEN:
     2343                checkCancelFlag()
     2344                time.sleep(5)
     2345        elif drivestatus() == CDROM.CDS_NO_DISC:
     2346            tray(CDROM.CDROMEJECT)
     2347            displayneededdisktype()
    23562348
    23572349    write("Finished burning ISO image")
    23582350
     
    23632355def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):
    23642356
    23652357    if getFileType(folder) == "mpegts":
    2366         command = "mythreplex --demux --fix_sync -t TS -o %s " % (folder + "/stream")
     2358        command = "mythreplex --demux --fix_sync -t TS -o %s " % quoteCmdArg(folder + "/stream")
    23672359        command += "-v %d " % (video[VIDEO_ID])
    23682360
    23692361        if audio1[AUDIO_ID] != -1:
     
    23832375                command += "-c %d " % (audio2[AUDIO_ID])
    23842376
    23852377    else:
    2386         command = "mythreplex --demux --fix_sync -o %s " % (folder + "/stream")
     2378        command = "mythreplex --demux --fix_sync -o %s " % quoteCmdArg(folder + "/stream")
    23872379        command += "-v %d " % (video[VIDEO_ID] & 255)
    23882380
    23892381        if audio1[AUDIO_ID] != -1:
     
    24032395            elif audio2[AUDIO_CODEC] == 'EAC3':
    24042396                command += "-c %d " % (audio2[AUDIO_ID] & 255)
    24052397
    2406     mediafile = quoteFilename(mediafile)
     2398    mediafile = quoteCmdArg(mediafile)
    24072399    command += mediafile
    24082400    write("Running: " + command)
    24092401
     
    24202412    M2Vsize0 = os.path.getsize(source)
    24212413    write("Initial M2Vsize is %.2f Mb , target is %.2f Mb" % ( (float(M2Vsize0)/mega), (float(M2Vsize0)/(factor*mega)) ))
    24222414
    2423     command = path_M2VRequantiser[0]   
     2415    command = quoteCmdArg(path_M2VRequantiser[0])   
    24242416    command += " %.5f "  % factor
    24252417    command += " %s "  % M2Vsize0
    2426     command += " <  %s " % source
    2427     command += " >  %s " % destination
     2418    command += " <  %s " % quoteCmdArg(source)
     2419    command += " >  %s " % quoteCmdArg(destination)
    24282420 
    24292421    write("Running: " + command)
    24302422    result = runCommand(command)
     2423    if result<>0:
     2424        fatalError("Failed while running M2VRequantiser. Command was %s" % command)
    24312425
    24322426    M2Vsize1 = os.path.getsize(destination)
    24332427       
    24342428    write("M2Vsize after requant is  %.2f Mb " % (float(M2Vsize1)/mega))
    24352429    fac1=float(M2Vsize0) / float(M2Vsize1)
    24362430    write("Factor demanded %.5f, achieved %.5f, ratio %.5f " % ( factor, fac1, fac1/factor))
    2437            
    2438     if result<>0:
    2439         fatalError("Failed while running M2VRequantiser. Command was %s" % command)
    24402431
    24412432#############################################################
    24422433# Calculates the total size of all the video, audio and menu files
     
    31953186                height = getScaledAttribute(node, "h")
    31963187                frames = int(secondsToFrames(menulength))
    31973188
    3198                 command = "mytharchivehelper -q -q --createthumbnail --infile  %s --thumblist '%s' --outfile '%s' --framecount %d" % (inputfile, starttime, outputfile, frames)
     3189                command = "mytharchivehelper -q -q --createthumbnail --infile  %s --thumblist '%s' --outfile %s --framecount %d" % (quoteCmdArg(inputfile), starttime, quoteCmdArg(outputfile), frames)
    31993190                result = runCommand(command)
    32003191                if (result != 0):
    32013192                    write( "mytharchivehelper failed with code %d. Command = %s" % (result, command) )
     
    40614052    # 2. if there is one or more stream(s) using the 2nd preferred language we use that
    40624053    # 3. if we still haven't found a stream we use the stream with the lowest PID
    40634054    # 4. we prefer ac3 over mp2
    4064     # 5. if there are more that one stream with the chosen language we use the one with the lowest PID
     4055    # 5. if there are more than one stream with the chosen language we use the one with the lowest PID
    40654056
    40664057    write("Preferred audio languages %s and %s" % (preferredlang1, preferredlang2))
    40674058
     
    47854776        tmpfile = node.attributes["filename"].value
    47864777        filename = os.path.basename(tmpfile)
    47874778
    4788         res = runCommand("mytharchivehelper -q -q --isremote --infile " + quoteFilename(tmpfile))
     4779        res = runCommand("mytharchivehelper -q -q --isremote --infile " + quoteCmdArg(tmpfile))
    47894780        if res == 2:
    47904781            # file is on a remote filesystem so copy it to a local file
    47914782            write("Copying file from " + tmpfile)
     
    48504841
    48514842        write( "Final DVD Video format will be " + videomode)
    48524843
    4853         #Ensure the destination dvd folder is empty
    4854         if doesFileExist(os.path.join(getTempPath(),"dvd")):
    4855             deleteAllFilesInFolder(os.path.join(getTempPath(),"dvd"))
    48564844
    48574845        #Loop through all the files
    48584846        files=media[0].getElementsByTagName("file")
     
    48624850
    48634851            if debug_secondrunthrough==False:
    48644852                #Delete all the temporary files that currently exist
    4865                 deleteAllFilesInFolder(getTempPath())
     4853                deleteEverythingInFolder(getTempPath())
    48664854
    48674855            #If User wants to, copy remote files to a tmp dir
    48684856            if copyremoteFiles==True:
    48694857                if debug_secondrunthrough==False:
    48704858                    localCopyFolder=os.path.join(getTempPath(),"localcopy")
    4871                     #If it already exists destroy it to remove previous debris
    4872                     if os.path.exists(localCopyFolder):
    4873                         #Remove all the files first
    4874                         deleteAllFilesInFolder(localCopyFolder)
    4875                         #Remove the folder
    4876                         os.rmdir (localCopyFolder)
    48774859                    os.makedirs(localCopyFolder)
    48784860                files=copyRemote(files,getTempPath())
    48794861
     
    48874869                folder=getItemTempPath(filecount)
    48884870
    48894871                if debug_secondrunthrough==False:
    4890                     #If it already exists destroy it to remove previous debris
    4891                     if os.path.exists(folder):
    4892                         #Remove all the files first
    4893                         deleteAllFilesInFolder(folder)
    4894                         subtitlefolder = os.path.join(folder, "stream.d")
    4895                         if os.path.exists(subtitlefolder):
    4896                             deleteAllFilesInFolder(subtitlefolder)
    4897                             os.rmdir(subtitlefolder)
    4898                         previewfolder = os.path.join(folder, "preview")
    4899                         if os.path.exists(previewfolder):
    4900                             deleteAllFilesInFolder(previewfolder)
    4901                             os.rmdir(previewfolder)
    4902                         #Remove the folder
    4903                         os.rmdir (folder)
    49044872                    os.makedirs(folder)
    49054873                #Do the pre-process work
    49064874                preProcessFile(node,folder,filecount)
     
    49874955                fatalError("The info.xml file (%s) doesn't look right" % os.path.join(folder,"info.xml"))
    49884956            title = expandItemText(infoDOM,"%title",1,0,0,0,0)
    49894957
    4990             # convert to ascii and truncate to 32 chars
    4991             title = unicodedata.normalize('NFKD', title).encode('ASCII', 'ignore')
    4992             title = title[:32]
     4958            # replace all non-ascii-cahracters
     4959            title.encode('ascii', 'replace').decode('ascii', 'replace')
     4960            title.strip()
     4961            # replace not-allowed characters
     4962            index = 0
     4963            title_new = ''
     4964            while (index < len(title)) and (index<=7):
     4965                if title[index].isalnum and title[index] != ' ':
     4966                    title_new += title[index]
     4967                else:
     4968                    title_new += '_'
     4969                index = index + 1
     4970            title = title_new.upper()
     4971            if len(title) < 1:
     4972                title = 'UNNAMED'
    49934973
    49944974            #Create the DVD ISO image
    49954975            if docreateiso == True or mediatype == FILE: