fbf9fdcdfc805cfa5bcf344a21e09bc0b4684ff6
[openblackhole/openblackhole-enigma2.git] / lib / python / Components / Converter / PliExtraInfo.py
1 # shamelessly copied from pliExpertInfo (Vali, Mirakels, Littlesat)
2
3 from enigma import iServiceInformation, iPlayableService
4 from Components.Converter.Converter import Converter
5 from Components.Element import cached
6 from Components.config import config
7 from Tools.Transponder import ConvertToHumanReadable, getChannelNumber
8 from Tools.GetEcmInfo import GetEcmInfo
9 from Poll import Poll
10
11 def addspace(text):
12         if text:
13                 text += " "
14         return text
15
16 class PliExtraInfo(Poll, Converter, object):
17         def __init__(self, type):
18                 Converter.__init__(self, type)
19                 Poll.__init__(self)
20                 self.type = type
21                 self.poll_interval = 1000
22                 self.poll_enabled = True
23                 self.caid_data = (
24                         ( "0x100",  "0x1ff", "Seca",     "S",  True  ),
25                         ( "0x500",  "0x5ff", "Via",      "V",  True  ),
26                         ( "0x600",  "0x6ff", "Irdeto",   "I",  True  ),
27                         ( "0x900",  "0x9ff", "NDS",      "Nd", True  ),
28                         ( "0xb00",  "0xbff", "Conax",    "Co", True  ),
29                         ( "0xd00",  "0xdff", "CryptoW",  "Cw", True  ),
30                         ( "0xe00",  "0xeff", "PowerVU",  "P",  False ),
31                         ("0x1700", "0x17ff", "Beta",     "B",  True  ),
32                         ("0x1800", "0x18ff", "Nagra",    "N",  True  ),
33                         ("0x2600", "0x2600", "Biss",     "Bi", False ),
34                         ("0x4ae0", "0x4ae1", "Dre",      "D",  False ),
35                         ("0x4aee", "0x4aee", "BulCrypt", "B1", False ),
36                         ("0x5581", "0x5581", "BulCrypt", "B2", False )
37                 )
38                 self.ca_table = (
39                         ("CryptoCaidSecaAvailable",     "S",    False),
40                         ("CryptoCaidViaAvailable",      "V",    False),
41                         ("CryptoCaidIrdetoAvailable",   "I",    False),
42                         ("CryptoCaidNDSAvailable",      "Nd",   False),
43                         ("CryptoCaidConaxAvailable",    "Co",   False),
44                         ("CryptoCaidCryptoWAvailable",  "Cw",   False),
45                         ("CryptoCaidPowerVUAvailable",  "P",    False),
46                         ("CryptoCaidBetaAvailable",     "B",    False),
47                         ("CryptoCaidNagraAvailable",    "N",    False),
48                         ("CryptoCaidBissAvailable",     "Bi",   False),
49                         ("CryptoCaidDreAvailable",      "D",    False),
50                         ("CryptoCaidBulCrypt1Available","B1",   False),
51                         ("CryptoCaidBulCrypt2Available","B2",   False),
52                         ("CryptoCaidSecaSelected",      "S",    True),
53                         ("CryptoCaidViaSelected",       "V",    True),
54                         ("CryptoCaidIrdetoSelected",    "I",    True),
55                         ("CryptoCaidNDSSelected",       "Nd",   True),
56                         ("CryptoCaidConaxSelected",     "Co",   True),
57                         ("CryptoCaidCryptoWSelected",   "Cw",   True),
58                         ("CryptoCaidPowerVUSelected",   "P",    True),
59                         ("CryptoCaidBetaSelected",      "B",    True),
60                         ("CryptoCaidNagraSelected",     "N",    True),
61                         ("CryptoCaidBissSelected",      "Bi",   True),
62                         ("CryptoCaidDreSelected",       "D",    True),
63                         ("CryptoCaidBulCrypt1Selected", "B1",   True),
64                         ("CryptoCaidBulCrypt2Selected", "B2",   True),
65                 )
66                 self.ecmdata = GetEcmInfo()
67                 self.feraw = self.fedata = self.updateFEdata = None
68
69         def getCryptoInfo(self, info):
70                 if (info.getInfo(iServiceInformation.sIsCrypted) == 1):
71                         data = self.ecmdata.getEcmData()
72                         self.current_source = data[0]
73                         self.current_caid = data[1]
74                         self.current_provid = data[2]
75                         self.current_ecmpid = data[3]
76                 else:
77                         self.current_source = ""
78                         self.current_caid = "0"
79                         self.current_provid = "0"
80                         self.current_ecmpid = "0"
81
82         def createCryptoBar(self, info):
83                 res = ""
84                 available_caids = info.getInfoObject(iServiceInformation.sCAIDs)
85
86                 for caid_entry in self.caid_data:
87                         if int(self.current_caid, 16) >= int(caid_entry[0], 16) and int(self.current_caid, 16) <= int(caid_entry[1], 16):
88                                 color="\c0000??00"
89                         else:
90                                 color = "\c007?7?7?"
91                                 try:
92                                         for caid in available_caids:
93                                                 if caid >= int(caid_entry[0], 16) and caid <= int(caid_entry[1], 16):
94                                                         color="\c00????00"
95                                 except:
96                                         pass
97
98                         if color != "\c007?7?7?" or caid_entry[4]:
99                                 if res: res += " "
100                                 res += color + caid_entry[3]
101
102                 res += "\c00??????"
103                 return res
104
105         def createCryptoSpecial(self, info):
106                 caid_name = "FTA"
107                 try:
108                         for caid_entry in self.caid_data:
109                                 if int(self.current_caid, 16) >= int(caid_entry[0], 16) and int(self.current_caid, 16) <= int(caid_entry[1], 16):
110                                         caid_name = caid_entry[2]
111                                         break
112                         return caid_name + ":%04x:%04x:%04x:%04x" % (int(self.current_caid,16), int(self.current_provid,16), info.getInfo(iServiceInformation.sSID), int(self.current_ecmpid,16))
113                 except:
114                         pass
115                 return ""
116
117         def createResolution(self, info):
118                 xres = info.getInfo(iServiceInformation.sVideoWidth)
119                 if xres == -1:
120                         return ""
121                 yres = info.getInfo(iServiceInformation.sVideoHeight)
122                 mode = ("i", "p", " ")[info.getInfo(iServiceInformation.sProgressive)]
123                 fps  = str((info.getInfo(iServiceInformation.sFrameRate) + 500) / 1000)
124                 return str(xres) + "x" + str(yres) + mode + fps
125
126         def createVideoCodec(self, info):
127                 return ("MPEG2", "MPEG4", "MPEG1", "MPEG4-II", "VC1", "VC1-SM", "")[info.getInfo(iServiceInformation.sVideoType)]
128
129         def createPIDInfo(self, info):
130                 vpid = info.getInfo(iServiceInformation.sVideoPID)
131                 apid = info.getInfo(iServiceInformation.sAudioPID)
132                 pcrpid = info.getInfo(iServiceInformation.sPCRPID)
133                 sidpid = info.getInfo(iServiceInformation.sSID)
134                 tsid = info.getInfo(iServiceInformation.sTSID)
135                 onid = info.getInfo(iServiceInformation.sONID)
136                 if vpid < 0 : vpid = 0
137                 if apid < 0 : apid = 0
138                 if pcrpid < 0 : pcrpid = 0
139                 if sidpid < 0 : sidpid = 0
140                 if tsid < 0 : tsid = 0
141                 if onid < 0 : onid = 0
142                 return "%d-%d:%05d:%04d:%04d:%04d" % (onid, tsid, sidpid, vpid, apid, pcrpid)
143
144         def createTransponderInfo(self, fedata, feraw):
145                 if not feraw:
146                         return ""
147                 elif "DVB-T" in feraw.get("tuner_type"):
148                         tmp = addspace(self.createChannelNumber(fedata, feraw)) + addspace(self.createFrequency(feraw)) + addspace(self.createPolarization(fedata))
149                 else:
150                         tmp = addspace(self.createFrequency(feraw)) + addspace(self.createPolarization(fedata))
151                 return addspace(self.createTunerSystem(fedata)) + tmp + addspace(self.createSymbolRate(fedata, feraw)) + addspace(self.createFEC(fedata, feraw)) \
152                         + addspace(self.createModulation(fedata)) + addspace(self.createOrbPos(feraw))
153
154         def createFrequency(self, feraw):
155                 frequency = feraw.get("frequency")
156                 if frequency:
157                         if "DVB-T" in feraw.get("tuner_type"):
158                                 return str(int(frequency / 1000000. + 0.5))
159                         else:
160                                 return str(int(frequency / 1000 + 0.5))
161                 return ""
162
163         def createChannelNumber(self, fedata, feraw):
164                 return "DVB-T" in feraw.get("tuner_type") and fedata.get("channel") or ""
165
166         def createSymbolRate(self, fedata, feraw):
167                 if "DVB-T" in feraw.get("tuner_type"):
168                         bandwidth = fedata.get("bandwidth")
169                         if bandwidth:
170                                 return bandwidth
171                 else:
172                         symbolrate = fedata.get("symbol_rate")
173                         if symbolrate:
174                                 return str(symbolrate / 1000)
175                 return ""
176
177         def createPolarization(self, fedata):
178                 return fedata.get("polarization_abbreviation") or ""
179
180         def createFEC(self, fedata, feraw):
181                 if "DVB-T" in feraw.get("tuner_type"):
182                         code_rate_lp = fedata.get("code_rate_lp")
183                         code_rate_hp = fedata.get("code_rate_hp")
184                         if code_rate_lp and code_rate_hp:
185                                 return code_rate_lp + "-" + code_rate_hp
186                 else:
187                         fec = fedata.get("fec_inner")
188                         if fec:
189                                 return fec
190                 return ""
191
192         def createModulation(self, fedata):
193                 if fedata.get("tuner_type") == _("Terrestrial"):
194                         constellation = fedata.get("constellation")
195                         if constellation:
196                                 return constellation
197                 else:
198                         modulation = fedata.get("modulation")
199                         if modulation:
200                                 return modulation
201                 return ""
202
203         def createTunerType(self, feraw):
204                 return feraw.get("tuner_type") or ""
205
206         def createTunerSystem(self, fedata):
207                 return fedata.get("system") or ""
208
209         def createOrbPos(self, feraw):
210                 orbpos = feraw.get("orbital_position")
211                 if orbpos > 1800:
212                         return str((float(3600 - orbpos)) / 10.0) + "\xc2\xb0 W"
213                 elif orbpos > 0:
214                         return str((float(orbpos)) / 10.0) + "\xc2\xb0 E"
215                 return ""
216
217         def createOrbPosOrTunerSystem(self, fedata,feraw):
218                 orbpos = self.createOrbPos(feraw)
219                 if orbpos is not "":
220                         return orbpos
221                 return self.createTunerSystem(fedata)
222
223         def createProviderName(self, info):
224                 return info.getInfoString(iServiceInformation.sProvider)
225
226         @cached
227         def getText(self):
228                 service = self.source.service
229                 if service is None:
230                         return ""
231                 info = service and service.info()
232
233                 if not info:
234                         return ""
235
236                 if self.type == "CryptoInfo":
237                         self.getCryptoInfo(info)
238                         if config.usage.show_cryptoinfo.value:
239                                 return addspace(self.createCryptoBar(info)) + self.createCryptoSpecial(info)
240                         else:
241                                 return addspace(self.createCryptoBar(info)) + addspace(self.current_source) + self.createCryptoSpecial(info)
242
243                 if self.type == "CryptoBar":
244                         self.getCryptoInfo(info)
245                         return self.createCryptoBar(info)
246
247                 if self.type == "CryptoSpecial":
248                         self.getCryptoInfo(info)
249                         return self.createCryptoSpecial(info)
250
251                 if self.type == "ResolutionString":
252                         return self.createResolution(info)
253
254                 if self.type == "VideoCodec":
255                         return self.createVideoCodec(info)
256
257                 if self.updateFEdata:
258                         feinfo = service.frontendInfo()
259                         if feinfo:
260                                 self.feraw = feinfo.getAll(config.usage.infobar_frontend_source.value == "settings")
261                                 if self.feraw:
262                                         self.fedata = ConvertToHumanReadable(self.feraw)
263
264                 feraw = self.feraw
265                 if not feraw:
266                         feraw = info.getInfoObject(iServiceInformation.sTransponderData)
267                         fedata = ConvertToHumanReadable(feraw)
268                 else:
269                         fedata = self.fedata
270
271                 if self.type == "All":
272                         self.getCryptoInfo(info)
273                         if config.usage.show_cryptoinfo.value:
274                                 return addspace(self.createProviderName(info)) + self.createTransponderInfo(fedata, feraw) + "\n" \
275                                 + addspace(self.createCryptoBar(info)) + addspace(self.createCryptoSpecial(info)) + "\n" \
276                                 + addspace(self.createPIDInfo(info)) + addspace(self.createVideoCodec(info)) + self.createResolution(info)
277                         else:
278                                 return addspace(self.createProviderName(info)) + self.createTransponderInfo(fedata, feraw) + "\n" \
279                                 + addspace(self.createCryptoBar(info)) + self.current_source + "\n" \
280                                 + addspace(self.createCryptoSpecial(info)) + addspace(self.createVideoCodec(info)) + self.createResolution(info)
281
282                 if self.type == "PIDInfo":
283                         return self.createPIDInfo(info)
284
285                 if not feraw:
286                         return ""
287
288                 if self.type == "ServiceInfo":
289                         return addspace(self.createProviderName(info)) + addspace(self.createTunerSystem(fedata)) + addspace(self.createFrequency(feraw)) + addspace(self.createPolarization(fedata)) \
290                         + addspace(self.createSymbolRate(fedata, feraw)) + addspace(self.createFEC(fedata, feraw)) + addspace(self.createModulation(fedata)) + addspace(self.createOrbPos(feraw)) \
291                         + addspace(self.createVideoCodec(info)) + self.createResolution(info)
292
293                 if self.type == "TransponderInfo":
294                         return self.createTransponderInfo(fedata, feraw)
295
296                 if self.type == "TransponderFrequency":
297                         return self.createFrequency(feraw)
298
299                 if self.type == "TransponderSymbolRate":
300                         return self.createSymbolRate(fedata, feraw)
301
302                 if self.type == "TransponderPolarization":
303                         return self.createPolarization(fedata)
304
305                 if self.type == "TransponderFEC":
306                         return self.createFEC(fedata, feraw)
307
308                 if self.type == "TransponderModulation":
309                         return self.createModulation(fedata)
310
311                 if self.type == "OrbitalPosition":
312                         return self.createOrbPos(feraw)
313
314                 if self.type == "TunerType":
315                         return self.createTunerType(feraw)
316
317                 if self.type == "TunerSystem":
318                         return self.createTunerSystem(fedata)
319
320                 if self.type == "OrbitalPositionOrTunerSystem":
321                         return self.createOrbPosOrTunerSystem(fedata,feraw)
322
323                 if self.type == "TerrestrialChannelNumber":
324                         return self.createChannelNumber(fedata, feraw)
325
326                 return _("invalid type")
327
328         text = property(getText)
329
330         @cached
331         def getBool(self):
332                 service = self.source.service
333                 info = service and service.info()
334
335                 if not info:
336                         return False
337
338                 request_caid = None
339                 for x in self.ca_table:
340                         if x[0] == self.type:
341                                 request_caid = x[1]
342                                 request_selected = x[2]
343                                 break
344
345                 if request_caid is None:
346                         return False
347
348                 if info.getInfo(iServiceInformation.sIsCrypted) != 1:
349                         return False
350
351                 data = self.ecmdata.getEcmData()
352
353                 if data is None:
354                         return False
355
356                 current_caid    = data[1]
357
358                 available_caids = info.getInfoObject(iServiceInformation.sCAIDs)
359
360                 for caid_entry in self.caid_data:
361                         if caid_entry[3] == request_caid:
362                                 if(request_selected):
363                                         if int(current_caid, 16) >= int(caid_entry[0], 16) and int(current_caid, 16) <= int(caid_entry[1], 16):
364                                                 return True
365                                 else: # request available
366                                         try:
367                                                 for caid in available_caids:
368                                                         if caid >= int(caid_entry[0], 16) and caid <= int(caid_entry[1], 16):
369                                                                 return True
370                                         except:
371                                                 pass
372
373                 return False
374
375         boolean = property(getBool)
376
377         def changed(self, what):
378                 if what[0] == self.CHANGED_SPECIFIC:
379                         self.updateFEdata = False
380                         if what[1] == iPlayableService.evNewProgramInfo:
381                                 self.updateFEdata = True
382                         if what[1] == iPlayableService.evEnd:
383                                 self.feraw = self.fedata = None
384                         Converter.changed(self, what)
385                 elif what[0] == self.CHANGED_POLL and self.updateFEdata is not None:
386                         self.updateFEdata = False
387                         Converter.changed(self, what)
388