aihdcontroler: fix encoding
[enigma2-plugins.git] / imdb / src / plugin.py
1 # -*- coding: UTF-8 -*-
2 from Plugins.Plugin import PluginDescriptor
3 from Tools.Downloader import downloadWithProgress
4 from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS
5 from twisted.web.client import getPage
6 from enigma import ePicLoad, eServiceReference, getDesktop
7 from Screens.Screen import Screen
8 from Screens.ChoiceBox import ChoiceBox
9 from Screens.VirtualKeyBoard import VirtualKeyBoard
10 from Components.ActionMap import ActionMap
11 from Components.Pixmap import Pixmap
12 from Components.Label import Label
13 from Components.ScrollLabel import ScrollLabel
14 from Components.Button import Button
15 from Components.AVSwitch import AVSwitch
16 from Components.MenuList import MenuList
17 from Components.ProgressBar import ProgressBar
18 from Components.Sources.StaticText import StaticText
19 from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigText, ConfigSelection
20 from Components.ConfigList import ConfigListScreen
21 from Components.PluginComponent import plugins
22 import os, re, random, string, six
23 from six.moves.urllib.parse import quote_plus
24
25 try:
26         import htmlentitydefs
27 except ImportError as ie:
28         from html import entities as htmlentitydefs
29         unichr = chr
30
31 sz_w = getDesktop(0).size().width()
32
33 config.plugins.imdb = ConfigSubsection()
34 config.plugins.imdb.showinplugins = ConfigYesNo(default = True)
35 config.plugins.imdb.showepisodeinfo = ConfigYesNo(default = True)
36 config.plugins.imdb.origskin = ConfigYesNo(default = True)
37 config.plugins.imdb.ignore_tags = ConfigText(visible_width = 50, fixed_size = False)
38 config.plugins.imdb.language = ConfigSelection(default = None, choices = [(None, _("Default")),("en-us", _("English")),("fr-fr", _("French")),("de-de", _("German")),("it-it", _("Italian")),("es-es", _("Spanish"))])
39
40 imdb_headers = {}
41 agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36'
42
43 def quoteEventName(eventName):
44         try:
45                 text = eventName.decode('utf8').replace(u'\x86', u'').replace(u'\x87', u'').encode('utf8')
46         except:
47                 text = eventName
48         return quote_plus(text, safe="+")
49
50 class IMDB(Screen):
51         if sz_w == 1920:
52                 skin = """
53                 <screen name="IMDBv2" position="center,110" size="1800,930" title="IMDb - Internet Movie Database">
54                 <eLabel backgroundColor="grey" position="10,80" size="1780,1" />
55                 <ePixmap pixmap="Default-FHD/skin_default/buttons/red.svg" position="10,5" size="300,70" />
56                 <ePixmap pixmap="Default-FHD/skin_default/buttons/green.svg" position="310,5" size="300,70" />
57                 <ePixmap pixmap="Default-FHD/skin_default/buttons/yellow.svg" position="610,5" size="300,70" />
58                 <ePixmap pixmap="Default-FHD/skin_default/buttons/blue.svg" position="910,5" size="300,70" />
59                 <widget backgroundColor="#9f1313" font="Regular;30" halign="center" name="key_red" position="10,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" transparent="1" valign="center" zPosition="1" />
60                 <widget backgroundColor="#1f771f" font="Regular;30" halign="center" name="key_green" position="310,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" transparent="1" valign="center" zPosition="1" />
61                 <widget backgroundColor="#a08500" font="Regular;30" halign="center" name="key_yellow" position="610,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" transparent="1" valign="center" zPosition="1" />
62                 <widget backgroundColor="#18188b" font="Regular;30" halign="center" name="key_blue" position="910,5" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2" size="300,70" transparent="1" valign="center" zPosition="1" />
63                 <widget font="Regular;34" halign="right" position="1650,25" render="Label" size="120,40" source="global.CurrentTime">
64                         <convert type="ClockToText">Default</convert>
65                 </widget>
66                 <widget font="Regular;34" halign="right" position="1240,25" render="Label" size="400,40" source="global.CurrentTime" >
67                         <convert type="ClockToText">Date</convert>
68                 </widget>
69                 <widget font="Regular;38" name="titlelabel" position="20,90" size="1780,45" foregroundColor="yellow"/>
70                 <widget enableWrapAround="1" name="menu" position="20,150" scrollbarMode="showOnDemand" size="1760,720" />
71                 <widget font="Regular;30" name="extralabel" position="20,150" size="1760,730" />
72                 <widget font="Regular;30" halign="left" name="ratinglabel" position="340,150" size="1000,40" foregroundColor="yellow"/>
73                 <widget name="starsbg" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IMDb/starsbar_empty.svg" position="20,150" size="300,31" />
74                 <widget name="stars" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IMDb/starsbar_filled.svg" position="20,150" size="300,31" transparent="1" />
75                 <widget name="poster" position="20,200" size="300,449" />
76                 <widget font="Regular;30" name="detailslabel" position="340,210" size="770,400" />
77                 <widget font="Regular;30" name="castlabel" position="1130,210" size="650,400" />
78                 <widget font="Regular;30" name="storylinelabel" position="20,660" size="1760,210" />
79                 <widget name="statusbar" halign="left" position="20,885" size="1600,35" font="Regular;30" foregroundColor="#b3b3b9" />
80                 </screen>"""
81         else:
82                 skin = """
83                 <screen name="IMDBv2" position="center,80" size="1200,610" title="IMDb - Internet Movie Database">
84                 <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40"/>
85                 <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40"/>
86                 <ePixmap pixmap="skin_default/buttons/yellow.png" position="410,5" size="200,40"/>
87                 <ePixmap pixmap="skin_default/buttons/blue.png" position="610,5" size="200,40"/>
88                 <widget name="key_red" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
89                 <widget name="key_green" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
90                 <widget name="key_yellow" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
91                 <widget name="key_blue" position="610,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-2,-2"/>
92                 <widget source="global.CurrentTime" render="Label" position="1120,12" size="60,25" font="Regular;22" halign="right">
93                         <convert type="ClockToText">Default</convert>
94                 </widget>
95                 <widget source="global.CurrentTime" render="Label" position="810,12" size="300,25" font="Regular;22" halign="right">
96                         <convert type="ClockToText">Format:%A %d. %B</convert>
97                 </widget>
98                 <eLabel position="10,50" size="1180,1" backgroundColor="grey"/>
99                 <widget name="titlelabel" position="20,55" size="1180,30" valign="center" font="Regular;24" foregroundColor="yellow"/>
100                 <widget name="menu" position="20,90" size="1160,480" zPosition="3" scrollbarMode="showOnDemand" enableWrapAround="1" />
101                 <widget name="extralabel" position="20,90" size="1160,490" font="Regular;20" />
102                 <widget name="ratinglabel" position="225,92" size="800,23" font="Regular;20" foregroundColor="yellow"/>
103                 <widget name="starsbg" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IMDb/starsbar_empty.svg" position="20,90" size="185,21"/>
104                 <widget name="stars" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IMDb/starsbar_filled.svg" position="20,90" size="185,21" transparent="1" />
105                 <widget name="poster" position="20,120" size="185,278"/>
106                 <widget name="detailslabel" position="225,130" size="450,270" font="Regular;20" />
107                 <widget name="castlabel" position="695,130" size="485,280" font="Regular;20" />
108                 <widget name="storylinelabel" position="20,410" size="1160,170" font="Regular;20" />
109                 <widget name="statusbar" position="20,580" size="1150,25" halign="left" font="Regular;20" foregroundColor="#b3b3b9" />
110                 </screen>"""
111
112         NBSP = unichr(htmlentitydefs.name2codepoint['nbsp']).encode("utf8")
113
114         def __init__(self, session, eventName, callbackNeeded=False):
115                 Screen.__init__(self, session)
116                 if config.plugins.imdb.origskin.value:
117                         self.skinName = ''.join([random.choice(string.ascii_letters + string.digits) for n in xrange(32)])
118                 else:
119                         self.skinName = "IMDBv2"
120
121                 for tag in config.plugins.imdb.ignore_tags.getValue().split(','):
122                         eventName = eventName.replace(tag,'')
123
124                 self.eventName = eventName
125
126                 self.callbackNeeded = callbackNeeded
127                 self.callbackData = ""
128                 self.callbackGenre = ""
129                 self.manualsearch = False
130
131                 self.dictionary_init()
132
133                 self["poster"] = Pixmap()
134                 self.picload = ePicLoad()
135                 self.picload_conn = self.picload.PictureData.connect(self.paintPosterPixmapCB)
136
137                 self["stars"] = ProgressBar()
138                 self["starsbg"] = Pixmap()
139                 self["stars"].hide()
140                 self["starsbg"].hide()
141                 self.ratingstars = -1
142
143                 self.setTitle(_("IMDb - Internet Movie Database"))
144                 self["titlelabel"] = Label("")
145                 self["titlelcd"] = StaticText("")
146                 self["detailslabel"] = ScrollLabel("")
147                 self["castlabel"] = ScrollLabel("")
148                 self["storylinelabel"] = ScrollLabel("")
149                 self["extralabel"] = ScrollLabel("")
150                 self["statusbar"] = Label("")
151                 self["ratinglabel"] = Label("")
152                 self.resultlist = []
153                 self["menu"] = MenuList(self.resultlist)
154                 self["menu"].hide()
155
156                 self["key_red"] = Button(_("Search"))
157                 self["key_green"] = Button("")
158                 self["key_yellow"] = Button("")
159                 self["key_blue"] = Button("")
160
161                 # 0 = multiple query selection menu page
162                 # 1 = movie info page
163                 # 2 = extra infos page
164                 self.Page = 0
165
166                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MovieSelectionActions", "DirectionActions"],
167                 {
168                         "ok": self.showDetails,
169                         "cancel": self.exit,
170                         "down": self.pageDown,
171                         "up": self.pageUp,
172                         "right": self.keyRight,
173                         "left": self.keyLeft,
174                         "red": self.openVirtualKeyBoard,
175                         "green": self.showMenu,
176                         "yellow": self.showDetails,
177                         "blue": self.showExtras,
178                         "contextMenu": self.contextMenuPressed,
179                         "showEventInfo": self.showDetails
180                 }, -1)
181
182                 self.getIMDB()
183
184         def title_setText(self, txt):
185                 StaticText.setText(self["titlelcd"], txt)
186                 self["titlelabel"].setText(txt)
187
188         def exit(self):
189                 if fileExists("/tmp/poster.jpg"):
190                         os.remove("/tmp/poster.jpg")
191                 if self.callbackNeeded:
192                         self.close([self.callbackData, self.callbackGenre])
193                 else:
194                         self.close()
195
196         def dictionary_init(self):
197                 self.generalinfomask = re.compile(
198                 '<h1.*?hero-title-block__title" class=.*?>(?P<title>.*?)</h1>*'
199                 '(?:.*?>(?P<g_episodes>Episodes)<span.*?>(?P<episodes>.*?)</span>)?'
200                 '(?:.*?class="OriginalTitle__OriginalTitleText.*?>(?P<g_originaltitle>.*?):\s.*?(?P<originaltitle>.*?)</div)?'
201                 '(?:.*?<label for="browse-episodes-season".*?>.*?(?P<seasons>\d+)\s(?P<g_seasons>seasons?)</label>)?'
202                 '(?:.*?<span.*?>(?P<g_director>Directors?)(?:</span>|</a>).*?<div.*?<ul.*?>(?P<director>.*?)</ul>)?'
203                 '(?:.*?<span.*?>(?P<g_creator>Creators?)(?:</span>|</a>).*?<div.*?<ul.*?>(?P<creator>.*?)</ul>)?'
204                 '(?:.*?<span.*?>(?P<g_writer>Writers?)(?:</span>|</a>).*?<div.*?<ul.*?>(?P<writer>.*?)</ul>)?'
205                 '(?:.*?<a.*?>(?P<g_premiere>Release date)</a>.*?<div.*?<ul.*?>(?P<premiere>.*?)</ul>)?'
206                 '(?:.*?<span.*?>(?P<g_country>Countr.*?of origin)</span>.*?<div.*?<ul.*?>(?P<country>.*?)</ul>)?'
207                 '(?:.*?<a.*?>(?P<g_alternativ>Also known as)</a>.*?<div.*?<ul.*?>(?P<alternativ>.*?)</ul>)?'
208                 '(?:.*?techspec_runtime.*?>(?P<g_runtime>Runtime)</span>.*?<div.*?>(?P<runtime>.*?)</div)?', re.S)
209
210                 self.extrainfomask = re.compile(
211                 '(?:.*?<div.*?class="GenresAndPlot__TextContainerBreakpointXL.*?>(?P<outline>.+?)</div>)?'
212                 '(?:.*?<a.*?>(?P<g_tagline>Taglines?)(?:</span>|</a>).*?<div.*?<ul.*?<li.*?<span.*?>(?P<tagline>.*?)</span>)?'
213                 '(?:.*?<a.*?>(?P<g_cert>Certificate|Motion Picture Rating \(MPAA\))</a>.*?<div.*?<ul.*?<li.*?<span.*?>(?P<cert>.*?)</span>)?'
214                 '(?:.*?<a.*?>(?P<g_trivia>Trivia)</a><div.*?<div.*?<div.*?<div.*?>(?P<trivia>.+?)</div>)?'
215                 '(?:.*?<a.*?>(?P<g_goofs>Goofs)</a><div.*?<div.*?<div.*?<div.*?>(?P<goofs>.+?)</div>)?'
216                 '(?:.*?<a.*?>(?P<g_quotes>Quotes)</a><div.*?<div.*?<div.*?<div.*?>(?P<quotes>.+?)</div>)?'
217                 '(?:.*?<a.*?>(?P<g_crazycredits>Crazy credits)</a><div.*?<div.*?<div.*?<div.*?>(?P<crazycredits>.+?)</div>)?'
218                 '(?:.*?<a.*?>(?P<g_alternateversions>Alternate versions)</a><div.*?<div.*?<div.*?<div.*?>(?P<alternateversions>.+?)</div>)?'
219                 '(?:.*?<a.*?>(?P<g_connections>Connections)</a><div.*?<div.*?<div.*?<div.*?>(?P<connections>.+?)</div>)?'
220                 '(?:.*?<a.*?>(?P<g_soundtracks>Soundtracks)</a><div.*?<div.*?<div.*?<div.*?>(?P<soundtracks>.+?)</div>)?'
221                 '(?:.*?<h3.*?>(?P<g_comments>User review)s.*?</h3>.*?<span.*?review-summary.*?>(?P<commenttitle>.*?)</span></div><div.*?<div.*?<div.*?>(?P<comment>.+?)</div>.*?<div.*?reviews-author.*?>.*?<ul.*?<li.*?>(?P<commenter>.+?)</li>)?'
222                 '(?:.*?<span.*?>(?P<g_language>Languages?)</span>.*?<div.*?<ul.*?>(?P<language>.*?)</ul>)?'
223                 '(?:.*?<a.*?>(?P<g_locations>Filming locations?)</a>.*?<div.*?<ul.*?>(?P<locations>.*?)</ul>)?'
224                 '(?:.*?<a.*?>(?P<g_company>Production compan.*?)</a>.*?<div.*?<ul.*?>(?P<company>.*?)</ul>)?'
225                 '(?:.*?<span.*?>(?P<g_color>Color)</span>.*?<div.*?<ul.*?>(?P<color>.*?)</ul>)?'
226                 '(?:.*?<span.*?>(?P<g_sound>Sound mix)</span>.*?<div.*?<ul.*?>(?P<sound>.*?)</ul>)?'
227                 '(?:.*?<span.*?>(?P<g_aspect>Aspect ratio)</span>.*?<div.*?<ul.*?<li.*?<span.*?>(?P<aspect>.*?)</div>)?', re.S)
228
229                 self.awardsmask = re.compile('<li.*?data-testid="award_information".*?><a.*?>(?P<awards>.+?)</span></li>', re.S)
230                 self.keywordsmask = re.compile('data-testid="storyline-plot-keywords">(?P<keywords>.*?)</div>', re.S)
231                 self.boxofficemask = re.compile('<h3.*?>(?P<g_boxoffice>Box office)</h3.*?<div.*?list-item__label">Budget</span>.*?list-content-item">(?P<boxofficebudget>.*?)</span>.*?list-content-item">(?P<boxofficegrossuscanada>.*?)</span>.*?list-content-item">(?P<boxofficeopening>.*?)</span>.*?list-content-item">(?P<boxofficeopeningdate>.*?)</span>.*?list-content-item">(?P<boxofficegrossworld>.*?)</span>', re.S)
232                 self.genreblockmask = re.compile('<li.*?storyline-genres.*?><span.*?>(?P<g_genres>Genres?)</span>.*?<div.*?><ul.*?>(?P<genres>.*?)</ul>', re.S)
233                 self.ratingmask = re.compile('<span.*?aggregate-rating__score.*?><span.*?>(?P<rating>.*?)</span>.*?<span.*?class=.*?class=.*?>(?P<ratingcount>.*?)</div', re.S)
234                 self.castmask = re.compile('title-cast-item__actor.*?>(?P<actor>.*?)</a>(?:<div.*?<ul.*?>(?P<character>.*?)</span.*?</ul></div>)?(?:<a.*?><span><span.*?>(?P<episodes>.*?)</span></span>)?', re.S)
235                 self.postermask = re.compile('<div.*?ipc-media--poster.*?<img.*?ipc-image.*?src="(http.*?)"', re.S)
236                 self.storylinemask = re.compile('<span.*?role="presentation".*?data-testid="plot-xl".*?>(?P<storyline>.*?)</span>.*?</div>.*?data-testid="storyline.*?<span>(?P<g_storyline>Storyline)</span>', re.S)
237
238                 self.htmltags = re.compile('<.*?>', re.S)
239                 self.allhtmltags = re.compile('<.*>', re.S)
240
241         def resetLabels(self):
242                 self["detailslabel"].setText("")
243                 self["ratinglabel"].setText("")
244                 self["castlabel"].setText("")
245                 self["storylinelabel"].setText("")
246                 if not len(self.resultlist) >= 1:
247                         self["key_green"].setText("")
248                 self["key_yellow"].setText("")
249                 self["key_blue"].setText("")
250                 self.title_setText("")
251                 self["extralabel"].setText("")
252                 self.ratingstars = -1
253
254         def pageUp(self):
255                 if self.Page == 0:
256                         self["menu"].instance.moveSelection(self["menu"].instance.moveUp)
257                 if self.Page == 1:
258                         self["castlabel"].pageUp()
259                         self["detailslabel"].pageUp()
260                         self["storylinelabel"].pageUp()
261                 if self.Page == 2:
262                         self["extralabel"].pageUp()
263
264         def pageDown(self):
265                 if self.Page == 0:
266                         self["menu"].instance.moveSelection(self["menu"].instance.moveDown)
267                 if self.Page == 1:
268                         self["castlabel"].pageDown()
269                         self["detailslabel"].pageDown()
270                         self["storylinelabel"].pageDown()
271                 if self.Page == 2:
272                         self["extralabel"].pageDown()
273
274         def keyLeft(self):
275                 if self.Page == 0:
276                         self["menu"].pageUp()
277                 if self.Page == 1:
278                         self["castlabel"].pageUp()
279                         self["detailslabel"].pageUp()
280                         self["storylinelabel"].pageUp()
281                 if self.Page == 2:
282                         self["extralabel"].pageUp()
283
284         def keyRight(self):
285                 if self.Page == 0:
286                         self["menu"].pageDown()
287                 if self.Page == 1:
288                         self["castlabel"].pageDown()
289                         self["detailslabel"].pageDown()
290                         self["storylinelabel"].pageDown()
291                 if self.Page == 2:
292                         self["extralabel"].pageDown()
293
294         def showMenu(self):
295                 if ( self.Page is 1 or self.Page is 2 ) and self.resultlist:
296                         self["menu"].show()
297                         self["stars"].hide()
298                         self["starsbg"].hide()
299                         self["ratinglabel"].hide()
300                         self["castlabel"].hide()
301                         self["storylinelabel"].hide()
302                         self["poster"].hide()
303                         self["extralabel"].hide()
304                         self["detailslabel"].hide()
305                         self.title_setText(_("Please select the matching entry"))
306                         self["key_blue"].setText("")
307                         self["key_green"].setText(_("Title Menu"))
308                         self["key_yellow"].setText("")
309                         self["statusbar"].setText("")
310                         self.Page = 0
311
312         def showDetails(self):
313                 self["ratinglabel"].show()
314                 self["castlabel"].show()
315                 self["detailslabel"].show()
316                 self["storylinelabel"].show()
317                 self["menu"].hide()
318
319                 if self.resultlist and self.Page == 0:
320                         link = self["menu"].getCurrent()[1]
321                         title = self["menu"].getCurrent()[0]
322                         self["statusbar"].setText(_("Re-Query IMDb: %s...") % (title))
323                         fetchurl = "https://www.imdb.com/title/" + link + "/"
324                         print("[IMDB] showDetails() downloading query " + fetchurl)
325                         getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery2).addErrback(self.http_failed)
326                         self.resetLabels()
327                         self.Page = 1
328
329                 if self.Page == 2:
330                         self["extralabel"].hide()
331                         self["poster"].show()
332                         if self.ratingstars > 0:
333                                 self["starsbg"].show()
334                                 self["stars"].show()
335                                 self["stars"].setValue(self.ratingstars)
336
337                         self.Page = 1
338
339         def showExtras(self):
340                 if self.Page == 1 and self['key_blue'].getText():
341                         self["extralabel"].show()
342                         self["detailslabel"].hide()
343                         self["castlabel"].hide()
344                         self["storylinelabel"].hide()
345                         self["poster"].hide()
346                         self["stars"].hide()
347                         self["starsbg"].hide()
348                         self["ratinglabel"].hide()
349                         self.Page = 2
350
351         def contextMenuPressed(self):
352                 list = [(_("Setup"), self.setup),]
353                 if fileExists(resolveFilename(SCOPE_PLUGINS, "Extensions/YTTrailer/plugin.py")):
354                         list.extend((
355                                 (_("Play Trailer"), self.openYttrailer),
356                                 (_("Search Trailer"), self.searchYttrailer),
357                         ))
358                         self.session.openWithCallback(self.menuCallback, ChoiceBox, title=_("IMDb Menu"), list = list,)
359                 else:
360                         self.setup()
361
362         def menuCallback(self, ret = None):
363                 ret and ret[1]()
364
365         def openYttrailer(self):
366                 try:
367                         from Plugins.Extensions.YTTrailer.plugin import YTTrailer, baseEPGSelection__init__
368                 except ImportError as ie:
369                         pass
370                 if baseEPGSelection__init__ is None:
371                         return
372
373                 ytTrailer = YTTrailer(self.session)
374                 ytTrailer.showTrailer(self.eventName)
375
376         def searchYttrailer(self):
377                 try:
378                         from Plugins.Extensions.YTTrailer.plugin import YTTrailerList, baseEPGSelection__init__
379                 except ImportError as ie:
380                         pass
381                 if baseEPGSelection__init__ is None:
382                         return
383
384                 self.session.open(YTTrailerList, self.eventName)
385
386         def openVirtualKeyBoard(self):
387                 if self.manualsearch:
388                         text = self.eventName
389                 else:
390                         text = ''
391                 self.session.openWithCallback(self.gotSearchString, VirtualKeyBoard, title = _("Enter text to search for"), text = text)
392
393         def gotSearchString(self, ret = None):
394                 if ret:
395                         self.eventName = ret
396                         self.Page = 0
397                         self.resultlist = []
398                         self["menu"].hide()
399                         self["ratinglabel"].show()
400                         self["castlabel"].show()
401                         self["storylinelabel"].show()
402                         self["detailslabel"].show()
403                         self["poster"].hide()
404                         self["stars"].hide()
405                         self["starsbg"].hide()
406                         self.manualsearch = True
407                         self.getIMDB()
408
409         def getIMDB(self):
410                 global imdb_headers
411                 #if config.plugins.imdb.language.value:
412                 #       imdb_headers = {'Accept-Language': config.plugins.imdb.language.value}
413                 #else:
414                 imdb_headers = {}
415                 self.resetLabels()
416                 if not self.eventName:
417                         s = self.session.nav.getCurrentService()
418                         info = s and s.info()
419                         event = info and info.getEvent(0) # 0 = now, 1 = next
420                         if event:
421                                 self.eventName = event.getEventName()
422                         else:
423                                 self.eventName = self.session.nav.getCurrentlyPlayingServiceReference().toString()
424                                 self.eventName = self.eventName.split('/')
425                                 self.eventName = self.eventName[-1]
426                                 self.eventName = self.eventName.replace('.',' ')
427                                 self.eventName = self.eventName.split('-')
428                                 self.eventName = self.eventName[0]
429                                 if self.eventName.endswith(' '):
430                                         self.eventName = self.eventName[:-1]
431                 if self.eventName:
432                         self["statusbar"].setText(_("Query IMDb: %s") % (self.eventName))
433                         fetchurl = "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + quoteEventName(self.eventName) + "&s=all"
434                         print("[IMDB] getIMDB() Downloading Query " + fetchurl)
435                         getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery).addErrback(self.http_failed)
436                 else:
437                         self["statusbar"].setText(_("Couldn't get Eventname"))
438
439         def html2utf8(self, in_html):
440                 utf8 = ('charSet="utf-8"' in in_html or 'charset="utf-8"' in in_html or 'charSet=utf-8' in in_html or 'charset=utf-8' in in_html)
441                 start = in_html.find('<nav id="imdbHeader"')
442                 if start == -1:
443                         start = 0
444                 end = in_html.find('<section data-testid="contribution"')
445                 if end == -1:
446                         end = len(in_html)
447                 in_html = in_html[start:end]
448                 in_html = re.sub(r'(?s)<(script|style|svg).*?</\1>', '', in_html)
449                 entitydict = {}
450                 entities = re.finditer(r'&(?:([A-Za-z0-9]+)|#x([0-9A-Fa-f]+)|#([0-9]+));', in_html)
451                 for x in entities:
452                         key = x.group(0)
453                         if key not in entitydict:
454                                 if x.group(1):
455                                         if x.group(1) in htmlentitydefs.name2codepoint:
456                                                 entitydict[key] = htmlentitydefs.name2codepoint[x.group(1)]
457                                 elif x.group(2):
458                                         entitydict[key] = str(int(x.group(2), 16))
459                                 else:
460                                         entitydict[key] = x.group(3)
461                 if utf8:
462                         for key, codepoint in six.iteritems(entitydict):
463                                 cp = six.unichr(int(codepoint))
464                                 if six.PY2:
465                                         cp = cp.encode('utf8')
466                                 in_html = in_html.replace(key, cp)
467                         self.inhtml = in_html
468                 else:
469                         for key, codepoint in six.iteritems(entitydict):
470                                 cp = six.unichr(int(codepoint))
471                                 if six.PY2:
472                                         cp = cp.encode('latin-1', 'ignore')
473                                 in_html = in_html.replace(key, cp)
474                         if six.PY2:
475                                 self.inhtml = in_html.decode('latin-1').encode('utf8')
476
477         def IMDBquery(self, data):
478                 self["statusbar"].setText(_("IMDb Download completed"))
479                 self.html2utf8(data)
480                 # logfile = open("/media/hdd/imdb.html", "w")
481                 # logfile.write(self.inhtml)
482                 # logfile.close()
483                 print('###############1')
484                 self.generalinfos = self.generalinfomask.search(self.inhtml)
485                 if self.generalinfos:
486                         self.IMDBparse()
487                 else:
488                         print('###############2')
489                         if not re.search('class="findHeader">No results found for', self.inhtml):
490                                 pos = self.inhtml.find("<table class=\"findList\">")
491                                 pos2 = self.inhtml.find("</table>",pos)
492                                 findlist = self.inhtml[pos:pos2]
493                                 searchresultmask = re.compile('<tr class=\"findResult (?:odd|even)\">.*?<td class=\"result_text\"> <a href=\"/title/(tt\d{7,8})/.*?\"\s?>(.*?)</td>', re.S)
494                                 searchresults = searchresultmask.finditer(findlist)
495                                 self.resultlist = [(self.htmltags.sub('', x.group(2)).strip(), x.group(1)) for x in searchresults]
496                                 Len = len(self.resultlist)
497                                 self["menu"].l.setList(self.resultlist)
498                                 if Len == 1:
499                                         self["key_green"].setText("")
500                                         self["statusbar"].setText(_("Re-Query IMDb: %s...") % (self.resultlist[0][0],))
501                                         self.eventName = self.resultlist[0][0]
502                                         link = self.resultlist[0][1]
503                                         fetchurl = "https://www.imdb.com/title/" + link + "/"
504                                         getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery).addErrback(self.http_failed)
505                                 elif Len > 1:
506                                         self.Page = 1
507                                         self.showMenu()
508                                 else:
509                                         self["statusbar"].setText(_("No IMDb match.") + ' ' + self.eventName)
510                         else:
511                                 splitpos = self.eventName.find('(')
512                                 if splitpos > 0:
513                                         self.eventName = self.eventName[:splitpos-1]
514                                         self["statusbar"].setText(_("Re-Query IMDb: %s...") % (self.eventName))
515                                         fetchurl = "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + quoteEventName(self.eventName) + "&s=all"
516                                         getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery).addErrback(self.http_failed)
517                                 else:
518                                         splitpos = self.eventName.find('-')
519                                         if splitpos > 0:
520                                                 self.eventName = self.eventName[:splitpos-1].strip()
521                                                 self["statusbar"].setText(_("Re-Query IMDb: %s...") % (self.eventName))
522                                                 fetchurl = "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + quoteEventName(self.eventName) + "&s=all"
523                                                 getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery).addErrback(self.http_failed)
524                                         else:
525                                                 self["statusbar"].setText(_("IMDb query failed!"))
526
527         def http_failed(self, error):
528                 text = _("IMDb Download failed")
529                 text += ": " + str(error)
530                 print("[IMDB] ",text)
531                 self["statusbar"].setText(text)
532
533         def IMDBquery2(self, data):
534                 self["statusbar"].setText(_("IMDb Re-Download completed"))
535                 self.html2utf8(data)
536                 # logfile = open("/media/hdd/imdb.html", "w")
537                 # logfile.write(self.inhtml)
538                 # logfile.close()
539                 print('###############3')
540                 self.generalinfos = self.generalinfomask.search(self.inhtml)
541                 self.IMDBparse()
542
543         def IMDBparse(self):
544                 self.Page = 1
545                 Detailstext = _("No details found.")
546                 if self.generalinfos:
547                         self["key_yellow"].setText(_("Details"))
548                         self["statusbar"].setText(_("IMDb Details parsed"))
549                         Titletext = self.generalinfos.group("title").replace(self.NBSP, ' ').strip()
550                         if len(Titletext) > 57:
551                                 Titletext = Titletext[0:54] + "..."
552                         self.title_setText(Titletext)
553
554                         Detailstext = ""
555                         addnewline = ""
556
557                         _("Genre:"), _("Genres:") # translate tags
558                         print('###############4')
559                         genreblock = self.genreblockmask.search(self.inhtml)
560                         if genreblock:
561                                 genres = ', '.join(re.split('\|+', self.htmltags.sub('|', genreblock.group("genres"))))
562                                 if genres:
563                                         Detailstext += addnewline + _(genreblock.group('g_genres')+":") + " " + genres.strip(', ').strip(',')
564                                         addnewline = "\n"
565
566                         _("Director:"), _("Directors:"), _("Creator:"), _("Creators:"), _("Writer:"), _("Writers:"), _('Episodes:'), _("Runtime:"), _("Release date:"), _("Country of origin:"), _("Countries of origin:"), _("Original title:"), _("Also known as:") # translate tags
567                         for category in ("director", "creator", "writer", "seasons", "episodes", "runtime", "premiere", "country", "originaltitle", "alternativ"):
568                                 try:
569
570                                         if self.generalinfos.group(category):
571                                                 if category == 'runtime':
572                                                         runtime = re.findall('(?:(\d+)\shours?|)\s{0,1}(?:(\d+)\sminutes?|)', self.htmltags.sub('', self.generalinfos.group(category)).replace('<!-- -->',''), re.S)
573                                                         print(runtime)
574                                                         if runtime:
575                                                                 if runtime[0][0] and runtime[0][1]:
576                                                                         runtime = str(60 * int(runtime[0][0]) + int(runtime[0][1]))
577                                                                         txt = runtime + " min"
578                                                                 elif runtime[0][0]:
579                                                                         runtime = str(60 * int(runtime[0][0]))
580                                                                         txt = runtime + " min"
581                                                                 elif runtime[0][1]:
582                                                                         txt = runtime[0][1] + " min"
583                                                         else:
584                                                                 txt = ', '.join(re.split('\|+', self.htmltags.sub('|', self.generalinfos.group(category)).strip('|').replace("\n", ' ')))
585                                                 elif category == 'seasons':
586                                                         txt = ' '.join(self.htmltags.sub(' ', self.generalinfos.group(category)).replace("\n", ' ').replace('See all', '...').split())
587                                                 elif category in ('director', 'creator', 'writer'):
588                                                         txt = ', '.join(re.split('\|+', self.htmltags.sub('|', self.generalinfos.group(category).replace('</a><span class="ipc-metadata-list-item__list-content-item--subText">', ' ')).strip('|').replace("\n", ' ')))
589                                                 elif category in ("premiere", "country", "originaltitle", "alternativ"):
590                                                         txt = ', '.join(re.split('\|+', self.htmltags.sub('|', self.generalinfos.group(category).replace('\n', ' ')).strip('|')))
591                                                 else:
592                                                         txt = ', '.join(re.split('\|+', self.htmltags.sub('|', self.generalinfos.group(category)).strip('|').replace("\n", ' ')))
593                                                 Detailstext += addnewline + _(self.generalinfos.group('g_' + category)+":") + " " + txt
594                                                 if category == 'seasons':
595                                                         Detailstext = Detailstext.replace('seasons:', _('Seasons:'))
596                                                 addnewline = "\n"
597                                 except IndexError:
598                                         pass
599
600                         print('###############5')
601                         rating = self.ratingmask.search(self.inhtml)
602                         Ratingtext = _("no user rating yet")
603                         if rating:
604                                 ratingval = rating.group("rating")
605                                 if ratingval != '<span id="voteuser"></span>':
606                                         count = ''
607                                         if rating.group("ratingcount"): count = ' (' + rating.group("ratingcount").replace(',','.') + ' ' + _("votes") +')'
608                                         Ratingtext = _("User Rating") + ": " + ratingval + "/10" + count
609                                         self.ratingstars = int(10*round(float(ratingval.replace(',','.')),1))
610                                         self["stars"].show()
611                                         self["stars"].setValue(self.ratingstars)
612                                         self["starsbg"].show()
613                         self["ratinglabel"].setText(str(Ratingtext))
614
615                         castresult = self.castmask.finditer(self.inhtml)
616                         if castresult:
617                                 Casttext = ""
618                                 for x in castresult:
619                                         Casttext += "\n" + self.htmltags.sub('', x.group('actor'))
620                                         if x.group('character'):
621                                                 chartext = self.htmltags.sub(' ', x.group('character').replace('/ ...', '')).replace('\n', ' ').replace(self.NBSP, ' ')
622                                                 Casttext += _(" as ") + ' '.join(chartext.split()).replace('…', '')
623                                                 try:
624                                                         if config.plugins.imdb.showepisodeinfo.value and x.group('episodes'):
625                                                                 Casttext += '\n(' + self.htmltags.sub('', re.sub(r"[0-9]+ eps", "", x.group('episodes').replace('episodes', _("episodes"))).replace(' • ', ', ')).strip() + ')'
626                                                 except IndexError:
627                                                         pass
628                                 if Casttext:
629                                         Casttext = _("Cast:") + " " + Casttext
630                                 else:
631                                         Casttext = _("No cast list found in the database.")
632                                 self["castlabel"].setText(Casttext)
633
634                         print('###############6')
635                         storylineresult = self.storylinemask.search(self.inhtml)
636                         if storylineresult:
637                                 _("Storyline:") # translate tag
638                                 Storyline = ""
639                                 if storylineresult.group("g_storyline"):
640                                         Storyline = _(storylineresult.group('g_storyline')+":") + "\n"
641                                         if not "Add content advisory" in storylineresult.group('storyline') and not 'data-testid="storyline-parents-guide"' in storylineresult.group('storyline'):
642                                                 Storyline = Storyline + re.sub('\s{5,30}',', ', self.htmltags.sub('', storylineresult.group('storyline').replace('\n','').replace('<br>', '\n').replace('<br/>', '\n').replace('<br />','\n').replace('&nbsp;','').replace('&quot;','"').replace('<span class="','')).strip())
643
644                                 if Storyline == _(storylineresult.group('g_storyline')+":") + "\n":
645                                         self["storylinelabel"].hide()
646                                 else:
647                                         self["storylinelabel"].setText(Storyline)
648
649                         print('###############7')
650                         posterurl = self.postermask.search(self.inhtml)
651                         if posterurl and posterurl.group(1).find("jpg") > 0:
652                                 posterurl = posterurl.group(1)
653                                 self["statusbar"].setText(_("Downloading Movie Poster: %s...") % (posterurl))
654                                 localfile = "/tmp/poster.jpg"
655                                 print("[IMDB] downloading poster " + posterurl + " to " + localfile)
656                                 download = downloadWithProgress(posterurl,localfile,headers=imdb_headers)
657                                 download.start().addCallback(self.IMDBPoster).addErrback(self.http_failed)
658                         else:
659                                 self.IMDBPoster("no poster")
660
661                         Extratext = ''
662
663                         print('###############8')
664                         extrainfos = self.extrainfomask.search(self.inhtml)
665
666                         if extrainfos:
667                                 _("Tagline:"), _("Taglines:") # translate tags
668                                 for category in ("outline", "tagline"):
669                                         try:
670                                                 if extrainfos.group(category):
671                                                         sep = "\n" if category in ("outline") else " "
672                                                         if category == "outline":
673                                                                 if "Add a plot" in extrainfos.group(category) or extrainfos.group(category) == "</span></p>":
674                                                                         continue
675                                                                 Extratext += "\n" + _("Plot outline:")
676                                                         else:
677                                                                 Extratext += "\n" + _(extrainfos.group('g_' + category)+":")
678                                                         txt = ', '.join(re.split('\|+', self.htmltags.sub('|', extrainfos.group(category).replace("\n", ' ').replace("<br>", '\n').replace("<br/>", '\n').replace('<br />', '\n')).strip('|').replace(' |' + self.NBSP, '').replace(self.NBSP, ' ')))
679                                                         Extratext += sep + txt + "\n"
680                                         except IndexError:
681                                                 pass
682
683                         print('###############9')
684                         keywordsresult = self.keywordsmask.search(self.inhtml)
685                         if keywordsresult:
686                                 keywords = keywordsresult.group('keywords').replace(' ', '_')
687                                 keywords = ', '.join(self.htmltags.sub(' ', keywords).split())
688                                 keywords = re.sub(', \d+ more', '', keywords.replace('_', ' '))
689                                 Extratext += "\n" + _("Keywords:") + " " + keywords + "\n"
690
691                         awardsresult = self.awardsmask.finditer(self.inhtml)
692                         if awardsresult:
693                                 awardslist = [' '.join(x.group('awards').split()) for x in awardsresult]
694                                 if awardslist:
695                                         awards = self.allhtmltags.sub(', ', ''.join(awardslist).replace('<b>', '').replace('Awards</a>', '').strip()).strip(', ')
696                                         Extratext += "\n" + _("Awards:") + " " + awards + "\n"
697
698                         print('###############10')
699                         boxofficeresult = self.boxofficemask.search(self.inhtml)
700                         if boxofficeresult:
701                                 boxoffice = "Budget " + boxofficeresult.group('boxofficebudget') + "\n" + "Opening weekend US & Canada " + boxofficeresult.group('boxofficeopening') + " (" + boxofficeresult.group('boxofficeopeningdate') + ")" + "\n" + "Gross US & Canada " + boxofficeresult.group('boxofficegrossuscanada') + "\n" "Gross worldwide " + boxofficeresult.group('boxofficegrossworld')
702                                 Extratext += "\n" + _("Box office:") + "\n" + boxoffice + "\n"
703
704                         if extrainfos:
705                                 _("Certificate:"), _("Motion Picture Rating (MPAA):"), _("Language:"), _("Languages:"), _("Color:"), _("Aspect ratio:"), _("Sound mix:"), _("Filming location:"), _("Filming locations:"), _("Production company:"), _("Production companies:"), _("Trivia:"), _("Goofs:"), _("Quotes:"), _("Crazy credits:"), _("Alternate versions:"), _("Connections:"), _("Soundtracks:"), _("User reviews:") # translate tags
706                                 for category in ("cert", "language", "color", "aspect", "sound", "locations", "company", "trivia", "goofs", "quotes", "crazycredits", "alternateversions", "connections", "soundtracks"):
707                                         try:
708                                                 if extrainfos.group(category):
709                                                         sep = "\n" if category in ("trivia", "goofs", "quotes", "connections", "crazycredits", "alternateversions", "soundtracks") else " "
710                                                         Extratext += "\n" + _(extrainfos.group('g_' + category)+":")
711                                                         if category in ("trivia", "goofs", "quotes", "connections", "crazycredits", "alternateversions", "soundtracks"):
712                                                                 txt = extrainfos.group(category).replace("<li>", '• ').replace("</li>", '\n').replace('Read all</a>', '').replace("</a>", '').replace("<br>", '\n').replace("<br/>", '\n').replace('<br />', '\n').replace("</p><p>", '\n')
713                                                                 txt = self.htmltags.sub('', txt).strip('\n')
714                                                         elif category in ("aspect", "sound"):
715                                                                 txt = extrainfos.group(category).replace(' : ', ':').replace('</a><span class="ipc-metadata-list-item__list-content-item--subText">', ' ').replace('</li>', ', ')
716                                                                 txt = self.htmltags.sub('', txt).strip(', ').strip()
717                                                         else:
718                                                                 txt = ', '.join(re.split('\|+', self.htmltags.sub('|', extrainfos.group(category).replace("\n", ' ').replace("<br>", '\n').replace("<br/>", '\n').replace('<br />', '\n')).strip('|').replace(' |' + self.NBSP, '').replace(self.NBSP, ' ')))
719                                                         Extratext += sep + txt + "\n"
720                                         except IndexError:
721                                                 pass
722                                 try:
723                                         if extrainfos.group("g_comments"):
724                                                 Extratext += "\n" + _(extrainfos.group("g_comments")+":") + "\n" + self.htmltags.sub('', extrainfos.group("commenttitle")) + " [" + ' '.join(self.htmltags.sub('', extrainfos.group("commenter")).split()) + "]\n" + self.htmltags.sub('', extrainfos.group("comment").replace("<br>", '\n').replace("<br/>", '\n').replace("<br />", '\n')) + "\n"
725                                 except IndexError:
726                                         pass
727
728                         if Extratext:
729                                 self["extralabel"].setText(Extratext.strip('\n'))
730                                 self["key_blue"].setText(_("Extra Info"))
731                         else:
732                                 self["key_blue"].setText("")
733
734                 self["extralabel"].hide()
735                 self["detailslabel"].setText(str(Detailstext))
736
737         def IMDBPoster(self, string):
738                 self["statusbar"].setText(_("IMDb Details parsed"))
739                 if not string:
740                         filename = "/tmp/poster.jpg"
741                 else:
742                         filename = resolveFilename(SCOPE_PLUGINS, "Extensions/IMDb/no_poster.png")
743                 sc = AVSwitch().getFramebufferScale()
744                 self.picload.setPara((self["poster"].instance.size().width(), self["poster"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
745                 self.picload.startDecode(filename)
746
747         def paintPosterPixmapCB(self, picInfo=None):
748                 ptr = self.picload.getData()
749                 if ptr != None:
750                         self["poster"].instance.setPixmap(ptr)
751                         self["poster"].show()
752
753         def setup(self):
754                 self.session.open(IMDbSetup)
755
756         def createSummary(self):
757                 return IMDbLCDScreenV2
758
759 class IMDbLCDScreenV2(Screen):
760         skin = (
761         """<screen title="IMDB Plugin" position="0,0" size="132,64" id="1">
762                 <widget name="headline" font="Display;22" halign="center" position="1,3" size="130,22"/>
763                 <widget source="parent.titlelcd" render="Label" font="Display;16" halign="center" valign="center" position="1,28" size="130,34"/>
764         </screen>""",
765         """<screen title="IMDB Plugin" position="0,0" size="96,64" id="2">
766                 <widget name="headline" font="Display;19" halign="center" position="0,2" size="96,20"/>
767                 <widget source="parent.titlelcd" render="Label" font="Display;15" halign="center" valign="center" position="0,28" size="96,34"/>
768         </screen>""",
769         """<screen title="IMDB Plugin" position="0,0" size="400,240" id="3">
770                 <ePixmap position="0,0" size="400,240" pixmap="skin_default/display_bg.png" zPosition="-1"/>
771                 <widget name="headline" font="Display;60" halign="center" position="0,5" size="400,60" transparent="1"/>
772                 <eLabel backgroundColor="yellow" position="0,75" size="400,2" />
773                 <widget source="parent.titlelcd" render="Label" font="Display;45" halign="center" valign="center" position="0,85" size="400,135" transparent="1"/>
774         </screen>""")
775
776         def __init__(self, session, parent):
777                 Screen.__init__(self, session, parent)
778                 self["headline"] = Label(_("IMDb Plugin"))
779
780 class IMDbSetup(Screen, ConfigListScreen):
781         def __init__(self, session):
782                 Screen.__init__(self, session)
783                 self.skinName = "Setup"
784
785                 self.setup_title = _("IMDb Setup")
786                 self.onChangedEntry = []
787
788                 self["key_green"] = StaticText(_("OK"))
789                 self["key_red"] = StaticText(_("Cancel"))
790                 self["description"] = Label("")
791
792                 self["actions"] = ActionMap(["SetupActions"],
793                         {
794                                 "cancel": self.keyCancel,
795                                 "save": self.keySave,
796                         }, -2)
797
798                 self.list = []
799                 ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
800                 self.createSetup()
801                 self.changedEntry()
802                 self.onLayoutFinish.append(self.layoutFinished)
803
804         def createSetup(self):
805                 self.list = []
806                 #self.list.append(getConfigListEntry(_("IMDb query language"), config.plugins.imdb.language))
807                 self.list.append(getConfigListEntry(_("Show in plugin browser"), config.plugins.imdb.showinplugins))
808                 self.list.append(getConfigListEntry(_("Use original IMDb skin:"), config.plugins.imdb.origskin))
809                 self.list.append(getConfigListEntry(_("Show episode and year information in cast list"), config.plugins.imdb.showepisodeinfo))
810                 self.list.append(getConfigListEntry(_("Words / phrases to ignore (comma separated)"), config.plugins.imdb.ignore_tags))
811                 self["config"].list = self.list
812                 self["config"].l.setList(self.list)
813
814         def layoutFinished(self):
815                 self.setTitle(_(self.setup_title))
816
817         def changedEntry(self):
818                 self.item = self["config"].getCurrent()
819                 for x in self.onChangedEntry:
820                         x()
821                 try:
822                         if isinstance(self["config"].getCurrent()[1], ConfigYesNo) or isinstance(self["config"].getCurrent()[1], ConfigSelection):
823                                 self.createSetup()
824                 except:
825                         pass
826
827         def getCurrentEntry(self):
828                 return self["config"].getCurrent() and self["config"].getCurrent()[0] or ""
829
830         def getCurrentValue(self):
831                 return self["config"].getCurrent() and str(self["config"].getCurrent()[1].getText()) or ""
832
833         def getCurrentDescription(self):
834                 return self["config"].getCurrent() and len(self["config"].getCurrent()) > 2 and self["config"].getCurrent()[2] or ""
835
836         def createSummary(self):
837                 from Screens.Setup import SetupSummary
838                 return SetupSummary
839
840         def keySave(self):
841                 self.saveAll()
842                 global imdb_headers
843                 #if config.plugins.imdb.language.value:
844                 #       imdb_headers = {'Accept-Language': config.plugins.imdb.language.value}
845                 #else:
846                 imdb_headers = {}
847                 if not config.plugins.imdb.showinplugins.value:
848                         for plugin in plugins.getPlugins(PluginDescriptor.WHERE_PLUGINMENU):
849                                 if plugin.name == _("IMDb Details"):
850                                         plugins.removePlugin(plugin)
851
852                 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
853                 self.close()
854
855 def eventinfo(session, eventname='', service='', **kwargs):
856         if not eventname:
857                 s = session.nav.getCurrentService()
858                 if s:
859                         info = s.info()
860                         event = info.getEvent(0) # 0 = now, 1 = next
861                         eventname = event and event.getEventName() or ''
862         else:
863                 eventname = eventname.getEventName()
864         session.open(IMDB, eventname)
865
866 def main(session, event='', **kwargs):
867         session.open(IMDB, event)
868
869 pluginlist = PluginDescriptor(name=_("IMDb Details"), description=_("Query details from the Internet Movie Database"), icon="imdb.png", where=PluginDescriptor.WHERE_PLUGINMENU, fnc=main, needsRestart=False)
870
871 def Plugins(**kwargs):
872         l = [PluginDescriptor(name=_("IMDb Details") + "...", description=_("Query details from the Internet Movie Database"), where=[PluginDescriptor.WHERE_EVENTINFO, PluginDescriptor.WHERE_EPG_SELECTION_SINGLE_BLUE, PluginDescriptor.WHERE_EVENTVIEW], fnc=eventinfo, needsRestart=False, ),]
873         if config.plugins.imdb.showinplugins.value:
874                 l.append(pluginlist)
875         return l