Bugfix: Custom Input
[enigma2-plugins.git] / werbezapper / src / WerbeZapper.py
1 import math
2
3 # for localized messages
4 from . import _
5
6 # GUI (Screens)
7 from Screens.ChoiceBox import ChoiceBox
8 from Screens.MessageBox import MessageBox
9 from Screens.Screen import Screen
10 from Tools.Notifications import AddPopup
11
12 # Timer
13 from enigma import eTimer
14
15 # For monitoring
16 from enigma import iPlayableService
17 from Components.ServiceEventTracker import ServiceEventTracker
18
19 # Get remaining time if timer is already active
20 from time import time
21
22 # Get event for monitoring
23 from enigma import eEPGCache
24
25
26 class WerbeZapper(Screen):
27         """Simple Plugin to automatically zap back to a Service after a given amount
28            of time."""
29         def __init__(self, session, servicelist, cleanupfnc = None):
30                 Screen.__init__(self, session)
31                 
32                 # Save Session&Servicelist
33                 self.session = session
34                 self.servicelist = servicelist
35                 
36                 # Create Timer
37                 self.zap_time = None
38                 self.zap_timer = eTimer()
39                 self.zap_timer.callback.append(self.zap)
40
41                 # Create Event Monitoring End Timer
42                 self.monitor_timer = eTimer()
43                 self.monitor_timer.callback.append(self.stopMonitoring)
44
45                 # Initialize services
46                 self.zap_service = None
47                 self.move_service = None
48                 self.root = None
49                 
50                 #       Initialize monitoring
51                 self.monitor_service = None
52                 self.event = None
53                 self.duration = 5
54                 self.__event_tracker = None
55                 
56                 # Keep Cleanup
57                 self.cleanupfnc = cleanupfnc
58
59         def showSelection(self):
60                 title = _("When to Zap back?")
61                 select = 4 # 5 Minutes
62                 keys = []       
63                         
64                 # Number keys
65                 choices = [
66                                                                 ('1 ' + _('minute'), 1),
67                                                                 ('2 ' + _('minutes'), 2),
68                                                                 ('3 ' + _('minutes'), 3),
69                                                                 ('4 ' + _('minutes'), 4),
70                                                                 ('5 ' + _('minutes'), 5),
71                                                                 ('6 ' + _('minutes'), 6),
72                                                                 ('7 ' + _('minutes'), 7),
73                                                                 ('8 ' + _('minutes'), 8),
74                                                                 ('9 ' + _('minutes'), 9),
75                                                                 ( _("Custom"), 'custom'),       # Key 0
76                                                         ]
77                 keys.extend( [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" ] )
78                 
79                 # Dummy entry to seperate the color keys
80                 choices.append( ( "------", 'close' ) )
81                 keys.append( "" )  # No key
82                 
83                 # Blue key - Covers the monitoring functions without closing Werbezapper
84                 if self.monitor_timer.isActive():
85                         #TODO what is monitored
86                         # Number Channel Name Remaining
87                         name = ""
88                         if self.event:
89                                 name = self.event and self.event.getEventName()
90                                 duration = ( self.event.getDuration() - ( time() - self.event.getBeginTime() ) ) / 60
91                                 title += "\n\n" + _("Monitoring:\n%s (%d Min)") % (name, duration)  #TODO Add remaining ?
92                         choices.append( ( _("Stop monitoring: %s") % (name), 'stopmonitoring' ) )
93                 else:
94                         choices.append( ( _("Start monitoring..."), 'startmonitoring' ) )
95                 keys.append( "blue" )
96
97                 # Red key - Covers all stop and close functions
98                 #if self.zap_timer.isActive() and self.monitor_timer.isActive():
99                 #       choices.append( ( _("Stop all"), 'stopall' ) )
100                 #       keys.append( "red" )
101                 #el
102                 if self.zap_timer.isActive() and self.zap_time:
103                         remaining = int( math.floor( self.zap_time - time() ) )
104                         remaining = remaining if remaining > 0 else 0
105                         remain = ("%d:%02d") % (remaining/60, remaining%60)
106                         title += "\n\n" + _("Zap back in %s") % (remain)
107                         remaining /= 60
108                         select = (remaining-1) if 1 < remaining and remaining < 10 else select
109                         choices.append( ( _("Stop timer (%s)") % (remain), 'stoptimer' ) )
110                         keys.append( "red" )
111                 #elif self.monitor_timer.isActive():
112                 #       choices.append( ( _("Stop monitoring"), 'stopmonitoring' ) )
113                 #       keys.append( "red" )
114                 else:
115                         choices.append( ( "------", 'close' ) )
116                         keys.append( "" )  # No key
117                 
118                 # Green key - Manual rezap
119                 if self.zap_timer.isActive():
120                         choices.append( ( _("Rezap"), 'rezap' ) )
121                         keys.append( "green" )
122                 else:
123                         choices.append( ( "------", 'close' ) )
124                         keys.append( "" )  # No key
125                 
126                 #TEST if monitoring not in title
127                 #if self.event:
128                 # Dummy entry to seperate the color keys
129                 #choices.append( ( "------", 'close' ) )
130                 #keys.append( "" )  # No key
131                 # Monitoring
132                 #choices.append( ( _("Monitoring:\n%s") %s ("self.event.getEventName()"), 'reopen' ) )
133                 #keys.append( "" )  # No key
134                                 
135                 # Select Timer Length
136                 print keys
137                 print choices
138                 self.session.openWithCallback(
139                         self.choicesCallback,
140                         ChoiceBox,
141                         title,
142                         choices,
143                         keys,
144                         select
145                 )
146                 
147         def choicesCallback(self, result):
148                 result = result and result[1]
149                 
150                 if result == "custom":
151                         from Screens.InputBox import InputBox
152                         from Components.Input import Input
153
154                         #TODO allow custom input in seconds or parts of a minute 1.5
155                         self.session.openWithCallback(
156                                 self.inputCallback,
157                                 InputBox,
158                                 title=_("How many minutes to wait until zapping back?"),
159                                 text="10",
160                                 maxSize=False,
161                                 type=Input.NUMBER
162                         )
163                         return
164                         
165                 elif result == "startmonitoring":
166                         self.startMonitoring()
167                 
168                 elif result == "stopmonitoring":
169                         self.stopMonitoring(False)
170                 
171                 elif result == "rezap":
172                         self.zap_timer.stop()
173                         self.zap_time = None
174                         self.zap()
175                 
176                 elif result == "stoptimer":
177                         # Stop Timer
178                         self.zap_timer.stop()
179                         self.zap_time = None
180                         
181                         # Reset Vars
182                         self.zap_service = None
183                         self.move_service = None
184                         self.root = None
185                 
186                 elif result == "reopen":
187                         self.showSelection()
188                 
189                 elif result == "close":
190                         pass
191                 
192                 elif isinstance(result, int):
193                         self.startTimer(result)
194                 
195                 self.cleanup()
196
197         def inputCallback(self, result):
198                 if result is not None:
199                         self.startTimer(int(result))
200                 else:
201                         # Clean up if possible
202                         self.cleanup()
203
204         def startTimer(self, duration=0, notify=True, zapto=None):
205                 if duration > 0:
206                         # Save the last selected rezap time for using for monitorint rezap time
207                         self.duration = duration
208                 else:
209                         # Reuse last duration
210                         duration = self.duration
211                 
212                 # Keep any service related information (zap_service might not equal move_service -> subservices)
213                 self.zap_service = zapto or self.session.nav.getCurrentlyPlayingServiceReference()
214                 self.move_service = self.servicelist.getCurrentSelection()
215                 self.root = self.servicelist.getRoot()
216
217                 #import ServiceReference
218                 #print [str(ServiceReference.ServiceReference(x)) for x in self.servicelist.getCurrentServicePath()]
219                 #print ServiceReference.ServiceReference(self.servicelist.getRoot())
220
221                 # Start Timer
222                 self.zap_time = time() + ( duration * 60 )
223                 self.zap_timer.startLongTimer( int( duration * 60 ) )
224                 
225                 if notify:
226                         # Remind the User of what he just did
227                         #TEST deactivate message on zap because of monitoring
228                         AddPopup(
229                                                                 _("Zapping back in %d Minute(s)") % (duration),
230                                                                 MessageBox.TYPE_INFO,
231                                                                 3,
232                                                                 "WerbeZapperZapStarted"
233                                                         )
234
235         def startMonitoring(self, notify=True):
236                 # Get current service and event
237                 service = self.session.nav.getCurrentService()
238                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
239                 self.monitor_service = ref
240
241                 # Notify us on new services
242                 # ServiceEventTracker will remove itself on close
243                 # evStart won't work, no service reference available
244                 if not self.__event_tracker:
245                         self.__event_tracker = ServiceEventTracker(screen=self, eventmap=
246                         {
247                                 iPlayableService.evTunedIn: self.serviceStarted,
248                         })
249
250                 # Get event information
251                 info = service and service.info()
252                 event = info and info.getEvent(0)
253                 if not event:
254                         # Alternative to get the current event
255                         epg = eEPGCache.getInstance()
256                         event = ref and ref.valid() and epg.lookupEventTime(ref, -1)
257                 if event:
258                         # Set monitoring end time
259                         self.event = event
260                         duration = event.getDuration() - ( time() - event.getBeginTime() )
261                         self.monitor_timer.startLongTimer( int( duration ) )
262                         if notify:
263                                 name = event and event.getEventName()
264                                 AddPopup(
265                                                                         _("WerbeZapper\nMonitoring started\n%s") % (name),
266                                                                         MessageBox.TYPE_INFO,
267                                                                         3,
268                                                                         "WerbeZapperMonitoringStarted"
269                                                                 )
270                 else:
271                         #TEST SF2 or something without an valid epg
272                         #IDEA detect event is finished
273                         #IDEA inputbox monitoring in minutes
274                         if notify:
275                                 AddPopup(
276                                                                         _("WerbeZapper\nMonitoring started unlimited\nHas to be deactivated manually"),
277                                                                         MessageBox.TYPE_INFO,
278                                                                         10,
279                                                                         "WerbeZapperMonitoringStartedUnlimited"
280                                                                 )
281
282         def stopMonitoring(self, notify=True):
283                 self.monitor_timer.stop()
284                 
285                 if notify:
286                         # Notify the User that the monitoring is ending
287                         #TODO get event channelnumber and channelname
288                         #number = 
289                         #channel = 
290                         #_("Monitoring\n%d %s %s\nends") % (number, channel, name),
291                         name = self.event and self.event.getEventName()
292                         AddPopup(
293                                                                 _("WerbeZapper\nMonitoring ends\n%s") % (name),
294                                                                 MessageBox.TYPE_INFO,
295                                                                 3,
296                                                                 "WerbeZapperMonitoringStopped"
297                                                         )
298                 
299                 self.monitor_service = None
300                 self.event = None
301
302         def serviceStarted(self):
303                 # Verify monitoring is active
304                 if self.monitor_service:
305                         # Verify there is no active zap timer                   
306                         if not self.zap_timer.isActive():
307                                 # Verify that the currently played service has changed
308                                 # Avoid that we trigger on a background recording or streaming service
309                                 #ref = self.session.nav.getCurrentlyPlayingServiceReference()
310                                 #if ref and self.monitor_service != ref:
311                                         # Start zap timer
312                                         self.startTimer(zapto=self.monitor_service)
313
314         def zap(self, notify= False):
315                 #TODO add notify ?
316                 if self.zap_service is not None:
317                         if self.root:
318                                 import ServiceReference
319                                 if not self.servicelist.preEnterPath(str(ServiceReference.ServiceReference(self.root))):
320                                         if self.servicelist.isBasePathEqual(self.root):
321                                                 self.servicelist.pathUp()
322                                                 self.servicelist.enterPath(self.root)
323                                         else:
324                                                 currentRoot = self.servicelist.getRoot()
325                                                 if currentRoot is None or currentRoot != self.root:
326                                                         self.servicelist.clearPath()
327                                                         self.servicelist.enterPath(self.root)
328
329                         if self.move_service:
330                                 self.servicelist.setCurrentSelection(self.move_service)
331                                 self.servicelist.zap()
332
333                         # Play zap_service (won't rezap if service equals to move_service)
334                         self.session.nav.playService(self.zap_service)
335
336                 # Cleanup if end timer is not running
337                 if not self.monitor_timer.isActive():
338                         
339                         # Reset services
340                         self.zap_service = None
341                         self.move_service = None
342                         self.root = None
343
344         def cleanup(self):
345                 # Clean up if no timer is running
346                 if self.monitor_timer and not self.monitor_timer.isActive() \
347                         and self.zap_timer and not self.zap_timer.isActive():
348                         if self.cleanupfnc:
349                                 self.cleanupfnc()
350
351         def shutdown(self):
352                 self.zap_timer.callback.remove(self.zap)
353                 self.zap_timer = None
354                 self.monitor_timer.callback.remove(self.stopMonitoring)
355                 self.monitor_timer = None