added zapstatistic plugin
[vuplus_dvbapp-plugin] / zapstatistic / src / plugin.py
1 # -*- coding: UTF-8 -*-
2 # Zap Statistic by AliAbdul
3 from Components.ActionMap import ActionMap
4 from Components.config import config
5 from Components.Label import Label
6 from Components.Language import language
7 from Components.MenuList import MenuList
8 from Components.MultiContent import MultiContentEntryText
9 from enigma import eListboxPythonMultiContent, eServiceReference, gFont
10 from os import environ
11 from Plugins.Plugin import PluginDescriptor\r
12 from Screens.ChoiceBox import ChoiceBox
13 from Screens.ParentalControlSetup import ProtectedScreen
14 from Screens.Screen import Screen
15 from ServiceReference import ServiceReference
16 from time import localtime, time
17 from Tools.Directories import fileExists, resolveFilename, SCOPE_LANGUAGE, SCOPE_PLUGINS
18 from xml.etree.cElementTree import parse
19 import gettext
20
21 ###########################################################
22
23 def localeInit():
24         lang = language.getLanguage()
25         environ["LANGUAGE"] = lang[:2]
26         gettext.bindtextdomain("enigma2", resolveFilename(SCOPE_LANGUAGE))
27         gettext.textdomain("enigma2")
28         gettext.bindtextdomain("ZapStatistic", "%s%s" % (resolveFilename(SCOPE_PLUGINS), "Extensions/ZapStatistic/locale/"))
29
30 def _(txt):
31         t = gettext.dgettext("ZapStatistic", txt)
32         if t == txt:
33                 t = gettext.gettext(txt)
34         return t
35
36 localeInit()\r
37 language.addCallback(localeInit)
38
39 ###########################################################
40
41 def decode_charset(str, charset):
42         try:
43                 uni = unicode(str, charset, 'strict')
44         except:
45                 uni = str
46         return uni
47
48 ###########################################################
49
50 def deformXml(xml):
51         xml = xml.replace("&", "&")
52         xml = xml.replace("'", "'")
53         xml = xml.replace("<", "&lt;")
54         xml = xml.replace(">", "&gt;")
55         xml = xml.replace('"', "&quot;")
56         return xml
57
58 def reformXml(xml):
59         xml = xml.replace("&amp;", "&")
60         xml = xml.replace("&apos;", "'")
61         xml = xml.replace("&lt;", "<")
62         xml = xml.replace("&gt;", ">")
63         xml = xml.replace("&quot;", '"')
64         return xml
65
66 ###########################################################
67
68 class ZapEntry:
69         def __init__(self, ref, begin=None, end=None):
70                 self.ref = ref
71                 self.name = ServiceReference(eServiceReference(ref)).getServiceName()
72                 if begin:
73                         self.begin = begin
74                 else:
75                         self.begin = time()
76                 self.end = end
77
78         def stop(self):
79                 self.end = time()
80
81 ###########################################################
82
83 class DurationZapEntry:
84         def __init__(self, zapentry):
85                 self.ref = zapentry.ref
86                 self.name = zapentry.name
87                 duration = zapentry.end - zapentry.begin
88                 self.duration = "%02d:%02d:%02d" % (duration/3600, (duration/60) - ((duration/3600) * 60), duration%60)
89                 t = localtime(zapentry.begin)
90                 self.begin = "%02d.%02d. %02d:%02d:%02d" % (t[2], t[1], t[3], t[4], t[5])
91
92 ###########################################################
93
94 class CombinedZapEntry:
95         def __init__(self, zapentry):
96                 self.ref = zapentry.ref
97                 self.name = zapentry.name
98                 self.duration = zapentry.end - zapentry.begin
99
100         def addDuration(self, zapentry):
101                 self.duration = self.duration + zapentry.end - zapentry.begin
102
103         def getDurationText(self):
104                 return "%02d:%02d:%02d" % (self.duration/3600, (self.duration/60) - ((self.duration/3600) * 60), self.duration%60)
105
106 ###########################################################
107
108 class ZapStatistic:
109         def __init__(self):
110                 self.xmlFile = "/etc/zapstastistic.xml"
111                 self.zapEntries = []
112                 self.currentEntry = None
113
114         def loadZapEntries(self):
115                 if fileExists(self.xmlFile):
116                         try:
117                                 menu = parse(self.xmlFile).getroot()
118                                 for item in menu.findall("entry"):
119                                         ref = item.get("ref") or None
120                                         if ref:
121                                                 ref = decode_charset(ref, "UTF-8").encode("UTF-8")
122                                                 ref = reformXml(ref)
123                                         begin = item.get("begin") or None
124                                         end = item.get("end") or None
125                                         if ref and begin and end:
126                                                 self.zapEntries.append(ZapEntry(ref, float(begin), float(end)))
127                         except:
128                                 print "[ZapStatistic] Error while reading xml file"
129
130         def saveZapEntries(self):
131                 xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n<zapstastistic>\n'
132                 for x in self.zapEntries:
133                         if not x.end:
134                                 x.end = time()
135                         xml += '\t<entry ref="%s" begin="%s" end ="%s" />\n' % (decode_charset(deformXml(x.ref), "UTF-8"), str(x.begin), str(x.end))
136                 xml += '</zapstastistic>'
137                 try:
138                         f = open(self.xmlFile, "w")
139                         f.write(xml.encode("UTF-8"))
140                         f.close()
141                 except:
142                         print "[ZapStatistic] Error while writing xml file"
143
144         def handlePlayServiceCommand(self, ref):
145                 self.handleStopServiceCommand()
146                 if ref:
147                         self.currentEntry = ZapEntry(ref.toString())
148
149         def handleStopServiceCommand(self):
150                 if self.currentEntry:
151                         self.currentEntry.stop()
152                         self.zapEntries.append(self.currentEntry)
153                         self.currentEntry = None
154
155 zapstatistic = ZapStatistic()
156
157 ###########################################################
158
159 global PlayService
160 global StopService
161 PlayService = None
162 StopService = None
163
164 def playService(ref, checkParentalControl=True, forceRestart=False):
165         if PlayService:
166                 zapstatistic.handlePlayServiceCommand(ref)
167                 PlayService(ref, checkParentalControl, forceRestart)
168
169 def stopService():
170         if StopService:
171                 zapstatistic.handleStopServiceCommand()
172                 StopService()
173
174 ###########################################################
175
176 class ZapStatisticBrowserList(MenuList):
177         def __init__(self, list, enableWrapAround=False):
178                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
179                 self.l.setItemHeight(25)
180                 self.l.setFont(0, gFont("Regular", 20))
181
182 def ZapStatisticBrowserListEntry(entry):
183         res = [entry]
184         t_begin = localtime(entry.begin)
185         t_end = localtime(entry.end)
186         res.append(MultiContentEntryText(pos=(0, 0), size=(240, 25), font=0, text="%02d.%02d. %02d:%02d:%02d - %02d:%02d:%02d" % (t_begin[2], t_begin[1], t_begin[3], t_begin[4], t_begin[5], t_end[3], t_end[4], t_end[5])))
187         res.append(MultiContentEntryText(pos=(250, 0), size=(310, 25), font=0, text=entry.name))
188         return res
189
190 def ZapStatisticBrowserDurationListEntry(entry):
191         res = [entry]
192         res.append(MultiContentEntryText(pos=(0, 0), size=(240, 25), font=0, text="%s (%s)" % (entry.duration, entry.begin)))
193         res.append(MultiContentEntryText(pos=(250, 0), size=(310, 25), font=0, text=entry.name))
194         return res
195
196 def ZapStatisticBrowserCombinedListEntry(entry):
197         res = [entry]
198         res.append(MultiContentEntryText(pos=(0, 0), size=(150, 25), font=0, text="%s" % (entry.getDurationText())))
199         res.append(MultiContentEntryText(pos=(160, 0), size=(400, 25), font=0, text=entry.name))
200         return res
201
202 ###########################################################
203
204 class ZapStatisticDurationScreen(Screen):
205         SORT_NAME_ASCENDING = 0
206         SORT_NAME_DESCENDING = 1
207         SORT_DURATION_ASCENDING = 2
208         SORT_DURATION_DESCENDING = 3
209         skin = """
210                 <screen position="center,center" size="560,450" title="%s" >
211                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
212                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
213                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
214                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
215                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
216                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
217                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
218                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
219                         <widget name="list" position="0,40" size="560,400" scrollbarMode="showOnDemand" />
220                 </screen>""" % _("Zap Statistic")
221
222         def __init__(self, session):
223                 Screen.__init__(self, session)
224                 
225                 self.sortType = self.SORT_NAME_ASCENDING
226                 
227                 self["key_red"] = Label(_("Sort (name+)"))
228                 self["key_green"] = Label(_("Sort (name-)"))
229                 self["key_yellow"] = Label(_("Sort (duration+)"))
230                 self["key_blue"] = Label(_("Sort (duration-)"))
231                 self["list"] = ZapStatisticBrowserList([])
232                 
233                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
234                         {
235                                 "ok": self.play,
236                                 "cancel": self.close,
237                                 "red": self.sortByNameAscending,
238                                 "green": self.sortByNameDescending,
239                                 "yellow": self.sortByDurationAscending,
240                                 "blue": self.sortByDurationDescending
241                         }, prio=-1)
242                 
243                 self.onLayoutFinish.append(self.buildList)
244
245         def sortList(self, l):
246                 if self.sortType == self.SORT_NAME_ASCENDING:
247                         return l.sort(key=self.buildSortNameKey, reverse=False)
248                 elif self.sortType == self.SORT_NAME_DESCENDING:
249                         return l.sort(key=self.buildSortNameKey, reverse=True)
250                 elif self.sortType == self.SORT_DURATION_ASCENDING:
251                         return l.sort(key=self.buildSortDurationKey, reverse=False)
252                 elif self.sortType == self.SORT_DURATION_DESCENDING:
253                         return l.sort(key=self.buildSortDurationKey, reverse=True)
254                 else:
255                         return l
256
257         def buildSortNameKey(self, x):
258                 try: name = x.name
259                 except: name = ""
260                 return (name and name.lower() or "")
261
262         def buildSortDurationKey(self, x):
263                 try: name = str(x.duration)
264                 except: name = ""
265                 return (name and name.lower() or "")
266
267         def buildList(self):
268                 list = []
269                 l = []
270                 for x in zapstatistic.zapEntries:
271                         l.append(DurationZapEntry(x))
272                 self.sortList(l)
273                 for x in l:
274                         list.append(ZapStatisticBrowserDurationListEntry(x))
275                 self["list"].setList(list)
276
277         def play(self):
278                 cur = self["list"].getCurrent()
279                 if cur:
280                         entry = cur[0]
281                         self.session.nav.playService(eServiceReference(entry.ref))
282
283         def sortByNameAscending(self):
284                 self.sortType = self.SORT_NAME_ASCENDING
285                 self.buildList()
286
287         def sortByNameDescending(self):
288                 self.sortType = self.SORT_NAME_DESCENDING
289                 self.buildList()
290
291         def sortByDurationAscending(self):
292                 self.sortType = self.SORT_DURATION_ASCENDING
293                 self.buildList()
294
295         def sortByDurationDescending(self):
296                 self.sortType = self.SORT_DURATION_DESCENDING
297                 self.buildList()
298
299 ###########################################################
300
301 class ZapStatisticCombinedScreen(Screen):
302         SORT_NAME_ASCENDING = 0
303         SORT_NAME_DESCENDING = 1
304         SORT_DURATION_ASCENDING = 2
305         SORT_DURATION_DESCENDING = 3
306         skin = """
307                 <screen position="center,center" size="560,450" title="%s" >
308                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
309                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
310                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
311                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
312                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
313                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
314                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
315                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
316                         <widget name="list" position="0,40" size="560,400" scrollbarMode="showOnDemand" />
317                 </screen>""" % _("Zap Statistic")
318
319         def __init__(self, session):
320                 Screen.__init__(self, session)
321                 
322                 self.list = []
323                 self.sortType = self.SORT_DURATION_DESCENDING
324                 
325                 self["key_red"] = Label(_("Sort (name+)"))
326                 self["key_green"] = Label(_("Sort (name-)"))
327                 self["key_yellow"] = Label(_("Sort (duration+)"))
328                 self["key_blue"] = Label(_("Sort (duration-)"))
329                 self["list"] = ZapStatisticBrowserList([])
330                 
331                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
332                         {
333                                 "ok": self.play,
334                                 "cancel": self.close,
335                                 "red": self.sortByNameAscending,
336                                 "green": self.sortByNameDescending,
337                                 "yellow": self.sortByDurationAscending,
338                                 "blue": self.sortByDurationDescending
339                         }, prio=-1)
340                 
341                 self.onLayoutFinish.append(self.buildList)
342
343         def sortList(self, l):
344                 if self.sortType == self.SORT_NAME_ASCENDING:
345                         return l.sort(key=self.buildSortNameKey, reverse=False)
346                 elif self.sortType == self.SORT_NAME_DESCENDING:
347                         return l.sort(key=self.buildSortNameKey, reverse=True)
348                 elif self.sortType == self.SORT_DURATION_ASCENDING:
349                         return l.sort(key=self.buildSortDurationKey, reverse=False)
350                 elif self.sortType == self.SORT_DURATION_DESCENDING:
351                         return l.sort(key=self.buildSortDurationKey, reverse=True)
352                 else:
353                         return l
354
355         def buildSortNameKey(self, x):
356                 try: name = x.name
357                 except: name = ""
358                 return (name and name.lower() or "")
359
360         def buildSortDurationKey(self, x):
361                 try: name = x.getDurationText()
362                 except: name = ""
363                 return (name and name.lower() or "")
364
365         def buildList(self):
366                 list = []
367                 if len(self.list) == 0:
368                         for x in zapstatistic.zapEntries:
369                                 added = False
370                                 for y in self.list:
371                                         if x.ref == y.ref:
372                                                 y.addDuration(x)
373                                                 added = True
374                                                 break
375                                 if added == False:
376                                         self.list.append(CombinedZapEntry(x))
377                 self.sortList(self.list)
378                 for x in self.list:
379                         list.append(ZapStatisticBrowserCombinedListEntry(x))
380                 self["list"].setList(list)
381
382         def play(self):
383                 cur = self["list"].getCurrent()
384                 if cur:
385                         entry = cur[0]
386                         self.session.nav.playService(eServiceReference(entry.ref))
387
388         def sortByNameAscending(self):
389                 self.sortType = self.SORT_NAME_ASCENDING
390                 self.buildList()
391
392         def sortByNameDescending(self):
393                 self.sortType = self.SORT_NAME_DESCENDING
394                 self.buildList()
395
396         def sortByDurationAscending(self):
397                 self.sortType = self.SORT_DURATION_ASCENDING
398                 self.buildList()
399
400         def sortByDurationDescending(self):
401                 self.sortType = self.SORT_DURATION_DESCENDING
402                 self.buildList()
403
404 ###########################################################
405
406 class ZapStatisticScreen(Screen, ProtectedScreen):
407         SORT_NAME_ASCENDING = 0
408         SORT_NAME_DESCENDING = 1
409         SORT_DATE_ASCENDING = 2
410         SORT_DATE_DESCENDING = 3
411         skin = """
412                 <screen position="center,center" size="560,450" title="%s" >
413                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" transparent="1" alphatest="on" />
414                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" transparent="1" alphatest="on" />
415                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" transparent="1" alphatest="on" />
416                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" transparent="1" alphatest="on" />
417                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
418                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
419                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
420                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
421                         <widget name="list" position="0,40" size="560,400" scrollbarMode="showOnDemand" />
422                 </screen>""" % _("Zap Statistic")
423
424         def __init__(self, session):
425                 Screen.__init__(self, session)
426                 ProtectedScreen.__init__(self)
427                 
428                 self.session = session
429                 self.sortType = self.SORT_DATE_ASCENDING
430                 
431                 self["key_red"] = Label(_("Delete"))
432                 self["key_green"] = Label(" ")
433                 self["key_yellow"] = Label(" ")
434                 self["key_blue"] = Label(_("Durations"))
435                 self["list"] = ZapStatisticBrowserList([])
436                 
437                 self["actions"] = ActionMap(["ColorActions", "OkCancelActions", "InfobarMenuActions"],
438                         {
439                                 "ok": self.play,
440                                 "cancel": self.close,
441                                 "red": self.delete,
442                                 "green": self.sortByName,
443                                 "yellow": self.sortByDate,
444                                 "blue": self.duration,\r
445                                 "mainMenu": self.menu
446                         }, prio=-1)
447                 
448                 self.onLayoutFinish.append(self.buildList)
449
450         def updateLabels(self):
451                 self["key_green"].setText(_("Sort (name+)"))
452                 self["key_yellow"].setText(_("Sort (date+)"))
453                 if self.sortType == self.SORT_NAME_ASCENDING:
454                         self["key_green"].setText(_("Sort (name-)"))
455                 if self.sortType == self.SORT_DATE_ASCENDING:
456                         self["key_yellow"].setText(_("Sort (date-)"))
457
458         def sortList(self, l):
459                 if self.sortType == self.SORT_NAME_ASCENDING:
460                         return l.sort(key=self.buildSortNameKey, reverse=False)
461                 elif self.sortType == self.SORT_NAME_DESCENDING:
462                         return l.sort(key=self.buildSortNameKey, reverse=True)
463                 elif self.sortType == self.SORT_DATE_ASCENDING:
464                         return l.sort(key=self.buildSortDateKey, reverse=False)
465                 elif self.sortType == self.SORT_DATE_DESCENDING:
466                         return l.sort(key=self.buildSortDateKey, reverse=True)
467                 else:
468                         return l
469
470         def buildSortNameKey(self, x):
471                 try: name = x.name
472                 except: name = ""
473                 return (name and name.lower() or "")
474
475         def buildSortDateKey(self, x):
476                 try: name = str(x.begin)
477                 except: name = ""
478                 return (name and name.lower() or "")
479
480         def buildList(self):
481                 list = []
482                 l = zapstatistic.zapEntries
483                 self.sortList(l)
484                 for x in l:
485                         list.append(ZapStatisticBrowserListEntry(x))
486                 self["list"].setList(list)
487                 self.updateLabels()
488
489         def isProtected(self):
490                 return config.ParentalControl.setuppinactive.value and config.ParentalControl.configured.value
491         
492         def pinEntered(self, result):
493                 if result is None:
494                         self.close()
495                 elif not result:
496                         self.close()
497
498         def play(self):
499                 cur = self["list"].getCurrent()
500                 if cur:
501                         entry = cur[0]
502                         self.session.nav.playService(eServiceReference(entry.ref))
503
504         def delete(self):
505                 cur = self["list"].getCurrent()
506                 if cur:
507                         entry = cur[0]
508                         idx = 0
509                         for x in zapstatistic.zapEntries:
510                                 if x == entry:
511                                         del zapstatistic.zapEntries[idx]
512                                         break
513                                 else:
514                                         idx += 1
515                         self.buildList()
516
517         def deleteAll(self):
518                 if len(zapstatistic.zapEntries):
519                         del zapstatistic.zapEntries
520                         zapstatistic.zapEntries = []
521                         self.buildList()
522
523         def sortByName(self):
524                 if self["key_green"].getText() == _("Sort (name-)"):
525                         self.sortType = self.SORT_NAME_DESCENDING
526                 else:
527                         self.sortType = self.SORT_NAME_ASCENDING
528                 self.buildList()
529
530         def sortByNameAscending(self):
531                 self.sortType = self.SORT_NAME_ASCENDING
532                 self.buildList()
533
534         def sortByNameDescending(self):
535                 self.sortType = self.SORT_NAME_DESCENDING
536                 self.buildList()
537
538         def sortByDate(self):
539                 if self["key_yellow"].getText() == _("Sort (date-)"):
540                         self.sortType = self.SORT_DATE_DESCENDING
541                 else:
542                         self.sortType = self.SORT_DATE_ASCENDING
543                 self.buildList()
544
545         def sortByDateAscending(self):
546                 self.sortType = self.SORT_DATE_ASCENDING
547                 self.buildList()
548
549         def sortByDateDescending(self):
550                 self.sortType = self.SORT_DATE_DESCENDING
551                 self.buildList()
552
553         def duration(self):
554                 self.session.open(ZapStatisticDurationScreen)
555
556         def combined(self):
557                 self.session.open(ZapStatisticCombinedScreen)
558
559         def menu(self):
560                 list = []\r
561                 list.append((_("Play entry"), self.play))\r
562                 list.append((_("Delete entry"), self.delete))\r
563                 list.append((_("Delete all entries"), self.deleteAll))\r
564                 list.append((_("Sort by name (ascending)"), self.sortByNameAscending))\r
565                 list.append((_("Sort by name (descending)"), self.sortByNameDescending))\r
566                 list.append((_("Sort by date (ascending)"), self.sortByDateAscending))\r
567                 list.append((_("Sort by date (descending)"), self.sortByDateDescending))\r
568                 list.append((_("Show duration window"), self.duration))\r
569                 list.append((_("Show combined duration window"), self.combined))\r
570                 list.append((_("Close plugin"), self.close))\r
571                 self.session.openWithCallback(self.menuCallback, ChoiceBox, title=_("Please choose a function..."), list=list)
572
573         def menuCallback(self, callback=None):\r
574                 if callback is not None:\r
575                         callback[1]()
576
577 ###########################################################
578
579 def main(session, **kwargs):
580         session.open(ZapStatisticScreen)
581
582 def sessionstart(reason, **kwargs):
583         if reason == 0:
584                 zapstatistic.loadZapEntries()
585                 session = kwargs["session"]
586                 global PlayService
587                 global StopService
588                 PlayService = session.nav.playService
589                 StopService = session.nav.stopService
590                 session.nav.playService = playService
591                 session.nav.stopService = stopService
592
593 def autostart(reason, **kwargs):
594         if reason == 1:
595                 zapstatistic.saveZapEntries()
596
597 def Plugins(**kwargs):
598         return [PluginDescriptor(name=_("Zap Statistic"), description=_("Shows the watched services with some statistic"), where=PluginDescriptor.WHERE_PLUGINMENU, fnc=main),
599                 PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, fnc=sessionstart),
600                 PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=autostart)]