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