1 # for localized messages
4 from enigma import eEPGCache, eServiceReference, RT_HALIGN_LEFT, \
5 RT_HALIGN_RIGHT, eListboxPythonMultiContent
7 from Tools.LoadPixmap import LoadPixmap
8 from ServiceReference import ServiceReference
10 from Screens.ChannelSelection import SimpleChannelSelection
11 from Screens.ChoiceBox import ChoiceBox
12 from Screens.EpgSelection import EPGSelection
13 from Screens.MessageBox import MessageBox
14 from Screens.Screen import Screen
15 from Screens.VirtualKeyBoard import VirtualKeyBoard
17 from Components.ActionMap import ActionMap
18 from Components.Button import Button
19 from Components.config import config
20 from Components.EpgList import EPGList, EPG_TYPE_SINGLE, EPG_TYPE_MULTI
21 from Components.TimerList import TimerList
22 from Components.Sources.ServiceEvent import ServiceEvent
23 from Components.Sources.Event import Event
25 from time import localtime
27 # Partnerbox installed?
29 from Plugins.Extensions.Partnerbox.PartnerboxEPGList import \
30 isInRemoteTimer, getRemoteClockPixmap
31 from Plugins.Extensions.Partnerbox.PartnerboxFunctions import \
32 SetPartnerboxTimerlist, isInTimerList, sendPartnerBoxWebCommand, \
33 FillE1TimerList, FillE2TimerList
34 import Plugins.Extensions.Partnerbox.PartnerboxFunctions \
35 as partnerboxfunctions
36 from Plugins.Extensions.Partnerbox.PartnerboxSetup import \
37 PartnerboxEntriesListConfigScreen
38 PartnerBoxInstalled = True
40 PartnerBoxInstalled = False
44 from Plugins.Extensions.AutoTimer.AutoTimerEditor import \
45 addAutotimerFromEvent, addAutotimerFromSearchString
46 autoTimerAvailable = True
48 autoTimerAvailable = False
50 baseEPGSelection__init__ = None
51 def EPGSelectionInit():
52 global baseEPGSelection__init__
53 if baseEPGSelection__init__ is None:
54 baseEPGSelection__init__ = EPGSelection.__init__
55 EPGSelection.__init__ = EPGSelection__init__
56 EPGSelection.bluePressed = bluePressed
58 def EPGSelection__init__(self, session, service, zapFunc=None, eventid=None, bouquetChangeCB=None, serviceChangeCB=None):
59 baseEPGSelection__init__(self, session, service, zapFunc, eventid, bouquetChangeCB, serviceChangeCB)
60 if self.type != EPG_TYPE_MULTI:
61 self["epgsearch_actions"] = ActionMap(["EPGSelectActions"],
63 "blue": self.bluePressed,
65 self["key_blue"].setText(_("EPG Search"))
67 def bluePressed(self):
69 # EPGList could be empty
70 cur = self["list"].getCurrent()
71 except: # XXX: is this an IndexError? always be as specific as possible ;-)
74 name = cur[0].getEventName()
75 self.session.open(EPGSearch,name , False)
77 class EPGSearchList(EPGList):
78 def __init__(self, type=EPG_TYPE_SINGLE, selChangedCB=None, timer=None):
79 EPGList.__init__(self, type, selChangedCB, timer)
80 self.l.setBuildFunc(self.buildEPGSearchEntry)
82 if PartnerBoxInstalled:
83 # Partnerbox Clock Icons
84 self.remote_clock_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock.png')
85 self.remote_clock_add_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_add.png')
86 self.remote_clock_pre_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_pre.png')
87 self.remote_clock_post_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_post.png')
88 self.remote_clock_prepost_pixmap = LoadPixmap('/usr/lib/enigma2/python/Plugins/Extensions/Partnerbox/icons/remote_epgclock_prepost.png')
90 def buildEPGSearchEntry(self, service, eventId, beginTime, duration, EventName):
91 rec1 = beginTime and self.timer.isInTimer(eventId, beginTime, duration, service)
93 if PartnerBoxInstalled:
94 rec2 = beginTime and isInRemoteTimer(self,beginTime, duration, service)
97 r1 = self.weekday_rect
98 r2 = self.datetime_rect
100 t = localtime(beginTime)
101 serviceref = ServiceReference(service) # for Servicename
103 None, # no private data needed
104 (eListboxPythonMultiContent.TYPE_TEXT, r1.left(), r1.top(), r1.width(), r1.height(), 0, RT_HALIGN_RIGHT, self.days[t[6]]),
105 (eListboxPythonMultiContent.TYPE_TEXT, r2.left(), r2.top(), r2.width(), r1.height(), 0, RT_HALIGN_RIGHT, "%02d.%02d, %02d:%02d"%(t[2],t[1],t[3],t[4]))
109 clock_pic = self.getClockPixmap(service, beginTime, duration, eventId)
110 # maybe Partnerbox too
112 clock_pic_partnerbox = getRemoteClockPixmap(self,service, beginTime, duration, eventId)
114 clock_pic = getRemoteClockPixmap(self,service, beginTime, duration, eventId)
116 # Partnerbox and local
118 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
119 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left() + 25, r3.top(), 21, 21, clock_pic_partnerbox),
120 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 50, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, serviceref.getServiceName() + ": " + EventName)))
123 (eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, r3.left(), r3.top(), 21, 21, clock_pic),
124 (eListboxPythonMultiContent.TYPE_TEXT, r3.left() + 25, r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, serviceref.getServiceName() + ": " + EventName)))
126 res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), r3.width(), r3.height(), 0, RT_HALIGN_LEFT, serviceref.getServiceName() + ": " + EventName))
129 class EPGSearch(EPGSelection):
130 def __init__(self, session, *args):
131 Screen.__init__(self, session)
132 self.skinName = "EPGSelection"
134 self.searchargs = args
137 # XXX: we lose sort begin/end here
138 self["key_yellow"] = Button(_("New Search"))
139 self["key_blue"] = Button(_("History"))
141 # begin stripped copy of EPGSelection.__init__
142 self.bouquetChangeCB = None
143 self.serviceChangeCB = None
144 self.ask_time = -1 #now
145 self["key_red"] = Button("")
146 self.closeRecursive = False
147 self.saved_title = None
148 self["Service"] = ServiceEvent()
149 self["Event"] = Event()
150 self.type = EPG_TYPE_SINGLE
151 self.currentService=None
154 self["key_green"] = Button(_("Add timer"))
155 self.key_green_choice = self.ADD_TIMER
156 self.key_red_choice = self.EMPTY
157 self["list"] = EPGSearchList(type = self.type, selChangedCB = self.onSelectionChanged, timer = session.nav.RecordTimer)
158 self["actions"] = ActionMap(["EPGSelectActions", "OkCancelActions", "MenuActions"],
161 "cancel": self.closeScreen,
162 "ok": self.eventSelected,
163 "timerAdd": self.timerAdd,
164 "yellow": self.yellowButtonPressed,
165 "blue": self.blueButtonPressed,
166 "info": self.infoKeyPressed,
167 "red": self.zapTo, # needed --> Partnerbox
168 "nextBouquet": self.nextBouquet, # just used in multi epg yet
169 "prevBouquet": self.prevBouquet, # just used in multi epg yet
170 "nextService": self.nextService, # just used in single epg yet
171 "prevService": self.prevService, # just used in single epg yet
174 self["actions"].csel = self
175 self.onLayoutFinish.append(self.onCreate)
176 # end stripped copy of EPGSelection.__init__
179 if PartnerBoxInstalled:
180 EPGSelection.PartnerboxInit(self, False)
184 self.searchEPG(*self.searchargs)
193 if PartnerBoxInstalled:
194 EPGSelection.GetPartnerboxTimerlist(self)
196 def closeScreen(self):
198 config.plugins.epgsearch.save()
199 EPGSelection.closeScreen(self)
201 def yellowButtonPressed(self):
202 self.session.openWithCallback(
205 title = _("Enter text to search for")
210 (_("Import from Timer"), self.importFromTimer),
211 (_("Import from EPG"), self.importFromEPG),
214 if autoTimerAvailable:
216 (_("Import from AutoTimer"), self.importFromAutoTimer),
217 (_("Save search as AutoTimer"), self.addAutoTimer),
218 (_("Export selected as AutoTimer"), self.exportAutoTimer),
221 self.session.openWithCallback(
227 def menuCallback(self, ret):
230 def importFromTimer(self):
231 self.session.openWithCallback(
236 def importFromEPG(self):
237 self.session.openWithCallback(
239 EPGSearchChannelSelection
242 def importFromAutoTimer(self):
243 removeInstance = False
246 from Plugins.Extensions.AutoTimer.plugin import autotimer
248 if autotimer is None:
249 removeInstance = True
251 from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer
252 autotimer = AutoTimer()
254 # Read in configuration
259 _("Could not read AutoTimer timer list: %s") % e,
260 type = MessageBox.TYPE_ERROR
263 # Fetch match strings
264 # XXX: we could use the timer title as description
265 options = [(x.match, x.match) for x in autotimer.getTimerList()]
267 self.session.openWithCallback(
268 self.searchEPGWrapper,
270 title = _("Select text to search for"),
274 # Remove instance if there wasn't one before
278 def addAutoTimer(self):
279 addAutotimerFromSearchString(self.session, self.currSearch)
281 def exportAutoTimer(self):
282 cur = self['list'].getCurrent()
285 addAutotimerFromEvent(self.session, cur[0], cur[1])
287 def blueButtonPressed(self):
288 options = [(x, x) for x in config.plugins.epgsearch.history.value]
291 self.session.openWithCallback(
292 self.searchEPGWrapper,
294 title = _("Select text to search for"),
301 type = MessageBox.TYPE_INFO
304 def searchEPGWrapper(self, ret):
306 self.searchEPG(ret[1])
308 def searchEPG(self, searchString = None, searchSave = True):
310 self.currSearch = searchString
313 history = config.plugins.epgsearch.history.value
314 if searchString not in history:
315 history.insert(0, searchString)
316 if len(history) > 10:
319 history.remove(searchString)
320 history.insert(0, searchString)
322 # Workaround to allow search for umlauts if we know the encoding (pretty bad, I know...)
323 encoding = config.plugins.epgsearch.encoding.value
324 if encoding != 'UTF-8':
326 searchString = searchString.decode('UTF-8', 'replace').encode(encoding)
327 except UnicodeDecodeError:
330 # Search EPG, default to empty list
331 epgcache = eEPGCache.getInstance() # XXX: the EPGList also keeps an instance of the cache but we better make sure that we get what we want :-)
332 ret = epgcache.search(('RIBDT', 200, eEPGCache.PARTIAL_TITLE_SEARCH, searchString, eEPGCache.NO_CASE_CHECK)) or []
333 ret.sort(key = lambda x: x[2]) # sort by time
341 class EPGSearchTimerImport(Screen):
342 def __init__(self, session):
343 Screen.__init__(self, session)
344 self.skinName = "TimerEditList"
349 self["timerlist"] = TimerList(self.list)
351 self["key_red"] = Button(_("Cancel"))
352 self["key_green"] = Button(_("OK"))
353 self["key_yellow"] = Button("")
354 self["key_blue"] = Button("")
356 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
359 "cancel": self.cancel,
360 "green": self.search,
363 self.onLayoutFinish.append(self.setCustomTitle)
365 def setCustomTitle(self):
366 self.setTitle(_("Select a timer to search"))
368 def fillTimerList(self):
372 for timer in self.session.nav.RecordTimer.timer_list:
373 l.append((timer, False))
375 for timer in self.session.nav.RecordTimer.processed_timers:
376 l.append((timer, True))
377 l.sort(key = lambda x: x[0].begin)
380 cur = self["timerlist"].getCurrent()
387 class EPGSearchChannelSelection(SimpleChannelSelection):
388 def __init__(self, session):
389 SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
390 self.skinName = "SimpleChannelSelection"
392 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
394 "showEPGList": self.channelSelected
397 def channelSelected(self):
398 ref = self.getCurrentSelection()
399 if (ref.flags & 7) == 7:
401 elif not (ref.flags & eServiceReference.isMarker):
402 self.session.openWithCallback(
404 EPGSearchEPGSelection,
409 def epgClosed(self, ret = None):
413 class EPGSearchEPGSelection(EPGSelection):
414 def __init__(self, session, ref, openPlugin):
415 EPGSelection.__init__(self, session, ref)
416 self.skinName = "EPGSelection"
417 self["key_green"].setText(_("Search"))
418 self.openPlugin = openPlugin
420 def infoKeyPressed(self):
424 cur = self["list"].getCurrent()
436 self.close(evt.getEventName())