VPS-Plugin: initial checkin
[enigma2-plugins.git] / vps / src_py / Vps_check.py
1 # -*- coding: utf-8 -*-
2
3 from . import _
4 from enigma import eTimer, eConsoleAppContainer, getBestPlayableServiceReference, eServiceReference, eEPGCache
5 from Screens.Screen import Screen
6 from Components.ActionMap import ActionMap
7 from Components.Sources.StaticText import StaticText
8 from Screens.MessageBox import MessageBox
9 from Tools.XMLTools import stringToXML
10 from Tools import Directories
11 from time import time
12 from Vps import vps_exe
13 import NavigationInstance
14 from xml.etree.cElementTree import parse as xml_parse
15
16 check_pdc_interval_available = 3600*24*30*6
17 check_pdc_interval_unavailable = 3600*24*30*2
18
19 # Prüfen, ob PDC-Descriptor vorhanden ist.
20 class VPS_check_PDC(Screen):
21         skin = """<screen name="vpsCheck" position="center,center" size="540,110" title="VPS-Plugin">
22                 <widget source="infotext" render="Label" position="10,10" size="520,90" font="Regular;21" valign="center" halign="center" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
23         </screen>"""
24         
25         def __init__(self, session, service, timer_entry):
26                 Screen.__init__(self, session)
27                 
28                 self["infotext"] = StaticText(_("VPS-Plugin checks if the channel supports VPS for manual timers ..."))
29                 
30                 self["actions"] = ActionMap(["OkCancelActions"], 
31                         {
32                                 "cancel": self.finish,
33                         }, -1)
34                 
35                 if service is None or service.ref.getPath():
36                         self.close()
37                         return
38
39                 self.service = service.ref
40                 self.program = eConsoleAppContainer()
41                 self.program.dataAvail.append(self.program_dataAvail)
42                 self.program.appClosed.append(self.program_closed)
43                 self.check = eTimer()
44                 self.check.callback.append(self.doCheck)
45                 self.simulate_recordService = None
46                 self.last_serviceref = None
47                 self.calledfinished = False
48                 
49                 self.checked_services = { }
50                 self.has_pdc = -1
51                 self.timer_entry = timer_entry
52                 
53                 if self.service and self.service.flags & eServiceReference.isGroup:
54                         self.service = getBestPlayableServiceReference(self.service, eServiceReference())
55                 self.service_ref_str = self.service.toString()
56                 
57                 self.load_pdc()
58                 
59                 try:
60                         if self.checked_services[self.service_ref_str]["has_pdc"] == True:
61                                 self.has_pdc = 1
62                         else:
63                                 self.has_pdc = 0
64                 except:
65                         self.has_pdc = -1
66                 
67                 self.check.start(100, True)
68                 
69         def load_pdc(self):
70                 try:
71                         doc = xml_parse(Directories.resolveFilename(Directories.SCOPE_CONFIG, "vps.xml"))
72                         xmlroot = doc.getroot()
73                         
74                         if xmlroot is not None:
75                                 for xml in xmlroot.findall("channel"):
76                                         serviceref = xml.get("serviceref").encode("utf-8")
77                                         has_pdc = xml.get("has_pdc")
78                                         last_check = xml.get("last_check")
79                                         self.checked_services[serviceref] = { }
80                                         self.checked_services[serviceref]["last_check"] = int(last_check)
81                                         if has_pdc == "1":
82                                                 self.checked_services[serviceref]["has_pdc"] = True
83                                         else:
84                                                 self.checked_services[serviceref]["has_pdc"] = False
85                 except:
86                         pass
87         
88         def save_pdc(self):
89                 list = []
90                 list.append('<?xml version="1.0" ?>\n')
91                 list.append('<pdc_available>\n')
92                 
93                 now = time()
94                 for ch in self.checked_services:
95                         if self.checked_services[ch]["last_check"] < (now - check_pdc_interval_available):
96                                 continue
97                         list.append('<channel')
98                         list.append(' serviceref="' + stringToXML(ch) + '"')
99                         list.append(' has_pdc="' + str(int(self.checked_services[ch]["has_pdc"])) + '"')
100                         list.append(' last_check="' + str(int(self.checked_services[ch]["last_check"])) + '"')
101                         list.append('></channel>\n')
102                 
103                 list.append('</pdc_available>\n')
104                 
105                 file = open(Directories.resolveFilename(Directories.SCOPE_CONFIG, "vps.xml"), "w")
106                 for x in list:
107                         file.write(x)
108                 file.close()
109         
110         def doCheck(self):
111                 if (self.has_pdc == 1 and self.checked_services[self.service_ref_str]["last_check"] > (time() - check_pdc_interval_available)) or (self.has_pdc == 0 and self.checked_services[self.service_ref_str]["last_check"] > (time() - check_pdc_interval_unavailable)):
112                         self.finish()
113                         return
114                 
115                 self.demux = -1
116                 if self.simulate_recordService is None:
117                         self.simulate_recordService = NavigationInstance.instance.recordService(self.service, True)
118                         if self.simulate_recordService:
119                                 res = self.simulate_recordService.start()
120                                 if res != 0 and res != -1:
121                                         # Fehler aufgetreten (kein Tuner frei?)
122                                         NavigationInstance.instance.stopRecordService(self.simulate_recordService)
123                                         self.simulate_recordService = None
124                                         
125                                         if self.last_serviceref is not None:
126                                                 self.finish()
127                                                 return
128                                         else:
129                                                 cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
130                                                 if cur_ref and not cur_ref.getPath():
131                                                         self.last_serviceref = cur_ref
132                                                         NavigationInstance.instance.playService(None)
133                                                         self.check.start(1500, True)
134                                                         return
135                                 else: # hat geklappt
136                                         self.check.start(1000, True)
137                                         return
138                 else:
139                         stream = self.simulate_recordService.stream()
140                         if stream:
141                                 streamdata = stream.getStreamingData()
142                                 if (streamdata and ('demux' in streamdata)):
143                                         self.demux = streamdata['demux']
144                         if self.demux != -1:
145                                 self.startProgram()
146                                 return
147                 
148                 if self.simulate_recordService is not None:
149                         NavigationInstance.instance.stopRecordService(self.simulate_recordService)
150                         self.simulate_recordService = None
151                 if self.last_serviceref is not None:
152                         NavigationInstance.instance.playService(self.last_serviceref)
153                 self.finish()
154         
155         def startProgram(self):
156                 sid = self.service.getData(1)
157                 tsid = self.service.getData(2)
158                 onid = self.service.getData(3)
159                 demux = "/dev/dvb/adapter0/demux" + str(self.demux)
160                 
161                 cmd = vps_exe + " "+ demux +" 10 "+ str(onid) +" "+ str(tsid) +" "+ str(sid) +" 0 0"
162                 self.program.execute(cmd)
163         
164         def program_closed(self, retval):
165                 if not self.calledfinished:
166                         self.setServicePDC(-1)
167                         self.finish()
168         
169         def program_dataAvail(self, str):
170                 lines = str.split("\n")
171                 for line in lines:
172                         if line == "PDC_AVAILABLE" and not self.calledfinished:
173                                 self.calledfinished = True
174                                 self.setServicePDC(1)
175                                 self.finish()
176                                 
177                         elif line == "NO_PDC_AVAILABLE" and not self.calledfinished:
178                                 self.calledfinished = True
179                                 self.setServicePDC(0)
180                                 self.finish()
181         
182         def setServicePDC(self, state):
183                 if state == -1:
184                         self.has_pdc = -1
185                         try:
186                                 del self.checked_services[self.service_ref_str]
187                         except:
188                                 pass
189                 elif state == 1:
190                         self.has_pdc = 1
191                         self.checked_services[self.service_ref_str] = { }
192                         self.checked_services[self.service_ref_str]["has_pdc"] = True
193                         self.checked_services[self.service_ref_str]["last_check"] = time()
194                 elif state == 0:
195                         self.has_pdc = 0
196                         self.checked_services[self.service_ref_str] = { }
197                         self.checked_services[self.service_ref_str]["has_pdc"] = False
198                         self.checked_services[self.service_ref_str]["last_check"] = time()
199                 
200                 self.save_pdc()
201                 
202         def finish(self):
203                 self.calledfinished = True
204                 self.check.stop()
205                 
206                 if self.simulate_recordService is not None:
207                         NavigationInstance.instance.stopRecordService(self.simulate_recordService)
208                         self.simulate_recordService = None
209                 
210                 if self.last_serviceref is not None:
211                         NavigationInstance.instance.playService(self.last_serviceref)
212                 
213                 if self.has_pdc == 1: # PDC vorhanden
214                         self.close()
215                 elif self.has_pdc == 0: # kein PDC
216                         #nachfragen
217                         self.session.openWithCallback(self.finish_callback, MessageBox, _("The selected channel doesn't support VPS for manually programmed timers!\n Do you really want to enable VPS?"), default = False)
218                 else: # konnte nicht ermitteln
219                         self.session.openWithCallback(self.finish_callback, MessageBox, _("The VPS-Plugin couldn't check if the selected channel supports VPS for manually programmed timers!\n Do you really want to enable VPS?"), default = False)
220         
221         
222         def finish_callback(self, result):
223                 if not result:
224                         self.timer_entry.timerentry_vpsplugin_enabled.value = False
225                         self.timer_entry.createSetup("config")
226                 
227                 self.close()
228