123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440 |
- # coding: utf-8
- """
- Enigma2 handling objects
- (c)Ivars 2013-2015, v0.2
- """
-
- import sys, os, os.path
- from urllib import quote, unquote
- from record3 import Rec
-
- class DBServices(object):
- """Dreambox services, stored in lamedb (E2)/services(E1) file handling class"""
-
- def __init__(self,service_path=None,enigma=2):
- self.enigma = enigma
- if not service_path:
- service_path = "enigma2" if sys.platform=="win32" else "/etc/enigma2"
- self.service_path = service_path
- #print service_path
-
- if self.enigma == 2:
- if not "ftp:" in service_path:
- self.service_fname= os.path.join(service_path,"lamedb")
- self.bouquets_fname = os.path.join(service_path, "bouquets.tv")
- else:
- sep = "" if service_path[-1]=="//" else "//"
- self.service_fname= service_path+sep+"lamedb"
- self.bouquets_fname = service_path+sep+"bouquets.tv"
-
- else: # ENIGMA === "1":
- self.service_fname = os.path.join(service_path,"services")
- self.bouquets_fname = os.path.join(service_path, "userbouquets.tv.epl")
- #print self.service_fname
- self.services = []
- self.index_sref= {}
- self.index_chid = {}
- self.index_name = {}
- self.index_provider = {}
- self.bouquets = []
- self.bouquets_services = {}
-
- self.transp = []
- self.tp_index_tpid = {}
- self.tp_index_pic ={}
-
- self._load_services()
- self._load_bouquets()
-
- def _load_services(self):
- #tpref - lamedb/transponders
- # NS:TSID:ONID
- # s FREQ:SR:POLAR:FREC:49:2:0
- # X X X
- # D D D D
-
- # lref - lamedb/services
- # SID:NS:TSID:ONID:STYPE:UNUSED(channelnumber in enigma1)
- # 0 1 2 3 4 5
- # X X X X D D
- # wref - bouquets/picon
- # REFTYPE:FLAGS:STYPE:SID:TSID:ONID:NS:PARENT_SID:PARENT_TSID:UNUSED
- # 0 1 2 3 4 5 6 7 8 9
- # D D X X X X X X X X
-
- f_services = open(self.service_fname,"r") if not self.service_fname[0:4] == "ftp:" else urllib2.urlopen(self.service_fname)
-
- line = f_services.readline()
- if not "eDVB services" in line:
- raise Exception("no correct lamedb file")
- line = f_services.readline()
-
- # Read transponders
- i = 0
- while True:
- line = f_services.readline()
- if "end" in line: break
- tp = Rec()
- #tp = {}
- ff = line.strip().split(":")
- tp["ns"] = ns = pos_str2int(ff[0])
- tp["tsid"] = tsid = int(ff[1],16)
- tp["onid"] = onid = int(ff[2],16)
- line = f_services.readline()
- tp["params"] = params = line.strip().split(" ")[1]
- ff = params.split(":")
- tp["freq"] = freq = int(ff[0][:-3])
- tp["polar"] = polar = int(ff[2])
- tp["tpid"] = tpid = (ns,tsid,onid)
- self.transp.append(tp)
- self.tp_index_tpid[tpid] = i
- self.tp_index_pic[(ns,freq,polar)] = i
-
- line = f_services.readline()
- i += 1
-
- # Reading services
- i= 0
- line = f_services.readline()
- while True:
-
- line = f_services.readline()
- if line[0:3] == "end": break
- if not line: break
- rec = Rec()
- #rec = {}
- rec["lref"] = line.lower().strip().decode("utf-8")
-
- line = f_services.readline()
- #line = line.replace('\xc2\x87', '').replace('\xc2\x86', '')
- #line = decode_charset(line)
- line = line.decode("utf-8")
- rec["name"] = line.strip()
-
- line = f_services.readline()
- provider = ""
- caid=[]
- for p in line.split(","):
- if p[0:2].lower() == "p:":
- provider = p[2:].strip()
- elif p[0:2].lower() == "c:":
- caid.append(p[2:].strip())
- if provider == "":
- provider = "unknown"
- rec["provider"] = provider.decode("utf-8")
-
- rec["sref"] = lref2sref(rec["lref"])
- r = lref_parse(rec["lref"])
- rec["stype"] = r["stype"]
- rec["chid"] = (r["sid"],r["tsid"],r["onid"])
- rec["caid"] = caid
- self.services.append(rec)
-
- self.index_sref[rec["sref"]] = i
- self.index_chid[rec["chid"]] = i
- name = rec["name"].lower()
- if not self.index_name.has_key(name): self.index_name[name] = []
- self.index_name[name].append(i)
- provider = rec["provider"].lower()
- if not self.index_provider.has_key(provider): self.index_provider[provider] = []
- self.index_provider[provider].append(i)
-
- i += 1
-
- f_services.close()
-
- def _load_bouquets(self):
- f_bouquets = open(self.bouquets_fname,"r") if not self.bouquets_fname[0:4] == "ftp:" else urllib2.urlopen(self.bouquets_fname)
- self.bouquets=Rec()
- for line in f_bouquets.readlines():
- if line[0:9] == "#SERVICE:":
- if self.enigma==1:
- bn = line.strip().split("/")
- else:
- bn = line.strip().split(":")
- bfn = bn[-1]
- bid = bfn.split(".")[1]
-
- ### Process one bouquet file ###
- bouq = Rec()
- bouq.bid = bid
- bouq.name = ""
- bouq.services=[]
- #fb = open(self.fname,"r") if not self.fname[0:4] == "ftp:" else urllib2.urlopen(self.fname)
- fb = open(os.path.join(self.service_path,bfn))
- i= 0
- line = fb.readline()
- while True:
- if line[0:5] == "#NAME":
- bouq.name = line.strip()[6:].decode("utf8")
- elif line[0:8] == "#SERVICE":
- sref = line.strip()[9:]
- s = sref_parse(sref)
- s["sref"] = sref
- if s["flags"] == 64:
- s["type"] = "marker"
- line = fb.readline()
- if line[0:12] =='#DESCRIPTION':
- s["name"] = line [13:].strip().decode("utf8")
- else: continue
- elif s["url"]: # IPTV stream
- s["type"] = "stream"
- s["sref"] = ":".join(s["sref"].split(":")[0:10])+":"
- line = fb.readline()
- if line[0:12] =='#DESCRIPTION':
- s["name"] = line [13:].strip().decode("utf8")
- else: continue
- bouq.services.append(s)
- line = fb.readline()
- if not line: break
- fb.close()
- self.bouquets[bid] = bouq
-
- f_bouquets.close()
-
- def _load_bouquets2(self):
- f_bouquets = open(self.bouquets_fname,"r") if not self.bouquets_fname[0:4] == "ftp:" else urllib2.urlopen(self.bouquets_fname)
- for line in f_bouquets.readlines():
- if line[0:9] == "#SERVICE:":
- if self.enigma==1:
- bn = line.strip().split("/")
- else:
- bn = line.strip().split(":")
- bfn = bn[-1]
- bid = bfn.split(".")[1]
- bouq = Bouquet(bid, self.service_path)
- self.bouquets.append(bouq)
- f_bouquets.close()
-
- def create_bouqet(self,bid,name):
- fname = "userbouquet.%s.tv"%bid
- f_bouquets = open(self.bouquets_fname,"r") if not self.bouquets_fname[0:4] == "ftp:" else urllib2.urlopen(self.bouquets_fname)
- lines = f_bouquets.read().strip()
- f_bouquets.close()
- if not fname in lines:
- lines += "\n#SERVICE: 1:7:1:0:0:0:0:0:0:0:%s\n"%fname
- f_bouquets = open(self.bouquets_fname,"w")
- f_bouquets.write(lines)
- f_bouquets.close()
- with open(os.path.join(self.service_path,fname), 'w') as f:
- f.write("#NAME %s"%name.encode("utf8"))
- pass
-
- def get_bouquets(self):
- if not self.bouquets:
- self._load_bouquets()
- return self.bouquets
-
- def get_bouquet_services(self,bn):
- if not self.bouquets:
- self._load_bouquets()
- return self.bouquets[bn].services
-
- #----------------------------------------------------------------------
- def save_bouquet(self,bn):
- """Save bouquet to file"""
- fn = "userbouquet.%s.tv"%bn
- fb = open(os.path.join(self.service_path,fn),"w")
- fb.write("#NAME %s\n"%self.bouquets[bn].name.encode("utf8"))
- for s in self.bouquets[bn].services:
- if s.type=="marker":
- fb.write("#SERVICE %s\n"%s.sref)
- fb.write("#DESCRIPTION %s\n"%s.name.encode("utf8"))
- elif s.type == "stream":
- fb.write("#SERVICE %s%s:%s\n"%(s.sref,quote(s.url),s.name.encode("utf8")))
- fb.write("#DESCRIPTION %s\n"%s.name.encode("utf8"))
- else:
- fb.write("#SERVICE %s\n"%s.sref)
- fb.close()
-
- def get_service_by_sref(self,sref):
- return self.services[self.index_sref[sref]] if self.index_sref.has_key(sref) else None
-
- def get_service_by_chid(self,chid):
- return self.services[self.index_chid[chid]] if self.index_chid.has_key(chid) else None
-
- def get_service_by_name(self,name):
- return [self.services[i] for i in self.index_name[name]] if name in self.index_name else None
-
- def get_service_by_provider(self,provider):
- return [self.services[i] for i in self.index_provider[provider]] if provider in self.index_privider else Non
-
- def get_transp_by_tpid(self,tpid):
- return self.transp[self.tp_index_tpid[tpid]] if self.tp_index_tpid.has_key(tpid) else None
-
- def get_transp_by_pic(self,picid):
- return self.transp[self.tp_index_pic[picid]] if self.tp_index_pic.has_key(picid) else None
-
- def find_sref(ns,freq,polar,sid):
- "Find service reference according to given parameters"
- tp = services.get_transp_by_pic((ns,freq,polar))
- if tp:
- serv = self.services.get_service_by_chid((sid,tp["tsid"],tp["onid"]))
- if serv:
- return serv["sref"]
- return ""
-
- ########################################################################
- class Bouquet(object):
- """Bouquet file object"""
-
- #----------------------------------------------------------------------
- def __init__(self, bid, service_path=None):
- """Constructor"""
- if not service_path:
- service_path = "enigma2" if sys.platform=="win32" else "/etc/enigma2"
- self.service_path = service_path
- self.bid = bid
- if not "ftp:" in service_path:
- self.fname = os.path.join(service_path, "userbouquet.%s.tv"%self.bid)
- else:
- sep = "" if service_path[-1]=="//" else "//"
- self.fname = os.path.join(service_path, "userbouquet.%s.tv"%self.bid)
- self.load()
-
- #----------------------------------------------------------------------
- def load(self):
- """Load bouquet from file"""
- self.services=[]
- fb = open(self.fname,"r") if not self.fname[0:4] == "ftp:" else urllib2.urlopen(self.fname)
- i= 0
- line = fb.readline()
- while True:
- if line[0:5] == "#NAME":
- self.name = line.strip()[6:].decode("utf8")
- elif line[0:8] == "#SERVICE":
- sref = line.strip()[9:]
- s = sref_parse(sref)
- s["sref"] = sref
- if s["flags"] == 64:
- s["type"] = "marker"
- line = fb.readline()
- if line[0:12] =='#DESCRIPTION':
- s["name"] = line [13:].strip().decode("utf8")
- else: continue
- elif s["url"]: # IPTV stream
- s["type"] = "stream"
- s["sref"] = ":".join(s["sref"].split(":")[0:10])
- line = fb.readline()
- if line[0:12] =='#DESCRIPTION':
- s["name"] = line [13:].strip().decode("utf8")
- else: continue
- self.services.append(s)
- line = fb.readline()
- if not line: break
- fb.close()
-
-
-
- def decode_charset(s):
- u = None
- if isinstance(s,unicode):
- return s
- charset_list=('iso-8859-4','iso-8859-1','iso-8859-2''iso-8859-15')
-
- for charset in charset_list:
- try:
- u=unicode(s,charset,"strict")
- except:
- pass
- else:
- break
-
- if u == None:
- raise Error, "CHARSET ERROR while decoding lamedb. Aborting !"
- else:
- return(u)
-
- # lref - lamedb/services
- # SID:NS:TSID:ONID:STYPE:UNUSED(channelnumber in enigma1)
- # 0 1 2 3 4 5
- # X X X X D D
- #
- # sref bouquets/picon
- # REFTYPE:FLAGS:STYPE:SID:TSID:ONID:NS:PARENT_SID:PARENT_TSID:UNUSED
- # 0 1 2 3 4 5 6 7 8 9
- # D D X X X X X X X X
-
- def lref2sref(s):
- "Converts service refefence from lamedb format to bouquets/picon (standard) format"
- f = s.split(":")
- sid = int(f[0],16)
- ns = int(f[1], 16)
- tsid = int(f[2],16)
- onid = int(f[3],16)
- stype = int(f[4])
-
- s2 = "1:0:%X:%X:%X:%X:%X:0:0:0:" % (stype,sid,tsid,onid,ns)
- return s2
-
- def lref_parse(s):
- "Parse lamedb/service string, return dictionary of items"
- f = s.split(":")
- #r = {}
- r = Rec()
- r["sid"] = int(f[0],16)
- r["ns"] = int(f[1], 16)
- r["tsid"] = int(f[2],16)
- r["onid"] = int(f[3],16)
- r["stype"] = int(f[4])
- return r
-
- def sref2lref(s):
- "Converts service refefence from bouquets/picon (standard) format to lamedb format"
- f = s.split(":")
- reftype = int(f[0])
- flags = int(f[1])
- stype = int(f[2],16)
- sid = int(f[3],16)
- tsid = int(f[4],16)
- onid = int(f[5],16)
- ns = int(f[6],16)
-
- s2 = "%04x:%08x:%04x:%04x:%i:0" % (sid,ns,tsid,onid,stype)
- return s2
-
- def sref_parse(s):
- "Parse service refefence string , return dictionary of items"
- f = s.split(":")
- #r = {}
- r = Rec()
- r["reftype"] = int(f[0])
- r["flags"] = int(f[1])
- r["stype"] = int(f[2],16)
- r["sid"] = int(f[3],16)
- r["tsid"] = int(f[4],16)
- r["onid"] = int(f[5],16)
- r["ns"] = int(f[6],16)
- r["url"] = unquote(f[10]) if len(f)>10 else ""
- return r
-
- pos_int2str = lambda pos_num: "%04x0000"%pos_num
- pos_str2int = lambda pos: int(pos[0:4],16)
-
- def decode_charset(s):
- u = None
- charset_list = ('utf-8','iso-8859-1','iso-8859-2','iso-8859-15')
-
- for charset in charset_list:
- try:
- u = unicode(s,charset,"strict")
- except:
- pass
- else:
- break
-
- if u == None:
- print("CHARSET ERROR while decoding string")
- sys.exit(1)
- else:
- return(u)
-
- import UserDict
-
- if __name__ == "__main__":
- #print "** Starting..."
- #sys.exit(main(sys.argv))
- e2 = DBServices()
- #e2.save_buquet("english")
- e2.create_bouqet("test", "Tests")
- pass
|