IMDb: fix runtime parsing
[enigma2-plugins.git] / zaphistorybrowser / src / plugin.py
1 # -*- coding: UTF-8 -*-
2 ## Zap-History Browser by AliAbdul
3 from Components.ActionMap import ActionMap
4 from Components.config import config, ConfigInteger, ConfigSelection, \
5                 ConfigYesNo, ConfigSet, ConfigSubsection, getConfigListEntry
6 from Components.ConfigList import ConfigListScreen
7 from Components.Label import Label
8 from Components.MenuList import MenuList
9 from Components.MultiContent import MultiContentEntryText
10 from enigma import eListboxPythonMultiContent, eServiceCenter, \
11                 eServiceReference, RT_VALIGN_CENTER, gFont
12 from os import environ
13 from Plugins.Plugin import PluginDescriptor
14 from Screens.ChannelSelection import ChannelSelection
15 from Screens.ParentalControlSetup import ProtectedScreen
16 from Screens.Screen import Screen
17 from enigma import eServiceReference
18 from skin import TemplatedListFonts, componentSizes
19
20 config.plugins.ZapHistoryConfigurator = ConfigSubsection()
21 config.plugins.ZapHistoryConfigurator.enable_zap_history = ConfigSelection(choices = {"off": _("disabled"), "on": _("enabled"), "parental_lock": _("disabled at parental lock")}, default="on")
22 config.plugins.ZapHistoryConfigurator.maxEntries_zap_history = ConfigInteger(default=20, limits=(1, 60))
23 config.plugins.ZapHistoryConfigurator.e1_like_history = ConfigYesNo(default = False)
24 config.plugins.ZapHistoryConfigurator.history_tv = ConfigSet(choices = [])
25 config.plugins.ZapHistoryConfigurator.history_radio = ConfigSet(choices = [])
26
27 ################################################
28
29 def addToHistory(instance, ref):
30         if config.plugins.ZapHistoryConfigurator.enable_zap_history.value == "off":
31                 return
32         if config.ParentalControl.configured.value and config.plugins.ZapHistoryConfigurator.enable_zap_history.value == "parental_lock":
33                 if parentalControl.getProtectionLevel(ref.toCompareString()) != -1:
34                         return
35         if instance.servicePath is not None:
36                 tmp = instance.servicePath[:]
37                 tmp.append(ref)
38                 try: del instance.history[instance.history_pos+1:]
39                 except Exception, e: pass
40                 if config.plugins.ZapHistoryConfigurator.e1_like_history.value and tmp in instance.history:
41                         instance.history.remove(tmp)
42                 instance.history.append(tmp)
43                 hlen = len(instance.history)
44                 if hlen > config.plugins.ZapHistoryConfigurator.maxEntries_zap_history.value:
45                         del instance.history[0]
46                         hlen -= 1
47                 instance.history_pos = hlen-1
48                 if config.plugins.ZapHistoryConfigurator.e1_like_history.value:
49                         # TODO: optimize this
50                         if instance.history == instance.history_tv:
51                                 config.plugins.ZapHistoryConfigurator.history_tv.value = [[y.toString() for y in x] for x in instance.history]
52                         else:
53                                 config.plugins.ZapHistoryConfigurator.history_radio.value = [[y.toString() for y in x] for x in instance.history]
54                         config.plugins.ZapHistoryConfigurator.save()
55
56 ChannelSelection.addToHistory = addToHistory
57
58 def newInit(self, session):
59         baseInit(self, session)
60         if config.plugins.ZapHistoryConfigurator.e1_like_history.value:
61                 append = self.history_tv.append
62                 for x in config.plugins.ZapHistoryConfigurator.history_tv.value:
63                         append([eServiceReference(y) for y in x])
64                 append = self.history_radio.append
65                 for x in config.plugins.ZapHistoryConfigurator.history_radio.value:
66                         append([eServiceReference(y) for y in x])
67
68                 # XXX: self.lastChannelRootTimer was always finished for me, so just fix its mistakes ;)
69                 if self.history == self.history_tv:
70                         self.history_pos = len(self.history_tv)-1
71                 else:
72                         self.history_pos = len(self.history_radio)-1
73
74 baseInit = ChannelSelection.__init__
75 ChannelSelection.__init__ = newInit
76
77 ################################################
78
79 class ZapHistoryConfigurator(ConfigListScreen, Screen):
80         skin = """
81                 <screen position="center,center" size="620,140" title="%s" >
82                         <widget name="config" position="10,10" size="600,120" enableWrapAround="1" scrollbarMode="showOnDemand" />
83                 </screen>""" % _("Zap-History Configurator")
84
85         def __init__(self, session):
86                 Screen.__init__(self, session)
87                 self.session = session
88                 
89                 ConfigListScreen.__init__(self, [
90                         getConfigListEntry(_("Enable zap history:"), config.plugins.ZapHistoryConfigurator.enable_zap_history),
91                         getConfigListEntry(_("Maximum zap history entries:"), config.plugins.ZapHistoryConfigurator.maxEntries_zap_history),
92                         getConfigListEntry(_("Enigma1-like history:"), config.plugins.ZapHistoryConfigurator.e1_like_history)])
93                 
94                 self["actions"] = ActionMap(["OkCancelActions"], {"ok": self.save, "cancel": self.exit}, -2)
95
96         def save(self):
97                 # alternative to notifier
98                 if config.plugins.ZapHistoryConfigurator.e1_like_history.value and config.plugins.ZapHistoryConfigurator.e1_like_history.isChanged():
99                         from Screens.InfoBar import InfoBar
100                         try:
101                                 csel = InfoBar.instance.servicelist
102                         except AttributeError, e:
103                                 pass
104                         else:
105                                 config.plugins.ZapHistoryConfigurator.history_tv.value = [[y.toString() for y in x] for x in csel.history_tv]
106                                 config.plugins.ZapHistoryConfigurator.history_radio.value = [[y.toString() for y in x] for x in csel.history_radio]
107                                 config.plugins.ZapHistoryConfigurator.history_tv.save()
108                                 config.plugins.ZapHistoryConfigurator.history_radio.save()
109
110                 for x in self["config"].list:
111                         x[1].save()
112                 self.close()
113
114         def exit(self):
115                 for x in self["config"].list:
116                         x[1].cancel()
117                 self.close()
118
119 ################################################
120
121 class ZapHistoryBrowserList(MenuList):
122         SKIN_COMPONENT_KEY = "ZapHistoryBrowserList"
123         SKIN_COMPONENT_SERVICE_NAME_HEIGHT = "serviceNameHeight"
124         SKIN_COMPONENT_EVENT_NAME_HEIGHT = "eventNameHeight"
125         SKIN_COMPONENT_LINE_SPACING = "lineSpacing"
126
127         def __init__(self, list, enableWrapAround=False):
128                 MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
129                 self.l.setItemHeight(componentSizes.itemHeight(self.SKIN_COMPONENT_KEY, 50))
130                 tlf = TemplatedListFonts()
131                 self.l.setFont(0, gFont(tlf.face(tlf.BIG), tlf.size(tlf.BIG)))
132                 self.l.setFont(1, gFont(tlf.face(tlf.SMALL), tlf.size(tlf.SMALL)))
133
134 def ZapHistoryBrowserListEntry(serviceName, eventName):
135         sizes = componentSizes[ZapHistoryBrowserList.SKIN_COMPONENT_KEY]
136         textWidth = sizes.get(componentSizes.ITEM_WIDTH, 800)
137         serviceNameHeight = sizes.get(ZapHistoryBrowserList.SKIN_COMPONENT_SERVICE_NAME_HEIGHT, 22)
138         eventNameHeight = sizes.get(ZapHistoryBrowserList.SKIN_COMPONENT_EVENT_NAME_HEIGHT, 20)
139         lineSpacing = sizes.get(ZapHistoryBrowserList.SKIN_COMPONENT_LINE_SPACING, 5)
140         res = [serviceName]
141         res.append(MultiContentEntryText(pos=(5,0), size=(textWidth, serviceNameHeight), font=0, flags = RT_VALIGN_CENTER, text=serviceName))
142         res.append(MultiContentEntryText(pos=(5, serviceNameHeight+lineSpacing), size=(textWidth, eventNameHeight), font=1, flags = RT_VALIGN_CENTER, text=eventName))
143         return res
144
145 ################################################
146
147 class ZapHistoryBrowser(Screen, ProtectedScreen):
148         skin = """
149         <screen position="center,120" size="820,520" title="%s" >
150                 <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
151                 <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40" alphatest="on" />
152                 <ePixmap pixmap="skin_default/buttons/yellow.png" position="410,5" size="200,40" alphatest="on" />
153                 <ePixmap pixmap="skin_default/buttons/blue.png" position="610,5" size="200,40" alphatest="on" />
154                 <widget name="key_red" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
155                 <widget name="key_green" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
156                 <widget name="key_yellow" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
157                 <widget name="key_blue" position="610,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
158                 <eLabel position="10,50" size="800,1" backgroundColor="grey" />
159                 <widget name="list" position="10,60" size="800,450" enableWrapAround="1" scrollbarMode="showOnDemand" />
160         </screen>""" % _("Zap-History Browser")
161
162         def __init__(self, session, servicelist):
163                 Screen.__init__(self, session)
164                 ProtectedScreen.__init__(self)
165                 self.session = session
166                 
167                 self.servicelist = servicelist
168                 self.serviceHandler = eServiceCenter.getInstance()
169                 self.allowChanges = True
170                 
171                 self["list"] = ZapHistoryBrowserList([])
172                 self["key_red"] = Label(_("Clear"))
173                 self["key_green"] = Label(_("Delete"))
174                 self["key_yellow"] = Label(_("Zap & Close"))
175                 self["key_blue"] = Label(_("Config"))
176                 
177                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions"],
178                         {
179                                 "ok": self.zap,
180                                 "cancel": self.close,
181                                 "red": self.clear,
182                                 "green": self.delete,
183                                 "yellow": self.zapAndClose,
184                                 "blue": self.config
185                         }, prio=-1)
186                 
187                 self.onLayoutFinish.append(self.buildList)
188
189         def buildList(self):
190                 list = []
191                 for x in self.servicelist.history:
192                         if len(x) == 2: # Single-Bouquet
193                                 ref = x[1]
194                         else: # Multi-Bouquet
195                                 ref = x[2]
196                         info = self.serviceHandler.info(ref)
197                         if info:
198                                 name = info.getName(ref).replace('\xc2\x86', '').replace('\xc2\x87', '')
199                                 event = info.getEvent(ref)
200                                 if event is not None:
201                                         eventName = event.getEventName()
202                                         if eventName is None:
203                                                 eventName = ""
204                                 else:
205                                         eventName = ""
206                         else:
207                                 name = "N/A"
208                                 eventName = ""
209                         list.append(ZapHistoryBrowserListEntry(name, eventName))
210                 list.reverse()
211                 self["list"].setList(list)
212
213         def zap(self):
214                 length = len(self.servicelist.history)
215                 if length > 0:
216                         self.servicelist.history_pos = (length - self["list"].getSelectionIndex()) - 1
217                         self.servicelist.setHistoryPath()
218
219         def clear(self):
220                 if self.allowChanges:
221                         for i in range(0, len(self.servicelist.history)):
222                                 del self.servicelist.history[0]
223                         self.buildList()
224                         self.servicelist.history_pos = 0
225
226         def delete(self):
227                 if self.allowChanges:
228                         length = len(self.servicelist.history)
229                         if length > 0:
230                                 idx = (length - self["list"].getSelectionIndex()) - 1
231                                 del self.servicelist.history[idx]
232                                 self.buildList()
233                                 currRef = self.session.nav.getCurrentlyPlayingServiceReference()
234                                 idx = 0
235                                 for x in self.servicelist.history:
236                                         if len(x) == 2: # Single-Bouquet
237                                                 ref = x[1]
238                                         else: # Multi-Bouquet
239                                                 ref = x[2]
240                                         if ref == currRef:
241                                                 self.servicelist.history_pos = idx
242                                                 break
243                                         else:
244                                                 idx += 1
245
246         def zapAndClose(self):
247                 self.zap()
248                 self.close()
249
250         def config(self):
251                 if self.allowChanges:
252                         self.session.open(ZapHistoryConfigurator)
253
254         def isProtected(self):
255                 return config.ParentalControl.setuppinactive.value and config.ParentalControl.configured.value
256         
257         def pinEntered(self, result):
258                 if result is None:
259                         self.allowChanges = False
260                 elif not result:
261                         self.allowChanges = False
262                 else:
263                         self.allowChanges = True
264
265 ################################################
266
267 def main(session, servicelist, **kwargs):
268         session.open(ZapHistoryBrowser, servicelist)
269
270 def Plugins(**kwargs):
271         return PluginDescriptor(name=_("Zap-History Browser"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, fnc=main)