Cross-eit.py

From MythTV Official Wiki
Revision as of 22:51, 16 March 2011 by Rune.evjen (talk | contribs) (Merge of previous version with MyGuide class from wagnerrp and proposed update as described in the Talk page)

Jump to: navigation, search

Important.png Note: The correct title of this article is cross-eit.py. It appears incorrectly here due to technical restrictions.


Author Rune Evjen
Description Script to export EPG from mythtv database to XMLTV format
Supports Version24.png  



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.

Script usage:

   cross-eit.py OPTIONS chanid1,xmlid1 chanid2,xmlid2 chanidN,xmlidN

Options:

   -o, --output=file   Write output to XML file. 
                       If this argument is not specified output is written to ./output.xml
   -h, --help          Show help text (this text)

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 -o /tmp/export.xml
   mythfilldatabase -v xmltv  --file 1 /tmp/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 [1]
formatted XML file.

check usage(): for further description
"""
import os
import datetime
import time
import sys
import getopt
from MythTV import Guide
from string import split
from xml.etree.ElementTree import Element, SubElement, tostring

def usage():
    print """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.

Script usage:
    cross-eit.py OPTIONS chanid1,xmlid1 chanid2,xmlid2 chanidN,xmlidN

Options:
    -o, --output=file   Write output to XML file. 
                        If this argument is not specified output is written to ./output.xml
    -h, --help          Show help text (this text)

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 -o /tmp/export.xml
    mythfilldatabase -v xmltv  --file 1 /tmp/export.xml

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

def read_arguments(argv):
    """
    Reads arguments argv, checks for valid options and parses channel information. Returns output file and channels
    """
    output="output.xml"
    try:
        opts, args = getopt.getopt(argv, "ho:", ["help", "output="]) 
    except getopt.GetoptError:           
        usage()                          
        sys.exit(2)
    for opt, arg in opts:                
        if opt in ("-h", "--help"):      
            usage()                     
            sys.exit(2)                  
        elif opt in ("-o", "--output"): 
            output = arg               
    if len(args) == 0:
        print "Error: No channels specified. Aborting...\n" % (args)
        usage()
        sys.exit(2)
    channels={}
    for arg in args:
        try:
            c,x=split(arg,",")
        except:
            print "Error: Not able to parse channel %s. Aborting...\n" % (arg)
            usage()
            sys.exit(2)       
        try:
            testint=int(c)
        except:
            print "Error: Channel number is not an integer - check you syntax. Aborting...\n"
            usage()
            sys.exit(2)
        if len(x) == 0:
            print "Error: please XMLTVID is not specified for channel %s. Aborting...\n" % (c)
            usage()
            sys.exit(2)       
        channels[int(c)]=x
    return channels, output


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")

class MyGuide( Guide ):
    @classmethod
    def fromChanID(cls, chanid, db=None):
        return cls._fromQuery("WHERE chanid=%s", (chanid,), db)

def schedule(channels):
    """
    Retrives EPG for channels 'channels'. Returns XML ELement 'tv'
    """
    #create xml object "tv"
    tv = Element('tv')
    #Read schedule for each channel and create XML elements
    for chan in channels:
        print "Processing channel number: %s, XMLTV id: %s" % (chan, channels[chan])
        count = 0
        for prog in MyGuide.fromChanID(chan):
            count += 1
            program         = SubElement(tv, 'programme', channel=channels[chan], start=d2s(prog.starttime), stop=d2s(prog.endtime))
            title           = SubElement(program, 'title')
            title.text      = prog.title
            subtitle        = SubElement(program, 'sub-title')
            subtitle.text   = prog.subtitle
            desc            = SubElement(program, 'desc')
            desc.text       = prog.description
            category        = SubElement(program, 'category')
            category.text   = prog.category
            if int(prog.previouslyshown) == 1:
                prev        = SubElement(program, 'previously-shown')
        print "Number of processed programs: %d\n" % count
    return tv
    
def writexmltv(elem, file):
    f = open(file,'w')
    print "Writing XMLTV EPG information to file %s\n" % file
    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(elem))
    f.close()

def main(args):
    """
    Main script
    """
    version = "v1.2"
    print "cross-eit %s\n" % version
    channels, outputfile = read_arguments(args)
    xmltags=schedule(channels)
    writexmltv(xmltags, outputfile)

if __name__ == "__main__":
    main(sys.argv[1:])