/[projects]/misc/xbmc/plugin.video.todic/default.py
ViewVC logotype

Diff of /misc/xbmc/plugin.video.todic/default.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1646 by torben, Sat Dec 3 12:01:56 2011 UTC revision 3211 by torben, Mon Sep 18 18:06:48 2017 UTC
# Line 1  Line 1 
1    
2    # This Python file uses the following encoding: utf-8
3    
4  '''  '''
5      Todic plugin for XBMC      Todic plugin for XBMC
6      Version 0.0.2      Version 1.7
7  '''  '''
8    
9  import sys  import sys
10  import cgi as urlparse  import os
11    
12    
13  import xbmc  import xbmc
14  import xbmcaddon  import xbmcaddon
15  import xbmcgui  import xbmcgui
16  import xbmcplugin  import xbmcplugin
17  import urllib  import urllib
18  import urllib2, re  import urllib2
19    
20    # import pprint
21    
22    from xml.dom.minidom import parseString
23    from time import time
24    
25  __addon__ = xbmcaddon.Addon(id='plugin.video.todic')  __addon__ = xbmcaddon.Addon(id='plugin.video.todic')
26  __key__ = __addon__.getSetting('xbmckey').lower()  __key__ = __addon__.getSetting('xbmckey').lower()
27  __backend__ = "http://todic.dk/xbmc.php?xbmckey=" + __key__  __entrypoint__ = __addon__.getSetting('entrypoint').lower()
28    __backend__ = "https://todic.dk/xbmc.php?xbmckey=" + __key__
29    
30    if __entrypoint__ == "alternative":
31            __backend__ = "https://alt.todic.dk/xbmc.php?xbmckey=" + __key__
32    
33    if __entrypoint__ == "testing":
34            __backend__ = "https://todic.dk/xbmc-beta.php?xbmckey=" + __key__
35            
36    print "[Todic] entrypoint: " + __entrypoint__
37    print "[Todic] backend: " + __backend__
38    
39    
40    fanartImage = os.path.join(__addon__.getAddonInfo('path'), 'movie_bg_blur.jpg')
41    datapath = xbmc.translatePath(
42        'special://profile/addon_data/plugin.video.todic/')
43    
44    ADDON_PATH = __addon__.getAddonInfo('path')
45    SkinMasterPath = os.path.join(ADDON_PATH, 'skins') + '/'
46    MySkinPath = (os.path.join(SkinMasterPath, '720p')) + '/'
47    MySkin = 'main.xml'
48    
49    
50    class TodicMovieDialog(xbmcgui.WindowXMLDialog):
51    
52        def __new__(cls):
53            return super(TodicMovieDialog, cls).__new__(cls, "main.xml", ADDON_PATH)
54    
55        def __init__(self):
56            super(TodicMovieDialog, self).__init__()
57            self.position = 0
58    
59        def onClick(self, controlId):
60            print "[Todic] MovieDialog OnClick: " + str(controlId)
61    
62            if (controlId == 50):
63                self.close()
64                play_real_video(self.url, self.name, 0)
65    
66            if (controlId == 51):
67                self.close()
68                play_real_video(self.url, self.name, self.position)
69    
70            if (controlId == 98):
71                self.close()
72    
73        def onInit(self):
74    
75            print "[Todic] MovieDialog onInit"
76            self.getControl(1).setLabel(self.name)
77            self.getControl(2).setLabel(self.moviegroups)
78            self.getControl(3).setLabel(self.description)
79            self.getControl(10).setLabel(self.playlength)
80            self.getControl(11).setLabel(self.codecdetails)
81    
82            if (self.position > 0):
83                self.getControl(51).setVisible(True)
84                self.getControl(50).setPosition(100, 570)
85                self.getControl(51).setPosition(450, 570)
86                self.getControl(50).controlLeft( self.getControl(51) )
87                self.getControl(50).controlRight( self.getControl(51) )
88            else:
89                self.getControl(51).setVisible(False)
90    
91            #orig_img_width = self.getControl(40).getWidth()
92            #self.starwidth = (float(self.imdbrating) / 10.0) * orig_img_width
93            #self.getControl(40).setWidth(int(self.starwidth))
94    
95        def setDetailsDoc(self, detailsDoc):
96            print "[Todic] MovieDialog setDetailsDoc:"
97            self.imdbrating = getText(detailsDoc.getElementsByTagName("imdbrating"))
98            self.moviegroups = getText(detailsDoc.getElementsByTagName("moviegroups"))
99            self.playlength = getText(detailsDoc.getElementsByTagName("playlength"))
100            self.codecdetails = getText(detailsDoc.getElementsByTagName("codecdetails"))
101            self.position = int( getText(detailsDoc.getElementsByTagName("position")) )
102    
103        def setUrl(self, url):
104            self.url = url
105    
106        def setName(self, name):
107            self.name = name
108    
109        def setDescription(self, description):
110            self.description = description
111    
112    
113    class TodicPlayer(xbmc.Player):
114    
115        def __init__(self, *args, **kwargs):
116            # xbmc.Player.__init__(selv,*args,**kwargs)
117            xbmc.Player.__init__(self)
118            self.stopped = False
119            self.started = False
120            self.playingPosition = 0.0
121            self.lastReport = 0
122            print "[TodicPlayer] init"
123    
124        def onPlayBackStarted(self):
125            self.started = True
126            print "[TodicPlayer] : started"
127    
128        #When user presses stop, we report back the the position registered in the last call to self.tick()
129        def onPlayBackStopped(self):
130            self.stopped = True
131            print "[TodicPlayer] : stopped"
132            self.reportPlaytime("stopped")
133    
134        def onPlayBackPaused(self):
135            print "[TodicPlayer] : paused"
136            self.reportPlaytime("paused")
137    
138        def onPlayBackResumed(self):
139            print "[TodicPlayer] : resumed"
140            self.reportPlaytime("resumed")
141    
142    
143        def onPlayBackEnded(self):
144            self.stopped = True
145            print "[TodicPlayer] : ended"
146            self.reportPlaytime("ended")
147    
148        def tick(self):
149            #print "[Todic] Tick: " + str( self.isPlaying() )
150            if ( self.isPlaying() ):
151                self.playingPosition = self.getTime()
152                now = time()
153                #print "[Todic] tick " + str(now) + " " + str(self.lastReport) + " : " +str(now - self.lastReport)
154                if ( (now - self.lastReport) > 60.0):
155                    self.lastReport = now
156                    self.reportPlaytime("playing")
157    
158        def reportPlaytime(self, subaction):
159            if (self.playingPosition > 60):
160                url = __backend__ + "&action=playbacktime&subaction=" + subaction + "&time=" + str( self.playingPosition )
161                print "[Todic] reportPlaytime:" + url
162                open_url_safe(url)
163    
164    
165    
166    def getText2(nodelist):
167        rc = []
168        for node in nodelist:
169            if node.nodeType == node.TEXT_NODE:
170                rc.append(node.data)
171            else:
172                rc.append(getText(node.childNodes))
173        return ''.join(rc)
174    
175    
176    def getText(nodelist):
177        if nodelist.length == 0:
178            return ''
179        else:
180            if nodelist[0].childNodes.length == 0:
181                return ''
182            else:
183                return nodelist[0].childNodes[0].nodeValue
184    
185    
186    
187    def SaveFile(path, data):
188        file = open(path, 'w')
189        file.write(data)
190        file.close()
191    
192    
193    
194  def open_url(url):  def open_url(url):
195          req = urllib2.Request(url)      req = urllib2.Request(url)
196          content = urllib2.urlopen(req)      content = urllib2.urlopen(req)
197          data = content.read()      data = content.read()
198          content.close()      content.close()
199          return data      return data
200    
201    
202    # wraps open url in a catch-all exception handler
203    # usefull for periodic back-reporting that should not interrupt the program flow
204    def open_url_safe(url):
205        try:
206            return open_url(url)
207        except:
208            print "[Todic] Some error during open_url call to ", url
209    
210    
211    
212  def rootMenu():  def rootMenu():
         link = open_url(__backend__)  
         m=re.compile('<title>(.+?)</title><url>(.+?)</url>').findall(link)  
         l = len(m)  
         for name,url in m:  
                 listitem = xbmcgui.ListItem(label = name, iconImage = 'DefaultFolder.png', thumbnailImage = 'DefaultFolder.png')  
                 u = sys.argv[0] + "?mode=1&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(url)  
                 ok = xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = u, listitem = listitem, isFolder = True, totalItems = l)  
   
         listitem = xbmcgui.ListItem(label = "Søg film ...", iconImage = 'DefaultFolder.png', thumbnailImage = 'DefaultFolder.png')  
         u = sys.argv[0] + "?mode=10&name=" + urllib.quote_plus(name)  
         ok = xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = u, listitem = listitem, isFolder = True, totalItems = l)  
   
         xbmcplugin.endOfDirectory(int(sys.argv[1]))  
   
   
 def buildList(url,title):  
         print '[TODIC]:'+str(url)          
         link = open_url(url)  
         ty=re.compile('<meta type=\'(.+?)\'').findall(link)  
         print '[TODIC]'+str(ty[0])  
   
         if ty[0] == 'clipList':  
                 mode = '50'  
                 folder = False  
         else:  
                 mode = '1'  
                 folder = True  
213    
214          m=re.compile('<title>(.+?)</title><url>(.+?)</url><cover>(.+?)</cover>').findall(link)      msg = open_url(__backend__ + "&action=messages")
215          l=len(m)      msg = msg.strip()
         for name,url,thumb in m:                          
                 listitem = xbmcgui.ListItem(label = name, iconImage = 'DefaultFolder.png', thumbnailImage = thumb)  
                 u = sys.argv[0] + "?mode=" + urllib.quote_plus(mode) + "&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(url)  
                 ok = xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = u, listitem = listitem, isFolder = folder, totalItems = l)  
         xbmcplugin.endOfDirectory(int(sys.argv[1]))  
216    
217        if msg != "":
218            dialog = xbmcgui.Dialog()
219            dialog.ok('XBMC Todic', msg)
220    
221        buildList(__backend__, "", False)  # call default list
222    
223        # Adde xtra items to root menu
224        listitem = xbmcgui.ListItem(
225            label="Søg Film ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
226        listitem.setProperty('Fanart_Image', fanartImage)
227    
228        u = sys.argv[0] + "?mode=10&name="
229        xbmcplugin.addDirectoryItem(
230            handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
231    
232        # add search series
233        listitem = xbmcgui.ListItem(
234            label="Søg Serier ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
235        listitem.setProperty('Fanart_Image', fanartImage)
236    
237        u = sys.argv[0] + "?mode=11&name="
238        xbmcplugin.addDirectoryItem(
239            handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
240    
241        xbmcplugin.endOfDirectory(int(sys.argv[1]))
242    
243    
244    def buildList(url, title, endlist=True):
245        print '[Todic]:' + str(url)
246    
247        link = open_url(url)
248        doc = parseString(link)
249        ty = doc.getElementsByTagName("meta")[0].getAttribute("type")
250        print '[Todic]' + str(ty)
251    
252        if ty == 'clipList':
253            mode = '50'
254            folder = False
255        else:
256            mode = '1'
257            folder = True
258    
259        entries = doc.getElementsByTagName("entry")
260        l = len(entries)
261    
262        for entry in entries:
263            name = getText(entry.getElementsByTagName("title"))
264            url = getText(entry.getElementsByTagName("url"))
265            thumb = getText(entry.getElementsByTagName("cover"))
266            playcount = getText(entry.getElementsByTagName("playcount"))
267    
268    
269            if playcount == '':
270                playcount = '0'
271            playcount = int(playcount)
272    
273    # print "name:" + name
274    #               print "url:" + url
275    #               print "thumb:" + thumb
276            listitem = xbmcgui.ListItem(
277                label=name, label2='test', iconImage='DefaultFolder.png', thumbnailImage=thumb)
278            listitem.setProperty('Fanart_Image', fanartImage)
279            if mode == '50':
280                infoLabels = {}
281                infoLabels['title'] = name
282                infoLabels['playcount'] = playcount
283                listitem.setInfo('video', infoLabels)
284    
285            name = name.encode('UTF-8')
286    
287            u = sys.argv[0] + "?mode=" + urllib.quote(mode) + "&name=" + urllib.quote(
288                name) + "&url=" + urllib.quote(url)
289            xbmcplugin.addDirectoryItem(
290                handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)
291    
292        if (endlist == True):
293            xbmcplugin.endOfDirectory(int(sys.argv[1]))
294    
295    
296  def play_video(url, name):  def play_video(url, name):
297          link = open_url(url)      description = ""
298          match=re.compile('<url>(.+?)</url>').findall(link)      playPosition = 0
299          url = match[0]      savedPosition = 0
300          print '[TODIC]:'+str(url)      try:
301          image = xbmc.getInfoImage( 'ListItem.Thumb' )          param1 = parse_parameter_string(url)
302          listitem = xbmcgui.ListItem(label = name , iconImage = 'DefaultVideo.png', thumbnailImage = image)          clipkey = param1["clipkey"]
303  #       listitem = xbmcgui.ListItem(label = name , iconImage = 'DefaultVideo.png', thumbnailImage = 'DefaultVideo.png')  
304          listitem.setInfo( type = "Video", infoLabels={ "Title": name } )          print "[Todic] ClipKey:" + clipkey
305          xbmc.Player(xbmc.PLAYER_CORE_AUTO).play(str(url), listitem)          detailurl = __backend__ + "&action=clipdetails&clipkey=" + clipkey
306          xbmc.sleep(200)          print "[Todic] detailURL = " + detailurl
307    
308            xml = open_url(detailurl)
309    
310            clipDetailsDoc = parseString(xml)
311            savedPosition = int( getText(clipDetailsDoc.getElementsByTagName("position")) )
312            description = getText(clipDetailsDoc.getElementsByTagName("description"))
313        except:
314            print "[Todic] Unexpected error:", sys.exc_info()[0]
315    
316        if (description == None or description == ""):
317            if (savedPosition > 0):
318                dialog = xbmcgui.Dialog()
319                #yes / true -afspil fra position
320                answer = dialog.yesno(heading='Todic', line1='Afspil fra sidste position', nolabel='Fra start', yeslabel='Fortsæt')
321                if (answer == True):
322                    playPosition = savedPosition
323            
324            play_real_video(url, name, playPosition)
325    
326        else:
327            d = TodicMovieDialog()
328            d.setDetailsDoc(clipDetailsDoc)
329            d.setName(name)
330            d.setUrl(url)
331            d.setDescription(description)
332    
333            d.doModal()
334    
335    
336    def play_real_video(url, name, position):
337        xml = open_url(url)
338        print '[Todic] url: ' + str(url)
339        print '[Todic] xml: ' + xml
340        print '[Todic] pos: ' + str(position)
341    
342        doc = parseString(xml)
343        url = getText(doc.getElementsByTagName("url"))
344    
345        subtitleurl = getText(doc.getElementsByTagName("subtitles"))
346        subtitlesfile = os.path.join(datapath, 'temp.srt')
347    
348        # if old srt file exists delete it first
349        if os.path.isfile(subtitlesfile):
350            os.unlink(subtitlesfile)
351    
352        print '[Todic] subs: ' + str(subtitleurl)
353        if len(subtitleurl) > 0:
354            subtitles = open_url(subtitleurl)
355            SaveFile(subtitlesfile, subtitles)
356            print '[Todic] downloaded subtitles'
357    
358        image = xbmc.getInfoImage('ListItem.Thumb')
359        listitem = xbmcgui.ListItem(
360            label=name, iconImage='DefaultVideo.png', thumbnailImage=image)
361        listitem.setInfo(type="Video", infoLabels={"Title": name})
362        listitem.setProperty('ResumeTime', '300')
363        listitem.setProperty('TotalTime', '3000')
364    
365        player = TodicPlayer()
366        player.play(str(url), listitem)
367    
368        # kan ikke loade subtitles hvis foerend playeren koerer
369        count = 0
370        while not xbmc.Player().isPlaying():
371            xbmc.sleep(250)
372            count += 1
373            if count > 10:
374                break
375    
376    
377    
378        if xbmc.Player().isPlaying():
379            if os.path.isfile(subtitlesfile):
380                player.setSubtitles(subtitlesfile)
381                print '[Todic] started subtitles'
382            else:
383                player.showSubtitles(False)
384    
385    
386            if (position > 0):
387                while (player.getTotalTime() == 0.0): #Vent indtil vi har beregnet hvor langt klippet er
388                    xbmc.sleep(250)
389    
390                print "[Todic] totalTime " +  str( player.getTotalTime() )
391                player.seekTime(position)
392    
393    
394        #Holder python kørernde indtil at det bliver bedt om at stoppe
395        while (not xbmc.abortRequested):
396            player.tick()
397            xbmc.sleep(500)
398    
399    
400    
401  def search():  def search():
402          search = getUserInput("Todic Søgning")      search = getUserInput("Todic Søgning")
403    
404          if (search != None and search != ""):      if (search != None and search != ""):
405                  url = __backend__ + "&action=search&search=" + urllib.quote_plus(search)          url = __backend__ + "&action=search&search=" + \
406                urllib.quote_plus(search)
407    
408                  #print "[TODIC] Search start: " + search          # print "[Todic] Search start: " + search
409                  #print "[TODIC] Search url: " + url          # print "[Todic] Search url: " + url
410    
411                  buildList(url, "søgning")          buildList(url, "søgning")
412    
           
413    
414    def searchSeries():
415        search = getUserInput("Todic Serie Søgning")
416    
417        if (search != None and search != ""):
418            url = __backend__ + "&action=searchseries&search=" + \
419                urllib.quote_plus(search)
420    
421                            # print "[Todic] Search start: " + search
422  #=================================== Tool Box =======================================          # print "[Todic] Search url: " + url
423    
424            buildList(url, "serie søgning")
425    
426    
427    #=================================== Tool Box =======================================
428  # shows a more userfriendly notification  # shows a more userfriendly notification
429  def showMessage(heading, message):  def showMessage(heading, message):
430          duration = 15*1000      duration = 15 * 1000
431          xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( heading, message, duration) )      xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
432                            (heading, message, duration))
433    
434    
435  # raise a keyboard for user input  # raise a keyboard for user input
436  def getUserInput(title = "Input", default="", hidden=False):  def getUserInput(title="Input", default="", hidden=False):
437          result = None      result = None
438    
439        # Fix for when this functions is called with default=None
440        if not default:
441            default = ""
442    
443        keyboard = xbmc.Keyboard(default, title)
444        keyboard.setHiddenInput(hidden)
445        keyboard.doModal()
446    
447          # Fix for when this functions is called with default=None      if keyboard.isConfirmed():
448          if not default:          result = keyboard.getText()
449                  default = ""  
450                                return result
         keyboard = xbmc.Keyboard(default, title)  
         keyboard.setHiddenInput(hidden)  
         keyboard.doModal()  
                   
         if keyboard.isConfirmed():  
                 result = keyboard.getText()  
                   
         return result  
451    
452    
453  def get_params():  def get_params():
454          param=[]      return parse_parameter_string(sys.argv[2])
455          paramstring=sys.argv[2]  
456          if len(paramstring)>=2:  
457                  params=sys.argv[2]  def parse_parameter_string(paramstring):
458                  cleanedparams=params.replace('?','')      param = []
459                  if (params[len(params)-1]=='/'):      if len(paramstring) >= 2:
460                          params=params[0:len(params)-2]          params = paramstring
461                  pairsofparams=cleanedparams.split('&')          cleanedparams = params.replace('?', '')
462                  param={}          if (params[len(params) - 1] == '/'):
463                  for i in range(len(pairsofparams)):              params = params[0:len(params) - 2]
464                          splitparams={}          pairsofparams = cleanedparams.split('&')
465                          splitparams=pairsofparams[i].split('=')          param = {}
466                          if (len(splitparams))==2:          for i in range(len(pairsofparams)):
467                                  param[splitparams[0]]=splitparams[1]                                                  splitparams = {}
468          return param              splitparams = pairsofparams[i].split('=')
469                if (len(splitparams)) == 2:
470                    param[splitparams[0]] = splitparams[1]
471        return param
472    
 params = get_params()  
 url = None  
 name = None  
 mode = None  
473    
474  params = get_params()  params = get_params()
475  url = None  url = None
476  name = None  name = None
477  mode = None  mode = None
478    
479    
480    #print params
481    
482  try:  try:
483          url = urllib.unquote_plus(params["url"])      url = urllib.unquote_plus(params["url"])
484  except:  except:
485          pass      pass
486  try:  try:
487          name = urllib.unquote_plus(params["name"])      name = urllib.unquote_plus(params["name"])
488  except:  except:
489          pass      pass
490  try:  try:
491          mode = int(params["mode"])      mode = int(params["mode"])
492  except:  except:
493          pass      pass
494    
495    
 if mode == None:  
         #build main menu  
         rootMenu()  
         
 elif mode == 1:  
         #build list of movie starting letters  
         buildList(url, name)  
496    
 elif mode == 10:  
         search()  
           
497    
498  elif mode == 50:  try:
499          play_video(url, name)      open_url("http://todic.dk")
500    except:
501        showMessage("Fejl", "Kunne ikke forbinde til todic.dk")
502        exit()
503    
504    
505    if url == 'refresh':
506        # xbmc.output("[tvserver] Container.Refresh") #20130418 xbmc.output virker
507        # ikke med XBMC12
508        xbmc.executebuiltin("Container.Refresh")
509    
510    
511  # xbmcplugin.endOfDirectory(int(sys.argv[1]))  elif mode == None:
512        # build main menu
513        rootMenu()
514    
515    elif mode == 1:
516        # build list of movie starting letters
517        buildList(url, name)
518    
519    elif mode == 10:
520        search()
521    
522    elif mode == 11:
523        searchSeries()
524    
525    
526    elif mode == 50:
527        play_video(url, name)

Legend:
Removed from v.1646  
changed lines
  Added in v.3211

  ViewVC Help
Powered by ViewVC 1.1.20