Index: mythplugins/mytharchive/mythburn/scripts/mythburn.py =================================================================== --- mythplugins/mytharchive/mythburn/scripts/mythburn.py (revision 27164) +++ mythplugins/mytharchive/mythburn/scripts/mythburn.py (working copy) @@ -67,15 +67,28 @@ #********************************************************************************* #Dont change the stuff below!! #********************************************************************************* -import os, string, socket, sys, getopt, traceback, signal +import os +import sys +import string +import getopt +import traceback +import signal import xml.dom.minidom -import Image, ImageDraw, ImageFont, ImageColor -import MySQLdb, codecs, unicodedata -import time, datetime, tempfile +import Image +import ImageDraw +import ImageFont +import ImageColor +import unicodedata +import time +import datetime +import tempfile from fcntl import ioctl import CDROM from shutil import copy +import MythTV +from MythTV.altdict import OrdDict + # media types (should match the enum in mytharchivewizard.h) DVD_SL = 0 DVD_DL = 1 @@ -169,6 +182,9 @@ # no. of processors we have access to cpuCount = 1 +DB = MythTV.MythDB() +MVID = MythTV.MythVideo(db=DB) + ############################################################# # fix rtl text where pyfribidi is not available @@ -314,44 +330,6 @@ return os.path.join(sharepath, "mytharchive", "encoder_profiles") ############################################################# -# Get the connection parameters needed to connect to the mythconverg DB - -def getMysqlDBParameters(): - global mysql_host - global mysql_user - global mysql_passwd - global mysql_db - global configHostname - global installPrefix - - f = tempfile.NamedTemporaryFile(); - result = os.spawnlp(os.P_WAIT, 'mytharchivehelper','mytharchivehelper', - '-p', f.name) - if result <> 0: - write("Failed to run mytharchivehelper to get mysql database parameters! " - "Exit code: %d" % result) - if result == 254: - fatalError("Failed to init mythcontext.\n" - "Please check the troubleshooting section of the README for ways to fix this error") - - f.seek(0) - mysql_host = f.readline()[:-1] - mysql_user = f.readline()[:-1] - mysql_passwd = f.readline()[:-1] - mysql_db = f.readline()[:-1] - configHostname = f.readline()[:-1] - installPrefix = f.readline()[:-1] - f.close() - del f - -############################################################# -# Returns a mySQL connection to mythconverg database. - -def getDatabaseConnection(): - """Returns a mySQL connection to mythconverg database.""" - return MySQLdb.connect(host=mysql_host, user=mysql_user, passwd=mysql_passwd, db=mysql_db, init_command='SET NAMES utf8') - -############################################################# # Returns true/false if a given file or path exists. def doesFileExist(file): @@ -869,20 +847,9 @@ # Save a setting to the settings table in the DB def saveSetting(name, data): - db = getDatabaseConnection() - cursor = db.cursor() + host = DB.gethostname() + db.settings[host][name] = data - cursor.execute("""DELETE FROM settings - WHERE value=%s - AND hostname=%s""", (name, configHostname)) - - cursor.execute("""INSERT INTO settings (value, data, hostname) - VALUES(%s, %s, %s)""", (name, data, configHostname)) - - db.close() - del db - del cursor - ############################################################# # Remove all archive items from the archiveitems DB table @@ -890,16 +857,9 @@ ''' Remove all archive items from the archiveitems DB table''' write("Removing all archive items from the archiveitems DB table") + with DB as cursor: + cursor.execute("DELETE FROM archiveitems") - db = getDatabaseConnection() - cursor = db.cursor() - - cursor.execute("DELETE FROM archiveitems") - - db.close() - del db - del cursor - ############################################################# # Load the options from the options node passed in the job file @@ -1357,377 +1317,107 @@ infoDOM = impl.createDocument(None, "fileinfo", None) top_element = infoDOM.documentElement + data = OrdDict((('type',''), ('filename',''), + ('title',''), ('recordingdate',''), + ('recordingtime',''), ('subtitle',''), + ('description',''), ('rating',''), + ('coverfile',''), ('cutlist',''))) + # if the jobfile has amended file details use them details = file.getElementsByTagName("details") if details.length > 0: - node = infoDOM.createElement("type") - node.appendChild(infoDOM.createTextNode(file.attributes["type"].value)) - top_element.appendChild(node) + data.type = file.attributes["type"].value + data.filename = file.attributes["filename"].value + data.title = details[0].attributes["title"].value + data.recordingdata = details[0].attributes["startdate"].value + data.recordingtime = details[0].attributes["starttime"].value + data.subtitle = details[0].attributes["subtitle"].value + data.description = getText(details[0]) - node = infoDOM.createElement("filename") - node.appendChild(infoDOM.createTextNode(file.attributes["filename"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("title") - node.appendChild(infoDOM.createTextNode(details[0].attributes["title"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("recordingdate") - node.appendChild(infoDOM.createTextNode(details[0].attributes["startdate"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("recordingtime") - node.appendChild(infoDOM.createTextNode(details[0].attributes["starttime"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("subtitle") - node.appendChild(infoDOM.createTextNode(details[0].attributes["subtitle"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("description") - node.appendChild(infoDOM.createTextNode(getText(details[0]))) - top_element.appendChild(node) - - node = infoDOM.createElement("rating") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("coverfile") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - #FIXME: add cutlist to details? - node = infoDOM.createElement("cutlist") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - # if this a myth recording we still need to find the chanid, starttime and hascutlist if file.attributes["type"].value=="recording": - basename = os.path.basename(file.attributes["filename"].value) + filename = file.attributes["filename"].value + try: + rec = DB.searchRecorded(basename=os.path.basename(filename)).next() + except StopIteration: + fatalError("Failed to get recording details from the DB for %s" % filename - db = getDatabaseConnection() - cursor = db.cursor() - cursor.execute("""SELECT starttime, chanid FROM recorded - WHERE basename=%s""", basename) + data.chanid = rec.chanid + data.starttime = rec.starttime.isoformat() - result = cursor.fetchall() - numrows = int(cursor.rowcount) - - #We must have exactly 1 row returned for this recording - if numrows!=1: - fatalError("Failed to get recording details from the DB for %s" % file.attributes["filename"].value) - - # iterate through resultset - for record in result: - node = infoDOM.createElement("chanid") - node.appendChild(infoDOM.createTextNode("%s" % record[1])) - top_element.appendChild(node) - - #date time is returned as 2005-12-19 00:15:00 - recdate = time.strptime(str(record[0])[0:19], "%Y-%m-%d %H:%M:%S") - node = infoDOM.createElement("starttime") - node.appendChild(infoDOM.createTextNode( time.strftime("%Y-%m-%dT%H:%M:%S", recdate))) - top_element.appendChild(node) - - starttime = record[0] - chanid = record[1] - - # find the cutlist if available - cursor = db.cursor() - cursor.execute("""SELECT mark, type FROM recordedmarkup - WHERE chanid=%s - AND starttime=%s - AND type IN(0,1) - ORDER BY mark""", (chanid, starttime)) - - if cursor.rowcount > 0: - node = infoDOM.createElement("hascutlist") - node.appendChild(infoDOM.createTextNode("yes")) - top_element.appendChild(node) - else: - node = infoDOM.createElement("hascutlist") - node.appendChild(infoDOM.createTextNode("no")) - top_element.appendChild(node) - - # find the cut list end marks if available to use as chapter marks + cutlist = rec.markup.getcutlist() + if len(cutlist): + data.hascutlist = 'yes' if file.attributes["usecutlist"].value == "0" and addCutlistChapters == True: - cursor = db.cursor() - cursor.execute("""SELECT mark, type FROM recordedmarkup - WHERE chanid=%s - AND starttime=%s - AND type=0 - ORDER BY mark""", (chanid, starttime)) - # get the resultset as a tuple - result = cursor.fetchall() - if cursor.rowcount > 0: - res, fps, ar = getVideoParams(folder) - chapterlist="00:00:00" - #iterate through marks, adding to chapterlist - for record in result: - chapterlist += "," + frameToTime(int(record[0]), float(fps)) + chapterlist = ['00:00:00'] + res, fps, ar = getVideoParams(folder) + for s,e in cutlist: + chapterlist.append(frameToTime(s, float(fps))) + data.chapterlist = ','.join(chapterlist) + else: + data.hascutlist = 'no' - node = infoDOM.createElement("chapterlist") - node.appendChild(infoDOM.createTextNode(chapterlist)) - top_element.appendChild(node) - - db.close() - del db - del cursor - elif file.attributes["type"].value=="recording": - basename = os.path.basename(file.attributes["filename"].value) - # connect - db = getDatabaseConnection() - # create a cursor - cursor = db.cursor() - # execute SQL statement - cursor.execute("""SELECT progstart, stars, cutlist, category, - description, subtitle, title, starttime, - chanid - FROM recorded - WHERE basename=%s""", basename) - # get the resultset as a tuple - result = cursor.fetchall() - # get the number of rows in the resultset - numrows = int(cursor.rowcount) - #We must have exactly 1 row returned for this recording - if numrows!=1: - fatalError("Failed to get recording details from the DB for %s" % file.attributes["filename"].value) + filename = file.attributes["filename"].value + try: + rec = DB.searchRecorded(basename=os.path.basename(filename)).next() + except StopIteration: + fatalError("Failed to get recording details from the DB for %s" % filename - # iterate through resultset - for record in result: - #write( record[0] , "-->", record[1], record[2], record[3]) - write( " " + record[6]) - #Create an XML DOM to hold information about this video file + write(" " + rec.title) + data.type = file.attributes["type"].value + data.filename = filename + data.title = rec.title + data.recordingdate = rec.progstart.strftime(dateformat) + data.recordingtime = rec.progstart.strftime(timeformat) + data.subtitle = rec.subtitle + data.description = rec.description + data.rating = str(rec.stars) + data.chanid = rec.chanid + data.starttime = rec.starttime.isoformat() - node = infoDOM.createElement("type") - node.appendChild(infoDOM.createTextNode(file.attributes["type"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("filename") - node.appendChild(infoDOM.createTextNode(file.attributes["filename"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("title") - node.appendChild(infoDOM.createTextNode(unicode(record[6], "UTF-8"))) - top_element.appendChild(node) - - #date time is returned as 2005-12-19 00:15:00 - recdate = time.strptime(str(record[0])[0:19], "%Y-%m-%d %H:%M:%S") - node = infoDOM.createElement("recordingdate") - node.appendChild(infoDOM.createTextNode( time.strftime(dateformat,recdate) )) - top_element.appendChild(node) - - node = infoDOM.createElement("recordingtime") - node.appendChild(infoDOM.createTextNode( time.strftime(timeformat,recdate))) - top_element.appendChild(node) - - node = infoDOM.createElement("subtitle") - node.appendChild(infoDOM.createTextNode(unicode(record[5], "UTF-8"))) - top_element.appendChild(node) - - node = infoDOM.createElement("description") - node.appendChild(infoDOM.createTextNode(unicode(record[4], "UTF-8"))) - top_element.appendChild(node) - - node = infoDOM.createElement("rating") - node.appendChild(infoDOM.createTextNode("%s" % record[1])) - top_element.appendChild(node) - - node = infoDOM.createElement("coverfile") - node.appendChild(infoDOM.createTextNode("")) - #node.appendChild(infoDOM.createTextNode(record[8])) - top_element.appendChild(node) - - node = infoDOM.createElement("chanid") - node.appendChild(infoDOM.createTextNode("%s" % record[8])) - top_element.appendChild(node) - - #date time is returned as 2005-12-19 00:15:00 - recdate = time.strptime(str(record[7])[0:19], "%Y-%m-%d %H:%M:%S") - node = infoDOM.createElement("starttime") - node.appendChild(infoDOM.createTextNode( time.strftime("%Y-%m-%dT%H:%M:%S", recdate))) - top_element.appendChild(node) - - starttime = record[7] - chanid = record[8] - - # find the cutlist if available - cursor = db.cursor() - # execute SQL statement - cursor.execute("""SELECT mark, type FROM recordedmarkup - WHERE chanid=%s - AND starttime=%s - AND type IN(0,1) - ORDER BY mark""", (chanid, starttime)) - - if cursor.rowcount > 0: - node = infoDOM.createElement("hascutlist") - node.appendChild(infoDOM.createTextNode("yes")) - top_element.appendChild(node) - else: - node = infoDOM.createElement("hascutlist") - node.appendChild(infoDOM.createTextNode("no")) - top_element.appendChild(node) - + cutlist = rec.markup.getcutlist() + if len(cutlist): + data.hascutlist = 'yes' if file.attributes["usecutlist"].value == "0" and addCutlistChapters == True: - # find the cut list end marks if available - cursor = db.cursor() - # execute SQL statement - cursor.execute("""SELECT mark, type FROM recordedmarkup - WHERE chanid=%s - AND starttime=%s - AND type=0 - ORDER BY mark""", (chanid, starttime)) - # get the resultset as a tuple - result = cursor.fetchall() - if cursor.rowcount > 0: - res, fps, ar = getVideoParams(folder) - chapterlist="00:00:00" - #iterate through marks, adding to chapterlist - for record in result: - chapterlist += "," + frameToTime(int(record[0]), float(fps)) + chapterlist = ['00:00:00'] + res, fps, ar = getVideoParams(folder) + for s,e in cutlist: + chapterlist.append(frameToTime(s, float(fps))) + data.chapterlist = ','.join(chapterlist) + else: + data.hascutlist = 'no' - node = infoDOM.createElement("chapterlist") - node.appendChild(infoDOM.createTextNode(chapterlist)) - top_element.appendChild(node) - - db.close() - del db - del cursor - elif file.attributes["type"].value=="video": - # connect - db = getDatabaseConnection() - # create a cursor - cursor = db.cursor() - # execute SQL statement - cursor.execute("""SELECT title, director, plot, rating, inetref, year, - userrating, length, coverfile, subtitle - FROM videometadata - WHERE filename LIKE %s""", '%'+file.attributes["filename"].value) - # get the resultset as a tuple - result = cursor.fetchall() - # get the number of rows in the resultset - numrows = int(cursor.rowcount) + filename = file.attributes["filename"].value + try: + vid = MVID.searchVideos(file=filename).next() + except StopIteration: + vid = Video.fromFilename(filename) - #title,director,plot,rating,inetref,year,userrating,length,coverfile - #We must have exactly 1 row returned for this recording - if numrows<>1: - #Theres no record in the database so use a dummy row so we dont die! - #title,director,plot,rating,inetref,year,userrating,length,coverfile - record = file.attributes["filename"].value, "","",0,"","",0,0,"" + data.type = file.attributes["type"].value + data.filename = filename + data.title = vid.title + if vid.year != 1895: + data.recordingdate = str(vid.year) + data.subtitle = vid.subtitle + if (vid.plot is not None) and (vid.plot != 'None'): + data.description = vid.plot + data.rating = str(vid.userrating) + if doesFileExist(rec.coverfile): + data.coverfile = vid.coverfile - for record in result: - write( " " + record[0]) - - node = infoDOM.createElement("type") - node.appendChild(infoDOM.createTextNode(file.attributes["type"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("filename") - node.appendChild(infoDOM.createTextNode(file.attributes["filename"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("title") - node.appendChild(infoDOM.createTextNode(unicode(record[0], "UTF-8"))) - top_element.appendChild(node) - - node = infoDOM.createElement("recordingdate") - date = int(record[5]) - if date != 1895: - node.appendChild(infoDOM.createTextNode("%s" % record[5])) - else: - node.appendChild(infoDOM.createTextNode("")) - - top_element.appendChild(node) - - node = infoDOM.createElement("recordingtime") - #node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("subtitle") - node.appendChild(infoDOM.createTextNode(unicode(record[9], "UTF-8"))) - top_element.appendChild(node) - - node = infoDOM.createElement("description") - if record[2] != None: - desc = unicode(record[2], "UTF-8") - if desc != "None": - node.appendChild(infoDOM.createTextNode(desc)) - else: - node.appendChild(infoDOM.createTextNode("")) - else: - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("rating") - node.appendChild(infoDOM.createTextNode("%s" % record[6])) - top_element.appendChild(node) - - node = infoDOM.createElement("cutlist") - #node.appendChild(infoDOM.createTextNode(record[2])) - top_element.appendChild(node) - - node = infoDOM.createElement("coverfile") - if doesFileExist(record[8]): - node.appendChild(infoDOM.createTextNode(record[8])) - else: - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - db.close() - del db - del cursor - elif file.attributes["type"].value=="file": + data.type = file.attributes["type"].value + data.filename = file.attributes["filename"].value + data.title = file.attributes["filename"].value - node = infoDOM.createElement("type") - node.appendChild(infoDOM.createTextNode(file.attributes["type"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("filename") - node.appendChild(infoDOM.createTextNode(file.attributes["filename"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("title") - node.appendChild(infoDOM.createTextNode(file.attributes["filename"].value)) - top_element.appendChild(node) - - node = infoDOM.createElement("recordingdate") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("recordingtime") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("subtitle") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("description") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("rating") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("cutlist") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - - node = infoDOM.createElement("coverfile") - node.appendChild(infoDOM.createTextNode("")) - top_element.appendChild(node) - # if the jobfile has thumb image details copy the images to the work dir thumbs = file.getElementsByTagName("thumbimages") if thumbs.length > 0: thumbs = thumbs[0] thumbs = file.getElementsByTagName("thumb") - thumblist = "" + thumblist = [] res, fps, ar = getVideoParams(folder) for thumb in thumbs: @@ -1735,20 +1425,18 @@ frame = thumb.attributes["frame"].value filename = thumb.attributes["filename"].value if caption != "Title": - if thumblist != "": - thumblist += "," + frameToTime(int(frame), float(fps)) - else: - thumblist += frameToTime(int(frame), float(fps)) + thumblist.append(frameToTime(int(frame), float(fps))) # copy thumb file to work dir copy(filename, folder) - node = infoDOM.createElement("thumblist") - node.appendChild(infoDOM.createTextNode(thumblist)) + data.thumblist = ','.join(thumblist) + + for k,v in data.items(): + node = infoDOM.createElement(k) + node.appendChild(infoDOM.createTextNode(v)) top_element.appendChild(node) - #top_element.appendChild(thumbs) - WriteXMLToFile (infoDOM, outputfile) ############################################################# @@ -1998,40 +1686,18 @@ def generateProjectXCutlist(chanid, starttime, folder): """generate cutlist_x.txt for ProjectX""" - sqlstatement = """SELECT mark FROM recordedmarkup - WHERE chanid = '%s' AND starttime = '%s' - AND type IN (0,1) ORDER BY mark""" % (chanid, starttime) + rec = DB.searchRecorded(chanid=chanid, starttime=starttime).next() + cutlist = rec.markup.getcutlist() - db = getDatabaseConnection() - cursor = db.cursor() - cursor.execute(sqlstatement) - result = cursor.fetchall() - numrows = int(cursor.rowcount) - - #We must have at least one row returned for this recording - if numrows==0: + if len(cutlist): + with open(os.path.join(folder, "cutlist_x.txt"), 'w') as cutlist_f: + for cut in cutlist: + cutlist_f.write('%d\n%d\n' % cut) + return True + else: write("No cutlist in the DB for chanid %s, starttime %s" % chanid, starttime) - db.close() - del db - del cursor return False - cutlist_f=open(os.path.join(folder, "cutlist_x.txt"), 'w') - cutlist_f.write("CollectionPanel.CutMode=2\n") - - # iterate through resultset - for i in range(len(result)): - if i == 0: - if result[i][0] <> 0 and result[i][0] != "": - cutlist_f.write("0\n") - if result[i][0] != "" and result[i][0] <> 0: - cutlist_f.write("%d\n" % result[i]) - - cutlist_f.close() - - return True - - ############################################################# # Use Project-X to cut commercials and/or demux an mpeg2 file