Cross-eit.py

From MythTV Official Wiki
Revision as of 17:43, 12 March 2011 by Rune.evjen (talk | contribs)

Jump to: navigation, search

This script fetches EPG data for specified channels from a mythtv database and exports this data to an XMLTV [1] formatted XML file.

The purpose of this is to extract EPG from channels with good data, and use this data to populate other channels where no data is available.

The program needs the following arguments: ./cross-eit.py chanid1,xmlid1 chanid2,xmlid2 chanidN,xmlidN XMLTV-export-file.xml

To check the channel numbers for the channels you want to extract EPG from, run the following command: mysql -u mythtv -p mythconverg -e "SELECT chanid,callsign from channel WHERE callsign='channel name'"

If you want to import the EPG data from the xml file using mythfilldatabase, you must add the appropriate xmltvid for each channel you want to import EPG to in mythweb [2] as well as uncheck the useonairguide for these channels.

Example: (assuming sourceid of 1 for mythtv) ./cross-eit.py 1004,tv2.guide 1108,history.guide 1022,natgeo.guide export.xml mythfilldatabase -v xmltv --file 1 export.xml

[1] http://wiki.xmltv.org/index.php/XMLTVFormat [2] http://localhost/mythweb/settings/tv/channels


Script.png cross-eit.py

#!/usr/bin/env python
# -*- coding: utf8 -*-
"""
This program fetches schedule information from a mythtv database and exports this data to an XMLTV 
formatted XML file.

check def help(): for further description
"""
import os
import datetime
import time
import MySQLdb
import sys
from string import split
from xml.etree.ElementTree import Element, SubElement, tostring
from xml.dom import minidom

def help():
    print("Script description:\n\n"
    "This script fetches EPG data for specified channels from a mythtv database and exports this data to an XMLTV [1] "
    "formatted XML file.\n\n"
    "The purpose of this is to extract EPG from channels with good data,\n"
    "and use this data to populate other channels where no data is available.\n\n"
    "The program needs the following arguments:\n"
    "\t./cross-eit.py chanid1,xmlid1 chanid2,xmlid2 chanidN,xmlidN XMLTV-export-file.xml\n\n"
    "To check the channel numbers for the channels you want to extract EPG from, run the following command:\n"
    "mysql -u mythtv -p mythconverg -e \"SELECT chanid,callsign from channel WHERE callsign='channel name'\"\n\n" 
    "If you want to import the EPG data from the xml file using mythfilldatabase, \n"
    "you must add the appropriate xmltvid for each channel you want to import EPG to in mythweb [2] as well as uncheck the useonairguide for these channels.\n\n"
    "Example: (assuming sourceid of 1 for mythtv)\n"
    "\t./cross-eit.py 1004,tv2.guide 1108,history.guide 1022,natgeo.guide export.xml\n"
    "\tmythfilldatabase -v xmltv  --file 1 export.xml\n\n"
    "[1] http://wiki.xmltv.org/index.php/XMLTVFormat\n"
    "[2] http://localhost/mythweb/settings/tv/channels")
def d2s(dateobj):
    """
    Reads dateobject and returns a string in XLMTV format with timezone offset.
    """
    date = dateobj + datetime.timedelta(seconds=time.timezone)
    return date.strftime("%Y%m%d%H%M%S")

def read_config_xml():
        """Reads in and parses a config.xml from a number of places:
           1) /etc/mythtv/config.xml
           2) /usr/share/mythtv/config.xml  
        """
        dictionary={"doc": None, 'DBHostName': None, 'DBUserName': None, 'DBPassword': None, 'DBName': None, 'SecurityPin' : None}
        for file in ['/etc/mythtv/config.xml', '/usr/share/mythtv/config.xml' ]:
            if file and os.path.exists(file):
                dictionary["doc"]=minidom.parse(file)
                for tag in dictionary:
                    elements=dictionary["doc"].getElementsByTagName(tag)
                    if elements:
                        dictionary[tag]=elements[0].childNodes[0].data
                break
        return dictionary

"""
Main script
"""
version = "v1.0"
print "Cross-Eit %s\n" % (version)
#Read and check arguments
if len(sys.argv) == 1:
    print "Error: No arguments specified. Aborting...\n"
    help()
    sys.exit()
elif sys.argv[1] == "-h" or sys.argv[1] == "--help" or sys.argv[1] == "-?":
    help()
    sys.exit()
   
channels = {}
for idx,val in enumerate(sys.argv):
    if idx == 0:
        pass
    elif idx == (len(sys.argv)-1):
        xmlfile=val
    else:
        s = val.split(",")
        if len(s) <> 2:
            print "Error: Not able to parse argument %s. Aborting...\n" % (s)
            help()
            sys.exit()
        try:
            testint=int(s[0])
        except:
            print "Error: Channel number is not an integer - check you syntax. Aborting...\n"
            help()
            sys.exit()
        if len(s[1]) == 0:
            print "XMLTVID is not specified for channel %s. Aborting...\n" % (s[0])
            help()
            sys.exit()       
        channels[s[0]]=s[1]

#create xml object "tv"
tv = Element('tv')
# Read local config and connect to database
mysqlconn=read_config_xml()
conn = MySQLdb.connect (host =  mysqlconn['DBHostName'],
                        user = mysqlconn['DBUserName'],
                        passwd = mysqlconn['DBPassword'],
                        db =  mysqlconn['DBName'])
cursor = conn.cursor(MySQLdb.cursors.DictCursor)

#Read schedule for each channel and create XML elements
for chan in channels.keys():
    print "Processing channel number: %s, XMLTV id: %s" % (chan, channels[chan])
    cursor.execute("SELECT starttime, endtime, title, subtitle, description, category, previouslyshown FROM program WHERE chanid=%s", chan)
    result_set = cursor.fetchall()
    #Read each row for channel 'chan'
    for row in result_set:
        program = SubElement(tv, 'programme', channel=channels[chan], start=d2s(row["starttime"]), stop=d2s(row["endtime"]))
        title = SubElement(program, 'title')
        title.text=row["title"]
        subtitle = SubElement(program, 'sub-title')
        subtitle.text=row["subtitle"]
        desc = SubElement(program, 'desc')
        desc.text=row["description"]
        category = SubElement(program, 'category')
        category.text=row["category"]
        if int(row["previouslyshown"]) == 1:
            #previsously shown
            prev=SubElement(program, 'previously-shown')
    print "Number of processed programs: %d" % cursor.rowcount
cursor.close()
print "Writing XML file %s" % (xmlfile)
f = open(xmlfile, "w")
#Create XML file and header
f.write('<?xml version="1.0" ?>\n')
f.write('<!DOCTYPE tv SYSTEM "xmltv.dtd">\n')
#write tv XML element including all program subelements
f.write(tostring(tv))
f.close()