1 # -*- coding: UTF-8 -*-
2 # To check if in Standby
6 from enigma import eServiceReference, eServiceCenter
9 from ServiceReference import ServiceReference
12 from EPGRefreshTimer import epgrefreshtimer, EPGRefreshTimerEntry, checkTimespan
14 # To calculate next timer execution
18 from xml.etree.cElementTree import parse as cet_parse
19 from Tools.XMLTools import stringToXML
20 from os import path as path
22 # We want a list of unique services
23 from EPGRefreshService import EPGRefreshService
26 from Components.config import config
28 # Path to configuration
29 CONFIG = "/etc/enigma2/epgrefresh.xml"
32 """Simple Class to refresh EPGData"""
36 self.services = (set(), set())
37 self.previousService = None
38 self.forcedScan = False
40 self.beginOfTimespan = 0
42 # Mtime of configuration files
45 # Read in Configuration
46 self.readConfiguration()
48 def readConfiguration(self):
49 # Check if file exists
50 if not path.exists(CONFIG):
53 # Check if file did not change
54 mtime = path.getmtime(CONFIG)
55 if mtime == self.configMtime:
59 self.configMtime = mtime
62 self.services[0].clear()
63 self.services[1].clear()
66 configuration= cet_parse(CONFIG).getroot()
69 for service in configuration.findall("service"):
72 # strip all after last : (custom name)
73 pos = value.rfind(':')
77 duration = service.get('duration', None)
78 duration = duration and int(duration)
80 self.services[0].add(EPGRefreshService(value, duration))
81 for bouquet in configuration.findall("bouquet"):
84 duration = bouquet.get('duration', None)
85 duration = duration and int(duration)
86 self.services[1].add(EPGRefreshService(value, duration))
88 def buildConfiguration(self, webif = False):
89 list = ['<?xml version="1.0" ?>\n<epgrefresh>\n\n']
92 TAGSERVICE='e2servicereference'
93 TAGBOUQUET='e2servicereference'
94 TAGNAME='e2servicename'
100 for service in self.services[0]:
101 ref = ServiceReference(service.sref)
102 list.extend((' <', TAGNAME, '>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</', TAGNAME, '>\n'))
103 list.extend((' <', TAGSERVICE))
104 if service.duration is not None:
105 list.extend((' duration="', str(service.duration), '"'))
106 list.extend(('>', stringToXML(service.sref), '</', TAGSERVICE, '>\n'))
107 for bouquet in self.services[1]:
108 ref = ServiceReference(bouquet.sref)
109 list.extend((' <', TAGNAME, '>', stringToXML(ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '')), '</', TAGNAME, '>\n'))
110 list.extend((' <', TAGBOUQUET))
111 if bouquet.duration is not None:
112 list.extend((' duration="', str(bouquet.duration), '"'))
113 list.extend(('>', stringToXML(bouquet.sref), '</', TAGBOUQUET, '>\n'))
115 list.append('\n</epgrefresh>')
119 def saveConfiguration(self):
120 file = open(CONFIG, 'w')
121 file.writelines(self.buildConfiguration())
125 def forceRefresh(self, session = None):
126 print "[EPGRefresh] Forcing start of EPGRefresh"
127 if self.session is None:
128 if session is not None:
129 self.session = session
133 self.forcedScan = True
134 self.prepareRefresh()
137 def start(self, session = None):
138 if session is not None:
139 self.session = session
141 epgrefreshtimer.setRefreshTimer(self.createWaitTimer)
144 print "[EPGRefresh] Stopping Timer"
145 epgrefreshtimer.clear()
147 def prepareRefresh(self):
148 print "[EPGRefresh] About to start refreshing EPG"
151 self.previousService = self.session.nav.getCurrentlyPlayingServiceReference()
153 # Maybe read in configuration
155 self.readConfiguration()
157 print "[EPGRefresh] Error occured while reading in configuration:", e
159 # This will hold services which are not explicitely in our list
160 additionalServices = []
161 additionalBouquets = []
163 # See if we are supposed to read in autotimer services
164 if config.plugins.epgrefresh.inherit_autotimer.value:
165 removeInstance = False
168 from Plugins.Extensions.AutoTimer.plugin import autotimer
170 if autotimer is None:
171 removeInstance = True
173 from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer
174 autotimer = AutoTimer()
176 # Read in configuration
179 print "[EPGRefresh] Could not inherit AutoTimer Services:", e
182 for timer in autotimer.getEnabledTimerList():
183 additionalServices.extend([EPGRefreshService(x, None) for x in timer.services])
184 additionalBouquets.extend([EPGRefreshService(x, None) for x in timer.bouquets])
186 # Remove instance if there wasn't one before
190 serviceHandler = eServiceCenter.getInstance()
191 for bouquet in self.services[1].union(additionalBouquets):
192 myref = eServiceReference(bouquet.sref)
193 list = serviceHandler.list(myref)
197 # TODO: I wonder if its sane to assume we get services here (and not just new lists)
199 additionalServices.append(EPGRefreshService(s.toString(), None))
202 del additionalBouquets[:]
206 for scanservice in self.services[0].union(additionalServices):
207 service = eServiceReference(scanservice.sref)
208 if not service.valid() \
209 or (service.flags & (eServiceReference.isMarker|eServiceReference.isDirectory)):
213 channelID = '%08x%04x%04x' % (
214 service.getUnsignedData(4), # NAMESPACE
215 service.getUnsignedData(2), # TSID
216 service.getUnsignedData(3), # ONID
219 if channelID not in channelIdList:
220 scanServices.append(scanservice)
221 channelIdList.append(channelID)
222 del additionalServices[:]
225 #print "[EPGRefresh] Services we're going to scan:", ', '.join([repr(x) for x in scanServices])
227 self.scanServices = scanServices
231 config.plugins.epgrefresh.lastscan.value = int(time())
232 config.plugins.epgrefresh.lastscan.save()
234 # Eventually force autotimer to parse epg
235 if config.plugins.epgrefresh.parse_autotimer.value:
236 removeInstance = False
239 from Plugins.Extensions.AutoTimer.plugin import autotimer
241 if autotimer is None:
242 removeInstance = True
244 from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer
245 autotimer = AutoTimer()
250 print "[EPGRefresh] Could not start AutoTimer:", e
252 # Remove instance if there wasn't one before
256 # shutdown if we're supposed to go to deepstandby and not recording
257 if not self.forcedScan and config.plugins.epgrefresh.afterevent.value \
258 and not Screens.Standby.inTryQuitMainloop:
261 Screens.Standby.TryQuitMainloop,
265 self.forcedScan = False
266 epgrefreshtimer.cleanup()
269 if self.previousService is not None or Screens.Standby.inStandby:
270 self.session.nav.playService(self.previousService)
276 # Abort if a scan finished later than our begin of timespan
277 if self.beginOfTimespan < config.plugins.epgrefresh.lastscan.value:
279 if config.plugins.epgrefresh.force.value \
280 or (Screens.Standby.inStandby and \
281 not self.session.nav.RecordTimer.isRecording()):
284 # We don't follow our rules here - If the Box is still in Standby and not recording we won't reach this line
286 if not checkTimespan(
287 config.plugins.epgrefresh.begin.value,
288 config.plugins.epgrefresh.end.value):
290 print "[EPGRefresh] Gone out of timespan while refreshing, sorry!"
293 print "[EPGRefresh] Box no longer in Standby or Recording started, rescheduling"
296 epgrefreshtimer.add(EPGRefreshTimerEntry(
297 time() + config.plugins.epgrefresh.delay_standby.value*60,
302 def createWaitTimer(self):
303 self.beginOfTimespan = time()
305 # Add wait timer to epgrefreshtimer
306 epgrefreshtimer.add(EPGRefreshTimerEntry(time() + 30, self.prepareRefresh))
308 def nextService(self):
310 print "[EPGRefresh] Maybe zap to next service"
314 service = self.scanServices.pop(0)
317 print "[EPGRefresh] Done refreshing EPG"
323 self.session.nav.playService(eServiceReference(service.sref))
326 delay = service.duration or config.plugins.epgrefresh.interval.value
327 epgrefreshtimer.add(EPGRefreshTimerEntry(
333 epgrefresh = EPGRefresh()