1 #######################################################################
3 # Merlin Programm Guide for Dreambox-Enigma2
4 # Coded by Vali (c)2010-2011
5 # Support: www.dreambox-tools.info
8 # This plugin is licensed under the Creative Commons
9 # Attribution-NonCommercial-ShareAlike 3.0 Unported License.
10 # To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
11 # or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
13 # Alternatively, this plugin may be distributed and executed on hardware which
14 # is licensed by Dream Multimedia GmbH.
17 # This plugin is NOT free software. It is open source, you are allowed to
18 # modify it (if you keep the license), but it may not be commercially
19 # distributed other than under the conditions noted above.
22 #######################################################################
26 from Plugins.Plugin import PluginDescriptor
27 from Screens.Screen import Screen
28 from Screens.EventView import EventViewSimple
29 from Screens.MessageBox import MessageBox
30 from Screens.ChoiceBox import ChoiceBox
31 from Screens.TimerEntry import TimerEntry
32 from Screens.TimerEdit import TimerSanityConflict
33 from Components.ConfigList import ConfigListScreen
34 from Components.ActionMap import ActionMap
35 from Components.MenuList import MenuList
36 from Components.Label import Label
37 from Components.EpgList import EPGList, EPG_TYPE_SINGLE, Rect
38 from Components.config import config, ConfigSubsection, ConfigYesNo, ConfigInteger, getConfigListEntry
39 from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN, fileExists
40 from Tools.LoadPixmap import LoadPixmap
41 from enigma import eServiceReference, eServiceCenter, getDesktop, eTimer, gFont, eListboxPythonMultiContent, RT_HALIGN_LEFT, RT_WRAP, eEPGCache
42 from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
43 from ServiceReference import ServiceReference
44 from ShowMe import ShowMe
45 from time import localtime
46 if fileExists("/usr/lib/enigma2/python/Plugins/Extensions/AutoTimer/AutoTimerEditor.pyo"):
47 from Plugins.Extensions.AutoTimer.AutoTimerEditor import addAutotimerFromEvent
48 from Plugins.Extensions.AutoTimer.plugin import main as AutoTimerView
51 AutoTimerPresent=False
52 if fileExists("/usr/lib/enigma2/python/Plugins/Extensions/IMDb/plugin.pyo"):
53 from Plugins.Extensions.IMDb.plugin import IMDB
57 if fileExists("/usr/lib/enigma2/python/Plugins/Extensions/EPGSearch/EPGSearch.pyo"):
58 from Plugins.Extensions.EPGSearch.EPGSearch import EPGSearchList, EPGSearch
65 config.plugins.MerlinEPG = ConfigSubsection()
66 config.plugins.MerlinEPG.Columns = ConfigYesNo(default=True)
67 config.plugins.MerlinEPG.StartFirst = ConfigYesNo(default=False)
68 config.plugins.MerlinEPG.Primetime = ConfigInteger(default=20, limits=(0, 23))
69 config.plugins.MerlinEPG.PTlow = ConfigInteger(default=10, limits=(0, 59))
70 config.plugins.MerlinEPG.PThi = ConfigInteger(default=20, limits=(0, 59))
71 config.plugins.MerlinEPG.AutoPT = ConfigYesNo(default=False)
72 config.plugins.MerlinEPG.ZapOnOK = ConfigYesNo(default=False)
73 config.plugins.MerlinEPG.PageUDonBouquets = ConfigYesNo(default=True)
77 def Plugins(**kwargs):
78 list = [(PluginDescriptor(name="Merlin Programm Guide", description="Merlin Programm Guide", where = PluginDescriptor.WHERE_EVENTINFO, fnc=startMerlinPG))]
79 list.append(PluginDescriptor(name="Merlin Programm Guide", where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=startMerlinPGnew))
84 def startMerlinPG(session, servicelist, **kwargs):
85 if config.plugins.MerlinEPG.Columns.value:
86 session.open(Merlin_PGII, servicelist)
88 session.open(Merlin_PGd, servicelist)
92 def startMerlinPGnew(session, **kwargs):
93 if "servicelist" in kwargs:
94 if config.plugins.MerlinEPG.Columns.value:
95 session.open(Merlin_PGII, kwargs["servicelist"])
97 session.open(Merlin_PGd, kwargs["servicelist"])
99 if config.plugins.MerlinEPG.Columns.value:
100 session.open(Merlin_PGII)
102 session.open(Merlin_PGd)
106 class MerlinPGsetup(ConfigListScreen, Screen):
108 <screen position="center,center" size="600,300" title="Merlin Programm Guide">
109 <widget name="config" position="10,10" size="580,280" scrollbarMode="showOnDemand" />
112 def __init__(self, session):
113 Screen.__init__(self, session)
115 clist.append(getConfigListEntry(_("Show EPG in columns:"), config.plugins.MerlinEPG.Columns))
116 clist.append(getConfigListEntry(_("Start allways on channel 1:"), config.plugins.MerlinEPG.StartFirst))
117 clist.append(getConfigListEntry(_("Primetime (h):"), config.plugins.MerlinEPG.Primetime))
118 clist.append(getConfigListEntry(_("Primetime from (m):"), config.plugins.MerlinEPG.PTlow))
119 clist.append(getConfigListEntry(_("Primetime to (m):"), config.plugins.MerlinEPG.PThi))
120 clist.append(getConfigListEntry(_("Auto-Primetime:"), config.plugins.MerlinEPG.AutoPT))
121 clist.append(getConfigListEntry(_("Zap with OK button (false=EventInfo):"), config.plugins.MerlinEPG.ZapOnOK))
122 clist.append(getConfigListEntry(_("Page-up/down with bouquet+/- :"), config.plugins.MerlinEPG.PageUDonBouquets))
123 ConfigListScreen.__init__(self, clist)
124 self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.set, "cancel": self.exit}, -2)
127 if not config.plugins.MerlinEPG.PThi.value > config.plugins.MerlinEPG.PTlow.value:
129 for x in self["config"].list:
134 for x in self["config"].list:
140 class MerlinEPGList(EPGList):
141 def __init__(self, type=EPG_TYPE_SINGLE, selChangedCB=None, timer = None):
142 EPGList.__init__(self, type, selChangedCB, timer)
143 self.l.setFont(0, gFont("Regular", 18))
144 self.PTpicture = LoadPixmap(cached=True, path="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/primetime.png")
147 def recalcEntrySize(self):
148 esize = self.l.getItemSize()
149 width = esize.width()
150 height = esize.height()
151 self.weekday_rect = Rect(120, -10, 200, 20)
152 self.datetime_rect = Rect(0, 0, 120, 20)
153 self.descr_rect = Rect(0, 22, width, height-23)
156 def buildSingleEntry(self, service, eventId, beginTime, duration, EventName):
157 (clock_pic, rec) = self.getPixmapForEntry(service, eventId, beginTime, duration)
159 r2=self.datetime_rect
161 t = localtime(beginTime)
162 self.evCnt = self.evCnt + 1
163 if (t[3]==config.plugins.MerlinEPG.Primetime.value) and (t[4]>=config.plugins.MerlinEPG.PTlow.value) and (t[4]<config.plugins.MerlinEPG.PThi.value):
166 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_LEFT, " _________________"),
167 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 100, 1, 21, 21, self.PTpicture),
168 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_LEFT, (("%02d:%02d"%(t[3],t[4]))+" - "+self.days[t[6]]))
173 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_LEFT, "___________________"),
174 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_LEFT, (("%02d:%02d"%(t[3],t[4]))+" - "+self.days[t[6]]))
178 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
179 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT|RT_WRAP, EventName)
182 res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT|RT_WRAP, EventName))
186 tmp = self.l.getCurrentSelection()
189 bt = localtime(tmp[2])
190 return ( bt[3], bt[4] )
192 def foudPrimetime(self):
193 for OneLine in range(0,self.evCnt):
194 evBgTime, evBgMin = self.getBgTime()
195 if evBgTime is not None:
196 if (evBgTime==config.plugins.MerlinEPG.Primetime.value) and (evBgMin>=config.plugins.MerlinEPG.PTlow.value) and (evBgMin<config.plugins.MerlinEPG.PThi.value):
204 class Merlin_PGII(Screen):
205 sz_w = getDesktop(0).size().width()
208 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1280,720" title="Merlin Program Guide">
209 <!-- DO NOT CHANGE THIS LINE !!!!!!!!!!!!!!! --><widget enableWrapAround="0" itemHeight="25" name="prg_list" position="-200,-200" size="50,125"/>
210 <widget font="Regular;18" halign="center" valign="center" name="currCh1" position="60,40" size="231,24" transparent="1" zPosition="2"/>
211 <widget font="Regular;18" halign="center" valign="center" name="currCh2" position="291,40" size="231,24" transparent="1" zPosition="2"/>
212 <widget font="Regular;18" halign="center" valign="center" name="currCh3" position="522,40" size="231,24" transparent="1" zPosition="2"/>
213 <widget font="Regular;18" halign="center" valign="center" name="currCh4" position="753,40" size="231,24" transparent="1" zPosition="2"/>
214 <widget font="Regular;18" halign="center" valign="center" name="currCh5" position="984,40" size="231,24" transparent="1" zPosition="2"/>
215 <widget backgroundColor="#10444649" name="Active1" position="60,80" size="225,560" transparent="0" zPosition="3"/>
216 <widget backgroundColor="#10444649" name="Active2" position="291,80" size="225,560" transparent="0" zPosition="3"/>
217 <widget backgroundColor="#10444649" name="Active3" position="522,80" size="225,560" transparent="0" zPosition="3"/>
218 <widget backgroundColor="#10444649" name="Active4" position="753,80" size="225,560" transparent="0" zPosition="3"/>
219 <widget backgroundColor="#10444649" name="Active5" position="984,80" size="225,560" transparent="0" zPosition="3"/>
220 <widget itemHeight="70" name="epg_list1" position="60,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
221 <widget itemHeight="70" name="epg_list2" position="291,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
222 <widget itemHeight="70" name="epg_list3" position="522,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
223 <widget itemHeight="70" name="epg_list4" position="753,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
224 <widget itemHeight="70" name="epg_list5" position="984,80" scrollbarMode="showOnDemand" size="225,560" transparent="1" zPosition="4"/>
225 <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/buttons.png" position="60,655" size="430,24"/>
226 <widget backgroundColor="background" font="Regular;18" foregroundColor="#ffc000" position="500,655" render="Label" size="200,24" source="global.CurrentTime" transparent="1" valign="center" zPosition="3">
227 <convert type="ClockToText">Format:%H:%M %a %d. %b</convert>
232 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1024,576" title="Merlin Program Guide">
233 <!-- DO NOT CHANGE THIS LINE !!!!!!!!!!!!!!! --><widget enableWrapAround="0" itemHeight="25" name="prg_list" position="-200,-200" size="50,100"/>
234 <widget font="Regular;18" halign="center" valign="center" name="currCh1" position="50,40" size="231,24" transparent="1" zPosition="2"/>
235 <widget font="Regular;18" halign="center" valign="center" name="currCh2" position="281,40" size="231,24" transparent="1" zPosition="2"/>
236 <widget font="Regular;18" halign="center" valign="center" name="currCh3" position="512,40" size="231,24" transparent="1" zPosition="2"/>
237 <widget font="Regular;18" halign="center" valign="center" name="currCh4" position="743,40" size="231,24" transparent="1" zPosition="2"/>
238 <widget backgroundColor="#10444649" name="Active1" position="50,80" size="225,420" transparent="0" zPosition="3"/>
239 <widget backgroundColor="#10444649" name="Active2" position="281,80" size="225,420" transparent="0" zPosition="3"/>
240 <widget backgroundColor="#10444649" name="Active3" position="512,80" size="225,420" transparent="0" zPosition="3"/>
241 <widget backgroundColor="#10444649" name="Active4" position="743,80" size="225,420" transparent="0" zPosition="3"/>
242 <widget itemHeight="70" name="epg_list1" position="50,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
243 <widget itemHeight="70" name="epg_list2" position="281,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
244 <widget itemHeight="70" name="epg_list3" position="512,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
245 <widget itemHeight="70" name="epg_list4" position="743,80" scrollbarMode="showOnDemand" size="225,420" transparent="1" zPosition="4"/>
246 <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/buttons.png" position="50,518" size="430,24"/>
247 <widget backgroundColor="background" font="Regular;18" foregroundColor="#ffc000" position="490,518" render="Label" size="200,24" source="global.CurrentTime" transparent="1" valign="center" zPosition="3">
248 <convert type="ClockToText">Format:%H:%M %a %d. %b</convert>
250 <!-- <widget font="Regular;18" name="fullEventInfo" position="300,200" size="300,200" transparent="0" zPosition="12"/> -->
254 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="720,576" title="Merlin Program Guide">
255 <!-- DO NOT CHANGE THIS LINE !!!!!!!!!!!!!!! --><widget enableWrapAround="0" itemHeight="25" name="prg_list" position="-200,-200" size="50,100"/>
256 <widget font="Regular;18" halign="center" valign="center" name="currCh1" position="50,35" size="155,36" transparent="1" zPosition="2"/>
257 <widget font="Regular;18" halign="center" valign="center" name="currCh2" position="205,35" size="155,36" transparent="1" zPosition="2"/>
258 <widget font="Regular;18" halign="center" valign="center" name="currCh3" position="360,35" size="155,36" transparent="1" zPosition="2"/>
259 <widget font="Regular;18" halign="center" valign="center" name="currCh4" position="515,35" size="155,36" transparent="1" zPosition="2"/>
260 <widget backgroundColor="#10444649" name="Active1" position="50,90" size="155,420" transparent="0" zPosition="3"/>
261 <widget backgroundColor="#10444649" name="Active2" position="205,90" size="155,420" transparent="0" zPosition="3"/>
262 <widget backgroundColor="#10444649" name="Active3" position="360,90" size="155,420" transparent="0" zPosition="3"/>
263 <widget backgroundColor="#10444649" name="Active4" position="515,90" size="155,420" transparent="0" zPosition="3"/>
264 <widget itemHeight="70" name="epg_list1" position="50,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
265 <widget itemHeight="70" name="epg_list2" position="205,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
266 <widget itemHeight="70" name="epg_list3" position="360,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
267 <widget itemHeight="70" name="epg_list4" position="515,90" scrollbarMode="showOnDemand" size="155,420" transparent="1" zPosition="4"/>
268 <ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/buttons.png" position="50,518" size="430,24"/>
269 <widget backgroundColor="background" font="Regular;18" foregroundColor="#ffc000" position="490,518" render="Label" size="200,24" source="global.CurrentTime" transparent="1" valign="center" zPosition="3">
270 <convert type="ClockToText">Format:%H:%M %a %d. %b</convert>
274 def __init__(self, session, servicelist=None):
275 Screen.__init__(self, session)
276 self.session = session
277 self.srvList = servicelist
283 if getDesktop(0).size().width() == 1280:
285 self["currCh5"] = Label(" ")
286 self["Active5"] = Label(" ")
287 self["epg_list5"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
290 self.CheckForEPG = eTimer()
291 self.CheckForEPG.callback.append(self.CheckItNow)
292 self.AutoPrime = eTimer()
293 self.AutoPrime.callback.append(self.go2Primetime)
294 self["prg_list"] = MenuList(self.getChannels())
295 self["fullEventInfo"] = Label(" ")
296 self["currCh1"] = Label(" ")
297 self["currCh2"] = Label(" ")
298 self["currCh3"] = Label(" ")
299 self["currCh4"] = Label(" ")
300 self["Active1"] = Label(" ")
301 self["Active2"] = Label(" ")
302 self["Active3"] = Label(" ")
303 self["Active4"] = Label(" ")
304 self["epg_list1"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
305 self["epg_list2"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
306 self["epg_list3"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
307 self["epg_list4"] = MerlinEPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
308 self["actions"] = ActionMap(["OkCancelActions", "EPGSelectActions", "DirectionActions", "ColorActions", "MenuActions", "NumberActions", "HelpActions", "InfobarActions"], {
310 "cancel": self.close,
311 "nextBouquet": self.AllUp,
312 "prevBouquet": self.AllDown,
313 "nextService": self.NextPage,
314 "prevService": self.PrevPage,
316 "rightRepeated": self.right,
318 "leftRepeated": self.left,
320 "upRepeated": self.up,
322 "downRepeated": self.down,
323 "info": self.showEventInfo,
325 "green": self.timerAdd,
326 "blue": self.ZapForRefresh,
327 "yellow": self.go2Primetime,
328 "menu": self.menuClicked,
329 "displayHelp": self.myhelp,
332 "7": self.findPrvBqt,
333 "9": self.findNextBqt,
334 "showMovies": self.editCurTimer,
335 "showTv": self.fullEPGlist
337 self.onLayoutFinish.append(self.onLayoutReady)
339 def getChannels(self):
341 serviceHandler = eServiceCenter.getInstance()
342 services = serviceHandler.list(eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'))
343 bouquets = services and services.getContent("SN", True)
344 for bouquet in bouquets:
345 services = serviceHandler.list(eServiceReference(bouquet[0]))
346 channels = services and services.getContent("SN", True)
347 for channel in channels:
348 if not channel[0].startswith("1:64:"):
350 self.list.append(str(indx) + ". " + channel[1].replace('\xc2\x86', '').replace('\xc2\x87', ''))
351 self.myServices.append(channel)
352 self.myBqts.append(bouquet)
353 self.chCount = indx - 1
356 def onLayoutReady(self):
357 service = self.session.nav.getCurrentService()
358 info = service and service.info()
359 if (info is not None) and not(config.plugins.MerlinEPG.StartFirst.value):
360 nameROH = info.getName().replace('\xc2\x86', '').replace('\xc2\x87', '')
361 for idx in range(1, len(self.list)):
362 name = str(idx) + ". " + nameROH
363 if name == self.list[idx-1]:
365 self["prg_list"].moveToIndex(idx-1)
367 self["prg_list"].moveToIndex(0)
370 def updateInfos(self):
371 if self.AutoPrime.isActive():
372 self.AutoPrime.stop()
373 self.displayActiveEPG()
374 prgIndex = self["prg_list"].getSelectionIndex()
375 CurrentPrg = self.myServices[prgIndex]
376 self["currCh1"].setText(str(CurrentPrg[1]))
377 l = self["epg_list1"]
379 myService = ServiceReference(CurrentPrg[0])
380 l.fillSingleEPG(myService)
381 prgIndex = prgIndex + 1
382 if prgIndex < (self.chCount+1):
383 self["epg_list2"].show()
384 CurrentPrg = self.myServices[prgIndex]
385 self["currCh2"].setText(str(CurrentPrg[1]))
386 l = self["epg_list2"]
388 myService = ServiceReference(CurrentPrg[0])
389 l.fillSingleEPG(myService)
391 self["currCh2"].setText(str(" "))
392 self["epg_list2"].hide()
393 prgIndex = prgIndex + 1
394 if prgIndex < (self.chCount+1):
395 self["epg_list3"].show()
396 CurrentPrg = self.myServices[prgIndex]
397 self["currCh3"].setText(str(CurrentPrg[1]))
398 l = self["epg_list3"]
400 myService = ServiceReference(CurrentPrg[0])
401 l.fillSingleEPG(myService)
403 self["currCh3"].setText(str(" "))
404 self["epg_list3"].hide()
405 prgIndex = prgIndex + 1
406 if prgIndex < (self.chCount+1):
407 self["epg_list4"].show()
408 CurrentPrg = self.myServices[prgIndex]
409 self["currCh4"].setText(str(CurrentPrg[1]))
410 CurrentPrg = self.myServices[prgIndex]
411 self["currCh4"].setText(str(CurrentPrg[1]))
412 l = self["epg_list4"]
414 myService = ServiceReference(CurrentPrg[0])
415 l.fillSingleEPG(myService)
417 self["currCh4"].setText(str(" "))
418 self["epg_list4"].hide()
420 prgIndex = prgIndex + 1
421 if prgIndex < (self.chCount+1):
422 self["epg_list5"].show()
423 CurrentPrg = self.myServices[prgIndex]
424 self["currCh5"].setText(str(CurrentPrg[1]))
425 l = self["epg_list5"]
427 myService = ServiceReference(CurrentPrg[0])
428 l.fillSingleEPG(myService)
430 self["currCh5"].setText(str(" "))
431 self["epg_list5"].hide()
432 if config.plugins.MerlinEPG.AutoPT.value:
433 self.AutoPrime.start(500)
435 def onSelectionChanged(self):
436 curEV = self["epg_list"+str(self.ActiveEPG)].getCurrent()
438 ext = event and event.getExtendedDescription() or ""
439 self["fullEventInfo"].setText(str(ext))
442 self["prg_list"].pageDown()
447 self["prg_list"].pageUp()
451 def displayActiveEPG(self):
452 for xA in range(1,self.Fields):
453 if xA == self.ActiveEPG:
454 self["Active"+str(xA)].show()
456 self["Active"+str(xA)].hide()
458 def getActivePrg(self):
459 return self["prg_list"].getSelectionIndex()+(self.ActiveEPG-1)
462 if (self.getActivePrg() > self.chCount) or (self.srvList==None):
464 CurrentPrg = self.myServices[self.getActivePrg()]
465 CurrentBqt = self.myBqts[self.getActivePrg()]
466 myService = ServiceReference(CurrentPrg[0])
467 myB = ServiceReference(CurrentBqt[0])
468 self.srvList.clearPath()
469 if self.srvList.bouquet_root != myB.ref:
470 self.srvList.enterPath(self.srvList.bouquet_root)
471 self.srvList.enterPath(myB.ref)
472 self.srvList.setCurrentSelection(myService.ref)
476 def ZapForRefresh(self):
477 if (self.getActivePrg() > self.chCount) or (self.srvList==None):
479 CurrentPrg = self.myServices[self.getActivePrg()]
480 myService = ServiceReference(CurrentPrg[0])
481 self.session.nav.playService(myService.ref)
482 self.CheckForEPG.start(4000, True)
484 def CheckItNow(self):
485 self.CheckForEPG.stop()
486 CurrentPrg = self.myServices[self.getActivePrg()]
487 l = self["epg_list"+str(self.ActiveEPG)]
489 myService = ServiceReference(CurrentPrg[0])
490 l.fillSingleEPG(myService)
493 self["epg_list"+str(self.ActiveEPG)].moveUp()
496 self["epg_list"+str(self.ActiveEPG)].moveDown()
499 if config.plugins.MerlinEPG.PageUDonBouquets.value:
500 for xU in range(1,self.Fields):
501 self["epg_list"+str(xU)].instance.moveSelection(self["epg_list"+str(xU)].instance.pageUp)
503 for xU in range(1,self.Fields):
504 self["epg_list"+str(xU)].moveUp()
507 if config.plugins.MerlinEPG.PageUDonBouquets.value:
508 for xU in range(1,self.Fields):
509 self["epg_list"+str(xU)].instance.moveSelection(self["epg_list"+str(xU)].instance.pageDown)
511 for xD in range(1,self.Fields):
512 self["epg_list"+str(xD)].moveDown()
515 for xD in range(1,self.Fields):
516 self["epg_list"+str(xD)].instance.moveSelection(self["epg_list"+str(xD)].instance.moveTop)
519 self["prg_list"].moveToIndex(0)
524 if self.ActiveEPG > 1:
525 self.ActiveEPG = self.ActiveEPG - 1
526 self.displayActiveEPG()
528 self["prg_list"].pageUp()
529 self.ActiveEPG = (self.Fields-1)
531 self.onSelectionChanged()
534 if self.ActiveEPG < (self.Fields-1):
535 self.ActiveEPG = self.ActiveEPG + 1
536 self.displayActiveEPG()
539 self.onSelectionChanged()
541 def showEventInfo(self):
543 self.showConfirmedInfo([None,"Ei"])
545 self.session.openWithCallback(self.showConfirmedInfo, ChoiceBox, title=_("Select Info type..."), list=[(_("Standard EPG info"), "Ei"),(_("IMDb info"), "Ii")])
547 def showConfirmedInfo(self,answer):
548 curEV = self["epg_list"+str(self.ActiveEPG)].getCurrent()
551 answer = answer and answer[1]
553 if event is not None:
554 self.session.open(EventViewSimple, event, service)
556 if event is not None:
557 IeventName=event.getEventName()
558 self.session.open(IMDB, IeventName)
561 if not AutoTimerPresent:
562 self.AddConfirmedTimer([None,"NT"])
564 self.session.openWithCallback(self.AddConfirmedTimer, ChoiceBox, title=_("Select timer type..."), list=[(_("Standard timer"), "NT"),(_("AutoTimer"), "AT"),(_("View AutoTimers"), "ATV")])
566 def AddConfirmedTimer(self, answer):
567 cur = self["epg_list"+str(self.ActiveEPG)].getCurrent()
572 eventid = event.getEventId()
573 refstr = serviceref.ref.toString()
574 answer = answer and answer[1]
576 addAutotimerFromEvent(self.session,evt=event,service=serviceref)
578 for timer in self.session.nav.RecordTimer.timer_list:
579 if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
580 cb_func = lambda ret : not ret or self.removeTimer(timer)
581 self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
584 newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
585 self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
586 elif answer == "ATV":
587 AutoTimerView(self.session)
589 def removeTimer(self, timer):
590 timer.afterEvent = AFTEREVENT.NONE
591 self.session.nav.RecordTimer.removeEntry(timer)
593 def finishedAdd(self, answer):
596 simulTimerList = self.session.nav.RecordTimer.record(entry)
597 if simulTimerList is not None:
598 for x in simulTimerList:
599 if x.setAutoincreaseEnd(entry):
600 self.session.nav.RecordTimer.timeChanged(x)
601 simulTimerList = self.session.nav.RecordTimer.record(entry)
602 if simulTimerList is not None:
603 self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
605 def finishSanityCorrection(self, answer):
606 self.finishedAdd(answer)
608 def menuClicked(self):
609 self.session.open(MerlinPGsetup)
611 def findNextBqt(self):
613 CurrBqt = self.myBqts[self.getActivePrg()]
615 for CurrIdx in range(self.getActivePrg(),self.chCount):
616 NewBqt = self.myBqts[CurrIdx]
617 if NewBqt != CurrBqt:
619 self["prg_list"].moveToIndex(CurrIdx)
622 def findPrvBqt(self):
624 CurrBqt = self.myBqts[self.getActivePrg()]
626 for CurrIdx in range(self.getActivePrg(),-1,-1):
627 NewBqt = self.myBqts[CurrIdx]
628 if NewBqt != CurrBqt:
630 self["prg_list"].moveToIndex(CurrIdx)
633 def go2Primetime(self):
634 if self.AutoPrime.isActive():
635 self.AutoPrime.stop()
636 for xFL in range(1, self.Fields):
637 self["epg_list"+str(xFL)].instance.moveSelection(self["epg_list"+str(xFL)].instance.moveTop)
638 for i in range(0,(self.Fields*3)):
639 self["epg_list"+str(xFL)].foudPrimetime()
642 self.session.open(ShowMe, "/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/help.jpg")
645 if config.plugins.MerlinEPG.ZapOnOK.value:
648 self.showConfirmedInfo([None,"Ei"])
650 def editCurTimer(self):
651 cur = self["epg_list"+str(self.ActiveEPG)].getCurrent()
656 eventid = event.getEventId()
657 refstr = serviceref.ref.toString()
658 for timer in self.session.nav.RecordTimer.timer_list:
659 if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
660 self.session.open(TimerEntry, timer)
662 def fullEPGlist(self):
664 self.session.open(myEPGSearch)
666 self.session.open(MessageBox, text = _('EPGsearch is not installed!'), type = MessageBox.TYPE_ERROR)
670 class Merlin_PGd(Screen):
672 sz_w = getDesktop(0).size().width()
677 <screen backgroundColor="#ffffffff" flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1280,720" title="Merlin Program Guide">
678 <widget backgroundColor="#ffffffff" position="0,0" render="Pig" size="520,292" source="session.VideoPicture" zPosition="-1"/>
679 <eLabel backgroundColor="#00111112" position="0,292" size="520,450" zPosition="1"/>
680 <eLabel backgroundColor="#00111112" position="520,0" size="760,720" zPosition="1"/>
681 <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/epg.png" position="1136,105" size="85,77" zPosition="5"/>
682 <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/channels.png" position="395,306" size="80,80" zPosition="5"/>
683 <ePixmap alphatest="on" name="red" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/red.png" position="70,635" size="35,25" zPosition="2"/>
684 <ePixmap alphatest="on" name="green" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/green.png" position="275,635" size="35,25" zPosition="2"/>
685 <eLabel backgroundColor="#00111112" font="Regular;18" position="110,635" size="131,24" text="ZAP" transparent="1" zPosition="2"/>
686 <eLabel backgroundColor="#00111112" font="Regular;18" position="315,635" size="191,24" text="TIMERS" transparent="1" zPosition="2"/>
687 <widget itemHeight="25" name="prg_list" position="75,306" scrollbarMode="showNever" size="400,300" transparent="1" zPosition="4"/>
688 <widget itemHeight="27" name="epg_list" position="570,105" scrollbarMode="showNever" size="651,540" transparent="1" zPosition="4"/>
689 <widget backgroundColor="#00111112" font="Regular;22" foregroundColor="#fcc000" halign="center" name="currCh" position="555,55" size="651,24" transparent="1" valign="center" zPosition="2"/>
693 <screen backgroundColor="#ffffffff" flags="wfNoBorder" name="Merlin_PG" position="0,0" size="1024,576" title="Merlin Program Guide">
694 <widget backgroundColor="#ffffffff" position="0,0" render="Pig" size="384,216" source="session.VideoPicture" zPosition="-1"/>
695 <eLabel backgroundColor="#00111112" position="0,216" size="384,366" zPosition="1"/>
696 <eLabel backgroundColor="#00111112" position="384,0" size="720,576" zPosition="1"/>
697 <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/epg.png" position="900,80" size="85,77" zPosition="5"/>
698 <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/channels.png" position="292,228" size="80,80" zPosition="5"/>
699 <ePixmap alphatest="on" name="red" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/red.png" position="40,520" size="35,25" zPosition="3"/>
700 <ePixmap alphatest="on" name="green" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/green.png" position="185,520" size="35,25" zPosition="3"/>
701 <eLabel backgroundColor="#00111112" font="Regular;18" position="80,520" size="92,24" text="ZAP" transparent="1" zPosition="2"/>
702 <eLabel backgroundColor="#00111112" font="Regular;18" position="230,520" size="141,24" text="TIMERS" transparent="1" zPosition="2"/>
703 <widget itemHeight="25" name="prg_list" position="40,228" scrollbarMode="showNever" size="332,275" transparent="1" zPosition="4"/>
704 <widget itemHeight="28" name="epg_list" position="395,80" scrollbarMode="showNever" size="590,448" transparent="1" zPosition="4"/>
705 <widget backgroundColor="#00111112" font="Regular;21" foregroundColor="#fcc000" halign="center" name="currCh" position="395,40" size="590,24" transparent="1" valign="center" zPosition="4"/>
709 <screen flags="wfNoBorder" name="Merlin_PG" position="0,0" size="720,576" title="Merlin Program Guide">
710 <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/mpgbgSD-fs8.png" position="0,0" size="720,576" zPosition="1"/>
711 <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/red.png" position="165,90" size="35,25" zPosition="2"/>
712 <ePixmap alphatest="on" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/green.png" position="165,110" size="35,25" zPosition="2"/>
713 <eLabel backgroundColor="#1f1f1f" font="Regular;15" foregroundColor="#f0f0f0" position="205,93" size="70,20" text="ZAP" transparent="1" zPosition="2"/>
714 <eLabel backgroundColor="#1f1f1f" font="Regular;15" foregroundColor="#f0f0f0" position="205,113" size="70,20" text="TIMERS" transparent="1" zPosition="2"/>
715 <widget name="prg_list" position="342,63" scrollbarMode="showOnDemand" size="327,150" zPosition="2" itemHeight="25"/>
716 <widget name="epg_list" position="57,238" scrollbarMode="showOnDemand" size="612,270" zPosition="2" itemHeight="27"/>
717 <widget font="Regular;22" foregroundColor="#ffc000" halign="center" name="currCh" position="57,133" size="252,66" transparent="1" valign="center" zPosition="2"/>
718 <widget font="LCD;28" halign="left" position="60,95" render="Label" size="91,32" source="global.CurrentTime" transparent="1" zPosition="3">
719 <convert type="ClockToText">Default</convert>
721 <widget font="Regular;16" position="60,65" render="Label" size="276,26" source="global.CurrentTime" transparent="1" zPosition="3">
722 <convert type="ClockToText">Date</convert>
726 def __init__(self, session, servicelist=None):
727 Screen.__init__(self, session)
728 self.session = session
732 self.srvList = servicelist
733 self.CheckForEPG = eTimer()
734 self.CheckForEPG.callback.append(self.CheckItNow)
735 self["currCh"] = Label(_("Channel"))
736 self["fullEventInfo"] = Label(" ")
737 self["prg_list"] = MenuList(self.getChannels())
738 self["epg_list"] = EPGList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
739 self["actions"] = ActionMap(["OkCancelActions", "EPGSelectActions", "ColorActions", "DirectionActions", "MenuActions", "HelpActions", "InfobarActions"], {
741 "cancel": self.close,
742 "nextBouquet": self.prgDown,
743 "prevBouquet": self.prgUp,
744 "nextService": self.prgPlus,
745 "prevService": self.prgMinus,
747 "green": self.timerAdd,
748 "blue": self.ZapForRefresh,
749 "yellow": self.go2now,
751 "menu": self.menuClicked,
752 "displayHelp": self.myhelp,
754 "rightRepeated": self.right,
756 "leftRepeated": self.left,
758 "upRepeated": self.up,
760 "downRepeated": self.down,
761 "showMovies": self.editCurTimer,
762 "showTv": self.fullEPGlist
764 self.onLayoutFinish.append(self.onLayoutReady)
766 def onLayoutReady(self):
767 service = self.session.nav.getCurrentService()
768 info = service and service.info()
769 if (info is not None) and not(config.plugins.MerlinEPG.StartFirst.value):
770 nameROH = info.getName().replace('\xc2\x86', '').replace('\xc2\x87', '')
771 for idx in range(1, len(self.list)):
772 name = str(idx) + ". " + nameROH
773 if name == self.list[idx-1]:
775 self["prg_list"].moveToIndex(idx-1)
777 self["prg_list"].moveToIndex(0)
780 def onSelectionChanged(self):
781 curEV = self["epg_list"].getCurrent()
783 ext = event and event.getExtendedDescription() or ""
784 self["fullEventInfo"].setText(str(ext))
787 self["prg_list"].down()
791 self["prg_list"].up()
795 self["prg_list"].pageDown()
799 self["prg_list"].pageUp()
802 def getChannels(self):
804 serviceHandler = eServiceCenter.getInstance()
805 services = serviceHandler.list(eServiceReference('1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 195) || (type == 25) FROM BOUQUET "bouquets.tv" ORDER BY bouquet'))
806 bouquets = services and services.getContent("SN", True)
807 for bouquet in bouquets:
808 services = serviceHandler.list(eServiceReference(bouquet[0]))
809 channels = services and services.getContent("SN", True)
810 for channel in channels:
811 if not channel[0].startswith("1:64:"):
813 self.list.append(str(indx) + ". " + channel[1].replace('\xc2\x86', '').replace('\xc2\x87', ''))
814 self.myServices.append(channel)
815 self.myBqts.append(bouquet)
818 def updateInfos(self):
821 CurrentPrg = self.myServices[self["prg_list"].getSelectionIndex()]
822 self["currCh"].setText(str(CurrentPrg[1]))
823 myService = ServiceReference(CurrentPrg[0])
824 l.fillSingleEPG(myService)
827 curEV = self["epg_list"].getCurrent()
830 if event is not None:
831 self.session.open(EventViewSimple, event, service)
834 if self.srvList==None:
836 CurrentPrg = self.myServices[self["prg_list"].getSelectionIndex()]
837 CurrentBqt = self.myBqts[self["prg_list"].getSelectionIndex()]
838 myService = ServiceReference(CurrentPrg[0])
839 myB = ServiceReference(CurrentBqt[0])
840 self.srvList.clearPath()
841 if self.srvList.bouquet_root != myB.ref:
842 self.srvList.enterPath(self.srvList.bouquet_root)
843 self.srvList.enterPath(myB.ref)
844 self.srvList.setCurrentSelection(myService.ref)
848 def ZapForRefresh(self):
849 if self.srvList==None:
851 CurrentPrg = self.myServices[self["prg_list"].getSelectionIndex()]
852 myService = ServiceReference(CurrentPrg[0])
853 self.session.nav.playService(myService.ref)
854 self.CheckForEPG.start(4000, True)
856 def CheckItNow(self):
857 self.CheckForEPG.stop()
861 if not AutoTimerPresent:
862 self.AddConfirmedTimer([None,"NT"])
864 self.session.openWithCallback(self.AddConfirmedTimer, ChoiceBox, title=_("Select timer type..."), list=[(_("Standard timer"), "NT"),(_("AutoTimer"), "AT"),(_("View AutoTimers"), "ATV")])
866 def AddConfirmedTimer(self, answer):
867 cur = self["epg_list"].getCurrent()
872 eventid = event.getEventId()
873 refstr = serviceref.ref.toString()
874 answer = answer and answer[1]
876 addAutotimerFromEvent(self.session,evt=event,service=serviceref)
878 for timer in self.session.nav.RecordTimer.timer_list:
879 if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
880 cb_func = lambda ret : not ret or self.removeTimer(timer)
881 self.session.openWithCallback(cb_func, MessageBox, _("Do you really want to delete %s?") % event.getEventName())
884 newEntry = RecordTimerEntry(serviceref, checkOldTimers = True, *parseEvent(event))
885 self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
886 elif answer == "ATV":
887 AutoTimerView(self.session)
889 def removeTimer(self, timer):
890 timer.afterEvent = AFTEREVENT.NONE
891 self.session.nav.RecordTimer.removeEntry(timer)
893 def finishedAdd(self, answer):
896 simulTimerList = self.session.nav.RecordTimer.record(entry)
897 if simulTimerList is not None:
898 for x in simulTimerList:
899 if x.setAutoincreaseEnd(entry):
900 self.session.nav.RecordTimer.timeChanged(x)
901 simulTimerList = self.session.nav.RecordTimer.record(entry)
902 if simulTimerList is not None:
903 self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
905 def finishSanityCorrection(self, answer):
906 self.finishedAdd(answer)
908 def menuClicked(self):
909 self.session.open(MerlinPGsetup)
912 self["epg_list"].instance.moveSelection(self["epg_list"].instance.moveTop)
915 self.session.open(ShowMe, "/usr/lib/enigma2/python/Plugins/Extensions/MerlinEPG/help.jpg")
918 self["epg_list"].moveUp()
921 self["epg_list"].moveDown()
924 self["epg_list"].instance.moveSelection(self["epg_list"].instance.pageUp)
927 self["epg_list"].instance.moveSelection(self["epg_list"].instance.pageDown)
929 def editCurTimer(self):
930 cur = self["epg_list"].getCurrent()
935 eventid = event.getEventId()
936 refstr = serviceref.ref.toString()
937 for timer in self.session.nav.RecordTimer.timer_list:
938 if timer.eit == eventid and timer.service_ref.ref.toString() == refstr:
939 self.session.open(TimerEntry, timer)
941 def fullEPGlist(self):
943 self.session.open(myEPGSearch)
945 self.session.open(MessageBox, text = _('EPGsearch is not installed!'), type = MessageBox.TYPE_ERROR)
950 class myEPGSearchList(EPGSearchList):
951 def __init__(self, type=EPG_TYPE_SINGLE, selChangedCB=None, timer=None):
952 EPGSearchList.__init__(self, type=EPG_TYPE_SINGLE, selChangedCB=None, timer=None)
953 EPGList.__init__(self, type, selChangedCB, timer)
954 self.l.setBuildFunc(self.buildEPGSearchEntry)
956 def buildEPGSearchEntry(self, service, eventId, beginTime, duration, EventName):
957 r1 = self.weekday_rect
958 r2 = self.datetime_rect
960 t = localtime(beginTime)
961 serviceref = ServiceReference(service)
964 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_LEFT, self.days[t[6]]),
965 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width()-20, r1.height(), 0, RT_HALIGN_LEFT, "%02d.%02d, %02d:%02d"%(t[2],t[1],t[3],t[4]))
967 res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, EventName + " <" + serviceref.getServiceName()))
973 class myEPGSearch(EPGSearch):
974 def __init__(self, session, *args):
975 EPGSearch.__init__(self, session)
976 Screen.__init__(self, session)
977 self.skinName = ["EPGSearch", "EPGSelection"]
978 self["list"] = myEPGSearchList(type = EPG_TYPE_SINGLE, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
979 self.onLayoutFinish.append(self.fillMe)
982 self["key_yellow"].hide()
983 self["key_green"].hide()
984 self["key_blue"].hide()
987 def searchEPG(self, searchString = None, searchSave = True):
989 encoding = config.plugins.epgsearch.encoding.value
990 epgcache = eEPGCache.getInstance()
991 ret = epgcache.search(('RIBDT', 2000, eEPGCache.PARTIAL_TITLE_SEARCH, "", eEPGCache.NO_CASE_CHECK)) or []
992 ret.sort(key = lambda x: x[4])
998 def blueButtonPressed(self):
1001 def yellowButtonPressed(self):