Talk:Cross-eit.py

From MythTV Official Wiki
Jump to: navigation, search

16/1-2011: Updated version added with: - adds better option parsing - uses class MyGuide written by wagnerrp

This is a merge of the proposed update below and use of MyGuide class.

Rune

15/1-2011: Proposed update of script. - adds better option parsing - uses MythDB to connect to mythtv database - uses new python bindings for EPG retrieval (guide and program)

This was written in parallel to the update from wagnerrp which uses the new python bindings, so I post this version for discussion or merge witch current wiki version.

Best regards,

Rune Evjen


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 MythDB
from string import split
from xml.etree.ElementTree import Element, SubElement, tostring

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 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.\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"
    "Script usage:\n"
    "\t./cross-eit.py OPTIONS chanid1,xmlid1 chanid2,xmlid2 chanidN,xmlidN \n\n"
    "Options:\n"
    "\t-o , --output=file\t\t Write output to XML file. If this argument is not specified output is written to ./output.xml\n"
    "\t-h, --help\t\t\\tShow help text (this text)\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 -o /tmp/export.xml\n"
    "\tmythfilldatabase -v xmltv  --file 1 /tmp/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 schedule(db, channels):
    """
    Connects to mythtv database 'db' and 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])
        guide=db.searchGuide(chanid=chan)
        for program in guide:
            prog = SubElement(tv, 'programme', channel=channels[chan], start=d2s(program.starttime), stop=d2s(program.endtime))
            title = SubElement(prog, 'title')
            title.text=program.title
            subtitle = SubElement(prog, 'sub-title')
            subtitle.text=program.subtitle
            desc = SubElement(prog, 'desc')
            desc.text=program.description
            category = SubElement(prog, 'category')
            category.text=program.category
            if program.previouslyshown == 1:
                prev=SubElement(prog, 'previously-shown')
    return tv
    
def writexmltv(elem, file):
    f = open(file,'w')
    print "writing to file %s" % (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.1"
    print "Cross-Eit %s" % (version)
    channels, outputfile= read_arguments(args)
    try:
        db=MythDB()
    except:
        print "Error: Not able to connect to database. Aborting..."
        exit(2)
    xmltags=schedule(db, channels)
    writexmltv(xmltags, outputfile)

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