Update MSNWeather.py
[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.*?class="TitleHeader__TitleText.*?>(?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                 '(?:.*?<span.*?>(?P<g_runtime>Runtime)</span>.*?<div.*?<ul.*?>(?P<runtime>.*?)</ul>)?', 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>Bez\S*?ge zu anderen Titeln|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 reviews)<span.*?UserReviewSummary__Summary.*?>(?P<commenttitle>.*?)</span></div.*?<div.*?<div.*?>(?P<comment>.+?)</div>.*?<div.*?UserReviewAuthor__AuthorContainer.*?>.*?<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.*?AggregateRatingButton__RatingScore.*?>(?P<rating>.*?)</span>.*?<span.*?AggregateRatingButton__TotalRatingAmount.*?>(?P<ratingcount>.*?)</div', re.S)
234                 self.castmask = re.compile('<a.*?StyledComponents__ActorName.*?>(?P<actor>.*?)</a>.*?StyledComponents__CharacterNameWithoutAs.*?>(?P<character>.*?)</span>(?:.*?<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('<section.*?<div.*?<div.*?<hgroup.*?<h3.*?>(?P<g_storyline>Storyline)</h3>.*?<div.*?<div.*?<div.*?<div.*?>(?P<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:
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('title-news-header')
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                 self.generalinfos = self.generalinfomask.search(self.inhtml)
481                 if self.generalinfos:
482                         self.IMDBparse()
483                 else:
484                         if not re.search('class="findHeader">No results found for', self.inhtml):
485                                 pos = self.inhtml.find("<table class=\"findList\">")
486                                 pos2 = self.inhtml.find("</table>",pos)
487                                 findlist = self.inhtml[pos:pos2]
488                                 searchresultmask = re.compile('<tr class=\"findResult (?:odd|even)\">.*?<td class=\"result_text\"> <a href=\"/title/(tt\d{7,8})/.*?\"\s?>(.*?)</td>', re.S)
489                                 searchresults = searchresultmask.finditer(findlist)
490                                 self.resultlist = [(self.htmltags.sub('', x.group(2)).strip(), x.group(1)) for x in searchresults]
491                                 Len = len(self.resultlist)
492                                 self["menu"].l.setList(self.resultlist)
493                                 if Len == 1:
494                                         self["key_green"].setText("")
495                                         self["statusbar"].setText(_("Re-Query IMDb: %s...") % (self.resultlist[0][0],))
496                                         self.eventName = self.resultlist[0][1]
497                                         fetchurl = "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + quoteEventName(self.eventName) + "&s=all"
498                                         getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery).addErrback(self.http_failed)
499                                 elif Len > 1:
500                                         self.Page = 1
501                                         self.showMenu()
502                                 else:
503                                         self["statusbar"].setText(_("No IMDb match.") + ' ' + self.eventName)
504                         else:
505                                 splitpos = self.eventName.find('(')
506                                 if splitpos > 0:
507                                         self.eventName = self.eventName[:splitpos-1]
508                                         self["statusbar"].setText(_("Re-Query IMDb: %s...") % (self.eventName))
509                                         fetchurl = "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + quoteEventName(self.eventName) + "&s=all"
510                                         getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery).addErrback(self.http_failed)
511                                 else:
512                                         splitpos = self.eventName.find('-')
513                                         if splitpos > 0:
514                                                 self.eventName = self.eventName[:splitpos-1].strip()
515                                                 self["statusbar"].setText(_("Re-Query IMDb: %s...") % (self.eventName))
516                                                 fetchurl = "https://www.imdb.com/find?ref_=nv_sr_fn&q=" + quoteEventName(self.eventName) + "&s=all"
517                                                 getPage(fetchurl, agent=agent, headers=imdb_headers).addCallback(self.IMDBquery).addErrback(self.http_failed)
518                                         else:
519                                                 self["statusbar"].setText(_("IMDb query failed!"))
520
521         def http_failed(self, error):
522                 text = _("IMDb Download failed")
523                 text += ": " + str(error)
524                 print("[IMDB] ",text)
525                 self["statusbar"].setText(text)
526
527         def IMDBquery2(self, data):
528                 self["statusbar"].setText(_("IMDb Re-Download completed"))
529                 self.html2utf8(data)
530                 self.generalinfos = self.generalinfomask.search(self.inhtml)
531                 self.IMDBparse()
532
533         def IMDBparse(self):
534                 self.Page = 1
535                 Detailstext = _("No details found.")
536                 if self.generalinfos:
537                         self["key_yellow"].setText(_("Details"))
538                         self["statusbar"].setText(_("IMDb Details parsed"))
539                         Titletext = self.generalinfos.group("title").replace(self.NBSP, ' ').strip()
540                         if len(Titletext) > 57:
541                                 Titletext = Titletext[0:54] + "..."
542                         self.title_setText(Titletext)
543
544                         Detailstext = ""
545                         addnewline = ""
546
547                         _("Genre:"), _("Genres:") # translate tags
548                         genreblock = self.genreblockmask.search(self.inhtml)
549                         if genreblock:
550                                 genres = ', '.join(re.split('\|+', self.htmltags.sub('|', genreblock.group("genres"))))
551                                 if genres:
552                                         Detailstext += addnewline + _(genreblock.group('g_genres')+":") + " " + genres.strip(', ').strip(',')
553                                         addnewline = "\n"
554
555                         _("Director:"), _("Directors:"), _("Creator:"), _("Creators:"), _("Writer:"), _("Writers:"), _('Episodes:'), _("Runtime:"), _("Release date:"), _("Country of origin:"), _("Countries of origin:"), _("Original title:"), _("Also known as:") # translate tags
556                         for category in ("director", "creator", "writer", "seasons", "episodes", "runtime", "premiere", "country", "originaltitle", "alternativ"):
557                                 try:
558
559                                         if self.generalinfos.group(category):
560                                                 if category == 'runtime':
561                                                         runtime = re.findall('(?:(\d+)h|)\s{0,1}(?:(\d+)min|)', self.htmltags.sub('', self.generalinfos.group(category)), re.S)
562                                                         if runtime:
563                                                                 if runtime[0][0] and runtime[0][1]:
564                                                                         runtime = str(60 * int(runtime[0][0]) + int(runtime[0][1]))
565                                                                         txt = runtime + " min"
566                                                                 elif runtime[0][0]:
567                                                                         runtime = str(60 * int(runtime[0][0]))
568                                                                         txt = runtime + " min"
569                                                                 elif runtime[0][1]:
570                                                                         txt = runtime[0][1] + " min"
571                                                         else:
572                                                                 txt = ', '.join(re.split('\|+', self.htmltags.sub('|', self.generalinfos.group(category)).strip('|').replace("\n", ' ')))
573                                                 elif category == 'seasons':
574                                                         txt = ' '.join(self.htmltags.sub(' ', self.generalinfos.group(category)).replace("\n", ' ').replace('See all', '...').split())
575                                                 elif category in ('director', 'creator', 'writer'):
576                                                         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", ' ')))
577                                                 elif category in ("premiere", "country", "originaltitle", "alternativ"):
578                                                         txt = ', '.join(re.split('\|+', self.htmltags.sub('|', self.generalinfos.group(category).replace('\n', ' ')).strip('|')))
579                                                 else:
580                                                         txt = ', '.join(re.split('\|+', self.htmltags.sub('|', self.generalinfos.group(category)).strip('|').replace("\n", ' ')))
581                                                 Detailstext += addnewline + _(self.generalinfos.group('g_' + category)+":") + " " + txt
582                                                 if category == 'seasons':
583                                                         Detailstext = Detailstext.replace('seasons:', _('Seasons:'))
584                                                 addnewline = "\n"
585                                 except IndexError:
586                                         pass
587
588                         rating = self.ratingmask.search(self.inhtml)
589                         Ratingtext = _("no user rating yet")
590                         if rating:
591                                 ratingval = rating.group("rating")
592                                 if ratingval != '<span id="voteuser"></span>':
593                                         count = ''
594                                         if rating.group("ratingcount"): count = ' (' + rating.group("ratingcount").replace(',','.') + ' ' + _("votes") +')'
595                                         Ratingtext = _("User Rating") + ": " + ratingval + "/10" + count
596                                         self.ratingstars = int(10*round(float(ratingval.replace(',','.')),1))
597                                         self["stars"].show()
598                                         self["stars"].setValue(self.ratingstars)
599                                         self["starsbg"].show()
600                         self["ratinglabel"].setText(str(Ratingtext))
601
602                         castresult = self.castmask.finditer(self.inhtml)
603                         if castresult:
604                                 Casttext = ""
605                                 for x in castresult:
606                                         Casttext += "\n" + self.htmltags.sub('', x.group('actor'))
607                                         if x.group('character'):
608                                                 chartext = self.htmltags.sub(' ', x.group('character').replace('/ ...', '')).replace('\n', ' ').replace(self.NBSP, ' ')
609                                                 Casttext += _(" as ") + ' '.join(chartext.split()).replace('…', '')
610                                                 try:
611                                                         if config.plugins.imdb.showepisodeinfo.value and x.group('episodes'):
612                                                                 Casttext += '\n(' + self.htmltags.sub('', re.sub(r"[0-9]+ eps", "", x.group('episodes').replace('episodes', _("episodes"))).replace(' • ', ', ')).strip() + ')'
613                                                 except IndexError:
614                                                         pass
615                                 if Casttext:
616                                         Casttext = _("Cast:") + " " + Casttext
617                                 else:
618                                         Casttext = _("No cast list found in the database.")
619                                 self["castlabel"].setText(Casttext)
620
621                         storylineresult = self.storylinemask.search(self.inhtml)
622                         if storylineresult:
623                                 _("Storyline:") # translate tag
624                                 Storyline = ""
625                                 if storylineresult.group("g_storyline"):
626                                         Storyline = _(storylineresult.group('g_storyline')+":") + "\n"
627                                         if not "Add content advisory" in storylineresult.group('storyline') and not 'data-testid="storyline-parents-guide"' in storylineresult.group('storyline'):
628                                                 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())
629
630                                 if Storyline == _(storylineresult.group('g_storyline')+":") + "\n":
631                                         self["storylinelabel"].hide()
632                                 else:
633                                         self["storylinelabel"].setText(Storyline)
634
635                         posterurl = self.postermask.search(self.inhtml)
636                         if posterurl and posterurl.group(1).find("jpg") > 0:
637                                 posterurl = posterurl.group(1)
638                                 self["statusbar"].setText(_("Downloading Movie Poster: %s...") % (posterurl))
639                                 localfile = "/tmp/poster.jpg"
640                                 print("[IMDB] downloading poster " + posterurl + " to " + localfile)
641                                 download = downloadWithProgress(posterurl,localfile,headers=imdb_headers)
642                                 download.start().addCallback(self.IMDBPoster).addErrback(self.http_failed)
643                         else:
644                                 self.IMDBPoster("no poster")
645
646                         Extratext = ''
647
648                         extrainfos = self.extrainfomask.search(self.inhtml)
649
650                         if extrainfos:
651                                 _("Tagline:"), _("Taglines:") # translate tags
652                                 for category in ("outline", "tagline"):
653                                         try:
654                                                 if extrainfos.group(category):
655                                                         sep = "\n" if category in ("outline") else " "
656                                                         if category == "outline":
657                                                                 if "Add a plot" in extrainfos.group(category) or extrainfos.group(category) == "</span></p>":
658                                                                         continue
659                                                                 Extratext += "\n" + _("Plot outline:")
660                                                         else:
661                                                                 Extratext += "\n" + _(extrainfos.group('g_' + category)+":")
662                                                         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, ' ')))
663                                                         Extratext += sep + txt + "\n"
664                                         except IndexError:
665                                                 pass
666
667                         keywordsresult = self.keywordsmask.search(self.inhtml)
668                         if keywordsresult:
669                                 keywords = keywordsresult.group('keywords').replace(' ', '_')
670                                 keywords = ', '.join(self.htmltags.sub(' ', keywords).split())
671                                 keywords = re.sub(', \d+ more', '', keywords.replace('_', ' '))
672                                 Extratext += "\n" + _("Keywords:") + " " + keywords + "\n"
673
674                         awardsresult = self.awardsmask.finditer(self.inhtml)
675                         if awardsresult:
676                                 awardslist = [' '.join(x.group('awards').split()) for x in awardsresult]
677                                 if awardslist:
678                                         awards = self.allhtmltags.sub(', ', ''.join(awardslist).replace('<b>', '').replace('Awards</a>', '').strip()).strip(', ')
679                                         Extratext += "\n" + _("Awards:") + " " + awards + "\n"
680
681                         boxofficeresult = self.boxofficemask.search(self.inhtml)
682                         if boxofficeresult:
683                                 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')
684                                 Extratext += "\n" + _("Box office:") + "\n" + boxoffice + "\n"
685
686                         if extrainfos:
687                                 _("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
688                                 for category in ("cert", "language", "color", "aspect", "sound", "locations", "company", "trivia", "goofs", "quotes", "crazycredits", "alternateversions", "connections", "soundtracks"):
689                                         try:
690                                                 if extrainfos.group(category):
691                                                         sep = "\n" if category in ("trivia", "goofs", "quotes", "connections", "crazycredits", "alternateversions", "soundtracks") else " "
692                                                         Extratext += "\n" + _(extrainfos.group('g_' + category)+":")
693                                                         if category in ("trivia", "goofs", "quotes", "connections", "crazycredits", "alternateversions", "soundtracks"):
694                                                                 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')
695                                                                 txt = self.htmltags.sub('', txt).strip('\n')
696                                                         elif category in ("aspect", "sound"):
697                                                                 txt = extrainfos.group(category).replace(' : ', ':').replace('</a><span class="ipc-metadata-list-item__list-content-item--subText">', ' ').replace('</li>', ', ')
698                                                                 txt = self.htmltags.sub('', txt).strip(', ').strip()
699                                                         else:
700                                                                 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, ' ')))
701                                                         Extratext += sep + txt + "\n"
702                                         except IndexError:
703                                                 pass
704                                 try:
705                                         if extrainfos.group("g_comments"):
706                                                 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"
707                                 except IndexError:
708                                         pass
709
710                         if Extratext:
711                                 self["extralabel"].setText(Extratext.strip('\n'))
712                                 self["extralabel"].hide()
713                                 self["key_blue"].setText(_("Extra Info"))
714                         else:
715                                 self["key_blue"].setText("")
716
717                 self["detailslabel"].setText(str(Detailstext))
718
719         def IMDBPoster(self, string):
720                 self["statusbar"].setText(_("IMDb Details parsed"))
721                 if not string:
722                         filename = "/tmp/poster.jpg"
723                 else:
724                         filename = resolveFilename(SCOPE_PLUGINS, "Extensions/IMDb/no_poster.png")
725                 sc = AVSwitch().getFramebufferScale()
726                 self.picload.setPara((self["poster"].instance.size().width(), self["poster"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
727                 self.picload.startDecode(filename)
728
729         def paintPosterPixmapCB(self, picInfo=None):
730                 ptr = self.picload.getData()
731                 if ptr != None:
732                         self["poster"].instance.setPixmap(ptr)
733                         self["poster"].show()
734
735         def setup(self):
736                 self.session.open(IMDbSetup)
737
738         def createSummary(self):
739                 return IMDbLCDScreenV2
740
741 class IMDbLCDScreenV2(Screen):
742         skin = (
743         """<screen title="IMDB Plugin" position="0,0" size="132,64" id="1">
744                 <widget name="headline" font="Display;22" halign="center" position="1,3" size="130,22"/>
745                 <widget source="parent.titlelcd" render="Label" font="Display;16" halign="center" valign="center" position="1,28" size="130,34"/>
746         </screen>""",
747         """<screen title="IMDB Plugin" position="0,0" size="96,64" id="2">
748                 <widget name="headline" font="Display;19" halign="center" position="0,2" size="96,20"/>
749                 <widget source="parent.titlelcd" render="Label" font="Display;15" halign="center" valign="center" position="0,28" size="96,34"/>
750         </screen>""",
751         """<screen title="IMDB Plugin" position="0,0" size="400,240" id="3">
752                 <ePixmap position="0,0" size="400,240" pixmap="skin_default/display_bg.png" zPosition="-1"/>
753                 <widget name="headline" font="Display;60" halign="center" position="0,5" size="400,60" transparent="1"/>
754                 <eLabel backgroundColor="yellow" position="0,75" size="400,2" />
755                 <widget source="parent.titlelcd" render="Label" font="Display;45" halign="center" valign="center" position="0,85" size="400,135" transparent="1"/>
756         </screen>""")
757
758         def __init__(self, session, parent):
759                 Screen.__init__(self, session, parent)
760                 self["headline"] = Label(_("IMDb Plugin"))
761
762 class IMDbSetup(Screen, ConfigListScreen):
763         def __init__(self, session):
764                 Screen.__init__(self, session)
765                 self.skinName = "Setup"
766
767                 self.setup_title = _("IMDb Setup")
768                 self.onChangedEntry = []
769
770                 self["key_green"] = StaticText(_("OK"))
771                 self["key_red"] = StaticText(_("Cancel"))
772                 self["description"] = Label("")
773
774                 self["actions"] = ActionMap(["SetupActions"],
775                         {
776                                 "cancel": self.keyCancel,
777                                 "save": self.keySave,
778                         }, -2)
779
780                 self.list = []
781                 ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
782                 self.createSetup()
783                 self.changedEntry()
784                 self.onLayoutFinish.append(self.layoutFinished)
785
786         def createSetup(self):
787                 self.list = []
788                 self.list.append(getConfigListEntry(_("IMDb query language"), config.plugins.imdb.language))
789                 self.list.append(getConfigListEntry(_("Show in plugin browser"), config.plugins.imdb.showinplugins))
790                 self.list.append(getConfigListEntry(_("Use original IMDb skin:"), config.plugins.imdb.origskin))
791                 self.list.append(getConfigListEntry(_("Show episode and year information in cast list"), config.plugins.imdb.showepisodeinfo))
792                 self.list.append(getConfigListEntry(_("Words / phrases to ignore (comma separated)"), config.plugins.imdb.ignore_tags))
793                 self["config"].list = self.list
794                 self["config"].l.setList(self.list)
795
796         def layoutFinished(self):
797                 self.setTitle(_(self.setup_title))
798
799         def changedEntry(self):
800                 self.item = self["config"].getCurrent()
801                 for x in self.onChangedEntry:
802                         x()
803                 try:
804                         if isinstance(self["config"].getCurrent()[1], ConfigYesNo) or isinstance(self["config"].getCurrent()[1], ConfigSelection):
805                                 self.createSetup()
806                 except:
807                         pass
808
809         def getCurrentEntry(self):
810                 return self["config"].getCurrent() and self["config"].getCurrent()[0] or ""
811
812         def getCurrentValue(self):
813                 return self["config"].getCurrent() and str(self["config"].getCurrent()[1].getText()) or ""
814
815         def getCurrentDescription(self):
816                 return self["config"].getCurrent() and len(self["config"].getCurrent()) > 2 and self["config"].getCurrent()[2] or ""
817
818         def createSummary(self):
819                 from Screens.Setup import SetupSummary
820                 return SetupSummary
821
822         def keySave(self):
823                 self.saveAll()
824                 global imdb_headers
825                 if config.plugins.imdb.language.value:
826                         imdb_headers = {'Accept-Language': config.plugins.imdb.language.value}
827                 else:
828                         imdb_headers = {}
829                 if not config.plugins.imdb.showinplugins.value:
830                         for plugin in plugins.getPlugins(PluginDescriptor.WHERE_PLUGINMENU):
831                                 if plugin.name == _("IMDb Details"):
832                                         plugins.removePlugin(plugin)
833
834                 plugins.readPluginList(resolveFilename(SCOPE_PLUGINS))
835                 self.close()
836
837 def eventinfo(session, eventname='', service='', **kwargs):
838         if not eventname:
839                 s = session.nav.getCurrentService()
840                 if s:
841                         info = s.info()
842                         event = info.getEvent(0) # 0 = now, 1 = next
843                         eventname = event and event.getEventName() or ''
844         else:
845                 eventname = eventname.getEventName()
846         session.open(IMDB, eventname)
847
848 def main(session, event='', **kwargs):
849         session.open(IMDB, event)
850
851 pluginlist = PluginDescriptor(name=_("IMDb Details"), description=_("Query details from the Internet Movie Database"), icon="imdb.png", where=PluginDescriptor.WHERE_PLUGINMENU, fnc=main, needsRestart=False)
852
853 def Plugins(**kwargs):
854         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, ),]
855         if config.plugins.imdb.showinplugins.value:
856                 l.append(pluginlist)
857         return l