/[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 1632 by torben, Sun Nov 27 12:49:10 2011 UTC revision 3249 by torben, Thu Feb 28 10:40:52 2019 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.3
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                tmpTime = self.getTime()
152    
153                #only report time if it has changed in the mean time
154                if tmpTime != self.playingPosition:
155                    self.playingPosition = tmpTime
156                    now = time()
157                    #print "[Todic] tick " + str(now) + " " + str(self.lastReport) + " : " +str(now - self.lastReport)
158                    if ( (now - self.lastReport) > 60.0):
159                        self.lastReport = now
160                        self.reportPlaytime("playing")
161    
162        def reportPlaytime(self, subaction):
163            if (self.playingPosition > 60):
164                url = __backend__ + "&action=playbacktime&subaction=" + subaction + "&time=" + str( self.playingPosition )
165                print( "[Todic] reportPlaytime:" + url)
166                open_url_safe(url)
167    
168    
169    
170    def getText2(nodelist):
171        rc = []
172        for node in nodelist:
173            if node.nodeType == node.TEXT_NODE:
174                rc.append(node.data)
175            else:
176                rc.append(getText(node.childNodes))
177        return ''.join(rc)
178    
179    
180    def getText(nodelist):
181        if nodelist.length == 0:
182            return ''
183        else:
184            if nodelist[0].childNodes.length == 0:
185                return ''
186            else:
187                return nodelist[0].childNodes[0].nodeValue
188    
189    
190    
191    def SaveFile(path, data):
192        file = open(path, 'w')
193        file.write(data)
194        file.close()
195    
196    
197    
198  def open_url(url):  def open_url(url):
199          req = urllib2.Request(url)      req = urllib2.Request(url)
200          content = urllib2.urlopen(req)      content = urllib2.urlopen(req)
201          data = content.read()      data = content.read()
202          content.close()      content.close()
203          return data      return data
204    
205    
206    # wraps open url in a catch-all exception handler
207    # usefull for periodic back-reporting that should not interrupt the program flow
208    def open_url_safe(url):
209        try:
210            return open_url(url)
211        except:
212            print( "[Todic] Some error during open_url call to ", url)
213    
214    
215    
216  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 ...", 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 '[TOD]'+str(ty[0])  
         m=re.compile('<title>(.+?)</title><url>(.+?)</url><cover>(.+?)</cover>').findall(link)  
         l=len(m)  
         for name,url,thumb in m:  
                 if ty[0] == 'clipList':  
                         mode = '50'  
                         folder = False  
                 else:  
                         mode = '2'  
                         folder = True  
                           
                 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]))  
   
 def buildSubList(url,title):  
         print '[TODIC]:'+str(url)  
         link = open_url(url)  
         m=re.compile('<title>(.+?)</title><url>(.+?)</url><cover>(.+?)</cover>').findall(link)  
         l = len(m)  
         for name,url,thumb in m:  
                 listitem = xbmcgui.ListItem(label = name, iconImage = 'DefaultFolder.png', thumbnailImage = thumb)  
                 u = sys.argv[0] + "?mode=50&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(url)  
                 ok = xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = u, listitem = listitem, isFolder = False, totalItems = l)  
         xbmcplugin.endOfDirectory(int(sys.argv[1]))  
217    
218        msg = open_url(__backend__ + "&action=messages")
219        msg = msg.strip()
220    
221        if msg != "":
222            dialog = xbmcgui.Dialog()
223            dialog.ok('XBMC Todic', msg)
224    
225        buildList(__backend__, "", False)  # call default list
226    
227        # Adde xtra items to root menu
228        listitem = xbmcgui.ListItem(
229            label="Søg Film ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
230        listitem.setProperty('Fanart_Image', fanartImage)
231    
232        u = sys.argv[0] + "?mode=10&name="
233        xbmcplugin.addDirectoryItem(
234            handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
235    
236        # add search series
237        listitem = xbmcgui.ListItem(
238            label="Søg Serier ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
239        listitem.setProperty('Fanart_Image', fanartImage)
240    
241        u = sys.argv[0] + "?mode=11&name="
242        xbmcplugin.addDirectoryItem(
243            handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
244    
245        xbmcplugin.endOfDirectory(int(sys.argv[1]))
246    
247    
248    def buildList(url, title, endlist=True):
249        print( '[Todic]:' + str(url) )
250    
251        link = open_url(url)
252        doc = parseString(link)
253        ty = doc.getElementsByTagName("meta")[0].getAttribute("type")
254        print( '[Todic]' + str(ty))
255    
256        if ty == 'clipList':
257            mode = '50'
258            folder = False
259        else:
260            mode = '1'
261            folder = True
262    
263        entries = doc.getElementsByTagName("entry")
264        l = len(entries)
265    
266        for entry in entries:
267            name = getText(entry.getElementsByTagName("title"))
268            url = getText(entry.getElementsByTagName("url"))
269            thumb = getText(entry.getElementsByTagName("cover"))
270            playcount = getText(entry.getElementsByTagName("playcount"))
271    
272    
273            if playcount == '':
274                playcount = '0'
275            playcount = int(playcount)
276    
277    # print "name:" + name
278    #               print "url:" + url
279    #               print "thumb:" + thumb
280            listitem = xbmcgui.ListItem(
281                label=name, label2='test', iconImage='DefaultFolder.png', thumbnailImage=thumb)
282            listitem.setProperty('Fanart_Image', fanartImage)
283            listitem.addContextMenuItems([('Refresh', 'Container.Refresh')])
284    
285            if mode == '50':
286                infoLabels = {}
287                infoLabels['title'] = name
288                infoLabels['playcount'] = playcount
289                listitem.setInfo('video', infoLabels)
290    
291            name = name.encode('UTF-8')
292    
293            u = sys.argv[0] + "?mode=" + urllib.quote(mode) + "&name=" + urllib.quote(
294                name) + "&url=" + urllib.quote(url)
295            xbmcplugin.addDirectoryItem(
296                handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)
297    
298        if (endlist == True):
299            xbmcplugin.endOfDirectory(int(sys.argv[1]))
300    
301    
302  def play_video(url, name):  def play_video(url, name):
303          link = open_url(url)      description = ""
304          match=re.compile('<url>(.+?)</url>').findall(link)      playPosition = 0
305          url = match[0]      savedPosition = 0
306          print '[TODIC]:'+str(url)      try:
307          image = xbmc.getInfoImage( 'ListItem.Thumb' )          param1 = parse_parameter_string(url)
308          listitem = xbmcgui.ListItem(label = name , iconImage = 'DefaultVideo.png', thumbnailImage = image)          clipkey = param1["clipkey"]
309  #       listitem = xbmcgui.ListItem(label = name , iconImage = 'DefaultVideo.png', thumbnailImage = 'DefaultVideo.png')  
310          listitem.setInfo( type = "Video", infoLabels={ "Title": name } )          print( "[Todic] ClipKey:" + clipkey)
311          xbmc.Player(xbmc.PLAYER_CORE_AUTO).play(str(url), listitem)          detailurl = __backend__ + "&action=clipdetails&clipkey=" + clipkey
312          xbmc.sleep(200)          print( "[Todic] detailURL = " + detailurl)
313    
314            xml = open_url(detailurl)
315    
316            clipDetailsDoc = parseString(xml)
317            savedPosition = int( getText(clipDetailsDoc.getElementsByTagName("position")) )
318            description = getText(clipDetailsDoc.getElementsByTagName("description"))
319        except:
320            print( "[Todic] Unexpected error:", sys.exc_info()[0] )
321    
322        if (description == None or description == ""):
323            if (savedPosition > 0):
324                dialog = xbmcgui.Dialog()
325                #yes / true -afspil fra position
326                answer = dialog.yesno(heading='Todic', line1='Afspil fra sidste position', nolabel='Fra start', yeslabel='Fortsæt')
327                if (answer == True):
328                    playPosition = savedPosition
329            
330            play_real_video(url, name, playPosition)
331    
332        else:
333            d = TodicMovieDialog()
334            d.setDetailsDoc(clipDetailsDoc)
335            d.setName(name)
336            d.setUrl(url)
337            d.setDescription(description)
338    
339            d.doModal()
340    
341    
342    def play_real_video(url, name, position):
343        xml = open_url(url)
344        print( '[Todic] url: ' + str(url) )
345        print( '[Todic] xml: ' + xml )
346        print( '[Todic] pos: ' + str(position) )
347    
348        doc = parseString(xml)
349        url = getText(doc.getElementsByTagName("url"))
350    
351        subtitleurl = getText(doc.getElementsByTagName("subtitles"))
352        subtitlesfile = os.path.join(datapath, 'temp.srt')
353    
354        # if old srt file exists delete it first
355        if os.path.isfile(subtitlesfile):
356            os.unlink(subtitlesfile)
357    
358        print( '[Todic] subs: ' + str(subtitleurl) )
359        if len(subtitleurl) > 0:
360            subtitles = open_url(subtitleurl)
361            SaveFile(subtitlesfile, subtitles)
362            print( '[Todic] downloaded subtitles' )
363    
364        image = xbmc.getInfoImage('ListItem.Thumb')
365        listitem = xbmcgui.ListItem(
366            label=name, iconImage='DefaultVideo.png', thumbnailImage=image)
367        listitem.setInfo(type="Video", infoLabels={"Title": name})
368        listitem.setProperty('ResumeTime', '300')
369        listitem.setProperty('TotalTime', '3000')
370    
371        player = TodicPlayer()
372        player.play(str(url), listitem)
373    
374        # kan ikke loade subtitles hvis foerend playeren koerer
375        count = 0
376        while not xbmc.Player().isPlaying():
377            xbmc.sleep(250)
378            count += 1
379            if count > 10:
380                break
381    
382    
383    
384        if xbmc.Player().isPlaying():
385            if os.path.isfile(subtitlesfile):
386                player.setSubtitles(subtitlesfile)
387                print( '[Todic] started subtitles')
388            else:
389                player.showSubtitles(False)
390    
391    
392            if (position > 0):
393                while (player.getTotalTime() == 0.0): #Vent indtil vi har beregnet hvor langt klippet er
394                    xbmc.sleep(250)
395    
396                print( "[Todic] totalTime " +  str( player.getTotalTime() ))
397                player.seekTime(position)
398    
399    
400        #Holder python kørernde indtil at det bliver bedt om at stoppe
401        while (not xbmc.abortRequested):
402            player.tick()
403            xbmc.sleep(500)
404    
405    
406    
407  def search():  def search():
408          search = getUserInput("Todic Søgning")      search = getUserInput("Todic Søgning")
409    
410          url = __backend__ + "&action=search&search=" + urllib.quote_plus(search)      if (search != None and search != ""):
411            url = __backend__ + "&action=search&search=" + \
412                urllib.quote_plus(search)
413    
414          print "[TODIC] Search start: " + search          # print "[Todic] Search start: " + search
415          print "[TODIC] Search url: " + url          # print "[Todic] Search url: " + url
416    
417          buildSubList(url, "søgning")          buildList(url, "søgning")
418    
           
419    
420    def searchSeries():
421        search = getUserInput("Todic Serie Søgning")
422    
423                        if (search != None and search != ""):
424  #=================================== Tool Box =======================================          url = __backend__ + "&action=searchseries&search=" + \
425                urllib.quote_plus(search)
426    
427            # print "[Todic] Search start: " + search
428            # print "[Todic] Search url: " + url
429    
430            buildList(url, "serie søgning")
431    
432    
433    #=================================== Tool Box =======================================
434  # shows a more userfriendly notification  # shows a more userfriendly notification
435  def showMessage(heading, message):  def showMessage(heading, message):
436          duration = 15*1000      duration = 15 * 1000
437          xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( heading, message, duration) )      xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
438                            (heading, message, duration))
439    
440    
441  # raise a keyboard for user input  # raise a keyboard for user input
442  def getUserInput(title = "Input", default="", hidden=False):  def getUserInput(title="Input", default="", hidden=False):
443          result = None      result = None
444    
445        # Fix for when this functions is called with default=None
446        if not default:
447            default = ""
448    
449          # Fix for when this functions is called with default=None      keyboard = xbmc.Keyboard(default, title)
450          if not default:      keyboard.setHiddenInput(hidden)
451                  default = ""      keyboard.doModal()
452                            
453          keyboard = xbmc.Keyboard(default, title)      if keyboard.isConfirmed():
454          keyboard.setHiddenInput(hidden)          result = keyboard.getText()
455          keyboard.doModal()  
456                        return result
         if keyboard.isConfirmed():  
                 result = keyboard.getText()  
                   
         return result  
457    
458    
459  def get_params():  def get_params():
460          param=[]      return parse_parameter_string(sys.argv[2])
461          paramstring=sys.argv[2]  
462          if len(paramstring)>=2:  
463                  params=sys.argv[2]  def parse_parameter_string(paramstring):
464                  cleanedparams=params.replace('?','')      param = []
465                  if (params[len(params)-1]=='/'):      if len(paramstring) >= 2:
466                          params=params[0:len(params)-2]          params = paramstring
467                  pairsofparams=cleanedparams.split('&')          cleanedparams = params.replace('?', '')
468                  param={}          if (params[len(params) - 1] == '/'):
469                  for i in range(len(pairsofparams)):              params = params[0:len(params) - 2]
470                          splitparams={}          pairsofparams = cleanedparams.split('&')
471                          splitparams=pairsofparams[i].split('=')          param = {}
472                          if (len(splitparams))==2:          for i in range(len(pairsofparams)):
473                                  param[splitparams[0]]=splitparams[1]                                                  splitparams = {}
474          return param              splitparams = pairsofparams[i].split('=')
475                if (len(splitparams)) == 2:
476                    param[splitparams[0]] = splitparams[1]
477        return param
478    
 params = get_params()  
 url = None  
 name = None  
 mode = None  
479    
480  params = get_params()  params = get_params()
481  url = None  url = None
482  name = None  name = None
483  mode = None  mode = None
484    
485    
486    #print params
487    
488  try:  try:
489          url = urllib.unquote_plus(params["url"])      url = urllib.unquote_plus(params["url"])
490  except:  except:
491          pass      pass
492  try:  try:
493          name = urllib.unquote_plus(params["name"])      name = urllib.unquote_plus(params["name"])
494  except:  except:
495          pass      pass
496  try:  try:
497          mode = int(params["mode"])      mode = int(params["mode"])
498  except:  except:
499          pass      pass
500    
501    
 if mode == None:  
         #build main menu  
         rootMenu()  
         
 elif mode == 1:  
         #build list of movie starting letters  
         buildList(url, name)  
502    
 elif mode == 2:  
         #build list of series          
         buildSubList(url, name)  
503    
504  elif mode == 10:  try:
505          search()      open_url("http://todic.dk")
506            except:
507        showMessage("Fejl", "Kunne ikke forbinde til todic.dk")
508        exit()
509    
510  elif mode == 50:  
511          play_video(url, name)  if url == 'refresh':
512        # xbmc.output("[tvserver] Container.Refresh") #20130418 xbmc.output virker
513        # ikke med XBMC12
514        xbmc.executebuiltin("Container.Refresh")
515    
516    
517    elif mode == None:
518        # build main menu
519        rootMenu()
520    
521  # xbmcplugin.endOfDirectory(int(sys.argv[1]))  elif mode == 1:
522        # build list of movie starting letters
523        buildList(url, name)
524    
525    elif mode == 10:
526        search()
527    
528    elif mode == 11:
529        searchSeries()
530    
531    
532    elif mode == 50:
533        play_video(url, name)

Legend:
Removed from v.1632  
changed lines
  Added in v.3249

  ViewVC Help
Powered by ViewVC 1.1.20