diff options
Diffstat (limited to 'abs/core/LinHES-config/autocard.py')
-rw-r--r--[-rwxr-xr-x] | abs/core/LinHES-config/autocard.py | 1306 |
1 files changed, 1049 insertions, 257 deletions
diff --git a/abs/core/LinHES-config/autocard.py b/abs/core/LinHES-config/autocard.py index f8bb173..c461714 100755..100644 --- a/abs/core/LinHES-config/autocard.py +++ b/abs/core/LinHES-config/autocard.py @@ -1,307 +1,1099 @@ #!/usr/bin/python2 -# import MySQL module -#jm -import MySQLdb import sys import getopt import socket -import os +import os , re import time import string import glob from string import letters from string import digits -def INSERTNULL_SOURCE(name,xmltvgrabber,userid,freqtable,lineupid,password,useeit): - cursor = db.cursor() - cursor.execute("INSERT INTO videosource(name,xmltvgrabber,userid,freqtable,lineupid,password,useeit) VALUES(%s,%s,%s,%s,%s,%s,%s);",(name,xmltvgrabber,userid,freqtable,lineupid,password,useeit)) - -def INSERTCARD_INTOMYTH(Device,Driver,Cardvendor): - global currenthostname - print Device - print Driver, - print Cardvendor - cursor = db.cursor() - insert = "false" - if Driver == "ivtv" : - cardtype="MPEG" - defaultinput="Tuner 1" - insert="true" - if Cardvendor == "pcHDTV HD3000 HDTV": - insert="false" - cardtype ="whocares" - - #print insert - if insert == "true" : - cursor.execute("INSERT INTO capturecard (videodevice,cardtype,defaultinput,hostname) VALUES(%s,%s,%s,%s);",(Device,cardtype,defaultinput,currenthostname)) - -def INSERTHDR_INTOMYTH(deviceid,tuner_number): - cardtype='HDHOMERUN' - defaultinput='MPEG2TS' - global currenthostname - print deviceid - print cardtype - print defaultinput - print tuner_number - cursor = db.cursor() - #print insert - cursor.execute("INSERT INTO capturecard (videodevice,cardtype,defaultinput,dbox2_port ,hostname) VALUES(%s,%s,%s,%s,%s);",(deviceid,cardtype,defaultinput,tuner_number,currenthostname)) - -def INSERTAUTOCARD(): - global cardlist - global currenthostname - # create a cursor - cursor = db.cursor() - - - for i in range( 1 , len(cardlist)): - insert = "false" -# print cardlist[i] - Device=cardlist[i][0] - Driver=cardlist[i][1] - Cardvendor=cardlist[i][2] - Businfo=cardlist[i][3] - if Driver == "ivtv" : - insert="true" - devicestatus="unused" - if Cardvendor == "pcHDTV HD3000 HDTV": - insert="false" - cardtype ="whocares" - if Driver == "hdr": - insert="true" - devicestatus="unused" - - if insert == "true" : - cursor.execute("delete from autocard where uniqid=%s;",(Businfo)) - if Driver=="hdr": - Cardvendor="HDHOMERUN Tuner 1" - cursor.execute("INSERT INTO autocard (dev,driver,description,uniqid,devicestatus,hostname) VALUES(%s,%s,%s,%s,%s,%s);",(Device,Driver,Cardvendor,Businfo,devicestatus,currenthostname)) - Cardvendor="HDHOMERUN Tuner 2" - cursor.execute("INSERT INTO autocard (dev,driver,description,uniqid,devicestatus,hostname) VALUES(%s,%s,%s,%s,%s,%s);",(Device,Driver,Cardvendor,Businfo,devicestatus,currenthostname)) +from xml.dom.minidom import parseString +import errno, fcntl +import urllib2,urllib,json +#http://code.activestate.com/recipes/576891/ + +class ApplicationLock: + ''' + Ensures application is running only once, by using a lock file. + + Ensure call to lock works. Then call unlock at program exit. + + You cannot read or write to the lock file, but for some reason you can + remove it. Once removed, it is still in a locked state somehow. Another + application attempting to lock against the file will fail, even though + the directory listing does not show the file. Mysterious, but we are glad + the lock integrity is upheld in such a case. + + Instance variables: + lockfile -- Full path to lock file + lockfd -- File descriptor of lock file exclusively locked + ''' + def __init__ (self, lockfile): + self.lockfile = lockfile + self.lockfd = None + + def lock (self): + ''' + Creates and holds on to the lock file with exclusive access. + Returns True if lock successful, False if it is not, and raises + an exception upon operating system errors encountered creating the + lock file. + ''' + try: + # + # Create or else open and trucate lock file, in read-write mode. + # + # A crashed app might not delete the lock file, so the + # os.O_CREAT | os.O_EXCL combination that guarantees + # atomic create isn't useful here. That is, we don't want to + # fail locking just because the file exists. + # + # Could use os.O_EXLOCK, but that doesn't exist yet in my Python + # + self.lockfd = os.open (self.lockfile, + os.O_TRUNC | os.O_CREAT | os.O_RDWR) + + # Acquire exclusive lock on the file, but don't block waiting for it + fcntl.flock (self.lockfd, fcntl.LOCK_EX | fcntl.LOCK_NB) + + # Writing to file is pointless, nobody can see it + os.write (self.lockfd, "My Lockfile") + + return True + except (OSError, IOError), e: + # Lock cannot be acquired is okay, everything else reraise exception + if e.errno in (errno.EACCES, errno.EAGAIN): + return False else: - cursor.execute("INSERT INTO autocard (dev,driver,description,uniqid,devicestatus,hostname) VALUES(%s,%s,%s,%s,%s,%s);",(Device,Driver,Cardvendor,Businfo,devicestatus,currenthostname)) + raise + + def unlock (self): + try: + # FIRST unlink file, then close it. This way, we avoid file + # existence in an unlocked state + os.unlink (self.lockfile) + # Just in case, let's not leak file descriptors + os.close (self.lockfd) + except (OSError, IOError), e: + # Ignore error destroying lock file. See class doc about how + # lockfile can be erased and everything still works normally. + pass +#------- START OF TUNER CLASSES----------- +class v4l_tuners(): + def __init__(self, device): + self.device = device + self.full_attribs = self.find_full_attribs() + self.full_udev_attribs = self.find_full_udev_attribs() + self.description,self.driver = self.find_description() + self.udev_props = self.parse_full_udev() + self.tuner_hash = self.find_tuner_hash() + self.udev_rule = self.create_udev_rule() + #self.staticdevice is set in create_udev_rule + + def find_full_attribs(self): + cmd = 'v4l2-ctl -D -d' + self.device + return os.popen(cmd).readlines() + + def find_full_udev_attribs(self): + cmd = 'udevadm info -a -p $(udevadm info -q path -n %s)' %self.device + return os.popen(cmd).readlines() + + def find_description(self): + for line in self.full_attribs: + #print line + pos = string.find(line,"Driver name") + if pos >=0: + splitline= line.split(':') + Driver=splitline[1].strip() + pos = string.find(line,"Card type") + if pos >=0: + splitline= line.split(':') + Cardtype=splitline[1].strip() + + pos = string.find(line,"Bus info") + if pos >=0: + splitline= line.split(':',1) + Businfo=splitline[1].strip() + return Cardtype,Driver + + def parse_full_udev(self): + udev_props = [] + #ATTRS{serial}=="00A2023E"\n', + #SUBSYSTEMS=="usb"\n', + #SUBSYSTEM=="video4linux"\n', + #KERNELS=="0000:08:08.0"\n', + #DRIVERS=="hdpvr"\n' + #DRIVERS=="ivtv"\n', + #ATTR{index}=="0" + match = ['SUBSYSTEM', + 'SUBSYSTEMS', + 'DRIVERS', + 'KERNELS', + 'ATTRS{serial}', + 'ATTR{name}', + 'ATTR{index}' + ] + + for item in match: + regex = re.compile('%s.*$' %item) + for line in self.full_udev_attribs: + m = regex.search(line.strip()) + if m: + #print line + udev_props.append(line.strip()) + break + + #throw out kernels for usb subsystems. + if 'SUBSYSTEMS=="usb"' in udev_props: + #print "found usb" + new_udev_props=[] + for index, item in enumerate(udev_props): + #print item,index + if item.startswith("DRIVERS=="): + continue + elif item.startswith("KERNELS=="): + continue + else: + new_udev_props.append(item) + udev_props = new_udev_props + + + return udev_props + + def is_hdpvr(self): + if self.description == "Hauppauge HD PVR": + return True + return False + + def is_mpeg(self): + if self.driver in ["ivtv","saa7164[0]","saa7164"]: + return True + return False + + def find_tuner_hash(self): + #tuner hash will be driven by card_type pci id and index + i='' + k='' + tuner_hash='' + card_type = self.get_card_type() + if card_type == "v4l_hdpvr": + for index, item in enumerate(self.udev_props): + if item.startswith("ATTRS{serial}=="): + hex_serial=item.split("==")[1].strip('''"''') + serial = int(hex_serial, 16) + tuner_hash="hdpvr_%s" %serial + + else: + for index, item in enumerate(self.udev_props): + if item.startswith("KERNELS=="): + k=item.split("==")[1].strip('''"''') + k=k.replace(":", "_") + k=k.replace("0", "") + k=k.replace(".", "") + + if item.startswith("ATTR{index}=="): + i=item.split("==")[1].strip('''"''') + + tuner_hash="%s%s%s" %(card_type,k,i) + + return tuner_hash + + def escapeSpecialCharacters ( self, text, characters ): + for character in characters: + text = text.replace( character, '\\' + character ) + return text + + def create_udev_rule(self): + #DRIVERS=="ivtv", ATTR{name}=="ivtv? encoder MPG", KERNELS=="0000:08:09.0" SYMLINK+="myth/aivtv2" + line = ','.join(self.udev_props) + line += ' SYMLINK+="vstatic/%s"' %(self.get_tuner_hash()) + self.staticdevice = "/dev/vstatic/%s" %(self.get_tuner_hash()) + return self.escapeSpecialCharacters(line,'[]') + + def card_mpeg_values(self): + values = { + 'CardType' : 'MPEG' , + 'VideoDevice' : self.staticdevice, + 'Defaultinput' : 'Television', + 'HostName' : self.localhostname, + 'dvb_wait_for_seqstart' :'1', + 'signal_timeout' :'1000', + 'channel_timeout' :'12000', + 'diseqcid' :'NULL', + 'dvb_eitscan' :'1' + } + + return values + + def card_hdpvr_values(self): + values = { + 'CardType' : 'HDPVR' , + 'VideoDevice' : self.staticdevice, + 'Defaultinput' : 'Television', + 'HostName' : self.localhostname, + 'dvb_wait_for_seqstart' :'1', + 'signal_timeout' :'1000', + 'channel_timeout' :'12000', + 'diseqcid' :'NULL', + 'dvb_eitscan' :'1' + } + return values + + def do_insert(self,values): + try: + header = { 'User-Agent' : "autocard" } + url="http://127.0.0.1:6544/Capture/AddCaptureCard/" + data = urllib.urlencode(values) + req = urllib2.Request(url, data, header) + self.response = urllib2.urlopen(req) + except: + print " **Insert of %s failed" %self.staticdevice + + def insert_myth(self,myth_tuner_list): + #check if tuner is already in the db + if self.staticdevice in myth_tuner_list: + print " *%s %s already in mythdb" %(self.get_card_type(),self.staticdevice) + else: + #determine values to use based on card type + print " Inserting %s" %self.staticdevice + if self.is_hdpvr() == True: + values = self.card_hdpvr_values() + self.do_insert(values) + elif self.is_mpeg() == True: + values = self.card_mpeg_values() + self.do_insert(values) + else: + print " Unknown V4l type, not adding to myth database" + return + + def set_hostname(self,hostname): + self.localhostname = hostname + + def set_tuner_index(self,index): + #only used by dvb, but here to be complete + self.tuner_index = index + + def get_dev_node(self): + return self.device + + def get_full_attribs(self): + return self.full_attribs + + def get_full_udev_attribs(self): + return self.full_udev_attribs + + def get_card_type(self): + if self.is_hdpvr() == True : + rc = "v4l_hdpvr" + elif self.is_mpeg() == True: + rc = "v4l_mpeg" + else: + rc = "v4l" + return rc + + def get_description(self): + return self.description + + def get_udev_probs(self): + return self.udev_props + + def get_tuner_hash(self): + return self.tuner_hash + + def get_udev_rule(self): + return self.udev_rule + + def get_static_device(self): + return self.staticdevice + + +#----- +class hdhr_tuners(): + def __init__(self, device,ip): + self.device = device + self.ip = ip + self.description = self.find_description() + self.staticdevice = device + + def find_description(self): + command = '/usr/bin/hdhomerun_config %s get /sys/hwmodel' %self.device + results=os.popen(command,'r') + return results.readline().strip() + + def insert_myth(self,hdhr_list): + if self.device in hdhr_list: + print " *hdhr %s already in mythtdb" %self.device + else: + print " Inserting HDHR %s" %self.device + self.do_insert() + pass + + def do_insert(self): + try: + header = { 'User-Agent' : "autocard" } + url="http://127.0.0.1:6544/Capture/AddCaptureCard/" + values = self.card_hdhr_values() + data = urllib.urlencode(values) + req = urllib2.Request(url, data, header) + self.response = urllib2.urlopen(req) + except: + print " **Insert of %s failed" %self.device + + def card_hdhr_values(self): + values = { + 'CardType' : 'HDHOMERUN' , + 'VideoDevice' : self.device, + 'Defaultinput' : 'Television', + 'HostName' : self.localhostname, + 'dvb_wait_for_seqstart' :'1', + 'signal_timeout' :'1000', + 'channel_timeout' :'3000', + 'diseqcid' :'NULL', + 'dvb_eitscan' :'1' + } + return values + + def set_hostname(self,hostname): + self.localhostname = hostname + + def set_tuner_index(self,index): + #only used by dvb, but here to be complete + self.tuner_index = index + + + def get_dev_node(self): + return self.device + + def get_card_type(self): + return "hdhr" + + def get_description(self): + desc = "%s - %s" %(self.description,self.ip) + return desc + + def get_udev_rule(self): + return + + def get_tuner_hash(self): + return self.device + + def get_static_device(self): + return self.staticdevice + + + + +#----- +class dvb_tuners(): + def __init__(self, device): + self.device = device + self.tuner_index = 1 + self.dvb_number = self.find_dvb_number() + self.description = self.find_description() + self.full_udev_attribs = self.find_full_udev_attribs() + self.udev_props = self.parse_full_udev() + self.tuner_hash = self.find_tuner_hash() + self.udev_rule = self.create_udev_rule() + #self.staticdevice is set in create_udev_rule + + def find_description(self): + command = '/usr/bin/dvb-fe-tool -g -a %s' %self.dvb_number + results=os.popen(command,'r') + line = results.readline().strip() + d = line.split('''(''') + return d[0] + + def find_full_udev_attribs(self): + cmd = 'udevadm info -a -p $(udevadm info -q path -n %s)' %self.device + return os.popen(cmd).readlines() + + def find_dvb_number(self): + #/dev/dvb/adapter2/frontend0 + d=self.device.split("/")[3] + dvb_number=d.partition("adapter")[2] + return dvb_number + + def parse_full_udev(self): + udev_props = ['KERNEL=="dvb?.frontend?"'] + #ATTRS{serial}=="00A2023E"\n', + #SUBSYSTEMS=="usb"\n', + #SUBSYSTEM=="video4linux"\n', + #KERNELS=="0000:08:08.0"\n', + #DRIVERS=="hdpvr"\n' + #DRIVERS=="ivtv"\n', + #ATTR{index}=="0" + #KERNEL=="dvb1.frontend0" + + match = ['SUBSYSTEM', + 'SUBSYSTEMS', + 'DRIVERS', + 'KERNELS', + 'ATTRS{serial}', + 'ATTR{name}', + 'ATTR{index}' + ] + + for item in match: + regex = re.compile('%s.*$' %item) + for line in self.full_udev_attribs: + m = regex.search(line.strip()) + if m: + #print line + udev_props.append(line.strip()) + break + + #throw out kernels for usb subsystems. + if 'SUBSYSTEMS=="usb"' in udev_props: + #print "found usb" + new_udev_props=[] + for index, item in enumerate(udev_props): + #print item,index + if item.startswith("DRIVERS=="): + continue + elif item.startswith("KERNELS=="): + continue + else: + new_udev_props.append(item) + udev_props = new_udev_props + return udev_props + + def find_tuner_hash(self): + #tuner hash will be driven by card_type pci id and index + i='' + k='' + tuner_hash='' + card_type = self.get_card_type() + + for index, item in enumerate(self.udev_props): + if item.startswith("KERNELS=="): + k=item.split("==")[1].strip('''"''') + k=k.replace(":", "_") + k=k.replace("0", "") + k=k.replace(".", "") + + if item.startswith("ATTR{index}=="): + i=item.split("==")[1].strip('''"''') + + tuner_hash="%s%s%s" %(card_type,k,i) + return tuner_hash + def escapeSpecialCharacters ( self, text, characters ): + for character in characters: + text = text.replace( character, '\\' + character ) + return text + def create_udev_rule(self): + line = ','.join(self.udev_props) + line += ' RUN+="/usr/MythVantage/bin/udev_link.sh %s $env{DEVNAME} "' %(self.get_tuner_hash()) + self.staticdevice = "/dev/dvb/adapter_static_%s_%s/frontend0" %(self.get_tuner_hash(),self.tuner_index) + return self.escapeSpecialCharacters(line,'[]') -def PRINTINFO(): - global cardlist + def insert_myth(self,myth_tuner_list): + if self.staticdevice in myth_tuner_list: + print " *dvb %s already in mythtdb" %self.staticdevice + else: + print " Inserting DVB Tuner %s" %self.staticdevice + self.do_insert() + pass - for list in cardlist: - if list != "_placeholder_": - print list - #print "-------------" + def do_insert(self): + try: + header = { 'User-Agent' : "autocard" } + url="http://127.0.0.1:6544/Capture/AddCaptureCard/" + values = self.card_dvb_values() + data = urllib.urlencode(values) + req = urllib2.Request(url, data, header) + self.response = urllib2.urlopen(req) + except: + print " **Insert of %s failed" %self.staticdevice -def GATHER_HDR(): - global cardlist + def card_dvb_values(self): + values = { + 'CardType' : 'DVB' , + 'VideoDevice' : self.staticdevice, + 'Defaultinput' : 'Television', + 'HostName' : self.localhostname, + 'dvb_wait_for_seqstart' :'1', + 'signal_timeout' :'1000', + 'channel_timeout' :'12000', + 'diseqcid' :'NULL', + 'dvb_on_demand' :'0', + 'dvb_eitscan' :'1' + } + return values + + def set_tuner_index(self,index): + self.tuner_index = index + self.tuner_hash = self.find_tuner_hash() + self.udev_rule = self.create_udev_rule() + + def set_hostname(self,hostname): + self.localhostname = hostname + + def get_dev_node(self): + return self.device + + def get_card_type(self): + return "dvb" + + def get_description(self): + return self.description + + def get_full_udev_attribs(self): + return self.full_udev_attribs + + def get_tuner_hash(self): + return self.tuner_hash + + def get_udev_rule(self): + return self.udev_rule + + def get_static_device(self): + return self.staticdevice +#-- +class infinitv_tuner(): + def __init__(self, tuner_number,ip): + self.tuner_number = tuner_number + self.ceton_defined_tuner = tuner_number + 1 + self.ip = ip + self.serial_num = self.find_serial() + self.connection = self.find_connection() + self.description = self.find_description() + self.staticdevice = self.find_static() + + def find_static(self): + static="%s-RTP.%s" %(self.ip,self.tuner_number) + return static + + def find_connection(self): + uri='get_var.json?i=0&s=diag&v=Host_Connection' + try: + url="http://%s/%s" %(self.ip,uri) + req = urllib2.Request(url) + r = urllib2.urlopen(req).read() + response = r.split()[2].strip('''"''') + except: + response='unknown' + return response + + def find_serial(self): + uri='get_var.json?i=0&s=diag&v=Host_Serial_Number' + try: + url="http://%s/%s" %(self.ip,uri) + req = urllib2.Request(url) + r = urllib2.urlopen(req).read() + response = r.split()[2].strip('''"''') + except: + response='unknown' + return response + + def find_description(self): + desc="Ceton InfiniTV %s Tuner %s" %(self.connection, + self.ceton_defined_tuner) + return desc + + def do_insert(self): + try: + header = { 'User-Agent' : "autocard" } + url="http://127.0.0.1:6544/Capture/AddCaptureCard/" + values = self.card_ceton_values() + data = urllib.urlencode(values) + req = urllib2.Request(url, data, header) + self.response = urllib2.urlopen(req) + except: + print " **Insert of %s failed" %self.staticdevice + + def card_ceton_values(self): + values = { + 'CardType' : 'CETON' , + 'VideoDevice' : self.staticdevice, + 'Defaultinput' : 'Television', + 'HostName' : self.localhostname, + 'dvb_wait_for_seqstart' :'1', + 'signal_timeout' :'1000', + 'channel_timeout' :'3000', + 'diseqcid' :'NULL', + 'dvb_eitscan' :'1' + } + return values + + def insert_myth(self,myth_tuner_list): + if self.staticdevice in myth_tuner_list: + print " *infinitv %s already in mythtdb" %self.staticdevice + else: + print " Inserting Ceton InfinitTV Tuner %s" %self.staticdevice + self.do_insert() + return + + def write_proxy(self): + directory="/etc/ceton_proxy.d" + if not os.path.exists(directory): + os.makedirs(directory) + proxy_file = "%s/%s" %(directory,self.get_proxy_num()) + try: + f = open(proxy_file,'w') + line="port=%s\n" %(self.get_proxy_num()) + f.write(line) + line="ip=%s\n" %(self.ip) + f.write(line) + except: + print " *Problem creating proxy file %s" %proxy_file + return + + def get_static_device(self): + return self.staticdevice + + def get_tuner_hash(self): + return self.staticdevice + + def set_proxy(self,proxy_num): + self.proxy_num = 7000 + proxy_num + return + + def set_hostname(self,hostname): + self.localhostname = hostname + return + + def set_tuner_index(self,index): + #only used by dvb, but here to be complete + self.tuner_index = index + return + def get_proxy_num(self): + return self.proxy_num + + def get_udev_rule(self): + return + + def get_card_type(self): + return "infinitv" + + def get_description(self): + desc = "%s - %s" %(self.description,self.ip) + return desc + + def get_serial_number(self): + return self.serial_num +#-- end infinitv + +#------------------END TUNER CLASSES----------------------- + +#------------------START OF TUNER GATHERING----------------- +def find_hdhr_tuner(hdhrdevice): + htuner_list=[] + command="/usr/bin/hdhomerun_config %s get /tuner%s/status" + #loop over 4 possible tuners + for i in range(4): + c=command %(hdhrdevice,i) + results=os.popen(c,'r') + lines=results.readlines() + try: + #if the first line starts with error, assume it's not a tuner and + #there are no more tuners for this device. + if lines[0].strip().startswith("ERROR"): + break + else: + t="%s-%s" %(hdhrdevice,i) + htuner_list.append(t) + except: + pass + return htuner_list + +def gather_hdhr(tuner_list): command="/usr/bin/hdhomerun_config --discover" results=os.popen(command,'r') - line=results.readline() - if line.strip().split()[0] == "no": - print "HDHOMERUN not detected" - else: - print line - hdrdevice=line.strip().split()[2] - print hdrdevice - Driver="hdr" - Device=hdrdevice - Cardtype="HDHOMERUN" - Businfo=hdrdevice - cardprops = [Device,Driver , Cardtype , Businfo] - cardlist.append(cardprops) - - -def GATHER_v4l_CARDS(): - global cardlist - cardlist=["_placeholder_"] - # print "Looking for v4l cards" + lines=results.readlines() + try: + if lines[0].strip().split()[0] == "no": + print "HDHOMERUN not detected" + else: + for line in lines: + hdhrdevice=line.strip().split()[2] + hdhrip = line.strip().split()[5] + tuners = find_hdhr_tuner(hdhrdevice) + for t in tuners: + tuner_list.append(hdhr_tuners(t,hdhrip)) + except: + print "Error finding HDHOMERUN" + return tuner_list + +def gather_v4l(tuner_list): try: - filelist = os.listdir('/dev/v4l/') + filelist = os.listdir('/dev/v4l/by-path/') except OSError: - filelist=" " + pass #fakelist=['/dev/v4l/video3', 'ivtv', 'WinTV PVR 500 (unit #2)', '0000:04:09.0'] #cardlist.append(fakelist) try: - filelist = glob.glob("/dev/v4l/video?") - Driver="" - Cardtype="" - Businfo="" - numcards = 0 - for Device in filelist: - #print card - numcards = numcards+1 - cmd = 'v4l2-ctl -D -d' + Device - for line in os.popen(cmd).readlines(): - #print line - pos = string.find(line,"Driver name") - if pos >=0: - splitline= line.split(':') - Driver=splitline[1].strip() - pos = string.find(line,"Card type") - if pos >=0: - splitline= line.split(':') - Cardtype=splitline[1].strip() - - pos = string.find(line,"Bus info") - if pos >=0: - splitline= line.split(':',1) - Businfo=splitline[1].strip() - - #print Device,Driver , Cardtype , Businfo,numcards - cardprops = [Device,Driver , Cardtype , Businfo] - cardlist.append(cardprops) + p = re.compile('^/dev/video?\d$') + filelist = glob.glob("/dev/v4l/by-path/*video*") + for device in filelist: + Device=os.path.realpath(device) + if not p.search(Device): + continue + #print "real device node" + #print Device + tuner_list.append(v4l_tuners(Device)) except IOError: - print "no v4l cards found" - sys.exit(2) - - -def WRITEUDEV_IVTV(): - global insertmyth - cursor = db.cursor() - #add ivtv,cid lookup loop through until empty. - cursor.execute("select distinct(uniqid) from autocard where driver='ivtv' and devicestatus='will-add'") - cidrows = cursor.fetchall() - for row in cidrows: - cid=row[0] - cursor.execute("select dev,driver,description,devicestatus,hostname from autocard where uniqid=%s limit 1;",(cid)) - result = cursor.fetchone() - description=result[2] - driver='DRIVERS==\"ivtv\"' - ATTRNAME='ATTR{name}=="ivtv? encoder MPG"' - KERNELS='KERNELS==\"' - KERNELS+=cid - KERNELS+="\"" - #filter out non digit or chars - keep=letters.join(digits) - description=filter(lambda c: c in keep, description) - devnode="ivtv/" - #devnode+=description + "_" - udevcid=cid.partition(":") - devnode+=udevcid[2] - devnode+="_video" - UDEV_RULE=driver +', '+ATTRNAME+', '+ KERNELS +', ' + 'NAME=\"' + devnode + '"' - print "Here is the udev rule" - print UDEV_RULE - filename='/etc/udev/rules.d/11-ivtv-'+cid+'.rules' - file = open(filename,'w') - file.write(UDEV_RULE) - if ( insertmyth == "true"): - devnode="/dev/"+devnode - INSERTCARD_INTOMYTH(devnode,"ivtv",description) - cursor.execute("update autocard set devicestatus='done' where uniqid=%s;",(cid)) -#now insert HDR - cursor.execute("select distinct(uniqid),description from autocard where driver='hdr' and devicestatus='will-add'") - cidrows = cursor.fetchall() - for row in cidrows: - if ( insertmyth == "true"): - deviceid=row[0] - #cardtype="HDHOMRUN" - #defaultinput="MPEG2TS" - dbox2_port=row[1] - tuner_number=dbox2_port.rpartition(' ')[2] - INSERTHDR_INTOMYTH(deviceid,tuner_number) - cursor.execute("update autocard set devicestatus='done' where uniqid=%s and description=%s;",(deviceid,dbox2_port)) - - - -def CLEARAUTOCARD(): - cursor = db.cursor() - cursor.execute("delete from autocard") - -def RELOADUDEV(): - print "relaoding udev rules" - os.system('udevcontrol reload_rules') - os.system('rmmod ivtv') - os.system('udevtrigger') - - -def usage(): - print " -h help" - print " -g gather and print out the found cards" - print " -w write out the udev rules" - print " -i insert cards into myth that are marked will-add(only used with -w)" - print " -r reload udev rules" - print " -c clear the autocard db" + print "no v4l cards found" + return tuner_list + +def gather_dvb(tuner_list): + try: + filelist = os.listdir('/dev/dvb/') + except OSError: + pass -def main(argv): - global db - global cardlist - global currenthostname - currenthostname="" - writeudev="false" - global insertmyth - insertmyth ="false" - - db = MySQLdb.connect(host="localhost", user="mythtv", passwd="mythtv", db="mythconverg") try: - cursor = db.cursor() - cursor.execute("describe autocard;") - except MySQLdb.Error, e: - cursor.execute("create table autocard(dev varchar(50),driver varchar(50),description varchar(50),uniqid varchar(50), devicestatus varchar(50),hostname varchar(50));") - print "table created" + for d in filelist: + if os.path.islink("/dev/dvb/"+d): + continue + Device=os.path.realpath("/dev/dvb/"+d+"/frontend0") + tuner_list.append(dvb_tuners(Device)) + except: + print "no dvb cards found" + return tuner_list - if ( currenthostname == "" ): - currenthostname = socket.gethostname() +def gather_ceton(tuner_list): + #find and configure ctn network interfaces + ceton_network_list = find_ceton_network_list() + #find all the cards on a network interface + for iface in ceton_network_list: + #command="cat /tmp/find_ceton.txt" + print "Scanning %s network for ceton infinitv" %iface + command="/usr/MythVantage/bin/discover_infinitv.py %s" %iface + results=os.popen(command,'r') + lines=results.readlines() + #try: + if lines[0].strip().split()[0] == "no": + print "Ceton not detected" + else: + for line in lines: + #Found InfiniTV. Location URL: http://192.168.200.1/description.xml + #cetondevice = line.strip().split()[0] + cetonip = line.strip().split("/")[2] + tuners = [0,1,2,3] + for t in tuners: + tuner_list.append(infinitv_tuner(t,cetonip)) + #except: + # print "Error finding Ceton InfinitTV" + + return tuner_list + +#------------------END OF TUNER GATHERING----------------- +#----linhes specific for networking +def config_ctn_network(ctn_iface): + etcnetdir = "/etc/net/ifaces/%s" %ctn_iface + if not os.path.exists(etcnetdir): + print "Creating config for interface %s" %ctn_iface + os.mkdir(etcnetdir) + outline=''' +TYPE=eth +DISABLED=no +BOOTPROTO=dhcp +ONBOOT=yes +CONFIG_WIRELESS=no +DHCP_ARGS="-C resolv.conf" + ''' + optionfile="%s/options" %etcnetdir + f = open(optionfile, 'w') + f.write(outline) + f.close() + command="/etc/net/scripts/network.init start" + os.system(command) + else: + pass #config is present + + +def find_ceton_network_list(): + import netifaces + + netinterfaces = netifaces.interfaces() + ctnip=[] + for i in netinterfaces: + if i.startswith("ctn") or i.startswith("usb"): + #configure and start ctn network + config_ctn_network(i) + + #read ip + ctnip.append(netifaces.ifaddresses(i) + [netifaces.AF_INET][0]['addr']) + return ctnip + +#--end of linhes specific + +def gather_tuners(): + tuner_list = [] + tuner_list = gather_hdhr(tuner_list) + tuner_list = gather_v4l(tuner_list) + tuner_list = gather_dvb(tuner_list) + tuner_list = gather_ceton(tuner_list) + #set the number of times we have seen a specific tuner_hash + #This will be used by dvb when tuner_hashs conflict + tuner_count = {} + for i in tuner_list: + th = i.get_tuner_hash() + if th in tuner_count: + tuner_count[th] += 1 + else: + tuner_count[th] = 1 + i.set_tuner_index(tuner_count[th]) + return tuner_list + +def trigger_udev(): + print "Reloading udev rules" + command = '/usr/bin/udevadm control --reload' + results=os.popen(command,'r') + + print "Triggering udev events" + command = '/usr/bin/udevadm trigger' + results=os.popen(command,'r') + +def write_udev_file(rule_list): + udevfile = '/etc/udev/rules.d/99-mv-persistent-video.rules' + try: + f = open(udevfile, 'w') + line = "#Do not edit this file, it is auto generated by autocard.py \n\n" + f.write(line) + for rule in rule_list: + if rule: + line = "%s \n" %(rule) + f.write(line) + f.close() + except: + print "Error creating %s" %udevfile + trigger_udev() + +def write_udev_map(tuner_list): + udevfile = '/etc/udev/mv-persistent-video.description' + try: + f = open(udevfile, 'w') + line = "#Do not edit this file, it is auto generated by autocard.py \n" + f.write(line) + line = "#This file is used to generate the static tuner card web page\n" + f.write(line) + for i in tuner_list: + if i.get_card_type() == "hdhr": + pass + line="hdhr:%s:%s" %(i.get_description(),i.get_static_device()) + f.write(line) + f.write("\n") + elif i.get_card_type() == "v4l_mpeg": + pass + line="V4L_mpeg:%s: %s " %(i.get_description(),i.get_static_device()) + f.write(line) + f.write("\n") + elif i.get_card_type() == "v4l": + pass + line="V4L:%s:%s " %(i.get_description(),i.get_static_device()) + f.write(line) + f.write("\n") + elif i.get_card_type() == "v4l_hdpvr": + pass + line="hdpvr:%s: %s " %(i.get_description(),i.get_static_device()) + f.write(line) + f.write("\n") + elif i.get_card_type() == "dvb": + line="dvb:%s: %s " %(i.get_description(),i.get_static_device()) + f.write(line) + f.write("\n") + elif i.get_card_type() == "infinitv": + line="infinitv:%s:%s:%s" %(i.get_description(), + i.get_static_device(), + i.get_proxy_num()) + f.write(line) + f.write("\n") + else: + print i + line = i + f.write(line) + f.write("\n") + except: + print "Error creating %s" %udevfile + f.close() + +def checkURL(url): try: - opts, args = getopt.getopt(argv, "hgwircd", ["help", "gathercards", "writeudev" ,"insert" , "reloadudev" , "clearautocard"] ) - except getopt.GetoptError: - sys.exit(2) - for opt, arg in opts: - if opt in ("-h", "--help"): - usage() - sys.exit() - elif opt in ( "-g" , "--gathercards"): - GATHER_v4l_CARDS() - GATHER_HDR() - INSERTAUTOCARD() - PRINTINFO() - elif opt in ("-w", "--writeudev"): - writeudev="true" - elif opt in ("-i", "--insert"): - insertmyth="true" - elif opt in ( "-r" , "--reloadudev"): - RELOADUDEV() - elif opt in ( "-c" , "--clearautocard"): - CLEARAUTOCARD() - elif opt in ( "-d" ): - INSERTCARD_INTOMYTH("file:/myth/video/TripThe1939.mpeg","ivtv","Dummy tuner") - INSERTNULL_SOURCE("dummy","/bin/true","","default","NULL","NULL","0") - - if ( writeudev == "true"): - WRITEUDEV_IVTV() + connection = urllib2.urlopen(url,None,3) + code=connection.getcode() + connection.close() + if code == 200: + rc=0 + #except urllib2.HTTPError, e: + except: + rc=1 + return rc +def getURL(url): + dom = None + try: + connection = urllib2.urlopen(url,None,3) + data = connection.read() + connection.close() + dom = parseString(data) + #except urllib2.HTTPError, e: + except: + pass + return dom +def find_hdhr_in_use(): + hdhr_list = [] + url='http://127.0.0.1:6544/Capture/GetCaptureCardList?CardType=HDHOMERUN' + data = getURL(url) + if data: + xmlTags = data.getElementsByTagName('VideoDevice') + for i in xmlTags: + xmlTag=i.toxml() + xmlData=xmlTag.replace('<VideoDevice>','').replace('</VideoDevice>','') + hdhr_list.append(xmlData) + return hdhr_list +def find_in_use_card_list(): + in_use_tuner_list=[] + url='http://127.0.0.1:6544/Capture/GetCaptureCardList?HostName=%s' %localhostname + data = getURL(url) -if __name__ == "__main__": - main(sys.argv[1:]) + if data: + xmlTags = data.getElementsByTagName('VideoDevice') + for i in xmlTags: + xmlTag=i.toxml() + xmlData=xmlTag.replace('<VideoDevice>','').replace('</VideoDevice>','') + in_use_tuner_list.append(xmlData) + return in_use_tuner_list + +def usuage(): + help=''' + Autocard.py is a program that will take the guess work out of setting up tuner/capture cards. + There are 4 options: + help : This help screen + print: Will find and printout any detected capture cards, including network based tuners like the hdhomerun_config + udev : This option creates a set of static device nodes for the local capture cards. + Rules are based on pci/usb path so moving the card into a different expansion slot will nullify the udev rule + HDPVR devices use the serial number as the primary key for the udev rule_list + + insertdb : This option will insert any detected cards into the MythTV database using the static device generated by udev. + This option will also generate udev rules. Tuners that are already defined will not be readded. + + write_proxy: This will write out the config used by the service ceton_proxy + all : The same as using print udev insertdb write_proxy + + + EX: + autocard.py print + autocard.py insertdb + ''' + print help + +def main(argv): + listcards = False + udev = False + insertdb = False + write_proxy = False + + if argv==[] or "help" in argv: + usuage() + sys.exit(0) + + if "print" in argv: + listcards = True + + if "udev" in argv: + udev = True + write_proxy = True + + if "insertdb" in argv: + insertdb = True + udev = True + write_proxy = True + if "write_proxy" in argv: + write_proxy = True + if "all" in argv: + udev = True + insertdb = True + listcards = True + write_proxy = True + tuner_list = gather_tuners() + rule_list = [] + #setting the proxy port for ceton webpage + ceton_proxy = 1 + for i in tuner_list: + if i.get_card_type() == "infinitv": + i.set_proxy(ceton_proxy) + ceton_proxy = ceton_proxy + 1 -#mysql> create table autocard(dev varchar(50),driver varchar(50),description varchar(50),uniqid varchar(50), devicestatus varchar(50),hostname varchar(50)); -#Query OK, 0 rows affected (0.14 sec) + #setting the hostname for each tuner + i.set_hostname(localhostname) + rule_list.append(i.get_udev_rule()) + if listcards == True: + print i.get_card_type() + print "----------------" + print "\t" , i.get_description() + print "\t" , i.get_static_device() -#mysql> describe autocard; -#+--------------+-------------+------+-----+---------+-------+ -#| Field | Type | Null | Key | Default | Extra | -#+--------------+-------------+------+-----+---------+-------+ -#| dev | varchar(50) | YES | | NULL | | -#| driver | varchar(50) | YES | | NULL | | -#| description | varchar(50) | YES | | NULL | | -#| uniqid | varchar(50) | YES | | NULL | | -#| devicestatus | varchar(50) | YES | | NULL | | -#| hostname | varchar(50) | YES | | NULL | | -#+--------------+-------------+------+-----+---------+-------+ + print("Writing out tuner map") + write_udev_map(tuner_list) + restart_proxy=False + if write_proxy == True: + for i in tuner_list: + if i.get_card_type() == "infinitv": + i.write_proxy() + restart_proxy=True + if restart_proxy == True: + command="add_service.sh cetonproxy" + os.system(command) + print" Restarting ceton proxy" + command="sv restart cetonproxy" + os.system(command) + if udev == True: + print("Writing out udev rules") + write_udev_file(rule_list) + if insertdb == True: + be_ready = False + i = 0 + while i < 10 or be_ready : + if checkURL('http://127.0.0.1:6544') == 0: + be_ready = True + break + i = i + 1 + print "Waiting for MythTV backend connection: %s/10" %i + time.sleep(5) + if be_ready == True : + #find all HDHR + in_use_hdhr_list = find_hdhr_in_use() + #find other cards local + in_use_local_card_list = find_in_use_card_list() + print "Adding cards to mythtv database" + for i in tuner_list: + if i.get_card_type() == "hdhr": + i.insert_myth(in_use_hdhr_list) + else: + i.insert_myth(in_use_local_card_list) + + +if __name__ == "__main__": + localhostname = socket.gethostname() + applock = ApplicationLock ('/var/run/autocard.lock') + if (applock.lock ()): + #print ("Obtained lock") + main(sys.argv[1:]) + #print ("Unlocking") + applock.unlock () + else: + print ("Unable to obtain lock, exiting") |