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

Legend:
Removed from v.1647  
changed lines
  Added in v.3209

  ViewVC Help
Powered by ViewVC 1.1.20