Ticket #13562: mytharchive_python3_compatibility-V2.patch

File mytharchive_python3_compatibility-V2.patch, 56.0 KB (added by rcrdnalor, 7 years ago)

Patch using the configured python version and updates compatibility of mythburn.py to python2 and python3 as well.

  • mythplugins/mytharchive/mytharchive/mythburn.cpp

    diff --git a/mythplugins/mytharchive/mytharchive/mythburn.cpp b/mythplugins/mytharchive/mytharchive/mythburn.cpp
    index 5ef8122904..fadbb2db94 100644
    a b  
    2929#include <mythsystemlegacy.h>
    3030#include <mythmiscutil.h>
    3131#include <exitcodes.h>
     32#include <mythconfig.h>
    3233
    3334// mytharchive
    3435#include "archiveutil.h"
    void MythBurn::runScript()  
    909910        QFile::remove(logDir + "/mythburncancel.lck");
    910911
    911912    createConfigFile(configDir + "/mydata.xml");
    912     commandline = "python " + GetShareDir() + "mytharchive/scripts/mythburn.py";
     913    commandline = PYTHON_EXE;
     914    commandline += " " + GetShareDir() + "mytharchive/scripts/mythburn.py";
    913915    commandline += " -j " + configDir + "/mydata.xml";          // job file
    914916    commandline += " -l " + logDir + "/progress.log";           // progress log
    915917    commandline += " > "  + logDir + "/mythburn.log 2>&1 &";    // Logs
  • mythplugins/mytharchive/mythburn/scripts/mythburn.py

    diff --git a/mythplugins/mytharchive/mythburn/scripts/mythburn.py b/mythplugins/mytharchive/mythburn/scripts/mythburn.py
    index 4f5a96d7ab..444cc12c08 100755
    a b  
    22# -*- coding: utf-8 -*-
    33from __future__ import unicode_literals
    44
     5# python 3 doesn't have a unicode type
     6try:
     7    unicode
     8except:
     9    unicode = str
     10
     11# python 3 doesn't have a long type
     12try:
     13    long
     14except:
     15    long = int
     16
     17
    518# mythburn.py
    619# The ported MythBurn scripts which feature:
    720
    from __future__ import unicode_literals  
    4962
    5063
    5164# version of script - change after each update
    52 VERSION="0.1.20131119-1"
     65VERSION="0.2.20200120-1"
    5366
    5467# keep all temporary files for debugging purposes
    5568# set this to True before a first run through when testing
    import unicodedata  
    96109import time
    97110import tempfile
    98111from fcntl import ioctl
    99 import CDROM
     112
     113try:
     114    import CDROM
     115except:    # not available on python3
     116    class CDROM(object):
     117        CDROM_DRIVE_STATUS = 0x5326
     118        CDROMEJECT = 0x5309
     119        CDS_TRAY_OPEN = 2
     120        CDROM_LOCKDOOR = 0x5329
     121        CDS_DRIVE_NOT_READY = 3
     122        CDROMRESET = 0x5312
     123        CDS_DISC_OK = 4
     124        CDS_NO_INFO = 0
     125
    100126from shutil import copy
    101127
    102128import MythTV
    drivespeed = 0;  
    155181#main menu aspect ratio (4:3 or 16:9)
    156182mainmenuAspectRatio = "16:9"
    157183
    158 #chapter menu aspect ratio (4:3, 16:9 or Video) 
     184#chapter menu aspect ratio (4:3, 16:9 or Video)
    159185#video means same aspect ratio as the video title
    160186chaptermenuAspectRatio = "Video"
    161187
    class FontDef(object):  
    279305def write(text, progress=True):
    280306    """Simple place to channel all text output through"""
    281307
    282     sys.stdout.write((text + "\n").encode("utf-8", "replace"))
     308    if sys.version_info == 2:
     309        sys.stdout.write((text + "\n").encode("utf-8", "replace"))
     310    else:
     311        sys.stdout.write(text + "\n")
    283312    sys.stdout.flush()
    284313
    285314    if progress == True and progresslog != "":
    def encodeMenu(background, tempvideo, music, musiclength, tempmovie, xmlfile, fi  
    505534    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" \
    506535              % (totalframes, framespersecond, quoteCmdArg(background), quoteCmdArg(path_mpeg2enc[0]), aspectratio, quoteCmdArg(tempvideo))
    507536    result = runCommand(command)
    508     if result<>0:
     537    if result!=0:
    509538        fatalError("Failed while running jpeg2yuv - %s" % command)
    510539
    511540    command = quoteCmdArg(path_mplex[0]) + " -f 8 -v 0 -o %s %s %s" % (quoteCmdArg(tempmovie), quoteCmdArg(tempvideo), quoteCmdArg(music))
    512541    result = runCommand(command)
    513     if result<>0:
     542    if result!=0:
    514543        fatalError("Failed while running mplex - %s" % command)
    515544
    516545    if xmlfile != "":
    517546        command = quoteCmdArg(path_spumux[0]) + " -m dvd -s 0 %s < %s > %s" % (quoteCmdArg(xmlfile), quoteCmdArg(tempmovie), quoteCmdArg(finaloutput))
    518547        result = runCommand(command)
    519         if result<>0:
     548        if result!=0:
    520549            fatalError("Failed while running spumux - %s" % command)
    521550    else:
    522551        os.rename(tempmovie, finaloutput)
    def encodeMenu(background, tempvideo, music, musiclength, tempmovie, xmlfile, fi  
    527556            os.remove(tempmovie)
    528557
    529558#############################################################
    530 # Return an xml node from a re-encoding profile xml file for 
     559# Return an xml node from a re-encoding profile xml file for
    531560# a given profile name
    532561
    533562def findEncodingProfile(profile):
    def getLengthOfVideo(index):  
    606635    return duration
    607636
    608637#############################################################
    609 # Gets the audio sample rate and number of channels of a video file 
     638# Gets the audio sample rate and number of channels of a video file
    610639# from its stream info file
    611640
    612641def getAudioParams(folder):
    def getVideoParams(folder):  
    643672    if video.attributes["aspectratio"].value != 'N/A':
    644673        aspect_ratio = video.attributes["aspectratio"].value
    645674    else:
    646         aspect_ratio = "1.77778" 
     675        aspect_ratio = "1.77778"
    647676
    648677    videores = video.attributes["width"].value + 'x' + video.attributes["height"].value
    649678    fps = video.attributes["fps"].value
    def createVideoChapters(itemnum, numofchapters, lengthofvideo, getthumbnails):  
    801830#############################################################
    802831# Creates some fixed length chapter marks
    803832
    804 def createVideoChaptersFixedLength(itemnum, segment, lengthofvideo): 
    805     """Returns chapter marks at cut list ends, 
     833def createVideoChaptersFixedLength(itemnum, segment, lengthofvideo):
     834    """Returns chapter marks at cut list ends,
    806835       or evenly spaced chapters 'segment' seconds through the file"""
    807836
    808837
    def getDefaultParametersFromMythTVDB():  
    845874    sqlstatement="""SELECT value, data FROM settings WHERE value IN(
    846875                        'DBSchemaVer',
    847876                        'ISO639Language0',
    848                         'ISO639Language1') 
     877                        'ISO639Language1')
    849878                    OR (hostname=%s AND value IN(
    850879                        'VideoStartupDir',
    851880                        'GalleryDir',
    def getOptions(options):  
    939968
    940969def expandItemText(infoDOM, text, itemnumber, pagenumber, keynumber,chapternumber, chapterlist ):
    941970    """Replaces keywords in a string with variables from the XML and filesystem"""
    942     text=string.replace(text,"%page","%s" % pagenumber)
     971    text=text.replace("%page","%s" % pagenumber)
    943972
    944973    #See if we can use the thumbnail/cover file for videos if there is one.
    945974    if getText( infoDOM.getElementsByTagName("coverfile")[0]) =="":
    946         text=string.replace(text,"%thumbnail", os.path.join( getItemTempPath(itemnumber), "title.jpg"))
     975        text=text.replace("%thumbnail", os.path.join( getItemTempPath(itemnumber), "title.jpg"))
    947976    else:
    948         text=string.replace(text,"%thumbnail", getText( infoDOM.getElementsByTagName("coverfile")[0]) )
     977        text=text.replace("%thumbnail", getText( infoDOM.getElementsByTagName("coverfile")[0]) )
    949978
    950     text=string.replace(text,"%itemnumber","%s" % itemnumber )
    951     text=string.replace(text,"%keynumber","%s" % keynumber )
     979    text=text.replace("%itemnumber","%s" % itemnumber )
     980    text=text.replace("%keynumber","%s" % keynumber )
    952981
    953     text=string.replace(text,"%title",getText( infoDOM.getElementsByTagName("title")[0]) )
    954     text=string.replace(text,"%subtitle",getText( infoDOM.getElementsByTagName("subtitle")[0]) )
    955     text=string.replace(text,"%description",getText( infoDOM.getElementsByTagName("description")[0]) )
    956     text=string.replace(text,"%type",getText( infoDOM.getElementsByTagName("type")[0]) )
     982    text=text.replace("%title",getText( infoDOM.getElementsByTagName("title")[0]) )
     983    text=text.replace("%subtitle",getText( infoDOM.getElementsByTagName("subtitle")[0]) )
     984    text=text.replace("%description",getText( infoDOM.getElementsByTagName("description")[0]) )
     985    text=text.replace("%type",getText( infoDOM.getElementsByTagName("type")[0]) )
    957986
    958     text=string.replace(text,"%recordingdate",getText( infoDOM.getElementsByTagName("recordingdate")[0]) )
    959     text=string.replace(text,"%recordingtime",getText( infoDOM.getElementsByTagName("recordingtime")[0]) )
     987    text=text.replace("%recordingdate",getText( infoDOM.getElementsByTagName("recordingdate")[0]) )
     988    text=text.replace("%recordingtime",getText( infoDOM.getElementsByTagName("recordingtime")[0]) )
    960989
    961     text=string.replace(text,"%duration", getFormatedLengthOfVideo(itemnumber))
     990    text=text.replace("%duration", getFormatedLengthOfVideo(itemnumber))
    962991
    963     text=string.replace(text,"%myfolder",getThemeFile(themeName,""))
     992    text=text.replace("%myfolder",getThemeFile(themeName,""))
    964993
    965994    if chapternumber>0:
    966         text=string.replace(text,"%chapternumber","%s" % chapternumber )
    967         text=string.replace(text,"%chaptertime","%s" % chapterlist[chapternumber - 1] )
    968         text=string.replace(text,"%chapterthumbnail", os.path.join( getItemTempPath(itemnumber), "chapter-%s.jpg" % chapternumber))
     995        text=text.replace("%chapternumber","%s" % chapternumber )
     996        text=text.replace("%chaptertime","%s" % chapterlist[chapternumber - 1] )
     997        text=text.replace(text,"%chapterthumbnail", os.path.join( getItemTempPath(itemnumber), "chapter-%s.jpg" % chapternumber))
    969998
    970999    return text
    9711000
    def intelliDraw(drawer, text, font, containerWidth):  
    9941023    #write("containerWidth: %s" % containerWidth)
    9951024    words = text.split()
    9961025    lines = [] # prepare a return argument
    997     lines.append(words) 
     1026    lines.append(words)
    9981027    finished = False
    9991028    line = 0
    10001029    while not finished:
    def intelliDraw(drawer, text, font, containerWidth):  
    10081037            if drawer.textsize(' '.join(thistext),font.getFont())[0] > containerWidth:
    10091038                # this is the heart of the algorithm: we pop words off the current
    10101039                # sentence until the width is ok, then in the next outer loop
    1011                 # we move on to the next sentence. 
     1040                # we move on to the next sentence.
    10121041                if str(thistext).find(' ') != -1:
    10131042                    newline.insert(0,thistext.pop(-1))
    10141043                else:
    def paintButton(draw, bgimage, bgimagemask, node, infoDOM, itemnum, page,  
    11331162#############################################################
    11341163# Paint some theme text on to an image
    11351164
    1136 def paintText(draw, image, text, node, color = None, 
     1165def paintText(draw, image, text, node, color = None,
    11371166              x = None, y = None, width = None, height = None):
    11381167    """Takes a piece of text and draws it onto an image inside a bounding box."""
    11391168    #The text is wider than the width of the bounding box
    11401169
    11411170    if x == None:
    1142         x = getScaledAttribute(node, "x") 
     1171        x = getScaledAttribute(node, "x")
    11431172        y = getScaledAttribute(node, "y")
    11441173        width = getScaledAttribute(node, "w")
    11451174        height = getScaledAttribute(node, "h")
    def paintImage(filename, maskfilename, imageDom, destimage, stretch=True):  
    12301259    (imgw, imgh) = picture.size
    12311260    write("Image (%s, %s) into space of (%s, %s) at (%s, %s)" % (imgw, imgh, w, h, xpos, ypos), False)
    12321261
    1233     # the theme can override the default stretch behaviour 
    1234     if imageDom.hasAttribute("stretch"): 
     1262    # the theme can override the default stretch behaviour
     1263    if imageDom.hasAttribute("stretch"):
    12351264        if imageDom.attributes["stretch"].value == "True":
    12361265            stretch = True
    12371266        else:
    def paintImage(filename, maskfilename, imageDom, destimage, stretch=True):  
    12721301    picture = picture.resize((imgw, imgh))
    12731302    picture = picture.convert("RGBA")
    12741303
    1275     if maskfilename <> None and doesFileExist(maskfilename):
     1304    if maskfilename != None and doesFileExist(maskfilename):
    12761305        maskpicture = Image.open(maskfilename, "r").resize((imgw, imgh))
    12771306        maskpicture = maskpicture.convert("RGBA")
    12781307    else:
    def paintImage(filename, maskfilename, imageDom, destimage, stretch=True):  
    12801309
    12811310    destimage.paste(picture, (xpos, ypos), maskpicture)
    12821311    del picture
    1283     if maskfilename <> None and doesFileExist(maskfilename):
     1312    if maskfilename != None and doesFileExist(maskfilename):
    12841313        del maskpicture
    12851314
    12861315    write ("Added image %s" % filename)
    def paintImage(filename, maskfilename, imageDom, destimage, stretch=True):  
    12941323def checkBoundaryBox(boundarybox, node):
    12951324    # We work out how much space all of our graphics and text are taking up
    12961325    # in a bounding rectangle so that we can use this as an automatic highlight
    1297     # on the DVD menu   
     1326    # on the DVD menu
    12981327    if getText(node.attributes["static"]) == "False":
    12991328        if getScaledAttribute(node, "x") < boundarybox[0]:
    13001329            boundarybox = getScaledAttribute(node, "x"), boundarybox[1], boundarybox[2], boundarybox[3]
    def getFileInformation(file, folder):  
    13891418        if file.attributes["type"].value=="recording":
    13901419            filename = file.attributes["filename"].value
    13911420            try:
    1392                 rec = DB.searchRecorded(basename=os.path.basename(filename)).next()
     1421                rec = next(DB.searchRecorded(basename=os.path.basename(filename)))
    13931422            except StopIteration:
    13941423                fatalError("Failed to get recording details from the DB for %s" % filename)
    13951424
    def getFileInformation(file, folder):  
    13971426            data.recordingtime = rec.starttime.isoformat()
    13981427            data.recordingdate = rec.starttime.isoformat()
    13991428
    1400             cutlist = rec.markup.getcutlist()
     1429            cutlist = list(rec.markup.getcutlist())    ### XXX should be fixed in Python Bindings for python3
    14011430            if len(cutlist):
    14021431                data.hascutlist = 'yes'
    14031432                if file.attributes["usecutlist"].value == "0" and addCutlistChapters == True:
    def getFileInformation(file, folder):  
    14121441    elif file.attributes["type"].value=="recording":
    14131442        filename = file.attributes["filename"].value
    14141443        try:
    1415             rec = DB.searchRecorded(basename=os.path.basename(filename)).next()
     1444            rec = next(DB.searchRecorded(basename=os.path.basename(filename)))
    14161445        except StopIteration:
    14171446            fatalError("Failed to get recording details from the DB for %s" % filename)
    14181447
    def getFileInformation(file, folder):  
    14281457        data.chanid         = rec.chanid
    14291458        data.starttime      = rec.starttime.utcisoformat()
    14301459
    1431         cutlist = rec.markup.getcutlist()
     1460        cutlist = list(rec.markup.getcutlist())  ### XXX should be fixed in Python Bindings for python3
    14321461        if len(cutlist):
    14331462            data.hascutlist = 'yes'
    14341463            if file.attributes["usecutlist"].value == "0" and addCutlistChapters == True:
    def getFileInformation(file, folder):  
    14431472    elif file.attributes["type"].value=="video":
    14441473        filename = file.attributes["filename"].value
    14451474        try:
    1446             vid = MVID.searchVideos(file=filename).next()
     1475            vid = next(MVID.searchVideos(file=filename))
    14471476        except StopIteration:
    14481477            vid = Video.fromFilename(filename)
    14491478
    def getFileInformation(file, folder):  
    14891518
    14901519        data.thumblist = ','.join(thumblist)
    14911520
    1492     for k,v in data.items():
     1521    for k,v in list(data.items()):
    14931522        write( "Node = %s, Data = %s" % (k, v))
    14941523        node = infoDOM.createElement(k)
    14951524        # v may be either an integer. Therefore we have to
    def getFileInformation(file, folder):  
    15071536# Write an xml file to disc
    15081537
    15091538def WriteXMLToFile(myDOM, filename):
     1539
    15101540    #Save the XML file to disk for use later on
    15111541    f=open(filename, 'w')
    15121542
    1513     if sys.hexversion >= 0x020703F0:
     1543    if sys.hexversion >= 0x03000000:
     1544        f.write(myDOM.toprettyxml(indent="    ", encoding="UTF-8").decode())
     1545    elif sys.hexversion >= 0x020703F0:
    15141546        f.write(myDOM.toprettyxml(indent="    ", encoding="UTF-8"))
    15151547    else:
    15161548        f.write(myDOM.toxml(encoding="UTF-8"))
    def multiplexMPEGStream(video, audio1, audio2, destination, syncOffset):  
    15881620
    15891621    write("Multiplexing MPEG stream to %s" % destination)
    15901622
    1591     # no need to use a sync offset if projectx was used to demux the streams 
     1623    # no need to use a sync offset if projectx was used to demux the streams
    15921624    if useprojectx:
    15931625        syncOffset = 0
    15941626    else:
    def multiplexMPEGStream(video, audio1, audio2, destination, syncOffset):  
    16311663
    16321664    if not doesFileExist(audio2):
    16331665        write("Available streams - video and one audio stream")
     1666        write("running %s -M -f 8 -v 0 --sync-offset %sms -o %s %s %s" %(path_mplex[0], syncOffset, destination, video, audio1))
    16341667        result=os.spawnlp(mode, path_mplex[0], path_mplex[1],
    16351668                    '-M',
    16361669                    '-f', '8',
    def multiplexMPEGStream(video, audio1, audio2, destination, syncOffset):  
    16631696        write("Checking integrity of subtitle pngs")
    16641697        command = quoteCmdArg(os.path.join(scriptpath, "testsubtitlepngs.sh")) + " " + quoteCmdArg(os.path.dirname(destination) + "/stream.d/spumux.xml")
    16651698        result = runCommand(command)
    1666         if result<>0:
     1699        if result!=0:
    16671700            fatalError("Failed while running testsubtitlepngs.sh - %s" % command)
    16681701
    16691702        write("Running spumux to add subtitles")
    16701703        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"))
    16711704        result = runCommand(command)
    1672         if result<>0:
     1705        if result!=0:
    16731706            nonfatalError("Failed while running spumux.\n"
    16741707                          "Command was - %s.\n"
    16751708                          "Look in the full log to see why it failed" % command)
    def getStreamInformation(filename, xmlFilename, lenMethod):  
    16911724
    16921725    result = runCommand(command)
    16931726
    1694     if result <> 0:
     1727    if result != 0:
    16951728        fatalError("Failed while running mytharchivehelper to get stream information.\n"
    16961729                   "Result: %d, Command was %s" % (result, command))
    16971730
    def runMythtranscode(chanid, starttime, destination, usecutlist, localfile):  
    17301763    """Use mythtranscode to cut commercials and/or clean up an mpeg2 file"""
    17311764
    17321765    try:
    1733         rec = DB.searchRecorded(chanid=chanid, starttime=starttime).next()
     1766        rec = next(DB.searchRecorded(chanid=chanid, starttime=starttime))
    17341767        cutlist = rec.markup.getcutlist()
    17351768    except StopIteration:
    17361769        cutlist = []
    17371770
    17381771    cutlist_s = ""
    1739     if usecutlist and len(cutlist):
     1772    if usecutlist and len(list(cutlist)):
    17401773        cutlist_s = "'"
    17411774        for cut in cutlist:
    17421775            cutlist_s += ' %d-%d ' % cut
    def runMythtranscode(chanid, starttime, destination, usecutlist, localfile):  
    17701803def generateProjectXCutlist(chanid, starttime, folder):
    17711804    """generate cutlist_x.txt for ProjectX"""
    17721805
    1773     rec = DB.searchRecorded(chanid=chanid, starttime=starttime).next()
     1806    rec = next(DB.searchRecorded(chanid=chanid, starttime=starttime))
    17741807    starttime = rec.starttime.utcisoformat()
    17751808    cutlist = rec.markup.getcutlist()
    17761809
    1777     if len(cutlist):
     1810    if len(list(cutlist)):
    17781811        with codecs.open(os.path.join(folder, "cutlist_x.txt"), 'w', 'utf-8') as cutlist_f:
    17791812            cutlist_f.write("CollectionPanel.CutMode=2\n")
    17801813            i = 0
    17811814            for cut in cutlist:
    17821815                # we need to reverse the cutlist because ProjectX wants to know
    17831816                # the bits to keep not what to cut
    1784                
     1817
    17851818                if i == 0:
    17861819                    if cut[0] != 0:
    17871820                        cutlist_f.write('0\n%d\n' % cut[0])
    def extractVideoFrame(source, destination, seconds):  
    19792012
    19802013        command = "mytharchivehelper -q -q --createthumbnail --infile %s --thumblist '%s' --outfile %s" % (quoteCmdArg(source), seconds, quoteCmdArg(destination))
    19812014        result = runCommand(command)
    1982         if result <> 0:
     2015        if result != 0:
    19832016            fatalError("Failed while running mytharchivehelper to get thumbnails.\n"
    19842017                       "Result: %d, Command was %s" % (result, command))
    19852018    try:
    19862019        myimage=Image.open(destination,"r")
    19872020
    1988         if myimage.format <> "JPEG":
     2021        if myimage.format != "JPEG":
    19892022            write( "Something went wrong with thumbnail capture - " + myimage.format)
    1990             return (0L,0L)
     2023            return (long(0),long(0))
    19912024        else:
    19922025            return myimage.size
    19932026    except IOError:
    1994         return (0L, 0L)
     2027        return (long(0),long(0))
    19952028
    19962029#############################################################
    19972030# Grabs a list of single frames from a file
    def extractVideoFrames(source, destination, thumbList):  
    20032036    command = "mytharchivehelper -q -q --createthumbnail --infile %s --thumblist '%s' --outfile %s" % (quoteCmdArg(source), thumbList, quoteCmdArg(destination))
    20042037    write(command)
    20052038    result = runCommand(command)
    2006     if result <> 0:
     2039    if result != 0:
    20072040        fatalError("Failed while running mytharchivehelper to get thumbnails.\n"
    20082041                   "Result: %d, Command was %s" % (result, command))
    20092042
    def encodeVideoToMPEG2(source, destvideofile, video, audio1, audio2, aspectratio  
    20832116    else:
    20842117        passLog = os.path.join(getTempPath(), 'pass')
    20852118
    2086         pass1 = string.replace(command, "%passno","1")
    2087         pass1 = string.replace(pass1, "%passlogfile", quoteCmdArg(passLog))
     2119        pass1 = command.replace("%passno","1")
     2120        pass1 = pass1.replace("%passlogfile", quoteCmdArg(passLog))
    20882121        write("Pass 1 - " + pass1)
    20892122        result = runCommand(pass1)
    20902123
    def encodeVideoToMPEG2(source, destvideofile, video, audio1, audio2, aspectratio  
    20952128        if os.path.exists(destvideofile):
    20962129            os.remove(destvideofile)
    20972130
    2098         pass2 = string.replace(command, "%passno","2")
    2099         pass2 = string.replace(pass2, "%passlogfile", passLog)
     2131        pass2 = command.replace("%passno","2")
     2132        pass2 = pass2.replace("%passlogfile", passLog)
    21002133        write("Pass 2 - " + pass2)
    21012134        result = runCommand(pass2)
    21022135
    def encodeNuvToMPEG2(chanid, starttime, mediafile, destvideofile, folder, profil  
    21172150    profileNode = findEncodingProfile(profile)
    21182151    parameters = profileNode.getElementsByTagName("parameter")
    21192152
    2120     # default values - will be overriden by values from the profile 
     2153    # default values - will be overriden by values from the profile
    21212154    outvideobitrate = "5000k"
    21222155    if videomode == "ntsc":
    21232156        outvideores = "720x480"
    def encodeNuvToMPEG2(chanid, starttime, mediafile, destvideofile, folder, profil  
    21982231    if cpuCount > 1:
    21992232        command += "-threads %d " % cpuCount
    22002233
    2201     command += "-f s16le -ar %s -ac %s -i %s " % (samplerate, channels, quoteCmdArg(os.path.join(folder, "audout"))) 
     2234    command += "-f s16le -ar %s -ac %s -i %s " % (samplerate, channels, quoteCmdArg(os.path.join(folder, "audout")))
    22022235    command += "-f rawvideo -pix_fmt yuv420p -s %s -aspect %s -r %s " % (videores, aspectratio, fps)
    22032236    command += "-i %s " % quoteCmdArg(os.path.join(folder, "vidout"))
    22042237    command += "-aspect %s -r %s " % (aspectratio, fps)
    def runDVDAuthor():  
    22352268    write( "Starting dvdauthor")
    22362269    checkCancelFlag()
    22372270    result=os.spawnlp(os.P_WAIT, path_dvdauthor[0],path_dvdauthor[1],'-x',os.path.join(getTempPath(),'dvdauthor.xml'))
    2238     if result<>0:
     2271    if result!=0:
    22392272        fatalError("Failed while running dvdauthor. Result: %d" % result)
    22402273    write( "Finished  dvdauthor")
    22412274
    def CreateDVDISO(title):  
    22522285
    22532286    result = runCommand(command)
    22542287
    2255     if result<>0:
     2288    if result!=0:
    22562289        fatalError("Failed while running mkisofs.\n"
    22572290                   "Command was %s" % command)
    22582291
    22592292    write("Finished creating ISO image")
    22602293
    22612294#############################################################
    2262 # Burns the contents of a directory to create a DVD 
     2295# Burns the contents of a directory to create a DVD
    22632296
    22642297
    22652298def BurnDVDISO(title):
    def BurnDVDISO(title):  
    23142347            except:
    23152348              write("Sending command ", action, " to drive failed", False)
    23162349              res = False
    2317             os.close(f) 
    2318         return res 
     2350            os.close(f)
     2351        return res
    23192352    def waitForDrive():
    23202353        tries = 0
    23212354        while drivestatus() == CDROM.CDS_DRIVE_NOT_READY:
    def BurnDVDISO(title):  
    23632396            result = runCommand(command)
    23642397            if result == 0:
    23652398                finished = True
    2366                
     2399
    23672400                # Wait till the drive is not busy any longer
    23682401                f = os.open(dvddrivepath, os.O_RDONLY | os.O_NONBLOCK)
    23692402                busy = True
    def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):  
    24272460        command = "mythreplex --demux --fix_sync -t TS -o %s " % quoteCmdArg(folder + "/stream")
    24282461        command += "-v %d " % (video[VIDEO_ID])
    24292462
    2430         if audio1[AUDIO_ID] != -1: 
     2463        if audio1[AUDIO_ID] != -1:
    24312464            if audio1[AUDIO_CODEC] == 'MP2':
    24322465                command += "-a %d " % (audio1[AUDIO_ID])
    24332466            elif audio1[AUDIO_CODEC] == 'AC3':
    def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):  
    24352468            elif audio1[AUDIO_CODEC] == 'EAC3':
    24362469                command += "-c %d " % (audio1[AUDIO_ID])
    24372470
    2438         if audio2[AUDIO_ID] != -1: 
     2471        if audio2[AUDIO_ID] != -1:
    24392472            if audio2[AUDIO_CODEC] == 'MP2':
    24402473                command += "-a %d " % (audio2[AUDIO_ID])
    24412474            elif audio2[AUDIO_CODEC] == 'AC3':
    def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):  
    24472480        command = "mythreplex --demux --fix_sync -o %s " % quoteCmdArg(folder + "/stream")
    24482481        command += "-v %d " % (video[VIDEO_ID] & 255)
    24492482
    2450         if audio1[AUDIO_ID] != -1: 
     2483        if audio1[AUDIO_ID] != -1:
    24512484            if audio1[AUDIO_CODEC] == 'MP2':
    24522485                command += "-a %d " % (audio1[AUDIO_ID] & 255)
    24532486            elif audio1[AUDIO_CODEC] == 'AC3':
    def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):  
    24562489                command += "-c %d " % (audio1[AUDIO_ID] & 255)
    24572490
    24582491
    2459         if audio2[AUDIO_ID] != -1: 
     2492        if audio2[AUDIO_ID] != -1:
    24602493            if audio2[AUDIO_CODEC] == 'MP2':
    24612494                command += "-a %d " % (audio2[AUDIO_ID] & 255)
    24622495            elif audio2[AUDIO_CODEC] == 'AC3':
    def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):  
    24702503
    24712504    result = runCommand(command)
    24722505
    2473     if result<>0:
     2506    if result!=0:
    24742507        fatalError("Failed while running mythreplex. Command was %s" % command)
    24752508
    24762509#############################################################
    def runM2VRequantiser(source,destination,factor):  
    24862519    command += " %s "  % M2Vsize0
    24872520    command += " <  %s " % quoteCmdArg(source)
    24882521    command += " >  %s " % quoteCmdArg(destination)
    2489  
     2522
    24902523    write("Running: " + command)
    24912524    result = runCommand(command)
    2492     if result<>0:
     2525    if result!=0:
    24932526        fatalError("Failed while running M2VRequantiser. Command was %s" % command)
    24942527
    24952528    M2Vsize1 = os.path.getsize(destination)
    2496        
     2529
    24972530    write("M2Vsize after requant is  %.2f Mb " % (float(M2Vsize1)/mega))
    24982531    fac1=float(M2Vsize0) / float(M2Vsize1)
    24992532    write("Factor demanded %.5f, achieved %.5f, ratio %.5f " % ( factor, fac1, fac1/factor))
    25002533
    25012534#############################################################
    2502 # Calculates the total size of all the video, audio and menu files 
     2535# Calculates the total size of all the video, audio and menu files
    25032536
    25042537def calculateFileSizes(files):
    25052538    """ Returns the sizes of all video, audio and menu files"""
    def calculateFileSizes(files):  
    25152548        #Process this file
    25162549        file=os.path.join(folder,"stream.mv2")
    25172550        #Get size of vobfile in MBytes
    2518         totalvideosize+=os.path.getsize(file) 
     2551        totalvideosize+=os.path.getsize(file)
    25192552
    25202553        #Get size of audio track 1
    25212554        if doesFileExist(os.path.join(folder,"stream0.ac3")):
    2522             totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.ac3")) 
     2555            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.ac3"))
    25232556        if doesFileExist(os.path.join(folder,"stream0.mp2")):
    2524             totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.mp2")) 
     2557            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream0.mp2"))
    25252558
    2526         #Get size of audio track 2 if available 
     2559        #Get size of audio track 2 if available
    25272560        if doesFileExist(os.path.join(folder,"stream1.ac3")):
    2528             totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.ac3")) 
     2561            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.ac3"))
    25292562        if doesFileExist(os.path.join(folder,"stream1.mp2")):
    2530             totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.mp2")) 
     2563            totalaudiosize+=os.path.getsize(os.path.join(folder,"stream1.mp2"))
    25312564
    25322565        # add chapter menu if available
    25332566        if doesFileExist(os.path.join(getTempPath(),"chaptermenu-%s.mpg" % filecount)):
    2534             totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"chaptermenu-%s.mpg" % filecount)) 
     2567            totalmenusize+=os.path.getsize(os.path.join(getTempPath(),"chaptermenu-%s.mpg" % filecount))
    25352568
    25362569        # add details page if available
    25372570        if doesFileExist(os.path.join(getTempPath(),"details-%s.mpg" % filecount)):
    def calculateFileSizes(files):  
    25472580########################################
    25482581#returns total size of bitrate-limited m2v files
    25492582
    2550 def total_mv2_brl(files,rate): 
    2551     tvsize=0 
     2583def total_mv2_brl(files,rate):
     2584    tvsize=0
    25522585    filecount=0
    25532586    for node in files:
    25542587        filecount+=1
    def total_mv2_brl(files,rate):  
    25572590        file=os.path.join(folder,"stream.mv2")
    25582591        progvsize=os.path.getsize(file)
    25592592        progvbitrate=progvsize/progduration
    2560         if progvbitrate>rate : 
     2593        if progvbitrate>rate :
    25612594            tvsize+=progduration*rate
    25622595        else:
    25632596            tvsize+=progvsize
    25642597
    2565     return tvsize   
     2598    return tvsize
    25662599
    25672600#########################################
    2568 # Uses requantiser if available to shrink the video streams so 
     2601# Uses requantiser if available to shrink the video streams so
    25692602# they will fit on a DVD
    25702603
    25712604def performMPEG2Shrink(files,dvdrsize):
    def performMPEG2Shrink(files,dvdrsize):  
    25822615
    25832616    #Subtract the audio, menus and packaging overhead from the size of the disk (we cannot shrink this further)
    25842617    mv2space=((dvdrsize*mega-totalmenusize)/fudge_pack)-totalaudiosize
    2585  
     2618
    25862619    if mv2space<0:
    25872620        fatalError("Audio and menu files are too big. No room for video. Giving up!")
    25882621
    def performMPEG2Shrink(files,dvdrsize):  
    26022635            vsize+=os.path.getsize(file)
    26032636            duration+=getLengthOfVideo(filecount)
    26042637
    2605         #We need to shrink the video files to fit into the space available.  It seems sensible 
    2606         #to do this by imposing a common upper limit on the mean video bit-rate of each recording; 
     2638        #We need to shrink the video files to fit into the space available.  It seems sensible
     2639        #to do this by imposing a common upper limit on the mean video bit-rate of each recording;
    26072640        #this will not further reduce the visual quality of any that were transmitted at lower bit-rates.
    26082641
    2609         #Now find the bit-rate limit by iteration between initially defined upper and lower bounds. 
     2642        #Now find the bit-rate limit by iteration between initially defined upper and lower bounds.
    26102643        #The code is based on 'rtbis' from Numerical Recipes by W H Press et al., CUP.
    2611        
     2644
    26122645        #A small multiple of the average input bit-rate should be ok as the initial upper bound,
    26132646        #(although a fixed value or one related to the max value could be used), and zero as the lower bound.
    26142647        #The function relating bit-rate upper limit to total file size is smooth and monotonic,
    2615         #so there should be no convergence problem. 
    2616      
     2648        #so there should be no convergence problem.
     2649
    26172650        vrLo=0.0
    26182651        vrHi=3.0*float(vsize)/duration
    2619        
     2652
    26202653        vrate=vrLo
    26212654        vrinc=vrHi-vrLo
    26222655        count=0
    def performMPEG2Shrink(files,dvdrsize):  
    26282661            testsize=total_mv2_brl(files,vrtest)
    26292662            if (testsize<mv2space):
    26302663                vrate=vrtest
    2631            
     2664
    26322665        write("vrate %.3f kb/s, testsize %.4f , mv2space %.4f Mb " % ((vrate)/1000.0, (testsize)/mega, (mv2space)/mega) )
    26332666        filecount=0
    26342667        for node in files:
    def createDVDAuthorXML(screensize, numberofitems):  
    27752808        #g4 holds the menu page last displayed
    27762809        pre = dvddom.createElement("pre")
    27772810        pre.appendChild(dvddom.createTextNode("{button=g2*1024;g4=%s;}" % page))
    2778         menupgc.appendChild(pre)   
     2811        menupgc.appendChild(pre)
    27792812
    27802813        vob = dvddom.createElement("vob")
    27812814        vob.setAttribute("file",os.path.join(getTempPath(),"menu-%s.mpg" % page))
    def createDVDAuthorXML(screensize, numberofitems):  
    28332866            elif chaptermenuAspectRatio == "16:9":
    28342867                video.setAttribute("aspect", "16:9")
    28352868                video.setAttribute("widescreen", "nopanscan")
    2836             else: 
     2869            else:
    28372870                # use same aspect ratio as the video
    28382871                if getAspectRatioOfVideo(itemnum) > aspectRatioThreshold:
    28392872                    video.setAttribute("aspect", "16:9")
    def createDVDAuthorXML(screensize, numberofitems):  
    28492882
    28502883                pre = dvddom.createElement("pre")
    28512884                mymenupgc.appendChild(pre)
    2852                 if wantDetailsPage: 
     2885                if wantDetailsPage:
    28532886                    pre.appendChild(dvddom.createTextNode("{button=s7 - 1 * 1024;}"))
    28542887                else:
    28552888                    pre.appendChild(dvddom.createTextNode("{button=s7 * 1024;}"))
    28562889
    28572890                vob = dvddom.createElement("vob")
    28582891                vob.setAttribute("file",os.path.join(getTempPath(),"chaptermenu-%s.mpg" % itemnum))
    2859                 mymenupgc.appendChild(vob)   
     2892                mymenupgc.appendChild(vob)
    28602893
    28612894                #Loop menu forever
    28622895                post = dvddom.createElement("post")
    28632896                post.appendChild(dvddom.createTextNode("jump cell 1;"))
    28642897                mymenupgc.appendChild(post)
    28652898
    2866                 # the first chapter MUST be 00:00:00 if its not dvdauthor adds it which 
     2899                # the first chapter MUST be 00:00:00 if its not dvdauthor adds it which
    28672900                # throws of the chapter selection - so make sure we add it if needed so we
    2868                 # can compensate for it in the chapter selection menu 
     2901                # can compensate for it in the chapter selection menu
    28692902                firstChapter = 0
    28702903                thumblist = createVideoChapters(itemnum, chapters, getLengthOfVideo(itemnum), False)
    28712904                chapterlist = string.split(thumblist, ",")
    def createDVDAuthorXML(screensize, numberofitems):  
    28762909                    #Add this recording to this page's menu...
    28772910                    button = dvddom.createElement("button")
    28782911                    button.setAttribute("name","%s" % x)
    2879                     if wantDetailsPage: 
     2912                    if wantDetailsPage:
    28802913                        button.appendChild(dvddom.createTextNode("jump title %s chapter %s;" % (1, firstChapter + x + 1)))
    28812914                    else:
    28822915                        button.appendChild(dvddom.createTextNode("jump title %s chapter %s;" % (1, firstChapter + x)))
    def createDVDAuthorXML(screensize, numberofitems):  
    29382971                    thumblist = '00:00:00,' + thumblist
    29392972                vob.setAttribute("chapters", thumblist)
    29402973            else:
    2941                 vob.setAttribute("chapters", 
     2974                vob.setAttribute("chapters",
    29422975                    createVideoChaptersFixedLength(itemnum,
    2943                                                    chapterLength, 
     2976                                                   chapterLength,
    29442977                                                   getLengthOfVideo(itemnum)))
    29452978
    29462979            vob.setAttribute("file",os.path.join(getItemTempPath(itemnum),"final.vob"))
    def createDVDAuthorXML(screensize, numberofitems):  
    30063039
    30073040    pre = dvddom.createElement("pre")
    30083041    pre.appendChild(dvddom.createTextNode(dvdcode))
    3009     menupgc.appendChild(pre)   
     3042    menupgc.appendChild(pre)
    30103043
    30113044    if wantIntro:
    30123045        #Menu creation is finished so we know how many pages were created
    def createDVDAuthorXML(screensize, numberofitems):  
    30183051            dvdcode+="jump menu %s;" % (page + 1)
    30193052            if (page>1):
    30203053                dvdcode+=" else "
    3021         dvdcode+="}"       
     3054        dvdcode+="}"
    30223055        vmgm_pre_node.appendChild(dvddom.createTextNode(dvdcode))
    30233056
    30243057    #write(dvddom.toprettyxml())
    def createDVDAuthorXML(screensize, numberofitems):  
    30263059    WriteXMLToFile (dvddom,os.path.join(getTempPath(),"dvdauthor.xml"))
    30273060
    30283061    #Destroy the DOM and free memory
    3029     dvddom.unlink()   
     3062    dvddom.unlink()
    30303063
    30313064#############################################################
    30323065# Creates the DVDAuthor xml file used to create a DVD with no main menu
    def createDVDAuthorXMLNoMenus(screensize, numberofitems):  
    32203253    dvddom.unlink()
    32213254
    32223255#############################################################
    3223 # Creates the directory to hold the preview images for an animated menu 
     3256# Creates the directory to hold the preview images for an animated menu
    32243257
    32253258def createEmptyPreviewFolder(videoitem):
    32263259    previewfolder = os.path.join(getItemTempPath(videoitem), "preview")
    def generateVideoPreview(videoitem, itemonthispage, menuitem, starttime, menulen  
    32643297                #see if this graphics item has a mask
    32653298                if node.hasAttribute("mask"):
    32663299                    imagemaskfilename = getThemeFile(themeName, node.attributes["mask"].value)
    3267                     if node.attributes["mask"].value <> "" and doesFileExist(imagemaskfilename):
     3300                    if node.attributes["mask"].value != "" and doesFileExist(imagemaskfilename):
    32683301                        maskpicture = Image.open(imagemaskfilename,"r").resize((width, height))
    32693302                        maskpicture = maskpicture.convert("RGBA")
    32703303
    def generateVideoPreview(videoitem, itemonthispage, menuitem, starttime, menulen  
    32763309def drawThemeItem(page, itemsonthispage, itemnum, menuitem, bgimage, draw,
    32773310                  bgimagemask, drawmask, highlightcolor, spumuxdom, spunode,
    32783311                  numberofitems, chapternumber, chapterlist):
    3279     """Draws text and graphics onto a dvd menu, called by 
     3312    """Draws text and graphics onto a dvd menu, called by
    32803313       createMenu and createChapterMenu"""
    32813314
    32823315    #Get the XML containing information about this item
    def drawThemeItem(page, itemsonthispage, itemnum, menuitem, bgimage, draw,  
    32873320        fatalError("The info.xml file (%s) doesn't look right" %
    32883321                    os.path.join(getItemTempPath(itemnum),"info.xml"))
    32893322
    3290     #boundarybox holds the max and min dimensions for this item 
     3323    #boundarybox holds the max and min dimensions for this item
    32913324    #so we can auto build a menu highlight box
    32923325    boundarybox = 9999,9999,0,0
    32933326    wantHighlightBox = True
    def drawThemeItem(page, itemsonthispage, itemnum, menuitem, bgimage, draw,  
    33193352
    33203353                # see if an image mask exists
    33213354                maskfilename = None
    3322                 if node.hasAttribute("mask") and node.attributes["mask"].value <> "":
     3355                if node.hasAttribute("mask") and node.attributes["mask"].value != "":
    33233356                    maskfilename = getThemeFile(themeName, node.attributes["mask"].value)
    33243357
    3325                 # if this is a thumb image and is a MythVideo coverart image then preserve 
     3358                # if this is a thumb image and is a MythVideo coverart image then preserve
    33263359                # its aspect ratio unless overriden later by the theme
    33273360                if (node.attributes["filename"].value == "%thumbnail"
    33283361                  and getText(infoDOM.getElementsByTagName("coverfile")[0]) !=""):
    def drawThemeItem(page, itemsonthispage, itemnum, menuitem, bgimage, draw,  
    33663399                button.setAttribute("name","previous")
    33673400                button.setAttribute("x0","%s" % getScaledAttribute(node, "x"))
    33683401                button.setAttribute("y0","%s" % getScaledAttribute(node, "y"))
    3369                 button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") + 
     3402                button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") +
    33703403                                                getScaledAttribute(node, "w")))
    33713404                button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") +
    33723405                                                getScaledAttribute(node, "h")))
    def drawThemeItem(page, itemsonthispage, itemnum, menuitem, bgimage, draw,  
    33903423                button.setAttribute("name","next")
    33913424                button.setAttribute("x0","%s" % getScaledAttribute(node, "x"))
    33923425                button.setAttribute("y0","%s" % getScaledAttribute(node, "y"))
    3393                 button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") + 
     3426                button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") +
    33943427                                                 getScaledAttribute(node, "w")))
    3395                 button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") + 
     3428                button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") +
    33963429                                                 getScaledAttribute(node, "h")))
    33973430                spunode.appendChild(button)
    33983431
    def drawThemeItem(page, itemsonthispage, itemnum, menuitem, bgimage, draw,  
    34113444            button.setAttribute("name","playall")
    34123445            button.setAttribute("x0","%s" % getScaledAttribute(node, "x"))
    34133446            button.setAttribute("y0","%s" % getScaledAttribute(node, "y"))
    3414             button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") + 
     3447            button.setAttribute("x1","%s" % (getScaledAttribute(node, "x") +
    34153448                                             getScaledAttribute(node, "w")))
    34163449            button.setAttribute("y1","%s" % (getScaledAttribute(node, "y") +
    34173450                                             getScaledAttribute(node, "h")))
    def drawThemeItem(page, itemsonthispage, itemnum, menuitem, bgimage, draw,  
    34263459                # draw background if required
    34273460                paintBackground(bgimage, node)
    34283461
    3429                 paintButton(draw, bgimage, bgimagemask, node, infoDOM, 
    3430                             itemnum, page, itemsonthispage, chapternumber, 
     3462                paintButton(draw, bgimage, bgimagemask, node, infoDOM,
     3463                            itemnum, page, itemsonthispage, chapternumber,
    34313464                            chapterlist)
    34323465
    34333466                button = spumuxdom.createElement("button")
    def createMenu(screensize, screendpi, numberofitems):  
    36213654
    36223655        #now that the base background has been made and all the previews generated
    36233656        #we need to add the previews to the background
    3624         #Assumption: We assume that there is nothing in the location of where the items go 
     3657        #Assumption: We assume that there is nothing in the location of where the items go
    36253658        #(ie, no text on the images)
    36263659
    36273660        itemsonthispage = 0
    def createChapterMenu(screensize, screendpi, numberofitems):  
    38133846            chapter+=1
    38143847
    38153848            drawThemeItem(page, itemsperpage, page, menuitem,
    3816                         overlayimage, draw, 
     3849                        overlayimage, draw,
    38173850                        bgimagemask, drawmask, highlightcolor,
    38183851                        spumuxdom, spunode,
    38193852                        999, chapter, chapterlist)
    def createChapterMenu(screensize, screendpi, numberofitems):  
    38733906            aspect_ratio = '2'
    38743907        elif chaptermenuAspectRatio == "16:9":
    38753908            aspect_ratio = '3'
    3876         else: 
     3909        else:
    38773910            if getAspectRatioOfVideo(page) > aspectRatioThreshold:
    38783911                aspect_ratio = '3'
    38793912            else:
    def isMediaAVIFile(file):  
    40434076    return Magic=="RIFF"
    40444077
    40454078#############################################################
    4046 # checks to see if an audio stream need to be converted to ac3 
     4079# checks to see if an audio stream need to be converted to ac3
    40474080
    40484081def processAudio(folder):
    40494082    """encode audio to ac3 for better compression and compatability with NTSC players"""
    def selectStreams(folder):  
    41354168    for node in nodes:
    41364169        index = int(node.attributes["ffmpegindex"].value)
    41374170        lang = node.attributes["language"].value
    4138         format = string.upper(node.attributes["codec"].value)
     4171        format = node.attributes["codec"].value.upper()
    41394172        pid = int(node.attributes["id"].value)
    41404173        if lang == preferredlang1 and format == "AC3":
    41414174            if found:
    def selectStreams(folder):  
    41504183        for node in nodes:
    41514184            index = int(node.attributes["ffmpegindex"].value)
    41524185            lang = node.attributes["language"].value
    4153             format = string.upper(node.attributes["codec"].value)
     4186            format = node.attributes["codec"].value.upper()
    41544187            pid = int(node.attributes["id"].value)
    41554188            if lang == preferredlang1 and format == "MP2":
    41564189                if found:
    def selectStreams(folder):  
    41644197    if not found:
    41654198        for node in nodes:
    41664199            index = int(node.attributes["ffmpegindex"].value)
    4167             format = string.upper(node.attributes["codec"].value)
     4200            format = node.attributes["codec"].value.upper()
    41684201            pid = int(node.attributes["id"].value)
    41694202            if not found:
    41704203                audio1 = (index, format, pid, lang)
    def selectStreams(folder):  
    41834216        for node in nodes:
    41844217            index = int(node.attributes["ffmpegindex"].value)
    41854218            lang = node.attributes["language"].value
    4186             format = string.upper(node.attributes["codec"].value)
     4219            format = node.attributes["codec"].value.upper()
    41874220            pid = int(node.attributes["id"].value)
    41884221            if lang == preferredlang2 and format == "AC3":
    41894222                if found:
    def selectStreams(folder):  
    41984231            for node in nodes:
    41994232                index = int(node.attributes["ffmpegindex"].value)
    42004233                lang = node.attributes["language"].value
    4201                 format = string.upper(node.attributes["codec"].value)
     4234                format = node.attributes["codec"].value.upper()
    42024235                pid = int(node.attributes["id"].value)
    42034236                if lang == preferredlang2 and format == "MP2":
    42044237                    if found:
    def selectStreams(folder):  
    42124245        if not found:
    42134246            for node in nodes:
    42144247                index = int(node.attributes["ffmpegindex"].value)
    4215                 format = string.upper(node.attributes["codec"].value)
     4248                format = node.attributes["codec"].value.upper()
    42164249                pid = int(node.attributes["id"].value)
    42174250                if not found:
    42184251                    # make sure we don't choose the same stream as audio1
    def selectSubtitleStream(folder):  
    42664299    for node in nodes:
    42674300        index = int(node.attributes["ffmpegindex"].value)
    42684301        lang = node.attributes["language"].value
    4269         format = string.upper(node.attributes["codec"].value)
     4302        format = node.attributes["codec"].value.upper()
    42704303        pid = int(node.attributes["id"].value)
    42714304        if not found and lang == preferredlang1 and format == "dvbsub":
    42724305            subtitle = (index, format, pid, lang)
    def selectSubtitleStream(folder):  
    42774310        for node in nodes:
    42784311            index = int(node.attributes["ffmpegindex"].value)
    42794312            lang = node.attributes["language"].value
    4280             format = string.upper(node.attributes["codec"].value)
     4313            format = node.attributes["codec"].value.upper()
    42814314            pid = int(node.attributes["id"].value)
    42824315            if not found and lang == preferredlang2 and format == "dvbsub":
    42834316                subtitle = (index, format, pid, lang)
    def selectSubtitleStream(folder):  
    42874320    if not found:
    42884321        for node in nodes:
    42894322            index = int(node.attributes["ffmpegindex"].value)
    4290             format = string.upper(node.attributes["codec"].value)
     4323            format = node.attributes["codec"].value.upper()
    42914324            pid = int(node.attributes["id"].value)
    42924325            if not found:
    42934326                subtitle = (index, format, pid, lang)
    def getStreamList(folder):  
    44144447def isFileOkayForDVD(file, folder):
    44154448    """return true if the file is dvd compliant"""
    44164449
    4417     if not string.lower(getVideoCodec(folder)).startswith("mpeg2video"):
     4450    if not getVideoCodec(folder).lower().startswith("mpeg2video"):
    44184451        return False
    44194452
     4453
    44204454#    if string.lower(getAudioCodec(folder)) != "ac3" and encodeToAC3:
    44214455#        return False
    44224456
    def processFile(file, folder, count):  
    44544488
    44554489#############################################################
    44564490# process a single file ready for burning using mythtranscode/mythreplex
    4457 # to cut and demux 
     4491# to cut and demux
    44584492
    44594493def doProcessFile(file, folder, count):
    44604494    """Process a single video/recording file ready for burning."""
    def doProcessFile(file, folder, count):  
    44944528        #can only use mythtranscode to cut commercials on mpeg2 files
    44954529        write("File type is '%s'" % getFileType(folder))
    44964530        write("Video codec is '%s'" % getVideoCodec(folder))
    4497         if string.lower(getVideoCodec(folder)).startswith("mpeg2video"):
     4531        if (getVideoCodec(folder)).lower().startswith("mpeg2video"):
    44984532            if file.attributes["usecutlist"].value == "1" and getText(infoDOM.getElementsByTagName("hascutlist")[0]) == "yes":
    44994533                # Run from local file?
    45004534                if file.hasAttribute("localfilename"):
    def doProcessFile(file, folder, count):  
    45104544                    write("Failed to run mythtranscode to remove unwanted segments")
    45114545            else:
    45124546                #does the user always want to run recordings through mythtranscode?
    4513                 #may help to fix any errors in the file 
    4514                 if (alwaysRunMythtranscode == True or 
     4547                #may help to fix any errors in the file
     4548                if (alwaysRunMythtranscode == True or
    45154549                        (getFileType(folder) == "mpegts" and isFileOkayForDVD(file, folder))):
    45164550                    # Run from local file?
    45174551                    if file.hasAttribute("localfilename"):
    def doProcessFile(file, folder, count):  
    45274561                        write("Failed to run mythtranscode to fix any errors")
    45284562    else:
    45294563        #does the user always want to run mpeg2 files through mythtranscode?
    4530         #may help to fix any errors in the file 
     4564        #may help to fix any errors in the file
    45314565        write("File type is '%s'" % getFileType(folder))
    45324566        write("Video codec is '%s'" % getVideoCodec(folder))
    45334567
    45344568        if (alwaysRunMythtranscode == True and
    4535                 string.lower(getVideoCodec(folder)).startswith("mpeg2video") and
     4569                getVideoCodec(folder).lower().startswith("mpeg2video") and
    45364570                isFileOkayForDVD(file, folder)):
    45374571            if file.hasAttribute("localfilename"):
    45384572                localfile = file.attributes["localfilename"].value
    def doProcessFile(file, folder, count):  
    45794613                mediafile = -1
    45804614                chanid = getText(infoDOM.getElementsByTagName("chanid")[0])
    45814615                starttime = getText(infoDOM.getElementsByTagName("starttime")[0])
    4582                 usecutlist = (file.attributes["usecutlist"].value == "1" and 
     4616                usecutlist = (file.attributes["usecutlist"].value == "1" and
    45834617                            getText(infoDOM.getElementsByTagName("hascutlist")[0]) == "yes")
    45844618            else:
    45854619                chanid = -1
    def doProcessFile(file, folder, count):  
    46124646            else:
    46134647                profile = defaultEncodingProfile
    46144648
    4615             #do the re-encode 
     4649            #do the re-encode
    46164650            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video,
    46174651                            audio1, audio2, aspectratio, profile)
    46184652            mediafile = os.path.join(folder, 'newfile2.mpg')
    def doProcessFileProjectX(file, folder, count):  
    46774711
    46784712    #As part of this routine we need to pre-process the video this MAY mean:
    46794713    #1. encoding to mpeg2 (if its an avi for instance or isn't DVD compatible)
    4680     #2. removing commercials/cleaning up mpeg2 stream 
     4714    #2. removing commercials/cleaning up mpeg2 stream
    46814715    #3. selecting audio track(s) to use and encoding audio from mp2 into ac3
    46824716    #4. de-multiplexing into video and audio steams
    46834717
    def doProcessFileProjectX(file, folder, count):  
    47334767                mediafile = -1
    47344768                chanid = getText(infoDOM.getElementsByTagName("chanid")[0])
    47354769                starttime = getText(infoDOM.getElementsByTagName("starttime")[0])
    4736                 usecutlist = (file.attributes["usecutlist"].value == "1" and 
     4770                usecutlist = (file.attributes["usecutlist"].value == "1" and
    47374771                            getText(infoDOM.getElementsByTagName("hascutlist")[0]) == "yes")
    47384772            else:
    47394773                chanid = -1
    def doProcessFileProjectX(file, folder, count):  
    47664800            else:
    47674801                profile = defaultEncodingProfile
    47684802
    4769             #do the re-encode 
     4803            #do the re-encode
    47704804            encodeVideoToMPEG2(mediafile, os.path.join(folder, "newfile2.mpg"), video,
    47714805                            audio1, audio2, aspectratio, profile)
    47724806            mediafile = os.path.join(folder, 'newfile2.mpg')
    def doProcessFileProjectX(file, folder, count):  
    47874821    # now attempt to split the source file into video and audio parts
    47884822    # using projectX
    47894823
    4790     # If this is an mpeg2 myth recording and there is a cut list available and the 
     4824    # If this is an mpeg2 myth recording and there is a cut list available and the
    47914825    # user wants to use it run projectx to cut out commercials etc
    47924826    if file.attributes["type"].value == "recording":
    47934827        if file.attributes["usecutlist"].value == "1" and getText(infoDOM.getElementsByTagName("hascutlist")[0]) == "yes":
    def processJob(job):  
    49955029                filecount+=1
    49965030                folder=getItemTempPath(filecount)
    49975031                #Multiplex this file
    4998                 #(This also removes non-required audio feeds inside mpeg streams 
     5032                #(This also removes non-required audio feeds inside mpeg streams
    49995033                #(through re-multiplexing) we only take 1 video and 1 or 2 audio streams)
    50005034                pid=multiplexMPEGStream(os.path.join(folder,'stream.mv2'),
    50015035                        os.path.join(folder,'stream0'),
    def main():  
    51665200    videopath = defaultsettings.get("VideoStartupDir", None)
    51675201    gallerypath = defaultsettings.get("GalleryDir", None)
    51685202    musicpath = defaultsettings.get("MusicLocation", None)
    5169     videomode = string.lower(defaultsettings["MythArchiveVideoFormat"])
     5203    videomode = defaultsettings["MythArchiveVideoFormat"].lower()
    51705204    temppath = os.path.join(defaultsettings["MythArchiveTempDir"], "work")
    51715205    logpath = os.path.join(defaultsettings["MythArchiveTempDir"], "logs")
    51725206    write("temppath: " + temppath)
    def main():  
    52335267        try:
    52345268            fd = os.open(lckpath, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
    52355269            try:
    5236                 os.write(fd, "%d\n" % os.getpid())
     5270                os.write(fd, b"%d\n" % os.getpid())
    52375271                os.close(fd)
    52385272            except:
    52395273                os.remove(lckpath)
    52405274                raise
    5241         except OSError, e:
     5275        except OSError as e:
    52425276            if e.errno == errno.EEXIST:
    52435277                write("Lock file exists -- already running???")
    52445278                sys.exit(1)
    def main():  
    52815315            # remove our lock file
    52825316            os.remove(lckpath)
    52835317
    5284             # make sure the files we created are read/writable by all 
     5318            # make sure the files we created are read/writable by all
    52855319            os.system("chmod -R a+rw-x+X %s" % defaultsettings["MythArchiveTempDir"])
    52865320    except SystemExit:
    52875321        write("Terminated")