fix title extraction on multiple search results, fix parsing of rating and genre
[enigma2-plugins.git] / imdb / src / plugin.py
1 # -*- coding: utf8 -*-
2 from Plugins.Plugin import PluginDescriptor
3 from twisted.web.client import downloadPage
4 from enigma import ePicLoad, eServiceReference
5 from Screens.Screen import Screen
6 from Screens.EpgSelection import EPGSelection
7 from Screens.ChannelSelection import SimpleChannelSelection
8 from Components.ActionMap import ActionMap
9 from Components.Pixmap import Pixmap
10 from Components.Label import Label
11 from Components.ScrollLabel import ScrollLabel
12 from Components.Button import Button
13 from Components.AVSwitch import AVSwitch
14 from Components.MenuList import MenuList
15 from Components.Language import language
16 from Components.ProgressBar import ProgressBar
17 from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
18 import re
19 import htmlentitydefs
20 import urllib
21
22 class IMDBChannelSelection(SimpleChannelSelection):
23         def __init__(self, session):
24                 SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
25                 self.skinName = "SimpleChannelSelection"
26
27                 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
28                         {
29                                 "showEPGList": self.channelSelected
30                         }
31                 )
32
33         def channelSelected(self):
34                 ref = self.getCurrentSelection()
35                 if (ref.flags & 7) == 7:
36                         self.enterPath(ref)
37                 elif not (ref.flags & eServiceReference.isMarker):
38                         self.session.openWithCallback(
39                                 self.epgClosed,
40                                 IMDBEPGSelection,
41                                 ref,
42                                 openPlugin = False
43                         )
44
45         def epgClosed(self, ret = None):
46                 if ret:
47                         self.close(ret)
48
49 class IMDBEPGSelection(EPGSelection):
50         def __init__(self, session, ref, openPlugin = True):
51                 EPGSelection.__init__(self, session, ref)
52                 self.skinName = "EPGSelection"
53                 self["key_green"].setText(_("Lookup"))
54                 self.openPlugin = openPlugin
55
56         def infoKeyPressed(self):
57                 self.timerAdd()
58
59         def timerAdd(self):
60                 cur = self["list"].getCurrent()
61                 evt = cur[0]
62                 sref = cur[1]
63                 if not evt: 
64                         return
65
66                 if self.openPlugin:
67                         self.session.open(
68                                 IMDB,
69                                 evt.getEventName()
70                         )
71                 else:
72                         self.close(evt.getEventName())
73
74         def onSelectionChanged(self):
75                 pass
76
77 class IMDB(Screen):
78         skin = """
79                 <screen name="IMDB" position="90,95" size="560,420" title="Internet Movie Database Details Plugin" >
80                         <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
81                         <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
82                         <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
83                         <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" zPosition="0" size="140,40" transparent="1" alphatest="on" />
84                         <widget name="key_red" position="0,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#9f1313" transparent="1" />
85                         <widget name="key_green" position="140,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#1f771f" transparent="1" />
86                         <widget name="key_yellow" position="280,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#a08500" transparent="1" />
87                         <widget name="key_blue" position="420,0" zPosition="1" size="140,40" font="Regular;20" valign="center" halign="center" backgroundColor="#18188b" transparent="1" />
88                         <widget name="titellabel" position="10,40" size="330,45" valign="center" font="Regular;22"/>
89                         <widget name="detailslabel" position="105,90" size="445,140" font="Regular;18" />
90                         <widget name="castlabel" position="10,235" size="540,155" font="Regular;18" />
91                         <widget name="extralabel" position="10,40" size="540,350" font="Regular;18" />
92                         <widget name="ratinglabel" position="340,62" size="210,20" halign="center" font="Regular;18" foregroundColor="#f0b400"/>
93                         <widget name="statusbar" position="10,404" size="540,16" font="Regular;16" foregroundColor="#cccccc" />
94                         <widget name="poster" position="4,90" size="96,140" alphatest="on" />
95                         <widget name="menu" position="10,115" size="540,275" zPosition="3" scrollbarMode="showOnDemand" />
96                         <widget name="starsbg" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IMDb/starsbar_empty.png" position="340,40" zPosition="0" size="210,21" transparent="1" alphatest="on" />
97                         <widget name="stars" position="340,40" size="210,21" pixmap="/usr/lib/enigma2/python/Plugins/Extensions/IMDb/starsbar_filled.png" transparent="1" />
98                 </screen>"""
99
100         def __init__(self, session, eventName, args = None):
101                 self.skin = IMDB.skin
102                 Screen.__init__(self, session)
103
104                 self.eventName = eventName
105
106                 self.dictionary_init()
107
108                 self["poster"] = Pixmap()
109                 self.picload = ePicLoad()
110                 self.picload.PictureData.get().append(self.paintPosterPixmapCB)
111
112                 self["stars"] = ProgressBar()
113                 self["starsbg"] = Pixmap()
114                 self["stars"].hide()
115                 self["starsbg"].hide()
116                 self.ratingstars = -1
117
118                 self["titellabel"] = Label("The Internet Movie Database")
119                 self["detailslabel"] = ScrollLabel("")
120                 self["castlabel"] = ScrollLabel("")
121                 self["extralabel"] = ScrollLabel("")
122                 self["statusbar"] = Label("")
123                 self["ratinglabel"] = Label("")
124                 self.resultlist = []
125                 self["menu"] = MenuList(self.resultlist)
126                 self["menu"].hide()
127
128                 self["key_red"] = Button(self._("Exit"))
129                 self["key_green"] = Button("")
130                 self["key_yellow"] = Button("")
131                 self["key_blue"] = Button("")
132
133                 # 0 = multiple query selection menu page
134                 # 1 = movie info page
135                 # 2 = extra infos page
136                 self.Page = 0
137
138                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MovieSelectionActions", "DirectionActions"],
139                 {
140                         "ok": self.showDetails,
141                         "cancel": self.close,
142                         "down": self.pageDown,
143                         "up": self.pageUp,
144                         "red": self.close,
145                         "green": self.showMenu,
146                         "yellow": self.showDetails,
147                         "blue": self.showExtras,
148                         "contextMenu": self.openChannelSelection,
149                         "showEventInfo": self.showDetails
150                 }, -1)
151
152                 self.getIMDB()
153
154         def dictionary_init(self):
155                 syslang = language.getLanguage()
156                 if syslang.find("de") is -1:
157                         self.IMDBlanguage = ""  # set to empty ("") for english version
158                 else:
159                         self.IMDBlanguage = "german." # it's a subdomain, so add a '.' at the end
160
161                 self.dict = {}
162                 self.dict["of"]="von"
163                 self.dict[" as "]=" als "
164                 self.dict["Ambiguous results"]="Kein eindeutiger Treffer"
165                 self.dict["Please select the matching entry"]="Bitte passenden Eintrag auswählen"
166                 self.dict["No IMDb match."]="Keine passenden Einträge gefunden."
167                 self.dict["IMDb query failed!"]="IMDb-Query fehlgeschlagen!"
168                 self.dict["No details found."]="Keine Details gefunden."
169                 self.dict["no user rating yet"]="noch keine Nutzerwertung"
170                 self.dict["Cast: "]="Darsteller: "
171                 self.dict["No cast list found in the database."]="Keine Darstellerliste in der Datenbank gefunden."
172                 self.dict["Exit"]="Beenden"
173                 self.dict["Extra Info"]="Zusatzinfos"
174                 self.dict["Title Menu"]="Titelauswahl"
175
176                 self.htmltags = re.compile('<.*?>')
177
178                 self.generalinfomask = re.compile(
179                 '<h1>(?P<title>.*?) <.*?</h1>.*?'
180                 '(?:.*?<h5>(?P<g_director>Regisseur|Directors?):</h5>.*?>(?P<director>.*?)</a>)*'
181                 '(?:.*?<h5>(?P<g_creator>Sch\S*?pfer|Creators?):</h5>.*?>(?P<creator>.*?)</a>)*'
182                 '(?:.*?<h5>(?P<g_seasons>Seasons):</h5>(?:.*?)<a href=\".*?\">(?P<seasons>\d+?)</a>\s+?(?:<a class|\|\s+?<a href="episodes#season-unknown))*'
183                 '(?:.*?<h5>(?P<g_writer>Drehbuch|Writer).*?</h5>.*?>(?P<writer>.*?)</a>)*'
184                 '(?:.*?<h5>(?P<g_premiere>Premiere|Release Date).*?</h5>\s.*?\n?(?P<premiere>.*?)\n\s.*?<)*'
185                 '(?:.*?<h5>(?P<g_alternativ>Alternativ|Also Known As):</h5>(?P<alternativ>.*?)<br>\s{0,8}<a.*?>(?:mehr|more))*'
186                 '(?:.*?<h5>(?P<g_country>Produktionsland|Country):</h5>.*?<a.*?>(?P<country>.*?)</a>(?:.*?mehr|\n</div>))*'
187                 , re.DOTALL)
188
189                 self.extrainfomask = re.compile(
190                 '(?:.*?<h5>(?P<g_tagline>Werbezeile|Tagline?):</h5>\n(?P<tagline>.+?)<)*'
191                 '(?:.*?<h5>(?P<g_outline>Kurzbeschreibung|Plot Outline):</h5>(?P<outline>.+?)<)*'
192                 '(?:.*?<h5>(?P<g_synopsis>Plot Synopsis):</h5>(?:.*?)(?:<a href=\".*?\">)*?(?P<synopsis>.+?)(?:</a>|</div>))*'
193                 '(?:.*?<h5>(?P<g_keywords>Plot Keywords):</h5>(?P<keywords>.+?)(?:mehr|more</a>|</div>))*'
194                 '(?:.*?<h5>(?P<g_awards>Filmpreise|Awards):</h5>(?P<awards>.+?)(?:mehr|more</a>|</div>))*'
195                 '(?:.*?<h5>(?P<g_runtime>L\S*?nge|Runtime):</h5>(?P<runtime>.+?)<)*'
196                 '(?:.*?<h5>(?P<g_language>Sprache|Language):</h5>(?P<language>.+?)</div>)*'
197                 '(?:.*?<h5>(?P<g_color>Farbe|Color):</h5>(?P<color>.+?)</div>)*'
198                 '(?:.*?<h5>(?P<g_aspect>Seitenverh\S*?ltnis|Aspect Ratio):</h5>(?P<aspect>.+?)(?:mehr|more</a>|</div>))*'
199                 '(?:.*?<h5>(?P<g_sound>Tonverfahren|Sound Mix):</h5>(?P<sound>.+?)</div>)*'
200                 '(?:.*?<h5>(?P<g_cert>Altersfreigabe|Certification):</h5>(?P<cert>.+?)</div>)*'
201                 '(?:.*?<h5>(?P<g_locations>Drehorte|Filming Locations):</h5>(?P<locations>.+?)(?:mehr|more</a>|</div>))*'
202                 '(?:.*?<h5>(?P<g_company>Firma|Company):</h5>(?P<company>.+?)(?:mehr|more</a>|</div>))*'
203                 '(?:.*?<h5>(?P<g_trivia>Dies und das|Trivia):</h5>(?P<trivia>.+?)(?:mehr|more</a>|</div>))*'
204                 '(?:.*?<h5>(?P<g_goofs>Pannen|Goofs):</h5>(?P<goofs>.+?)(?:mehr|more</a>|</div>))*'
205                 '(?:.*?<h5>(?P<g_quotes>Dialogzitate|Quotes):</h5>(?P<quotes>.+?)(?:mehr|more</a>|</div>))*'
206                 '(?:.*?<h5>(?P<g_connections>Bez\S*?ge zu anderen Titeln|Movie Connections):</h5>(?P<connections>.+?)(?:mehr|more</a>|</div>))*'
207                 '(?:.*?<h3>(?P<g_comments>Nutzerkommentare|User Comments)</h3>.*?<a href="/user/ur\d{7,7}/comments">(?P<commenter>.+?)\n</div>.*?<p>(?P<comment>.+?)</p>)*'
208                 , re.DOTALL)
209
210         def _(self, in_string):
211                 out_string = in_string
212                 if ((self.IMDBlanguage).find("german")) != -1:
213                         out_string = self.dict.get(in_string, in_string)
214                 return out_string
215
216         def resetLabels(self):
217                 self["detailslabel"].setText("")
218                 self["ratinglabel"].setText("")
219                 self["titellabel"].setText("")
220                 self["castlabel"].setText("")
221                 self["titellabel"].setText("")
222                 self["extralabel"].setText("")
223                 self.ratingstars = -1
224
225         def pageUp(self):
226                 if self.Page == 0:
227                         self["menu"].instance.moveSelection(self["menu"].instance.moveUp)
228                 if self.Page == 1:
229                         self["castlabel"].pageUp()
230                         self["detailslabel"].pageUp()
231                 if self.Page == 2:
232                         self["extralabel"].pageUp()
233
234         def pageDown(self):
235                 if self.Page == 0:
236                         self["menu"].instance.moveSelection(self["menu"].instance.moveDown)
237                 if self.Page == 1:
238                         self["castlabel"].pageDown()
239                         self["detailslabel"].pageDown()
240                 if self.Page == 2:
241                         self["extralabel"].pageDown()
242
243         def showMenu(self):
244                 if ( self.Page is 1 or self.Page is 2 ) and self.resultlist:
245                         self["menu"].show()
246                         self["stars"].hide()
247                         self["starsbg"].hide()
248                         self["ratinglabel"].hide()
249                         self["castlabel"].hide()
250                         self["poster"].hide()
251                         self["extralabel"].hide()
252                         self["titellabel"].setText(self._("Ambiguous results"))
253                         self["detailslabel"].setText(self._("Please select the matching entry"))
254                         self["detailslabel"].show()
255                         self["key_blue"].setText("")
256                         self["key_green"].setText(self._("Title Menu"))
257                         self["key_yellow"].setText(self._("Details"))
258                         self.Page = 0
259
260         def showDetails(self):
261                 self["ratinglabel"].show()
262                 self["castlabel"].show()
263                 self["detailslabel"].show()
264
265                 if self.resultlist and self.Page == 0:
266                         link = self["menu"].getCurrent()[1]
267                         title = self["menu"].getCurrent()[0]
268                         self["statusbar"].setText("Re-Query IMDb: "+title+"...")
269                         localfile = "/tmp/imdbquery2.html"
270                         fetchurl = "http://" + self.IMDBlanguage + "imdb.com/title/" + link
271                         print "[IMDB] downloading query " + fetchurl + " to " + localfile
272                         downloadPage(fetchurl,localfile).addCallback(self.IMDBquery2).addErrback(self.fetchFailed)
273                         self["menu"].hide()
274                         self.resetLabels()
275                         self.Page = 1
276
277                 if self.Page == 2:
278                         self["extralabel"].hide()
279                         self["poster"].show()
280                         if self.ratingstars > 0:
281                                 self["starsbg"].show()
282                                 self["stars"].show()
283                                 self["stars"].setValue(self.ratingstars)
284
285                         self.Page = 1
286
287         def showExtras(self):
288                 if self.Page == 1:
289                         self["extralabel"].show()
290                         self["detailslabel"].hide()
291                         self["castlabel"].hide()
292                         self["poster"].hide()
293                         self["stars"].hide()
294                         self["starsbg"].hide()
295                         self["ratinglabel"].hide()
296                         self.Page = 2
297
298         def openChannelSelection(self):
299                 self.session.openWithCallback(
300                         self.channelSelectionClosed,
301                         IMDBChannelSelection
302                 )
303
304         def channelSelectionClosed(self, ret = None):
305                 if ret:
306                         self.eventName = ret
307                         self.getIMDB()
308
309         def getIMDB(self):
310                 self.resetLabels()
311                 if self.eventName is "":
312                         s = self.session.nav.getCurrentService()
313                         info = s.info()
314                         event = info.getEvent(0) # 0 = now, 1 = next
315                         if event:
316                                 self.eventName = event.getEventName()
317                 if self.eventName is not "":
318                         self["statusbar"].setText("Query IMDb: " + self.eventName + "...")
319                         event_quoted = urllib.quote(self.eventName.decode('utf8').encode('latin-1','ignore'))
320                         localfile = "/tmp/imdbquery.html"
321                         fetchurl = "http://" + self.IMDBlanguage + "imdb.com/find?q=" + event_quoted + "&s=tt&site=aka"
322                         print "[IMDB] Downloading Query " + fetchurl + " to " + localfile
323                         downloadPage(fetchurl,localfile).addCallback(self.IMDBquery).addErrback(self.fetchFailed)
324                 else:
325                         self["statusbar"].setText("Could't get Eventname -_-")
326
327         def fetchFailed(self,string):
328                 print "[IMDB] fetch failed " + string
329                 self["statusbar"].setText("IMDb Download failed -_-")
330
331         def html2utf8(self,in_html):
332                 htmlentitynumbermask = re.compile('(&#(\d{1,5}?);)')
333                 htmlentitynamemask = re.compile('(&(\D{1,5}?);)')
334
335                 entities = htmlentitynamemask.finditer(in_html)
336                 entitydict = {}
337
338                 for x in entities:
339                         entitydict[x.group(1)] = x.group(2)
340
341                 for key, name in entitydict.items():
342                         entitydict[key] = htmlentitydefs.name2codepoint[name]
343
344                 entities = htmlentitynumbermask.finditer(in_html)
345
346                 for x in entities:
347                         entitydict[x.group(1)] = x.group(2)
348
349                 for key, codepoint in entitydict.items():
350                         in_html = in_html.replace(key, (unichr(int(codepoint)).encode('latin-1')))
351
352                 self.inhtml = in_html.decode('latin-1').encode('utf8')
353
354         def IMDBquery(self,string):
355                 print "[IMDBquery]"
356                 self["statusbar"].setText("IMDb Download completed")
357
358                 self.html2utf8(open("/tmp/imdbquery.html", "r").read())
359
360                 self.generalinfos = self.generalinfomask.search(self.inhtml)
361
362                 if self.generalinfos:
363                         self.IMDBparse()
364                 else:
365                         if re.search("<title>(?:IMDb.{0,9}Search|IMDb Titelsuche)</title>", self.inhtml):
366                                 searchresultmask = re.compile("<tr> <td.*?img src.*?>.*?<a href=\".*?/title/(tt\d{7,7})/\".*?>(.*?)</td>", re.DOTALL)
367                                 searchresults = searchresultmask.finditer(self.inhtml)
368                                 self.resultlist = []
369                                 if searchresults:
370                                         for x in searchresults:
371                                                 self.resultlist.append((self.htmltags.sub('',x.group(2)), x.group(1)))
372                                         self["menu"].l.setList(self.resultlist)
373                                 if len(self.resultlist) > 1:
374                                         self.Page = 1
375                                         self.showMenu()
376                                 else:
377                                         self["detailslabel"].setText(self._("No IMDb match."))
378                                         self["statusbar"].setText("No IMDb match")
379                         else:
380                                 splitpos = self.eventName.find('(')
381                                 if splitpos > 0 and self.eventName.endswith(')'):
382                                         self.eventName = self.eventName[splitpos+1:-1]
383                                         self["statusbar"].setText("Re-Query IMDb: " + self.eventName + "...")
384                                         event_quoted = urllib.quote(self.eventName.decode('utf8').encode('latin-1','ignore'))
385                                         localfile = "/tmp/imdbquery.html"
386                                         fetchurl = "http://" + self.IMDBlanguage + "imdb.com/find?q=" + event_quoted + "&s=tt&site=aka"
387                                         print "[IMDB] Downloading Query " + fetchurl + " to " + localfile
388                                         downloadPage(fetchurl,localfile).addCallback(self.IMDBquery).addErrback(self.fetchFailed)
389                                 else:
390                                         self["detailslabel"].setText(self._("IMDb query failed!"))
391
392         def IMDBquery2(self,string):
393                 self["statusbar"].setText("IMDb Re-Download completed")
394                 self.html2utf8(open("/tmp/imdbquery2.html", "r").read())
395                 self.generalinfos = self.generalinfomask.search(self.inhtml)
396                 self.IMDBparse()
397
398         def IMDBparse(self):
399                 print "[IMDBparse]"
400                 self.Page = 1
401                 Detailstext = self._("No details found.")
402                 if self.generalinfos:
403                         self["key_yellow"].setText(self._("Details"))
404                         self["statusbar"].setText("IMDb Details parsed ^^")
405                         Titeltext = self.generalinfos.group("title")
406                         if len(Titeltext) > 57:
407                                 Titeltext = Titeltext[0:54] + "..."
408                         self["titellabel"].setText(Titeltext)
409
410                         Detailstext = ""
411
412                         genreblockmask = re.compile('<h5>Genre:</h5>(.*?)(?:mehr|more|</div>)', re.DOTALL)
413                         genreblock = genreblockmask.findall(self.inhtml)
414                         genremask = re.compile('(?:\">|\s)(.*?)(?:</a|\s)')
415                         if genreblock:
416                                 genres = genremask.finditer(genreblock[0])
417                                 if genres:
418                                         Detailstext += "Genre: "
419                                         for x in genres:
420                                                 Detailstext += x.group(1) + " "
421                         detailscategories = ["director", "creator", "writer", "premiere", "seasons", "country"]
422
423                         for category in detailscategories:
424                                 if self.generalinfos.group('g_'+category):
425                                         Detailstext += "\n" + self.generalinfos.group('g_'+category) + ": " + self.generalinfos.group(category)
426
427                         if self.generalinfos.group("alternativ"):
428                                 Detailstext += "\n" + self.generalinfos.group("g_alternativ") + ": " + self.htmltags.sub('',(self.generalinfos.group("alternativ").replace('\n','').replace("<br>",'\n').replace("  ",' ')))
429
430                         ratingmask = re.compile('<h5>(?P<g_rating>Nutzer-Bewertung|User Rating):</h5>.*?<b>(?P<rating>.*?)/10</b>', re.DOTALL)
431                         rating = ratingmask.search(self.inhtml)
432                         Ratingtext = self._("no user rating yet")
433                         if rating:
434                                 Ratingtext = rating.group("g_rating") + ": " + rating.group("rating") + " / 10"
435                                 self.ratingstars = int(10*round(float(rating.group("rating").replace(',','.')),1))
436                                 self["stars"].show()
437                                 self["stars"].setValue(self.ratingstars)
438                                 self["starsbg"].show()
439                         self["ratinglabel"].setText(Ratingtext)
440                         castmask = re.compile('<td class="nm">.*?>(.*?)</a>.*?<td class="char">(?:<a.*?>)?(.*?)(?:</a>)?</td>', re.DOTALL)
441                         castresult = castmask.finditer(self.inhtml)
442                         if castresult:
443                                 Casttext = ""
444                                 for x in castresult:
445                                         Casttext += "\n" + self.htmltags.sub('', x.group(1))
446                                         if x.group(2):
447                                                 Casttext += self._(" als ") + self.htmltags.sub('', x.group(2).replace('/ ...',''))
448                                 if Casttext is not "":
449                                         Casttext = self._("Cast: ") + Casttext
450                                 else:
451                                         Casttext = self._("No cast list found in the database.")
452                                 self["castlabel"].setText(Casttext)
453                         postermask = re.compile('<div class="photo">.*?<img .*? src=\"(http.*?)\" .*?>', re.DOTALL)
454                         posterurl = postermask.search(self.inhtml)
455                         if posterurl and posterurl.group(1).find("jpg") > 0:
456                                 posterurl = posterurl.group(1)
457                                 self["statusbar"].setText("Downloading Movie Poster: "+posterurl+"...")
458                                 localfile = "/tmp/poster.jpg"
459                                 print "[IMDB] downloading poster " + posterurl + " to " + localfile
460                                 downloadPage(posterurl,localfile).addCallback(self.IMDBPoster).addErrback(self.fetchFailed)
461                         else:
462                                 self.IMDBPoster("kein Poster")
463                         extrainfos = self.extrainfomask.search(self.inhtml)
464
465                         if extrainfos:
466                                 Extratext = "Extra Info\n"
467                                 extracategories = ["tagline","outline","synopsis","keywords","awards","runtime","language","color","aspect","sound","cert","locations","company","trivia","goofs","quotes","connections"]
468
469                                 for category in extracategories:
470                                         if extrainfos.group('g_'+category):
471                                                 Extratext += extrainfos.group('g_'+category) + ": " + self.htmltags.sub('',extrainfos.group(category).replace("\n",'').replace("<br>",'\n')) + "\n"
472                                 if extrainfos.group("g_comments"):
473                                         Extratext += extrainfos.group("g_comments") + " [" + self.htmltags.sub('',extrainfos.group("commenter")) + "]: " + self.htmltags.sub('',extrainfos.group("comment").replace("\n",' ')) + "\n"
474
475                                 self["extralabel"].setText(Extratext)
476                                 self["extralabel"].hide()
477                                 self["key_blue"].setText(self._("Extra Info"))
478
479                 self["detailslabel"].setText(Detailstext)
480
481         def IMDBPoster(self,string):
482                 self["statusbar"].setText("IMDb Details parsed ^^")
483                 if not string:
484                         filename = "/tmp/poster.jpg"
485                 else:
486                         filename = resolveFilename(SCOPE_PLUGINS, "Extensions/IMDb/no_poster.png")
487                 sc = AVSwitch().getFramebufferScale()
488                 self.picload.setPara((self["poster"].instance.size().width(), self["poster"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
489                 self.picload.startDecode(filename)
490
491         def paintPosterPixmapCB(self, picInfo=None):
492                 ptr = self.picload.getData()
493                 if ptr != None:
494                         self["poster"].instance.setPixmap(ptr.__deref__())
495                         self["poster"].show()
496
497         def createSummary(self):
498                 return IMDbLCDScreen
499
500 class IMDbLCDScreen(Screen):
501         skin = """
502         <screen position="0,0" size="132,64" title="IMDB Plugin">
503                 <widget name="headline" position="4,0" size="128,22" font="Regular;20"/>
504                 <widget source="session.Event_Now" render="Label" position="6,26" size="120,34" font="Regular;14" >
505                         <convert type="EventName">Name</convert>
506                 </widget>
507         </screen>"""
508
509         def __init__(self, session, parent):
510                 Screen.__init__(self, session)
511                 self["headline"] = Label("IMDB Plugin")
512
513 def eventinfo(session, servicelist, **kwargs):
514         ref = session.nav.getCurrentlyPlayingServiceReference()
515         session.open(IMDBEPGSelection, ref)
516
517 def main(session, eventName="", **kwargs):
518         session.open(IMDB, eventName)
519
520 def Plugins(**kwargs):
521         try:
522                 return [PluginDescriptor(name="IMDb Details",
523                                 description=_("Query details from the Internet Movie Database"),
524                                 icon="imdb.png",
525                                 where = PluginDescriptor.WHERE_PLUGINMENU,
526                                 fnc = main),
527                                 PluginDescriptor(name="IMDb Details",
528                                 description=_("Query details from the Internet Movie Database"),
529                                 where = PluginDescriptor.WHERE_EVENTINFO,
530                                 fnc = eventinfo)
531                                 ]
532         except AttributeError:
533                 wherelist = [PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU]
534                 return PluginDescriptor(name="IMDb Details",
535                                 description=_("Query details from the Internet Movie Database"),
536                                 icon="imdb.png",
537                                 where = wherelist,
538                                 fnc=main)