tvcharts: update to 1.1 (on behalf of Homey)
[enigma2-plugins.git] / tvcharts / src / plugin.py
1 #####################################################
2 # TVCharts Plugin for Enigma2 Dreamboxes
3 # Coded by Homey (c) 2010
4 #
5 # Version: 1.1
6 # Support: www.i-have-a-dreambox.com
7 #####################################################
8 from Components.About import about
9 from Components.ActionMap import ActionMap
10 from Components.Button import Button
11 from Components.config import config, configfile, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigInteger, ConfigSelection
12 from Components.ConfigList import ConfigList, ConfigListScreen
13 from Components.Label import Label
14 from Components.MenuList import MenuList
15 from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
16 from Components.Network import iNetwork
17 from Components.ServiceEventTracker import ServiceEventTracker
18 from Components.Sources.StaticText import StaticText
19 from Components.UsageConfig import preferredTimerPath
20 from Components.Pixmap import Pixmap
21 from RecordTimer import RecordTimer, RecordTimerEntry, parseEvent
22 from ServiceReference import ServiceReference
23 from Screens.EventView import EventViewSimple
24 from Screens.MessageBox import MessageBox
25 from Screens.Screen import Screen
26 from Screens.Setup import SetupSummary
27 from Screens.TimerEntry import TimerEntry
28 from Screens.TimerEdit import TimerSanityConflict
29 from Tools.Directories import fileExists
30 from Tools.HardwareInfo import HardwareInfo
31 from Plugins.Plugin import PluginDescriptor
32
33 from enigma import eTimer, eEPGCache, loadJPG, loadPNG, loadPic, eListboxPythonMultiContent, gFont, eServiceReference, eServiceCenter, iPlayableService
34 from time import gmtime, strftime
35 from twisted.web.client import getPage
36 from xml.dom.minidom import parse, parseString
37 from urllib import urlencode
38
39 import timer
40 import xml.etree.cElementTree
41 import Screens.Standby
42
43 ##############################
44 #####  CONFIG SETTINGS   #####
45 ##############################
46 config.plugins.tvcharts = ConfigSubsection()
47 config.plugins.tvcharts.enabled = ConfigYesNo(default = True)
48 config.plugins.tvcharts.maxentries = ConfigInteger(default=10, limits=(5, 100))
49 config.plugins.tvcharts.maxtimerentries = ConfigInteger(default=10, limits=(5, 100))
50 config.plugins.tvcharts.submittimers = ConfigYesNo(default = True)
51 config.plugins.tvcharts.bouquetfilter = ConfigYesNo(default = True)
52
53 ##########################################################
54 session = [ ]
55
56 #Channellist Menu Entry
57 class ChannelListMenu(MenuList):
58         def __init__(self, list, enableWrapAround=False):
59                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
60                 self.l.setFont(0, gFont("Regular", 24))
61                 self.l.setFont(1, gFont("Regular", 20))
62                 self.l.setFont(2, gFont("Regular", 16))
63                 self.l.setItemHeight(76)
64
65 def ChannelListEntryComponent(type, channelname, serviceref, eventid, eventname, starttime, endtime, usercount, percent):
66         res = [ (serviceref, eventid) ]
67
68         # PIXMAP / PICON
69         pixmap = "/usr/share/enigma2/skin_default/picon_default.png"
70         searchPaths = ('/usr/share/enigma2/picon/','/media/cf/picon/','/media/usb/picon/')
71
72         srefstring = serviceref
73         pos = srefstring.rfind(':')
74         if pos != -1:
75                 srefstring = srefstring[:pos].rstrip(':').replace(':','_')
76                 for path in searchPaths:
77                         pngname = path + srefstring + ".png"
78                         if fileExists(pngname):
79                                 pixmap = pngname
80
81         # Build Menu
82         if type == "tvcharts":
83                 res.append(MultiContentEntryPixmapAlphaTest(pos=(8, 8), size=(100, 60), png=loadPNG(pixmap)))
84                 res.append(MultiContentEntryText(pos=(130, 5), size=(480, 30), font=0, text="%s (Viewer: %s)" % (channelname, usercount)))
85                 res.append(MultiContentEntryText(pos=(130, 35), size=(480, 25), font=1, text=eventname))
86         elif type == "timercharts":
87                 res.append(MultiContentEntryPixmapAlphaTest(pos=(10, 10), size=(100, 60), png=loadPNG(pixmap)))
88                 res.append(MultiContentEntryText(pos=(130, 5), size=(480, 28), font=0, text="%s (User: %s)" % (channelname, usercount)))
89                 res.append(MultiContentEntryText(pos=(130, 33), size=(480, 25), font=1, text=eventname))
90                 res.append(MultiContentEntryText(pos=(130, 57), size=(480, 20), font=2, text="%s Uhr - %s Uhr (%smin)" % (strftime("%d.%m.%Y %H:%M", gmtime(starttime)), strftime("%H:%M", gmtime(endtime)), int((endtime-starttime)/60))))
91         elif type == "moviecharts":
92                 res.append(MultiContentEntryPixmapAlphaTest(pos=(8, 8), size=(100, 60), png=loadPNG(pixmap)))
93                 res.append(MultiContentEntryText(pos=(130, 5), size=(480, 30), font=0, text=eventname))
94                 res.append(MultiContentEntryText(pos=(130, 33), size=(480, 25), font=1, text="Viewer: %s" % (usercount)))
95                 res.append(MultiContentEntryText(pos=(130, 57), size=(480, 20), font=2, text="%s Uhr - %s" % (strftime("%d.%m.%Y %H:%M", gmtime(starttime)), channelname)))
96
97         return res
98
99 ##############################
100 #####   TV Charts MAIN   #####
101 ##############################
102
103 class TVChartsMain(Screen):
104
105         skin = """
106         <screen position="center,center" size="620,510" title="TV Charts">
107                 <widget name="channellist" position="10,10" zPosition="1" size="600,458" scrollbarMode="showOnDemand" />
108                 <widget name="info" position="0,447" zPosition="2" size="620,20" font="Regular;18" noWrap="1" foregroundColor="#ffffff" transparent="1" halign="center" valign="center" />
109                 <ePixmap name="red"    position="22,470"  zPosition="3" size="140,40" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/TVCharts/images/key_red.png" transparent="1" alphatest="on" />
110                 <ePixmap name="green"  position="167,470" zPosition="3" size="140,40" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/TVCharts/images/key_green.png" transparent="1" alphatest="on" />
111                 <ePixmap name="yellow" position="312,470" zPosition="3" size="140,40" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/TVCharts/images/key_yellow.png" transparent="1" alphatest="on" />
112                 <ePixmap name="blue"   position="457,470" zPosition="3" size="140,40" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/TVCharts/images/key_blue.png" transparent="1" alphatest="on" />
113                 <widget name="key_red" position="22,470" zPosition="4" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
114                 <widget name="key_green" position="167,470" zPosition="4" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
115                 <widget name="key_yellow" position="312,470" zPosition="4" size="140,40" valign="center" halign="center"  font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
116                 <widget name="key_blue" position="457,470" zPosition="4" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
117         </screen>"""
118
119         def __init__(self, session):
120                 Screen.__init__(self, session)
121
122                 self.session = session
123
124                 self["channellist"] = ChannelListMenu([])
125                 self["info"] = Label()
126
127                 self["key_red"] = Button("TV Charts")
128                 self["key_green"] = Button("Timer Charts")
129                 self["key_yellow"] = Button("Movie Charts")
130                 self["key_blue"] = Button("Settings")
131
132                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "EPGSelectActions"],
133                 {
134                         "ok": self.okClicked,
135                         "red": self.switchToTVCharts,
136                         "green": self.switchToTimerCharts,
137                         "yellow": self.switchToMovieCharts,
138                         "blue": self.SettingsMenu,
139                         "info": self.ShowEventInfo,
140                         "cancel": self.close
141                 }, -1)
142
143                 self.epgcache = eEPGCache.getInstance()
144                 self.eventcache = []
145
146                 self.RefreshTimer = eTimer()
147                 self.RefreshTimer.callback.append(self.downloadList)
148
149                 self.onLayoutFinish.append(self.firstPluginExec)
150
151         def firstPluginExec(self):
152                 self.updateEventCache()
153                 self.switchToTVCharts()
154
155         def okClicked(self):
156                 current = self["channellist"].getCurrent()
157                 if current is None:
158                         return
159
160                 if self.mode == "tvcharts":
161                         self.session.nav.playService(eServiceReference(str(current[0][0])))
162                 elif self.mode == "timercharts":
163                         serviceref = ServiceReference(current[0][0])
164                         eventid = int(current[0][1])
165                         event = self.getEventFromId(serviceref, eventid)
166                         if event is not None:
167                                 newEntry = RecordTimerEntry(serviceref, *parseEvent(event), checkOldTimers = True, dirname = preferredTimerPath())
168                                 self.session.openWithCallback(self.addTimerCallback, TimerEntry, newEntry)
169                         else:
170                                 self.session.open(MessageBox, "Sorry, no EPG Info available for this event", type=MessageBox.TYPE_ERROR, timeout=10)
171                 elif self.mode == "moviecharts":
172                         print "[TVCharts] ToDo: Show Movie Info here ..."
173                         return
174
175         def addTimerCallback(self, answer):
176                 if answer[0]:
177                         entry = answer[1]
178                         simulTimerList = self.session.nav.RecordTimer.record(entry)
179                         if simulTimerList is not None:
180                                 for x in simulTimerList:
181                                         if x.setAutoincreaseEnd(entry):
182                                                 self.session.nav.RecordTimer.timeChanged(x)
183                                 simulTimerList = self.session.nav.RecordTimer.record(entry)
184                                 if simulTimerList is not None:
185                                         self.session.openWithCallback(self.finishSanityCorrection, TimerSanityConflict, simulTimerList)
186                 else:
187                         print "Timeredit aborted"
188
189         def finishSanityCorrection(self, answer):
190                 self.addTimerCallback(answer)
191
192         def SettingsMenu(self):
193                 self.session.open(TVChartsSetup)
194
195         def ShowEventInfo(self):
196                 current = self["channellist"].getCurrent()
197                 if current is None:
198                         return
199
200                 serviceref = current[0][0]
201                 eventid = current[0][1]
202
203                 service = ServiceReference(serviceref)
204                 event = self.getEventFromId(service, eventid)
205
206                 if event is not None:
207                         self.session.open(EventViewSimple, event, service)
208
209         def getEventFromId(self, service, eventid):
210                 event = None
211                 if self.epgcache is not None and eventid is not None:
212                         event = self.epgcache.lookupEventId(service.ref, eventid)
213                 return event
214
215         def updateEventCache(self):
216                 try:
217                         from Screens.ChannelSelection import service_types_tv
218                         from Components.Sources.ServiceList import ServiceList
219                         bouquetlist = ServiceList(eServiceReference(service_types_tv + ' FROM BOUQUET "bouquets.tv" ORDER BY bouquet'), validate_commands=False).getServicesAsList()
220                         for bouquetitem in bouquetlist:
221                                 serviceHandler = eServiceCenter.getInstance()
222                                 list = serviceHandler.list(eServiceReference(str(bouquetitem[0])))
223                                 services = list and list.getContent('S')
224                                 search = ['IBDCTSERNX']
225
226                                 if services: # It's a Bouquet
227                                         search.extend([(service, 0, -1) for service in services])
228
229                                 events = self.epgcache.lookupEvent(search)
230
231                                 for eventinfo in events:
232                                         #0 eventID | 4 eventname | 5 short descr | 6 long descr | 7 serviceref | 8 channelname
233                                         self.eventcache.append((eventinfo[0], eventinfo[7], eventinfo[8], eventinfo[4]))
234
235                 except Exception:
236                         print "[TVCharts Plugin] Error creating eventcache!"
237
238         def switchToTVCharts(self):
239                 self.mode = "tvcharts"
240                 self.setTitle("TV Charts")
241                 self["channellist"].setList([])
242                 self.feedurl = "http://www.dreambox-plugins.de/feeds/topchannels.php"
243                 self.downloadList()
244
245         def switchToTimerCharts(self):
246                 self.mode = "timercharts"
247                 self.setTitle("Timer Charts")
248                 self["channellist"].setList([])
249                 self.feedurl = "http://www.dreambox-plugins.de/feeds/toptimers.php?limit=%s" % config.plugins.tvcharts.maxtimerentries.value
250                 self.downloadList()
251
252         def switchToMovieCharts(self):
253                 self.mode = "moviecharts"
254                 self.setTitle("Movie Charts")
255                 self["channellist"].setList([])
256                 self.feedurl = "http://www.dreambox-plugins.de/feeds/topmovies.php"
257                 self.downloadList()
258
259         def downloadList(self):
260                 if config.plugins.tvcharts.enabled.value:
261                         self["info"].setText("Download feeds from server ...")
262                         getPage(self.feedurl).addCallback(self.downloadListCallback).addErrback(self.downloadListError)
263                 else:
264                         self["info"].setText("Error: Plugin disabled in Settings ...")
265
266         def downloadListError(self, error=""):
267                 print str(error)
268                 self.session.open(MessageBox, "Error downloading Feed:\n%s" % str(error), type=MessageBox.TYPE_ERROR)
269                 self["info"].setText("Error downloading Feed!")
270
271         def downloadListCallback(self, page=""):
272                 self["info"].setText("Parsing Feeds ...")
273
274                 channellist = []
275                 channelcount = 0
276                 useronline = 0
277                 totalusers = 0
278                 totaltimer = 0
279                 totalmovies = 0
280                 xml = parseString(page)
281
282                 #channellist.append(ChannelListEntryComponent("NAME", "SERVICEREF", "EVENTNAME", "USERCOUNT", "PERCENT"))
283
284                 if self.mode == "tvcharts":
285                         for node in xml.getElementsByTagName("DATA"):
286                                 useronline = int(node.getElementsByTagName("USERCOUNT")[0].childNodes[0].data)
287                                 totalusers = int(node.getElementsByTagName("TOTALUSERS")[0].childNodes[0].data)
288
289                         for node in xml.getElementsByTagName("CHANNEL"):
290                                 event_id = None
291                                 channelname =str(node.getElementsByTagName("NAME")[0].childNodes[0].data)
292                                 serviceref = str(node.getElementsByTagName("SERVICEREF")[0].childNodes[0].data)
293                                 eventname = str(node.getElementsByTagName("EVENTNAME")[0].childNodes[0].data)
294                                 usercount = int(node.getElementsByTagName("USERCOUNT")[0].childNodes[0].data)
295                                 percent = int(node.getElementsByTagName("PERCENT")[0].childNodes[0].data)
296                                 inBouquet = False
297
298                                 # Look for favourite channel for this event in my bouqets
299                                 for sepginfo in self.eventcache:
300                                         if sepginfo[2] == channelname:
301                                                 inBouquet = True
302                                         if sepginfo[3] == eventname:
303                                                 event_id = sepginfo[0]
304                                         if sepginfo[3] == eventname and sepginfo[1] != serviceref:
305                                                 if channelname[0:3].lower() == sepginfo[2][0:3].lower():
306                                                         serviceref = sepginfo[1]
307                                                         channelname = sepginfo[2]
308                                                 inBouquet = True
309                                                 break
310                                         elif sepginfo[3] == eventname and sepginfo[1] == serviceref:
311                                                 break
312
313                                 # Skip Channels that are not in my bouquets
314                                 if config.plugins.tvcharts.bouquetfilter.value and not inBouquet:
315                                         continue
316
317                                 # Skip Channels that are not in my bouquets
318                                 channelcount += 1
319                                 if channelcount > config.plugins.tvcharts.maxentries.value:
320                                         break
321
322                                 # Add to List
323                                 channellist.append(ChannelListEntryComponent(self.mode, channelname, serviceref, event_id, eventname, 0, 0, usercount, percent))
324
325                         if totalusers > 0:
326                                 self.setTitle("TV Charts (User online: %s of %s)" % (useronline, totalusers))
327
328                 elif self.mode == "timercharts":
329                         for node in xml.getElementsByTagName("DATA"):
330                                 totaltimer = int(node.getElementsByTagName("TIMERCOUNT")[0].childNodes[0].data)
331
332                         for node in xml.getElementsByTagName("TIMER"):
333                                 eitID = int(node.getElementsByTagName("ID")[0].childNodes[0].data)
334                                 channelname = str(node.getElementsByTagName("CHANNELNAME")[0].childNodes[0].data)
335                                 serviceref = str(node.getElementsByTagName("SERVICEREF")[0].childNodes[0].data)
336                                 eventname = str(node.getElementsByTagName("EVENTNAME")[0].childNodes[0].data)
337                                 starttime = int(node.getElementsByTagName("STARTTIME")[0].childNodes[0].data)
338                                 endtime = int(node.getElementsByTagName("ENDTIME")[0].childNodes[0].data)
339                                 usercount = int(node.getElementsByTagName("USERCOUNT")[0].childNodes[0].data)
340                                 percent = int(node.getElementsByTagName("PERCENT")[0].childNodes[0].data)
341
342                                 # Look for favourite channel for this event in my bouqets
343                                 for sepginfo in self.eventcache:
344                                         if sepginfo[2] == channelname:
345                                                 serviceref = sepginfo[1]
346                                                 channelname = sepginfo[2]
347                                                 inBouquet = True
348                                                 break
349                                                 
350                                 # Add to List
351                                 channellist.append(ChannelListEntryComponent(self.mode, channelname, serviceref, eitID, eventname, starttime, endtime, usercount, percent))
352
353                         if totaltimer > 0:
354                                 self.setTitle("Timer Charts (Total Timer: %s)" % (totaltimer))
355
356                 elif self.mode == "moviecharts":
357                         for node in xml.getElementsByTagName("DATA"):
358                                 totalmovies = int(node.getElementsByTagName("MOVIECOUNT")[0].childNodes[0].data)
359
360                         for node in xml.getElementsByTagName("MOVIE"):
361                                 eventid = int(node.getElementsByTagName("EVENTID")[0].childNodes[0].data)
362                                 eventname = str(node.getElementsByTagName("EVENTNAME")[0].childNodes[0].data)
363                                 channelname = str(node.getElementsByTagName("CHANNELNAME")[0].childNodes[0].data)
364                                 serviceref = str(node.getElementsByTagName("SERVICEREF")[0].childNodes[0].data)
365                                 starttime = int(node.getElementsByTagName("STARTTIME")[0].childNodes[0].data)
366                                 usercount = int(node.getElementsByTagName("USERCOUNT")[0].childNodes[0].data)
367
368                                 # Add to List
369                                 channellist.append(ChannelListEntryComponent(self.mode, channelname, serviceref, eventid, eventname, starttime, 0, usercount, 0))
370
371                         #if totalmovies > 0:
372                         #       self.setTitle("Movie Charts (Total Movies: %s)" % (totalmovies))
373
374                 self["info"].setText("")
375                 self["channellist"].setList(channellist)
376
377                 self.RefreshTimer.start(60000, True)
378
379 ############################
380 #####  SETTINGS SCREEN #####
381 ############################
382 class TVChartsSetup(Screen, ConfigListScreen):
383         def __init__(self, session):
384                 Screen.__init__(self, session)
385                 self.skinName = [ "TVChartsSetup", "Setup" ]
386                 self.setup_title = _("TV Charts Settings")
387
388                 self.onChangedEntry = [ ]
389                 self.list = [ ]
390                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changedEntry)
391
392                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
393                 {
394                         "ok": self.SaveSettings,
395                         "green": self.SaveSettings,
396                         "red": self.Exit,
397                         "cancel": self.Exit
398                 }, -2)
399
400                 self["key_green"] = StaticText(_("OK"))
401                 self["key_red"] = StaticText(_("Cancel"))
402
403                 self.createSetup()
404                 self.onLayoutFinish.append(self.layoutFinished)
405
406         def layoutFinished(self):
407                 self.setTitle(self.setup_title)
408
409         def createSetup(self):
410                 self.list = [ getConfigListEntry(_("TV Charts Plugin Enable"), config.plugins.tvcharts.enabled) ]
411                 if config.plugins.tvcharts.enabled.value:
412                         self.list.extend((
413                                 getConfigListEntry(_("Max Toplist Entries"), config.plugins.tvcharts.maxentries),
414                                 getConfigListEntry(_("Max Timerlist Entries"), config.plugins.tvcharts.maxtimerentries),
415                                 getConfigListEntry(_("Enable Bouquet-Filter?"), config.plugins.tvcharts.bouquetfilter),
416                                 getConfigListEntry(_("Submit Timerlist?"), config.plugins.tvcharts.submittimers),
417                         ))
418
419                 self["config"].list = self.list
420                 self["config"].setList(self.list)
421
422         def keyLeft(self):
423                 ConfigListScreen.keyLeft(self)
424                 if self["config"].getCurrent()[1] == config.plugins.tvcharts.enabled:
425                         self.createSetup()
426
427         def keyRight(self):
428                 ConfigListScreen.keyRight(self)
429                 if self["config"].getCurrent()[1] == config.plugins.tvcharts.enabled:
430                         self.createSetup()
431
432         def changedEntry(self):
433                 for x in self.onChangedEntry:
434                         x()
435
436         def getCurrentEntry(self):
437                 return self["config"].getCurrent()[0]
438
439         def getCurrentValue(self):
440                 return str(self["config"].getCurrent()[1].getText())
441
442         def createSummary(self):
443                 return SetupSummary
444
445         def SaveSettings(self):
446                 config.plugins.tvcharts.save()
447                 configfile.save()
448                 self.close()
449
450         def Exit(self):
451                 self.close()
452
453
454 ##############################
455 #####   UPDATE STATUS    #####
456 ##############################
457 class DBUpdateStatus(Screen):
458         def __init__(self, session):
459                 Screen.__init__(self, session)
460
461                 self.DBStatusTimer = eTimer()
462                 self.DBStatusTimer.callback.append(self.updateStatus)
463
464                 self.__event_tracker = ServiceEventTracker(screen = self, eventmap =
465                         {
466                                 iPlayableService.evUpdatedInfo: self.restartTimer,
467                                 iPlayableService.evUpdatedEventInfo: self.restartTimer
468                         })
469
470                 self.recordtimer = session.nav.RecordTimer
471                 self.NetworkConnectionAvailable = False
472
473                 self.onShow.append(self.restartTimer)
474
475         def restartTimer(self):
476                 if self.NetworkConnectionAvailable:
477                         self.DBStatusTimer.stop()
478                         self.DBStatusTimer.start(15000, True)
479                 else:
480                         iNetwork.checkNetworkState(self.checkNetworkCB)
481
482         def checkNetworkCB(self, data):
483                 if data is not None:
484                         if data <= 2:
485                                 self.NetworkConnectionAvailable = True
486                                 self.DBStatusTimer.start(15000, True)
487                         else:
488                                 self.NetworkConnectionAvailable = False
489                                 self.DBStatusTimer.stop()
490
491         def updateStatus(self):
492                 print "[TVCharts] Status Update ..."
493                 self.DBStatusTimer.stop()
494
495                 if not config.plugins.tvcharts.enabled.value or Screens.Standby.inStandby:
496                         return
497
498                 # Get Channelname
499                 ref = self.session.nav.getCurrentlyPlayingServiceReference()
500                 if ref is not None:
501                         serviceHandler = eServiceCenter.getInstance()
502                         info = serviceHandler.info(ref)
503                         channel_name = info and info.getName(ref).replace('\xc2\x86', '').replace('\xc2\x87', '').decode("utf-8", "ignore").encode("utf-8") or ""
504                         self.serviceref = ref.toString()
505                 else:
506                         channel_name = ""
507                         self.serviceref = ""
508
509                 # Get Event Info
510                 service = self.session.nav.getCurrentService()
511                 info = service and service.info()
512                 event = info and info.getEvent(0)
513                 event_name = event and event.getEventName() or ""
514                 event_begin = 0
515
516                 if event is not None:
517                         curEvent = parseEvent(event)
518                         event_begin = int(curEvent[0])+(config.recording.margin_before.value*60)
519
520                 # Get Box Info
521                 self.BoxID = iNetwork.getAdapterAttribute("eth0", "mac")
522                 self.DeviceName = HardwareInfo().get_device_name()
523                 self.EnigmaVersion = about.getEnigmaVersionString()
524                 self.ImageVersion = about.getVersionString()
525
526                 # Get TimerList
527                 self.timerlist = ""
528                 if config.plugins.tvcharts.submittimers.value:
529                         try:
530                                 for timer in self.recordtimer.timer_list:
531                                         if timer.disabled == 0 and timer.justplay == 0:
532                                                 self.timerlist += "%s|%s|%s|%s|%s|%s\n" % (timer.eit,str(int(timer.begin)+(config.recording.margin_before.value*60)), str(int(timer.end)-(config.recording.margin_after.value*60)), str(timer.service_ref), timer.name, timer.service_ref.getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', '').decode("utf-8", "ignore").encode("utf-8"))
533                         except Exception:
534                                 print "[TVCharts] Error loading timers!"
535
536                 # Status Update
537                 url = "http://www.dreambox-plugins.de/feeds/TVCharts/status.php"
538                 getPage(url, method='POST', headers={'Content-Type':'application/x-www-form-urlencoded'}, postdata=urlencode({'boxid' : self.BoxID, 'devicename' : self.DeviceName, 'imageversion' : self.ImageVersion, 'enigmaversion' : self.EnigmaVersion, 'lastchannel' : channel_name, 'lastevent' : event_name, 'lastbegin' : event_begin, 'lastserviceref' : self.serviceref, 'timerlist' : self.timerlist}))
539
540                 # Restart Timer
541                 self.DBStatusTimer.start(900000, True)
542
543
544 ############################
545 #####    INIT PLUGIN   #####
546 ############################
547 def main(session, **kwargs):
548         session.open(TVChartsMain)
549
550 def autostart(reason, **kwargs):
551         global session
552         if "session" in kwargs:
553                 session = kwargs["session"]
554                 DBUpdateStatus(session)
555
556 def Plugins(path, **kwargs):
557         return [
558                 PluginDescriptor(where = [PluginDescriptor.WHERE_SESSIONSTART], fnc = autostart),
559                 PluginDescriptor(name="TV Charts", description="TV Charts Plugin", where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main),
560                 PluginDescriptor(name="TV Charts", description="TV Charts Plugin", where=PluginDescriptor.WHERE_PLUGINMENU, fnc=main) ]