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