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

Legend:
Removed from v.1678  
changed lines
  Added in v.3262

  ViewVC Help
Powered by ViewVC 1.1.20