/[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 1648 by torben, Sun Dec 4 14:40:44 2011 UTC revision 3255 by torben, Mon Mar 4 13:36:03 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
 import cgi as urlparse  
10  import os  import os
11    
12    
# Line 13  import xbmcaddon Line 15  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  fanartImage = os.path.join(__addon__.getAddonInfo('path'), 'fanart.jpg')  __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')  
                 listitem.setProperty('Fanart_Image', fanartImage)  
   
                 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')  
         listitem.setProperty('Fanart_Image', fanartImage)  
   
         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  
217    
218          m=re.compile('<title>(.+?)</title><url>(.+?)</url><cover>(.+?)</cover><description>(.*)</description>').findall(link)      msg = open_url(__backend__ + "&action=messages")
219          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)  
                 listitem.setProperty('Fanart_Image', fanartImage)  
   
                 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]))  
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')
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                if playcount > 0:
290                    listitem.setArt( {'thumb': thumb} ) #not pretty - but at least we can show a different icon for unwatched/watched in kodi18  
291                listitem.setInfo('video', infoLabels)
292                listitem.setProperty('IsPlayable', 'true')
293    
294            name = name.encode('UTF-8')
295    
296            u = sys.argv[0] + "?mode=" + urllib.quote(mode) + "&name=" + urllib.quote(
297                name) + "&url=" + urllib.quote(url)
298            xbmcplugin.addDirectoryItem(
299                handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)
300    
301        if (endlist == True):
302            xbmcplugin.endOfDirectory(int(sys.argv[1]))
303    
304    
305  def play_video(url, name):  def play_video(url, name):
306          link = open_url(url)      description = ""
307          match=re.compile('<url>(.+?)</url>').findall(link)      playPosition = 0
308          url = match[0]      savedPosition = 0
309          print '[TODIC]:'+str(url)      try:
310          image = xbmc.getInfoImage( 'ListItem.Thumb' )          param1 = parse_parameter_string(url)
311          listitem = xbmcgui.ListItem(label = name , iconImage = 'DefaultVideo.png', thumbnailImage = image)          clipkey = param1["clipkey"]
312  #       listitem = xbmcgui.ListItem(label = name , iconImage = 'DefaultVideo.png', thumbnailImage = 'DefaultVideo.png')  
313          listitem.setInfo( type = "Video", infoLabels={ "Title": name } )          print( "[Todic] ClipKey:" + clipkey)
314          xbmc.Player(xbmc.PLAYER_CORE_AUTO).play(str(url), listitem)          detailurl = __backend__ + "&action=clipdetails&clipkey=" + clipkey
315          xbmc.sleep(200)          print( "[Todic] detailURL = " + detailurl)
316    
317            xml = open_url(detailurl)
318    
319            clipDetailsDoc = parseString(xml)
320            savedPosition = int( getText(clipDetailsDoc.getElementsByTagName("position")) )
321            description = getText(clipDetailsDoc.getElementsByTagName("description"))
322        except:
323            print( "[Todic] Unexpected error:", sys.exc_info()[0] )
324    
325        if (description == None or description == ""):
326            if (savedPosition > 0):
327                dialog = xbmcgui.Dialog()
328                #yes / true -afspil fra position
329                answer = dialog.yesno(heading='Todic', line1='Afspil fra sidste position', nolabel='Fra start', yeslabel='Fortsæt')
330                if (answer == True):
331                    playPosition = savedPosition
332            
333            play_real_video(url, name, playPosition)
334    
335        else:
336            d = TodicMovieDialog()
337            d.setDetailsDoc(clipDetailsDoc)
338            d.setName(name)
339            d.setUrl(url)
340            d.setDescription(description)
341    
342            d.doModal()
343    
344    
345    def play_real_video(url, name, position):
346        xml = open_url(url)
347        print( '[Todic] url: ' + str(url) )
348        print( '[Todic] xml: ' + xml )
349        print( '[Todic] pos: ' + str(position) )
350    
351        doc = parseString(xml)
352        url = getText(doc.getElementsByTagName("url"))
353    
354        subtitleurl = getText(doc.getElementsByTagName("subtitles"))
355    
356    
357        print( '[Todic] subs: ' + str(subtitleurl) )
358    
359        image = xbmc.getInfoImage('ListItem.Thumb')
360        listitem = xbmcgui.ListItem(
361            label=name, iconImage='DefaultVideo.png', thumbnailImage=image)
362        listitem.setInfo(type="Video", infoLabels={"Title": name})
363    
364        listitem.setProperty('StartOffset', str(position) )
365    
366        if len(subtitleurl) > 0:
367            listitem.setSubtitles([subtitleurl])
368    
369        player = TodicPlayer()
370        player.play(str(url), listitem)
371    
372    
373        #Holder python kørernde indtil at det bliver bedt om at stoppe
374        while (not xbmc.abortRequested):
375            player.tick()
376            xbmc.sleep(500)
377    
378    
379    
380  def search():  def search():
381          search = getUserInput("Todic Søgning")      search = getUserInput("Todic Søgning")
382    
383        if (search != None and search != ""):
384            url = __backend__ + "&action=search&search=" + \
385                urllib.quote_plus(search)
386    
387            # print "[Todic] Search start: " + search
388            # print "[Todic] Search url: " + url
389    
390          if (search != None and search != ""):          buildList(url, "søgning")
                 url = __backend__ + "&action=search&search=" + urllib.quote_plus(search)  
391    
                 #print "[TODIC] Search start: " + search  
                 #print "[TODIC] Search url: " + url  
392    
393                  buildList(url, "søgning")  def searchSeries():
394        search = getUserInput("Todic Serie Søgning")
395    
396                if (search != None and search != ""):
397            url = __backend__ + "&action=searchseries&search=" + \
398                urllib.quote_plus(search)
399    
400            # print "[Todic] Search start: " + search
401            # print "[Todic] Search url: " + url
402    
403                            buildList(url, "serie søgning")
404  #=================================== Tool Box =======================================  
405    
406    #=================================== Tool Box =======================================
407  # shows a more userfriendly notification  # shows a more userfriendly notification
408  def showMessage(heading, message):  def showMessage(heading, message):
409          duration = 15*1000      duration = 15 * 1000
410          xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( heading, message, duration) )      xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
411                            (heading, message, duration))
412    
413    
414  # raise a keyboard for user input  # raise a keyboard for user input
415  def getUserInput(title = "Input", default="", hidden=False):  def getUserInput(title="Input", default="", hidden=False):
416          result = None      result = None
417    
418        # Fix for when this functions is called with default=None
419        if not default:
420            default = ""
421    
422        keyboard = xbmc.Keyboard(default, title)
423        keyboard.setHiddenInput(hidden)
424        keyboard.doModal()
425    
426        if keyboard.isConfirmed():
427            result = keyboard.getText()
428    
429          # Fix for when this functions is called with default=None      return result
         if not default:  
                 default = ""  
                           
         keyboard = xbmc.Keyboard(default, title)  
         keyboard.setHiddenInput(hidden)  
         keyboard.doModal()  
                   
         if keyboard.isConfirmed():  
                 result = keyboard.getText()  
                   
         return result  
430    
431    
432  def get_params():  def get_params():
433          param=[]      return parse_parameter_string(sys.argv[2])
434          paramstring=sys.argv[2]  
435          if len(paramstring)>=2:  
436                  params=sys.argv[2]  def parse_parameter_string(paramstring):
437                  cleanedparams=params.replace('?','')      param = []
438                  if (params[len(params)-1]=='/'):      if len(paramstring) >= 2:
439                          params=params[0:len(params)-2]          params = paramstring
440                  pairsofparams=cleanedparams.split('&')          cleanedparams = params.replace('?', '')
441                  param={}          if (params[len(params) - 1] == '/'):
442                  for i in range(len(pairsofparams)):              params = params[0:len(params) - 2]
443                          splitparams={}          pairsofparams = cleanedparams.split('&')
444                          splitparams=pairsofparams[i].split('=')          param = {}
445                          if (len(splitparams))==2:          for i in range(len(pairsofparams)):
446                                  param[splitparams[0]]=splitparams[1]                                                  splitparams = {}
447          return param              splitparams = pairsofparams[i].split('=')
448                if (len(splitparams)) == 2:
449                    param[splitparams[0]] = splitparams[1]
450        return param
451    
 params = get_params()  
 url = None  
 name = None  
 mode = None  
452    
453  params = get_params()  params = get_params()
454  url = None  url = None
455  name = None  name = None
456  mode = None  mode = None
457    
458    
459    #print params
460    
461  try:  try:
462          url = urllib.unquote_plus(params["url"])      url = urllib.unquote_plus(params["url"])
463  except:  except:
464          pass      pass
465  try:  try:
466          name = urllib.unquote_plus(params["name"])      name = urllib.unquote_plus(params["name"])
467  except:  except:
468          pass      pass
469  try:  try:
470          mode = int(params["mode"])      mode = int(params["mode"])
471  except:  except:
472          pass      pass
473    
474    
 if mode == None:  
         #build main menu  
         rootMenu()  
         
 elif mode == 1:  
         #build list of movie starting letters  
         buildList(url, name)  
475    
 elif mode == 10:  
         search()  
           
476    
477  elif mode == 50:  try:
478          play_video(url, name)      open_url("http://todic.dk")
479    except:
480        showMessage("Fejl", "Kunne ikke forbinde til todic.dk")
481        exit()
482    
483    
484    if url == 'refresh':
485        # xbmc.output("[tvserver] Container.Refresh") #20130418 xbmc.output virker
486        # ikke med XBMC12
487        xbmc.executebuiltin("Container.Refresh")
488    
489    
490    elif mode == None:
491        # build main menu
492        rootMenu()
493    
494    elif mode == 1:
495        # build list of movie starting letters
496        buildList(url, name)
497    
498    elif mode == 10:
499        search()
500    
501  # xbmcplugin.endOfDirectory(int(sys.argv[1]))  elif mode == 11:
502        searchSeries()
503    
504    
505    elif mode == 50:
506        play_video(url, name)

Legend:
Removed from v.1648  
changed lines
  Added in v.3255

  ViewVC Help
Powered by ViewVC 1.1.20