5f875520776259e4fff76569c0752eed54c053b8
[openblackhole/openblackhole-enigma2.git] / lib / python / Screens / EventView.py
1 from Screen import Screen
2 from Screens.TimerEdit import TimerSanityConflict
3 from Screens.MessageBox import MessageBox
4 from Screens.ChoiceBox import ChoiceBox
5 from Components.ActionMap import ActionMap
6 from Components.Button import Button
7 from Components.Label import Label
8 from Components.ScrollLabel import ScrollLabel
9 from Components.PluginComponent import plugins
10 from Components.MenuList import MenuList
11 from Components.TimerList import TimerList
12 from Components.UsageConfig import preferredTimerPath
13 from Components.Sources.ServiceEvent import ServiceEvent
14 from Components.Sources.Event import Event
15 from enigma import eEPGCache, eTimer, eServiceReference
16 from RecordTimer import RecordTimerEntry, parseEvent, AFTEREVENT
17 from TimerEntry import TimerEntry
18 from Plugins.Plugin import PluginDescriptor
19 from Tools.BoundFunction import boundFunction
20 from time import localtime
21 from Components.config import config
22
23 class EventViewBase:
24         ADD_TIMER = 0
25         REMOVE_TIMER = 1
26
27         def __init__(self, event, Ref, callback=None, similarEPGCB=None):
28                 self.similarEPGCB = similarEPGCB
29                 self.cbFunc = callback
30                 self.currentService=Ref
31                 self.isRecording = (not Ref.ref.flags & eServiceReference.isGroup) and Ref.ref.getPath()
32                 self.event = event
33                 self["Service"] = ServiceEvent()
34                 self["Event"] = Event()
35                 self["epg_description"] = ScrollLabel()
36                 self["FullDescription"] = ScrollLabel()
37                 self["datetime"] = Label()
38                 self["channel"] = Label()
39                 self["duration"] = Label()
40                 self["key_red"] = Button("")
41                 if similarEPGCB is not None:
42                         self.SimilarBroadcastTimer = eTimer()
43                         self.SimilarBroadcastTimer.callback.append(self.getSimilarEvents)
44                 else:
45                         self.SimilarBroadcastTimer = None
46                 self.key_green_choice = self.ADD_TIMER
47                 if self.isRecording:
48                         self["key_green"] = Button("")
49                 else:
50                         self["key_green"] = Button(_("Add timer"))
51                 self["key_yellow"] = Button("")
52                 self["key_blue"] = Button("")
53                 self["actions"] = ActionMap(["OkCancelActions", "EventViewActions"],
54                         {
55                                 "cancel": self.close,
56                                 "ok": self.close,
57                                 "pageUp": self.pageUp,
58                                 "pageDown": self.pageDown,
59                                 "prevEvent": self.prevEvent,
60                                 "nextEvent": self.nextEvent,
61                                 "timerAdd": self.timerAdd,
62                                 "openSimilarList": self.openSimilarList,
63                                 "contextMenu": self.doContext,
64                         })
65                 self.onShown.append(self.onCreate)
66
67         def onCreate(self):
68                 self.setService(self.currentService)
69                 self.setEvent(self.event)
70
71         def prevEvent(self):
72                 if self.cbFunc is not None:
73                         self.cbFunc(self.setEvent, self.setService, -1)
74
75         def nextEvent(self):
76                 if self.cbFunc is not None:
77                         self.cbFunc(self.setEvent, self.setService, +1)
78
79         def removeTimer(self, timer):
80                 timer.afterEvent = AFTEREVENT.NONE
81                 self.session.nav.RecordTimer.removeEntry(timer)
82                 self["key_green"].setText(_("Add timer"))
83                 self.key_green_choice = self.ADD_TIMER
84
85         def timerAdd(self):
86                 if self.isRecording:
87                         return
88                 event = self.event
89                 serviceref = self.currentService
90                 if event is None:
91                         return
92                 eventid = event.getEventId()
93                 begin = event.getBeginTime()
94                 end = begin + event.getDuration()
95                 refstr = ':'.join(serviceref.ref.toString().split(':')[:11])
96                 isRecordEvent = False
97                 for timer in self.session.nav.RecordTimer.timer_list:
98                         needed_ref = ':'.join(timer.service_ref.ref.toString().split(':')[:11]) == refstr
99                         if needed_ref and timer.eit == eventid and (begin < timer.begin <= end or timer.begin <= begin <= timer.end):
100                                 isRecordEvent = True
101                                 break
102                         elif needed_ref and timer.repeated and self.session.nav.RecordTimer.isInRepeatTimer(timer, event):
103                                 isRecordEvent = True
104                                 break
105                 if isRecordEvent:
106                         title_text = timer.repeated and _("Attention, this is repeated timer!\n") or ""
107                         menu = [(_("Delete timer"), "delete"),(_("Edit timer"), "edit")]
108                         buttons = ["red", "green"]
109                         def timerAction(choice):
110                                 if choice is not None:
111                                         if choice[1] == "delete":
112                                                 self.removeTimer(timer)
113                                         elif choice[1] == "edit":
114                                                 self.session.open(TimerEntry, timer)
115                         self.session.openWithCallback(timerAction, ChoiceBox, title=title_text + _("Select action for timer '%s'.") % timer.name, list=menu, keys=buttons)
116                 else:
117                         newEntry = RecordTimerEntry(self.currentService, checkOldTimers = True, dirname = preferredTimerPath(), *parseEvent(self.event))
118                         self.session.openWithCallback(self.finishedAdd, TimerEntry, newEntry)
119
120         def finishedAdd(self, answer):
121                 print "finished add"
122                 if answer[0]:
123                         entry = answer[1]
124                         simulTimerList = self.session.nav.RecordTimer.record(entry)
125                         if simulTimerList is not None:
126                                 for x in simulTimerList:
127                                         if x.setAutoincreaseEnd(entry):
128                                                 self.session.nav.RecordTimer.timeChanged(x)
129                                 simulTimerList = self.session.nav.RecordTimer.record(entry)
130                                 if simulTimerList is not None:
131                                         if not entry.repeated and not config.recording.margin_before.value and not config.recording.margin_after.value and len(simulTimerList) > 1:
132                                                 change_time = False
133                                                 conflict_begin = simulTimerList[1].begin
134                                                 conflict_end = simulTimerList[1].end
135                                                 if conflict_begin == entry.end:
136                                                         entry.end -= 30
137                                                         change_time = True
138                                                 elif entry.begin == conflict_end:
139                                                         entry.begin += 30
140                                                         change_time = True
141                                                 if change_time:
142                                                         simulTimerList = self.session.nav.RecordTimer.record(entry)
143                                         if simulTimerList is not None:
144                                                 self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
145                         self["key_green"].setText(_("Change timer"))
146                         self.key_green_choice = self.REMOVE_TIMER
147                 else:
148                         self["key_green"].setText(_("Add timer"))
149                         self.key_green_choice = self.ADD_TIMER
150                         print "Timeredit aborted"
151
152         def finishSanityCorrection(self, answer):
153                 self.finishedAdd(answer)
154
155         def setService(self, service):
156                 self.currentService=service
157                 self["Service"].newService(service.ref)
158                 if self.isRecording:
159                         self["channel"].setText(_("Recording"))
160                 else:
161                         name = service.getServiceName()
162                         if name is not None:
163                                 self["channel"].setText(name)
164                         else:
165                                 self["channel"].setText(_("unknown service"))
166
167         def sort_func(self,x,y):
168                 if x[1] < y[1]:
169                         return -1
170                 elif x[1] == y[1]:
171                         return 0
172                 else:
173                         return 1
174
175         def setEvent(self, event):
176                 self.event = event
177                 self["Event"].newEvent(event)
178                 if event is None:
179                         return
180                 text = event.getEventName()
181                 short = event.getShortDescription()
182                 ext = event.getExtendedDescription()
183                 if short == text:
184                         short = ""
185                 if short and ext:
186                         ext = short + "\n\n" + ext
187                 elif short:
188                         ext = short
189
190                 if text and ext:
191                         text += "\n\n"
192                 text += ext
193
194                 self.setTitle(event.getEventName())
195                 self["epg_description"].setText(text)
196                 self["FullDescription"].setText(ext)
197                 self["datetime"].setText(event.getBeginTimeString())
198                 self["duration"].setText(_("%d min")%(event.getDuration()/60))
199                 self["key_red"].setText("")
200                 if self.SimilarBroadcastTimer is not None:
201                         self.SimilarBroadcastTimer.start(400,True)
202
203                 serviceref = self.currentService
204                 eventid = self.event.getEventId()
205                 begin = event.getBeginTime()
206                 end = begin + event.getDuration()
207                 refstr = ':'.join(serviceref.ref.toString().split(':')[:11])
208                 isRecordEvent = False
209                 for timer in self.session.nav.RecordTimer.timer_list:
210                         needed_ref = ':'.join(timer.service_ref.ref.toString().split(':')[:11]) == refstr
211                         if needed_ref and (timer.eit == eventid and (begin < timer.begin <= end or timer.begin <= begin <= timer.end) or timer.repeated and self.session.nav.RecordTimer.isInRepeatTimer(timer, event)):
212                                 isRecordEvent = True
213                                 break
214                 if isRecordEvent and self.key_green_choice != self.REMOVE_TIMER:
215                         self["key_green"].setText(_("Change timer"))
216                         self.key_green_choice = self.REMOVE_TIMER
217                 elif not isRecordEvent and self.key_green_choice != self.ADD_TIMER:
218                         self["key_green"].setText(_("Add timer"))
219                         self.key_green_choice = self.ADD_TIMER
220
221
222         def pageUp(self):
223                 self["epg_description"].pageUp()
224                 self["FullDescription"].pageUp()
225
226         def pageDown(self):
227                 self["epg_description"].pageDown()
228                 self["FullDescription"].pageDown()
229
230         def getSimilarEvents(self):
231                 # search similar broadcastings
232                 if not self.event:
233                         return
234                 refstr = str(self.currentService)
235                 id = self.event.getEventId()
236                 epgcache = eEPGCache.getInstance()
237                 ret = epgcache.search(('NB', 100, eEPGCache.SIMILAR_BROADCASTINGS_SEARCH, refstr, id))
238                 if ret is not None:
239                         text = '\n\n' + _('Similar broadcasts:')
240                         ret.sort(self.sort_func)
241                         for x in ret:
242                                 t = localtime(x[1])
243                                 text += '\n%d.%d.%d, %2d:%02d  -  %s'%(t[2], t[1], t[0], t[3], t[4], x[0])
244                         descr = self["epg_description"]
245                         descr.setText(descr.getText()+text)
246                         descr = self["FullDescription"]
247                         descr.setText(descr.getText()+text)
248                         self["key_red"].setText(_("Similar"))
249
250         def openSimilarList(self):
251                 if self.similarEPGCB is not None and self["key_red"].getText():
252                         id = self.event and self.event.getEventId()
253                         refstr = str(self.currentService)
254                         if id is not None:
255                                 self.similarEPGCB(id, refstr)
256
257         def doContext(self):
258                 if self.event:
259                         text = _("Select action")
260                         menu = [(p.name, boundFunction(self.runPlugin, p)) for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EVENTINFO) \
261                                 if 'servicelist' not in p.__call__.func_code.co_varnames \
262                                         if 'selectedevent' not in p.__call__.func_code.co_varnames ]
263                         if len(menu) == 1:
264                                 menu and menu[0][1]()
265                         elif len(menu) > 1:
266                                 def boxAction(choice):
267                                         if choice:
268                                                 choice[1]()
269                                 text += _(": %s") % self.event.getEventName()
270                                 self.session.openWithCallback(boxAction, ChoiceBox, title=text, list=menu)
271
272         def runPlugin(self, plugin):
273                 plugin(session=self.session, service=self.currentService, event=self.event, eventName=self.event.getEventName())
274
275 class EventViewSimple(Screen, EventViewBase):
276         def __init__(self, session, Event, Ref, callback=None, similarEPGCB=None):
277                 Screen.__init__(self, session)
278                 self.skinName = "EventView"
279                 EventViewBase.__init__(self, Event, Ref, callback, similarEPGCB)
280
281 class EventViewEPGSelect(Screen, EventViewBase):
282         def __init__(self, session, Event, Ref, callback=None, singleEPGCB=None, multiEPGCB=None, similarEPGCB=None):
283                 Screen.__init__(self, session)
284                 self.skinName = "EventView"
285                 EventViewBase.__init__(self, Event, Ref, callback, similarEPGCB)
286                 self["key_yellow"].setText(_("Single EPG"))
287                 self["key_blue"].setText(_("Multi EPG"))
288                 self["epgactions"] = ActionMap(["EventViewEPGActions"],
289                         {
290                                 "openSingleServiceEPG": singleEPGCB,
291                                 "openMultiServiceEPG": multiEPGCB,
292                         })