|
@@ -0,0 +1,576 @@
|
|
1
|
+# coding: utf-8
|
|
2
|
+#
|
|
3
|
+# This file is part of GetPicons - enigma2 plugin to download picons from lyngsat.com
|
|
4
|
+# Copyright (c) 2016 ivars777 (ivars777@gmail.com)
|
|
5
|
+# Distributed under the GNU GPL v3. For full terms see http://www.gnu.org/licenses/gpl-3.0.en.html
|
|
6
|
+
|
|
7
|
+"""
|
|
8
|
+Dowload and create Enigma2 channels' picons files form lyngsat.com
|
|
9
|
+
|
|
10
|
+Usage [options]
|
|
11
|
+Options:
|
|
12
|
+ -p PACKAGE_LIST, --package=PACKAGE_LIST list of package names (html file name in lyngsat),
|
|
13
|
+ e.g "viasat,ntvplus36"
|
|
14
|
+ -s SAT_LIST, --sat=SAT_LIST list of sattelite positions, e.g. "4.9,-0.8"
|
|
15
|
+ -z SIZE icon size, e.g. "100x60", default - "220x132"
|
|
16
|
+ -f PATH, --folder PATH picon files output folder, default - "/media/hdd/picon"
|
|
17
|
+ -e PATH, --enigma PATH enigma2 folder whera lamedb,settings are located, default - "/etc/enigma2"
|
|
18
|
+ you can use urls, e.g. "ftp://root@receiver_address/etc/enigma2"
|
|
19
|
+ -o, -overwrite overwrite existing picons file (default - no)
|
|
20
|
+ -d, -debug display work progress and write debug info to file for not found services
|
|
21
|
+ -h, --help this help file
|
|
22
|
+
|
|
23
|
+(c)Ivars777 (ivars777@gmail.com) 2013-2015, v0.2
|
|
24
|
+"""
|
|
25
|
+
|
|
26
|
+import sys, os, os.path, getopt
|
|
27
|
+import re
|
|
28
|
+import urllib2
|
|
29
|
+import requests
|
|
30
|
+
|
|
31
|
+try:
|
|
32
|
+ import Image
|
|
33
|
+except:
|
|
34
|
+ from PIL import Image
|
|
35
|
+from StringIO import StringIO
|
|
36
|
+import logging
|
|
37
|
+
|
|
38
|
+options = args = None
|
|
39
|
+_sd= lambda x,d: d if x is None else x # set default value
|
|
40
|
+_sl= lambda x: False if x is None else True # set True of False for option
|
|
41
|
+
|
|
42
|
+def parse_arguments(argv,opt_short,opt_long):
|
|
43
|
+ "Parse command line arguments"
|
|
44
|
+ try:
|
|
45
|
+ options, args = getopt.gnu_getopt(argv, opt_short,opt_long)
|
|
46
|
+ options = Rec(dict([(o[0].replace("-",""),o[1]) for o in options]))
|
|
47
|
+ except getopt.GetoptError, err:
|
|
48
|
+ print err.msg
|
|
49
|
+ print __doc__
|
|
50
|
+ sys.exit(2)
|
|
51
|
+ if options.has_key("h") or options.has_key("help"):
|
|
52
|
+ print __doc__
|
|
53
|
+ sys.exit(2)
|
|
54
|
+ return options,args
|
|
55
|
+
|
|
56
|
+services = None
|
|
57
|
+
|
|
58
|
+def main(argv):
|
|
59
|
+ global options, args, services
|
|
60
|
+
|
|
61
|
+ # Parsing options
|
|
62
|
+ opt_short = 'p:s:z:f:e:odh'
|
|
63
|
+ opt_long = ["package=","sat","folder=","enigma=","overwrite","debug","help"]
|
|
64
|
+ options,args = parse_arguments(argv[1:], opt_short, opt_long)
|
|
65
|
+ options.package = _sd(options.package,_sd(options.p,""))
|
|
66
|
+ options.sat = _sd(options.sat,_sd(options.s,""))
|
|
67
|
+ options.enigma = _sd(options.enigma,_sd(options.e,"/etc/enigma2"))
|
|
68
|
+ options.folder = _sd(options.folder,_sd(options.f,"/media/hdd/picon"))
|
|
69
|
+ options.size = _sd(options.size,_sd(options.z,"220x132"))
|
|
70
|
+ options.overwrite = _sl(_sd(options.overwrite,options.o))
|
|
71
|
+ options.debug = _sl(_sd(options.debug,options.d))
|
|
72
|
+
|
|
73
|
+ options.w,options.h = map(int,options.size.split("x"))
|
|
74
|
+ if not os.path.exists(options.folder):
|
|
75
|
+ os.makedirs(options.folder)
|
|
76
|
+
|
|
77
|
+ if options.debug:
|
|
78
|
+ #filename="get_picons.log" if not os.name == "posix" else "/var/log/get_picons.log"
|
|
79
|
+ filename = os.path.join(options.folder,"get_picons.log")
|
|
80
|
+ FORMAT = "%(asctime)-15s %(message)s"
|
|
81
|
+ logging.basicConfig(filename=filename, format=FORMAT,level=logging.DEBUG)
|
|
82
|
+
|
|
83
|
+ print "** Analyzing lamedb"
|
|
84
|
+ services = DBServices(options.enigma)
|
|
85
|
+ if options.sat:
|
|
86
|
+ package_list = []
|
|
87
|
+ for sat in options.sat.split(","):
|
|
88
|
+ package_list.extend(get_packages(sat))
|
|
89
|
+ elif options.package:
|
|
90
|
+ package_list = options.package.split(",")
|
|
91
|
+ else: # get sattelite list from Enigma settings
|
|
92
|
+ sat_list = []
|
|
93
|
+ package_list = []
|
|
94
|
+ if not "ftp:" in options.enigma:
|
|
95
|
+ fname = os.path.join(options.enigma,"settings")
|
|
96
|
+ f = open(fname)
|
|
97
|
+ else:
|
|
98
|
+ sep = "" if options.enigma[-1]=="//" else "//"
|
|
99
|
+ fname = options.enigma + sep + "settings"
|
|
100
|
+ f = urllib2.urlopen(fname)
|
|
101
|
+ for line in f:
|
|
102
|
+ if not "config.Nims.0.advanced.sat." in line: continue
|
|
103
|
+ sat_list.append(line.split(".")[5])
|
|
104
|
+ for sat in sat_list:
|
|
105
|
+ package_list.extend(get_packages(sat))
|
|
106
|
+
|
|
107
|
+ for package in package_list:
|
|
108
|
+ create_picons(package)
|
|
109
|
+
|
|
110
|
+def create_picons(package):
|
|
111
|
+ "Create picons files for package"
|
|
112
|
+ global services,options
|
|
113
|
+ url_package = "http://www.lyngsat.com/packages/%s.html"%package
|
|
114
|
+ if options.debug:
|
|
115
|
+ print "** Downloading and looking %s for picons"%url_package
|
|
116
|
+ num_picons = 0
|
|
117
|
+ num_skipped = 0
|
|
118
|
+ num = 0
|
|
119
|
+ try:
|
|
120
|
+ #soup = html = urllib2.urlopen(url_package).read().decode("latin1")
|
|
121
|
+ soup = html = get_page(url_package).decode("latin1")
|
|
122
|
+ except:
|
|
123
|
+ raise Exception("Package page '%s' does not found"%url_package)
|
|
124
|
+ title = re.search("<title>(.+?)</title>", soup, re.DOTALL | re.IGNORECASE).group(1)
|
|
125
|
+ pos = re.search("\d+\.\d+",title).group().replace(".","")
|
|
126
|
+ ew = re.search("\xb0.",title).group()[1]
|
|
127
|
+ ns = int(pos)
|
|
128
|
+ if ew == "W":
|
|
129
|
+ ns = 3600 - ns
|
|
130
|
+ if ns==48: ns=49
|
|
131
|
+ if ns==359: ns=360
|
|
132
|
+ #pos = "%04x0000"%ns
|
|
133
|
+ #pos_num = int(pos[0:4],16)
|
|
134
|
+ title2 = title[0:title.index("- LyngSat")]
|
|
135
|
+ print "** %s: "%title2.replace(u'\xb0',""),
|
|
136
|
+ tables = re.findall(r"<table width=720 border cellspacing=0 cellpadding=0>\s*(?:(?=<tr>))(.+?)</table>", soup, re.DOTALL | re.IGNORECASE)
|
|
137
|
+ for table in tables:
|
|
138
|
+ tr= html_findall("tr",table)
|
|
139
|
+ for i in range(2,len(tr)-1):
|
|
140
|
+ td= html_findall("td",tr[i])
|
|
141
|
+ if len(td) == 10:
|
|
142
|
+ freq,polar = re.search(r"<b>(\d+) ([HVLR])", tr[i], re.DOTALL | re.IGNORECASE).groups()
|
|
143
|
+ freq = int(freq)
|
|
144
|
+ p_value = {"H":0,"V":1,"L":2,"R":3}
|
|
145
|
+ polar = p_value[polar]
|
|
146
|
+ b=1
|
|
147
|
+ else:
|
|
148
|
+ b=0
|
|
149
|
+ icon_url = html_attr("src",td[b])
|
|
150
|
+ if icon_url:
|
|
151
|
+ icon_url = "http://www.lyngsat.com" + icon_url.group(1).replace("/icon","/logo").replace(".gif",".jpg")
|
|
152
|
+ else:
|
|
153
|
+ icon_url = ""
|
|
154
|
+ name = html_text(td[b+1]).group(1)
|
|
155
|
+ sid = html_text(td[b+5])
|
|
156
|
+ sid = sid.group(1).replace(" ","") if sid else ""
|
|
157
|
+ sid = int(sid) if sid and not sid == u"-" else ""
|
|
158
|
+ vpid = html_text(td[b+6])
|
|
159
|
+ vpid = vpid.group(1).replace(" ","") if vpid else ""
|
|
160
|
+ #try:
|
|
161
|
+ # vpid = int(vpid)
|
|
162
|
+ #except Exception:
|
|
163
|
+ # vpid = None
|
|
164
|
+ #vpid = int(vpid) if vpid and not vpid == u"-" else None
|
|
165
|
+ if not sid or not vpid or icon_url=="":
|
|
166
|
+ continue
|
|
167
|
+
|
|
168
|
+ if options.debug:
|
|
169
|
+ print " package:%i/%s: service:%s "%(ns,package, name.encode("ascii","replace")),
|
|
170
|
+ num += 1
|
|
171
|
+
|
|
172
|
+ sref = find_sref(ns,freq,polar,sid)
|
|
173
|
+ if not sref:
|
|
174
|
+ sref = find_sref(ns,freq+1,polar,sid)
|
|
175
|
+ if not sref:
|
|
176
|
+ sref = find_sref(ns,freq-1,polar,sid)
|
|
177
|
+ if not sref:
|
|
178
|
+ if options.debug:
|
|
179
|
+ print " -- NOK (no sref in lamedb!)"
|
|
180
|
+ logging.debug(u" no sref - package:%i/%s: service:%s pos:%s/%s freq:%i polar:%s sid:%i/%x"%(ns,package, name,ns, pos_int2str(ns),freq,polar,sid,sid))
|
|
181
|
+ continue
|
|
182
|
+
|
|
183
|
+ fname = sref.replace(":","_")
|
|
184
|
+ fname = fname[:-1]+".png"
|
|
185
|
+ fname = os.path.join(options.folder, fname)
|
|
186
|
+ if os.path.exists(fname) and not options.overwrite:
|
|
187
|
+ if options.debug: print " -- skipped"
|
|
188
|
+ num_skipped += 1
|
|
189
|
+ continue
|
|
190
|
+
|
|
191
|
+ #try:
|
|
192
|
+ #im = Image.open(StringIO(urllib2.urlopen(icon_url).read()))
|
|
193
|
+ data = get_page(icon_url)
|
|
194
|
+ im = Image.open(StringIO(data))
|
|
195
|
+ #im = im.crop((0,10,132,89))
|
|
196
|
+
|
|
197
|
+ im = im.resize((options.w,options.h), Image.ANTIALIAS)
|
|
198
|
+ im = im.convert('P', palette=Image.ADAPTIVE)
|
|
199
|
+ #except Exception:
|
|
200
|
+ # im = None
|
|
201
|
+ if not im:
|
|
202
|
+ if options.debug: print " -- NOK (no picon image)"
|
|
203
|
+ continue
|
|
204
|
+
|
|
205
|
+ if options.debug: print " -- downloaded"
|
|
206
|
+ im.save(fname,"png")
|
|
207
|
+ num_picons += 1
|
|
208
|
+
|
|
209
|
+ print "%i picons created, %i skipped"%(num_picons,num_skipped)
|
|
210
|
+
|
|
211
|
+def get_packages(sat):
|
|
212
|
+ "Get packages list (names) for sattelite from lyngsat.com page"
|
|
213
|
+ global options
|
|
214
|
+ sat= sat.replace(".","")
|
|
215
|
+ num = int(sat)
|
|
216
|
+ if num>1800: num = num - 3600
|
|
217
|
+ if num>0 and num<730: soup = get_soup("europe")
|
|
218
|
+ elif num>730 and num<1600: soup = get_soup("asia")
|
|
219
|
+ elif num<0 and num>-610: soup = get_soup("atlantic")
|
|
220
|
+ elif num<-610 and num>-1600: soup = get_soup("america")
|
|
221
|
+ else:
|
|
222
|
+ return []
|
|
223
|
+ i1,i2 = gr=re.search(r"<table cellspacing=0 border>\s*(?:(?=<tr>))(.+?)</table>", soup, re.DOTALL | re.IGNORECASE).span()
|
|
224
|
+ packages = []
|
|
225
|
+ for s in re.findall("<tr>(.+?)</tr>", soup[i1:i2], re.DOTALL | re.IGNORECASE):
|
|
226
|
+ gr = re.search(r"(\d+.)</font><font size=1>(\d).+#176;([EW])", s,re.DOTALL | re.IGNORECASE).groups()
|
|
227
|
+ pos = int("".join(gr[:-1]).replace(".",""))
|
|
228
|
+ if gr[2] == "W": pos = -pos
|
|
229
|
+ if abs(num - pos) <=2:
|
|
230
|
+ package = re.search(r"www\.lyngsat\.com/packages/(\w.+?)\.html", s, re.DOTALL | re.IGNORECASE).group(1)
|
|
231
|
+ packages.append(package)
|
|
232
|
+ return packages
|
|
233
|
+
|
|
234
|
+soups = {}
|
|
235
|
+def get_soup(region):
|
|
236
|
+ if soups.has_key(region):
|
|
237
|
+ return soups[region]
|
|
238
|
+ url = "http://www.lyngsat.com/packages/%s.html"%region
|
|
239
|
+ if options.debug:
|
|
240
|
+ print "** Downloading and looking %s for packages"%url
|
|
241
|
+ try:
|
|
242
|
+ #html = urllib2.urlopen(url).read().decode("latin1")
|
|
243
|
+ html = get_page(url).decode("latin1")
|
|
244
|
+ except:
|
|
245
|
+ raise Exception("Packege page '%s' does not found"%url)
|
|
246
|
+ soups[region] = html
|
|
247
|
+ return soups[region]
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+def find_sref(ns,freq,polar,sid):
|
|
251
|
+ "Find service reference according to given parameters"
|
|
252
|
+ global services
|
|
253
|
+ tp = services.get_transp_by_pic((ns,freq,polar))
|
|
254
|
+ if tp:
|
|
255
|
+ serv = services.get_service_by_chid((sid,tp["tsid"],tp["onid"]))
|
|
256
|
+ if serv:
|
|
257
|
+ return serv["sref"]
|
|
258
|
+
|
|
259
|
+class DBServices(object):
|
|
260
|
+ """Dreambox services, stored in lamedb (E2)/services(E1) file handling class"""
|
|
261
|
+
|
|
262
|
+ def __init__(self,service_path,enigma=2):
|
|
263
|
+ self.enigma = enigma
|
|
264
|
+ self.service_path = service_path
|
|
265
|
+
|
|
266
|
+ if self.enigma == 2:
|
|
267
|
+ if not "ftp:" in service_path:
|
|
268
|
+ self.service_fname= os.path.join(service_path,"lamedb")
|
|
269
|
+ self.bouquets_fname = os.path.join(service_path, "bouquets.tv")
|
|
270
|
+ else:
|
|
271
|
+ sep = "" if service_path[-1]=="//" else "//"
|
|
272
|
+ self.service_fname= service_path+sep+"lamedb"
|
|
273
|
+ self.bouquets_fname = service_path+sep+"bouquets.tv"
|
|
274
|
+
|
|
275
|
+ else: # ENIGMA === "1":
|
|
276
|
+ self.service_fname = os.path.join(service_path,"services")
|
|
277
|
+ self.bouquets_fname = os.path.join(service_path, "userbouquets.tv.epl")
|
|
278
|
+
|
|
279
|
+ self.services = []
|
|
280
|
+ self.index_sref= {}
|
|
281
|
+ self.index_chid = {}
|
|
282
|
+ self.index_name = {}
|
|
283
|
+ self.index_provider = {}
|
|
284
|
+ self.bouquets = []
|
|
285
|
+ self.bouquets_services = {}
|
|
286
|
+
|
|
287
|
+ self.transp = []
|
|
288
|
+ self.tp_index_tpid = {}
|
|
289
|
+ self.tp_index_pic ={}
|
|
290
|
+
|
|
291
|
+ self._load_services()
|
|
292
|
+ #self._load_bouquets()
|
|
293
|
+
|
|
294
|
+ def _load_services(self):
|
|
295
|
+ #tpref - lamedb/transponders
|
|
296
|
+ # NS:TSID:ONID
|
|
297
|
+ # s FREQ:SR:POLAR:FREC:49:2:0
|
|
298
|
+ # X X X
|
|
299
|
+ # D D D D
|
|
300
|
+
|
|
301
|
+ # lref - lamedb/services
|
|
302
|
+ # SID:NS:TSID:ONID:STYPE:UNUSED(channelnumber in enigma1)
|
|
303
|
+ # 0 1 2 3 4 5
|
|
304
|
+ # X X X X D D
|
|
305
|
+ # wref bouquets/picon
|
|
306
|
+ # REFTYPE:FLAGS:STYPE:SID:TSID:ONID:NS:PARENT_SID:PARENT_TSID:UNUSED
|
|
307
|
+ # 0 1 2 3 4 5 6 7 8 9
|
|
308
|
+ # D D X X X X X X X X
|
|
309
|
+
|
|
310
|
+ f_services = open(self.service_fname,"r") if not self.service_fname[0:4] == "ftp:" else urllib2.urlopen(self.service_fname)
|
|
311
|
+
|
|
312
|
+ line = f_services.readline()
|
|
313
|
+ if not "eDVB services" in line:
|
|
314
|
+ raise Exception("no correct lamedb file")
|
|
315
|
+ line = f_services.readline()
|
|
316
|
+
|
|
317
|
+ # Read transponders
|
|
318
|
+ i = 0
|
|
319
|
+ while True:
|
|
320
|
+ line = f_services.readline()
|
|
321
|
+ if "end" in line: break
|
|
322
|
+ #tp = record.Rec()
|
|
323
|
+ tp = {}
|
|
324
|
+ ff = line.strip().split(":")
|
|
325
|
+ tp["ns"] = ns = pos_str2int(ff[0])
|
|
326
|
+ tp["tsid"] = tsid = int(ff[1],16)
|
|
327
|
+ tp["onid"] = onid = int(ff[2],16)
|
|
328
|
+ line = f_services.readline()
|
|
329
|
+ tp["params"] = params = line.strip().split(" ")[1]
|
|
330
|
+ ff = params.split(":")
|
|
331
|
+ tp["freq"] = freq = int(ff[0][:-3])
|
|
332
|
+ tp["polar"] = polar = int(ff[2])
|
|
333
|
+ tp["tpid"] = tpid = (ns,tsid,onid)
|
|
334
|
+ self.transp.append(tp)
|
|
335
|
+ self.tp_index_tpid[tpid] = i
|
|
336
|
+ self.tp_index_pic[(ns,freq,polar)] = i
|
|
337
|
+
|
|
338
|
+ line = f_services.readline()
|
|
339
|
+ i += 1
|
|
340
|
+
|
|
341
|
+ # Reading services
|
|
342
|
+ i= 0
|
|
343
|
+ line = f_services.readline()
|
|
344
|
+ while True:
|
|
345
|
+
|
|
346
|
+ line = f_services.readline()
|
|
347
|
+ if line[0:3] == "end": break
|
|
348
|
+ if not line: break
|
|
349
|
+ #rec = record.Rec()
|
|
350
|
+ rec = {}
|
|
351
|
+ rec["lref"] = line.lower().strip().decode("utf-8")
|
|
352
|
+
|
|
353
|
+ line = f_services.readline()
|
|
354
|
+ #line = line.replace('\xc2\x87', '').replace('\xc2\x86', '')
|
|
355
|
+ #line = decode_charset(line)
|
|
356
|
+ line = line.decode("utf-8")
|
|
357
|
+ rec["name"] = line.strip()
|
|
358
|
+
|
|
359
|
+ line = f_services.readline()
|
|
360
|
+ pl = line.split(",")
|
|
361
|
+ provider = ""
|
|
362
|
+ for p in pl:
|
|
363
|
+ if p[0:2] == "p:":
|
|
364
|
+ provider = p[2:].strip()
|
|
365
|
+ break
|
|
366
|
+ if provider == "":
|
|
367
|
+ provider = "unknown"
|
|
368
|
+ rec["provider"] = provider.decode("utf-8")
|
|
369
|
+
|
|
370
|
+ rec["sref"] = lref2sref(rec["lref"])
|
|
371
|
+ r = lref_parse(rec["lref"])
|
|
372
|
+ rec["stype"] = r["stype"]
|
|
373
|
+ rec["chid"] = (r["sid"],r["tsid"],r["onid"])
|
|
374
|
+ self.services.append(rec)
|
|
375
|
+
|
|
376
|
+ self.index_sref[rec["sref"]] = i
|
|
377
|
+ self.index_chid[rec["chid"]] = i
|
|
378
|
+ name = rec["name"].lower()
|
|
379
|
+ if not self.index_name.has_key(name): self.index_name[name] = []
|
|
380
|
+ self.index_name[name].append(i)
|
|
381
|
+ provider = rec["provider"].lower()
|
|
382
|
+ if not self.index_provider.has_key(provider): self.index_provider[provider] = []
|
|
383
|
+ self.index_provider[provider].append(i)
|
|
384
|
+
|
|
385
|
+ i += 1
|
|
386
|
+
|
|
387
|
+ f_services.close()
|
|
388
|
+
|
|
389
|
+ def _load_bouquets(self):
|
|
390
|
+ f_bouquets = open(self.bouquets_fname,"r") if not self.bouquets_fname[0:4] == "ftp:" else urllib2.urlopen(self.bouquets_fname)
|
|
391
|
+ for line in f_bouquets.readlines():
|
|
392
|
+ if line[0:9] == "#SERVICE:":
|
|
393
|
+ if self.enigma==1:
|
|
394
|
+ bn = line.strip().split("/")
|
|
395
|
+ else:
|
|
396
|
+ bn = line.strip().split(":")
|
|
397
|
+ bfn = bn[-1]
|
|
398
|
+ bf = open(os.path.join(self.service_path,bfn))
|
|
399
|
+ for line2 in bf.readlines():
|
|
400
|
+ if line2[0:5] == "#NAME":
|
|
401
|
+ bname = line2.strip()[6:]
|
|
402
|
+ self.bouquets.append(bname)
|
|
403
|
+ self.bouquets_services[bname] = []
|
|
404
|
+ elif line2[0:8] == "#SERVICE":
|
|
405
|
+ sref = line2.strip()[9:]
|
|
406
|
+ r = sref_parse(sref)
|
|
407
|
+ if r["flags"] == 64: continue
|
|
408
|
+ self.bouquets_services[bname].append(sref)
|
|
409
|
+ bf.close()
|
|
410
|
+ f_bouquets.close()
|
|
411
|
+
|
|
412
|
+ def get_bouquets(self):
|
|
413
|
+ if not self.bouquets:
|
|
414
|
+ self._load_bouquets()
|
|
415
|
+ return self.bouquets
|
|
416
|
+
|
|
417
|
+ def get_bouquet_services(self,bn):
|
|
418
|
+ if not self.bouquets:
|
|
419
|
+ self._load_bouquets()
|
|
420
|
+ return [self.get_service_by_sref(sref) for sref in self.bouquets_services[bn]]
|
|
421
|
+
|
|
422
|
+ def get_service_by_sref(self,sref):
|
|
423
|
+ return self.services[self.index_sref[sref]] if self.index_sref.has_key(sref) else None
|
|
424
|
+
|
|
425
|
+ def get_service_by_chid(self,chid):
|
|
426
|
+ return self.services[self.index_chid[chid]] if self.index_chid.has_key(chid) else None
|
|
427
|
+
|
|
428
|
+ def get_service_by_name(self,name):
|
|
429
|
+ return [self.services[i] for i in self.index_name[name]]
|
|
430
|
+
|
|
431
|
+ def get_service_by_provider(self,provider):
|
|
432
|
+ return [self.services[i] for i in self.index_provider[provider]]
|
|
433
|
+
|
|
434
|
+ def get_transp_by_tpid(self,tpid):
|
|
435
|
+ return self.transp[self.tp_index_tpid[tpid]] if self.tp_index_tpid.has_key(tpid) else None
|
|
436
|
+
|
|
437
|
+ def get_transp_by_pic(self,picid):
|
|
438
|
+ return self.transp[self.tp_index_pic[picid]] if self.tp_index_pic.has_key(picid) else None
|
|
439
|
+
|
|
440
|
+def decode_charset(s):
|
|
441
|
+ u = None
|
|
442
|
+ if isinstance(s,unicode):
|
|
443
|
+ return s
|
|
444
|
+ charset_list=('iso-8859-4','iso-8859-1','iso-8859-2''iso-8859-15')
|
|
445
|
+
|
|
446
|
+ for charset in charset_list:
|
|
447
|
+ try:
|
|
448
|
+ u=unicode(s,charset,"strict")
|
|
449
|
+ except:
|
|
450
|
+ pass
|
|
451
|
+ else:
|
|
452
|
+ break
|
|
453
|
+
|
|
454
|
+ if u == None:
|
|
455
|
+ raise Error, "CHARSET ERROR while decoding lamedb. Aborting !"
|
|
456
|
+ else:
|
|
457
|
+ return(u)
|
|
458
|
+
|
|
459
|
+# lref - lamedb/services
|
|
460
|
+# SID:NS:TSID:ONID:STYPE:UNUSED(channelnumber in enigma1)
|
|
461
|
+# 0 1 2 3 4 5
|
|
462
|
+# X X X X D D
|
|
463
|
+#
|
|
464
|
+# wref bouquets/picon
|
|
465
|
+# REFTYPE:FLAGS:STYPE:SID:TSID:ONID:NS:PARENT_SID:PARENT_TSID:UNUSED
|
|
466
|
+# 0 1 2 3 4 5 6 7 8 9
|
|
467
|
+# D D X X X X X X X X
|
|
468
|
+
|
|
469
|
+def lref2sref(s):
|
|
470
|
+ "Converts service refefence from lamedb format to bouquets/picon (standard) format"
|
|
471
|
+ f = s.split(":")
|
|
472
|
+ sid = int(f[0],16)
|
|
473
|
+ ns = int(f[1], 16)
|
|
474
|
+ tsid = int(f[2],16)
|
|
475
|
+ onid = int(f[3],16)
|
|
476
|
+ stype = int(f[4])
|
|
477
|
+
|
|
478
|
+ s2 = "1:0:%X:%X:%X:%X:%X:0:0:0:" % (stype,sid,tsid,onid,ns)
|
|
479
|
+ return s2
|
|
480
|
+
|
|
481
|
+def lref_parse(s):
|
|
482
|
+ "Parse lamedb/service string, return dictionary of items"
|
|
483
|
+ f = s.split(":")
|
|
484
|
+ r = {}
|
|
485
|
+ r["sid"] = int(f[0],16)
|
|
486
|
+ r["ns"] = int(f[1], 16)
|
|
487
|
+ r["tsid"] = int(f[2],16)
|
|
488
|
+ r["onid"] = int(f[3],16)
|
|
489
|
+ r["stype"] = int(f[4])
|
|
490
|
+ return r
|
|
491
|
+
|
|
492
|
+def sref2lref(s):
|
|
493
|
+ "Converts service refefence from bouquets/picon (standard) format to lamedb format"
|
|
494
|
+ f = s.split(":")
|
|
495
|
+ reftype = int(f[0])
|
|
496
|
+ flags = int(f[1])
|
|
497
|
+ stype = int(f[2],16)
|
|
498
|
+ sid = int(f[3],16)
|
|
499
|
+ tsid = int(f[4],16)
|
|
500
|
+ onid = int(f[5],16)
|
|
501
|
+ ns = int(f[6],16)
|
|
502
|
+
|
|
503
|
+ s2 = "%04x:%08x:%04x:%04x:%i:0" % (sid,ns,tsid,onid,stype)
|
|
504
|
+ return s2
|
|
505
|
+
|
|
506
|
+def sref_parse(s):
|
|
507
|
+ "Parse service refefence string , return dictionary of items"
|
|
508
|
+ f = s.split(":")
|
|
509
|
+ r = {}
|
|
510
|
+ r["reftype"] = int(f[0])
|
|
511
|
+ r["flags"] = int(f[1])
|
|
512
|
+ r["stype"] = int(f[2],16)
|
|
513
|
+ r["sid"] = int(f[3],16)
|
|
514
|
+ r["tsid"] = int(f[4],16)
|
|
515
|
+ r["onid"] = int(f[5],16)
|
|
516
|
+ r["ns"] = int(f[6],16)
|
|
517
|
+ return r
|
|
518
|
+
|
|
519
|
+pos_int2str = lambda pos_num: "%04x0000"%pos_num
|
|
520
|
+pos_str2int = lambda pos: int(pos[0:4],16)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+def decode_charset(s):
|
|
524
|
+ u = None
|
|
525
|
+ charset_list = ('utf-8','iso-8859-1','iso-8859-2','iso-8859-15')
|
|
526
|
+
|
|
527
|
+ for charset in charset_list:
|
|
528
|
+ try:
|
|
529
|
+ u = unicode(s,charset,"strict")
|
|
530
|
+ except:
|
|
531
|
+ pass
|
|
532
|
+ else:
|
|
533
|
+ break
|
|
534
|
+
|
|
535
|
+ if u == None:
|
|
536
|
+ print("CHARSET ERROR while decoding string")
|
|
537
|
+ sys.exit(1)
|
|
538
|
+ else:
|
|
539
|
+ return(u)
|
|
540
|
+
|
|
541
|
+headers2dict = lambda h: dict([l.strip().split(": ") for l in h.strip().splitlines()])
|
|
542
|
+headers = headers2dict("""
|
|
543
|
+User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
|
|
544
|
+Referer: http://www.lyngsat.com/
|
|
545
|
+""")
|
|
546
|
+
|
|
547
|
+def get_page(url):
|
|
548
|
+
|
|
549
|
+ r=requests.get(url,headers=headers)
|
|
550
|
+ return r.content
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+html_text = lambda html: re.search(r">([^<^\n]+?)<", html, re.DOTALL | re.IGNORECASE)
|
|
554
|
+html_tag = lambda tag, html: re.search(r"<%s\b[^>]*>(.*?)</%s>"%(tag,tag), html, re.DOTALL | re.IGNORECASE)
|
|
555
|
+html_attr = lambda attr,html: re.search("""%s="?([^'" >]+)"""%(attr), html, re.DOTALL | re.IGNORECASE)
|
|
556
|
+html_findall_content = lambda tag,html: re.findall(r"<%s\b[^>]*>(.*?)</%s>"%(tag,tag), html, re.DOTALL | re.IGNORECASE)
|
|
557
|
+html_findall = lambda tag,html: re.findall(r"<%s\b[^>]*>.*?</%s>"%(tag,tag), html, re.DOTALL | re.IGNORECASE)
|
|
558
|
+
|
|
559
|
+import UserDict
|
|
560
|
+class Rec(UserDict.DictMixin):
|
|
561
|
+ "Dict like class allowing a.x instead of a['x']"
|
|
562
|
+ def __init__(self, dict=None, **kwargs):
|
|
563
|
+ self.__dict__ = {}
|
|
564
|
+ if dict is not None:
|
|
565
|
+ self.update(dict)
|
|
566
|
+ if len(kwargs):
|
|
567
|
+ self.update(kwargs)
|
|
568
|
+ def __setitem__(self, name, value): setattr(self, name, value)
|
|
569
|
+ def __getitem__(self, name): return getattr(self,name,None)
|
|
570
|
+ def __getattr__(self,key): return None
|
|
571
|
+ def has_key(self,key): return True if self.__dict__.has_key(key) else False
|
|
572
|
+ def keys(self): return list(self.__dict__)
|
|
573
|
+
|
|
574
|
+if __name__ == "__main__":
|
|
575
|
+ #print "** Starting..."
|
|
576
|
+ sys.exit(main(sys.argv))
|