MythDataGrabber

From MythTV Official Wiki
Revision as of 20:25, 20 October 2010 by Outleradam (talk | contribs) (Examples)

Jump to: navigation, search

This Python script is a work in progress --Outleradam 03:06, 19 October 2010 (UTC)

MythDataGrabber is designed to take an input of a file and output database information and commercial skip data in a "var = value" format.

MythDataGrabber

This script was originally designed as a database interface for mythicalLibrarian.

Inputs

MythDataGrabber --filename=file.ext : returns information to a file
--Display           : Display output, default: write to file
--DBHostName        : sets the DB Host, default: localhost
--DBName            : sets the DB Name, default: mythconverg
--DBUserName        : sets the User Name, default: mythtv
--DBPassword        : sets the Password, default: mythtv
--DBPin             : sets the Pin, default: 0
--output=file.txt   : sets the output, default: ./showData.txt
--version|-v|-ver   : displays version information

Outputs

mythtv@XBMC-live:~$ /usr/local/bin/MythDataGrabber --filename='1045_20101005120000.mpg' --DBHostName='192.168.1.110' --DBName='mythconverg' --DBUserName='mythtv' --DBPassword='mythtv' --DBPin="" --Display
Establishing database connection
chanid = "1045"
starttime = "2010-10-05 12:00:00"
endtime = "2010-10-05 13:00:00"
title = "Caprica"
subtitle = "Reins of a Waterfall"
description = "Amanda's public admission about Zoe's role in the bombing ignites a media backlash against the Graystones; Sam and Joseph confront Daniel."
category = "Science fiction"
hostname = "XBMC-live"
bookmark = "0"
editing = "0"
cutlist = "0"
autoexpire = "0"
commflagged = "1"
recgroup = "Default"
recordid = "21"
seriesid = "EP01213751"
programid = "EP012137510003"
lastmodified = "2010-10-05 12:00:02"
filesize = "1754496464"
stars = "0.0"
previouslyshown = "1"
originalairdate = "2010-02-05"
preserve = "0"
findid = "0"
deletepending = "0"
transcoder = "0"
timestretch = "1.0"
recpriority = "98"
basename = "1045_20101005120000.mpg"
progstart = "2010-10-05 12:00:00"
progend = "2010-10-05 13:00:00"
playgroup = "Default"
profile = "Default"
duplicate = "1"
transcoded = "0"
watched = "0"
storagegroup = "Default"
bookmarkupdate = "None" 

startdata[0] = "13663"
startdata[1] = "32548"
startdata[2] = "51539"
startdata[3] = "64846"
startdata[4] = "79186"
stopdata[0] = "18660"
stopdata[1] = "37724"
stopdata[2] = "55599"
stopdata[3] = "71311"
stopdata[4] = "85012"
Operation complete

If --Display is not specified, MythDataGrabber will create a file called ./showData.txt and dump it's information there.

Examples

BASH:

mkfifo dbOut
MythDataGrabber --filename="myfile.ext" --Display>dbOut
while read var equals value 
do
   test "$equals" = "=" && declare $var=$value
done<DBOut
MovieAirDate=$airdate; OriginalAirDate=$originalairdate; ShowCategory=$category; Stars=$stars; Plot=$description; Zap2itSeriesID=$seriesid; ProgramID=$programid; ChanID=$chanid; ShowStartTime=$starttime


Use from the command line:

$ MythDataGrabber --filename=1000_20101010101010.mpg --DBHostName=localhost --DBName=mythconverg --DBUserName=mythtv --DBPassword=mythtv --output=/home/myfile.txt

Code

This script may be used for any purpose to obtain information from the database


PythonIcon.png mythdatagrabber.py

#!/usr/bin/python
from MythTV import MythDB
import sys
import os

def version():
    print """ Written by Mike Szczys and Adam Outler
 for support, please visit: http://forum.xbmc.org/showthread.php?t=65644
 This file was written for the mythicalLibrarian project,
 and is licensed under the Apache License which requires a notification
 to outleradam (at) hotmail.com as a formality before any derrivative
 work.  We just want to hear about your project.
 ------------------------------------------------------------------
Beta
  %s utilizes mythtv python bindings to obtain information
  about a recording and will print the information to a file.
""" % os.path.basename(sys.argv[0])
    return 0

def help():
    name = os.path.basename(sys.argv[0])
    print """ %s is designed to pull data from MythTV python bindings.

Usage:
 %s --filename=file.ext : returns information to a file
       --Display           : Display output, default: write to file
       --DBHostName        : sets the DB Host, default: localhost
       --DBName            : sets the DB Name, default: mythconverg
       --DBUserName        : sets the User Name, default: mythtv
       --DBPassword        : sets the Password, default: mythtv
       --DBPin             : sets the Pin, default: 0
       --output=file.txt   : sets the output, default: ./showData.txt
       --version|-v|-ver   : displays version information
       -auto               : attempts to pull databse login info from mysql.txt
 example:
 $ %s --filename=1000_20101010101010.mpg --DBHostName=localhost --DBName=mythconverg --DBUserName=mythtv --DBPassword=mythtv --output=/home/myfile.txt
""" % (name, name, name)
    return 0

def invalidFile():
    print """target is not valid.  Please choose a valid target.
usage: %s --filename=""" % os.path.basename(sys.argv[0])
    help()
    return 0

filename = '1006_20100823173000.mpg'
#requires libmyth-python python-lxml

#Setup default database information
dbInfo = {
    "DBHostName"  : "localhost",
    "DBName"      : "mythconverg",
    "DBUserName"  : "mythtv",
    "DBPassword"  : "mythtv",
    "DBPin"         : "0"
    }
#Setup other default option information
options = {
    "DisplayData" : "False",
    "auto"        : "False" ,
    "output"      : "./showData.txt",
    "filename"    : ""
    }  

#A list of valid command line options (anything with an = sign) and flags
validOptions = ['--DBHostName','--DBName','--DBUserName','--DBPassword', '--filename', '--output', '--DBPin']
validFlags = ['-auto'] #auto flag looks up login from mysql.txt
validVersionFlags = ['-v','--version','-ver']
validHelpFlags = ['-?','--help','-h']
validDisplayFlags = [ '-d', '--Display' ] 
                
####
#Handle Command Line Arguments
####

#If there were no arguments
if len(sys.argv) < 2:
    print "ERROR: Filename must be passed as an argument"
    print
    help()
    print sys.argv[0]
    print __file__
    sys.exit(1)

#If the first argument is not a flag, treat it as the filename
if not sys.argv[1].startswith('-'):
    options['filename'] = os.path.basename(sys.argv[1])
    #Make arg list without script name and filename
    myArgs = sys.argv[2:]
else:
    #Make arg list without script name
    myArgs = sys.argv[1:]  


#parse through the arguments
if len(myArgs) > 0:
    for arg in myArgs:
        #Test to see if this is an option flag
        if '=' in arg and arg.split('=')[0] in validOptions:
            #This is a valid option, do something with it

            #Testing to see if it's database login info
            if arg.split('=')[0][2:] in dbInfo:
                #It's a DB login item, save it in dbInfo
                dbInfo[arg.split('=')[0][2:]] = arg.split('=')[1].replace('"','')  

            #If it's not, it must be a misc option
            elif arg.split('=')[0][2:] in options:
                #It is in the options dictionary, save it
                options[arg.split('=')[0][2:]] = arg.split('=')[1].replace('"','') 

            #If it wasn't either, then we've got problems
            else:
                print "ERROR: Option flag was valid but something went wrong trying to use" + arg
                sys.exit(1) 

        #Test to see if this is a version flag
        elif arg in validVersionFlags:
            version()
            sys.exit(0) 

        #Test to see if this is a help flag
        elif arg in validHelpFlags:
            help()
            sys.exit(0) 

        #Test for the rest of the valid flags
        elif arg in validFlags:
            print "  Error: --invalid flag"
            help()
            sys.exit(0)

        elif arg in validDisplayFlags:
            options['DisplayData'] = 'True'
         	 	
        else:
            #this is an unacceptable argument, raise an exception
            print "ERROR: Invalid command line argument: " + arg
            help()
            sys.exit(1)


#Stop execution if no filename has been set yet
if 'filename' not in options:
    #No filename has been passed
    print "ERROR: No filename specified"
    help()
    sys.exit(1) 

###############################
#Function: readMysqlTxt
#Arguments: None
#Returns: list of five values:
#  0 or 1 for success or error
#  DBHostName
#  DBName
#  DBUserName
#  DBPassword
#
#Note: Need to add error catching in case file read problems
###############################
def readMysqlTxt():
    #Read database settings from ~/.mythtv/mysql.txt
    mysqlTXT = os.path.expanduser('~') + "/.mythtv/mysql.txt" 

    dbdata = {}
    for line in open(mysqlTXT,'r'):
        if line.startswith('#'):
            continue
        if '=' in line:
            o,v = line.strip().split('=')
            dbdata[o.strip()] = v.strip()
    return dbdata

#Get data from mythtv database
print 'Establishing database connection'
try:
    #Defaults or args
    db = MythDB(**dbInfo) 
except: 
    try:
        #mythtv preconfigured options
        print 'Failed: attempting to use system default configuration'
        db = MythDB(DBPin=dbInfo['DBPin']) 
    except:
        try:
            #read from the mysql.txt
            print 'Failed: attempting to read from default mythtv file'
            db = MythDB(**readMysqlTxt()) 
        except: 
            print 'Failed: Please specify database information manually'
            sys.exit(' See --help for more information.')

try:
    rec = db.searchRecorded(basename=options['filename']).next()
except StopIteration:
    raise Exception('Recording Not Found')


####
#Commercial skip information
####
markupstart,markupstop = zip(*rec.markup.getskiplist())
f = None
try:
    # set the file object
    if options['DisplayData'] == 'False':
        f = open(options['output'], 'w')
    else:
        f = sys.stdout

    # loop through Recorded items
    for x in rec.items():
        f.write('%s = "%s"\n' % x)
    # loop through comm-start points
    for i,data in enumerate(markupstart):
        f.write('startdata[%s] = "%s"\n' % (i, data))
    # loop through comm-end points
    for i,data in enumerate(markupstop):
        f.write('stopdata[%s] = "%s"\n' % (i, data))
    if rec.chanid != '':
        print "Operation complete"
except:
    options['DisplayData'] = 'True'
    print "Failed To Write File.  Displaying data."
finally:
    # close file if not stdout
    if f is not None:
        if f.fileno() != 1:
            f.close()