/[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 2601 by torben, Mon Jul 13 14:33:39 2015 UTC revision 3264 by torben, Fri Feb 26 12:24:06 2021 UTC
# Line 3  Line 3 
3    
4  '''  '''
5      Todic plugin for XBMC      Todic plugin for XBMC
6      Version 0.0.15      Version 1.9.3
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  # 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    __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')  fanartImage = os.path.join(__addon__.getAddonInfo('path'), 'movie_bg_blur.jpg')
43  datapath = xbmc.translatePath(  datapath = xbmcvfs.translatePath(
44      'special://profile/addon_data/plugin.video.todic/')      'special://profile/addon_data/plugin.video.todic/')
45    
46  ADDON_PATH = __addon__.getAddonInfo('path')  ADDON_PATH = __addon__.getAddonInfo('path')
# Line 42  class TodicMovieDialog(xbmcgui.WindowXML Line 56  class TodicMovieDialog(xbmcgui.WindowXML
56    
57      def __init__(self):      def __init__(self):
58          super(TodicMovieDialog, self).__init__()          super(TodicMovieDialog, self).__init__()
59            self.position = 0
60    
61      def onClick(self, controlId):      def onClick(self, controlId):
62          print "OnClick: " + str(controlId)          print( "[Todic] MovieDialog OnClick: " + str(controlId) )
63    
64          if (controlId == 50):          if (controlId == 50):
65              self.close()              self.close()
66              play_real_video(self.url, self.name)              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):          if (controlId == 98):
73              self.close()              self.close()
74    
75      def onInit(self):      def onInit(self):
76    
77          print "ONINIT"          print( "[Todic] MovieDialog onInit" )
78          self.getControl(1).setLabel(self.name)          self.getControl(1).setLabel(self.name)
79          self.getControl(2).setLabel(self.moviegroups)          self.getControl(2).setLabel(self.moviegroups)
80          self.getControl(3).setLabel(self.description)          self.getControl(3).setLabel(self.description)
81          self.getControl(10).setLabel(self.playlength)          self.getControl(10).setLabel(self.playlength)
82          self.getControl(11).setLabel(self.codecdetails)          self.getControl(11).setLabel(self.codecdetails)
83    
84          orig_img_width = self.getControl(40).getWidth()          if (self.position > 0):
85          self.starwidth = (float(self.imdbrating) / 10.0) * orig_img_width              self.getControl(51).setVisible(True)
86          self.getControl(40).setWidth(int(self.starwidth))              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):      def setUrl(self, url):
         print "SETURL:" + url  
106          self.url = url          self.url = url
         self.fetchClipDetails()  
   
     def fetchClipDetails(self):  
         param1 = parse_parameter_string(self.url)  
   
         self.clipkey = param1["clipkey"]  
         print "CLIPKEY:" + self.clipkey  
         detailurl = __backend__ + "&action=clipdetails&clipkey=" + self.clipkey  
   
         xml = open_url(detailurl)  
   
         doc = parseString(xml)  
         self.imdbrating = getText(doc.getElementsByTagName("imdbrating"))  
         self.moviegroups = getText(doc.getElementsByTagName("moviegroups"))  
         self.playlength = getText(doc.getElementsByTagName("playlength"))  
         self.codecdetails = getText(doc.getElementsByTagName("codecdetails"))  
107    
108      def setName(self, name):      def setName(self, name):
109          self.name = name          self.name = name
# Line 97  class TodicPlayer(xbmc.Player): Line 116  class TodicPlayer(xbmc.Player):
116    
117      def __init__(self, *args, **kwargs):      def __init__(self, *args, **kwargs):
118          # xbmc.Player.__init__(selv,*args,**kwargs)          # xbmc.Player.__init__(selv,*args,**kwargs)
119          xbmc.Player.__init__(self, xbmc.PLAYER_CORE_MPLAYER)          xbmc.Player.__init__(self)
120          self.stopped = False          self.stopped = False
121          self.started = False          self.started = False
122          print "[TodicPlayer] init"          self.playingPosition = 0.0
123            self.lastReport = 0
124            print( "[TodicPlayer] init")
125    
 #       @catchall  
126      def onPlayBackStarted(self):      def onPlayBackStarted(self):
127          self.started = True          self.started = True
128          print "[TodicPlayer] : started"          print( "[TodicPlayer] : started")
 #               super.onPlayBackStarted()  
129    
130        #When user presses stop, we report back the the position registered in the last call to self.tick()
131      def onPlayBackStopped(self):      def onPlayBackStopped(self):
132          self.stopped = True          self.stopped = True
133          print "[TodicPlayer] : stopped"          print( "[TodicPlayer] : stopped")
134            self.reportPlaytime("stopped")
135    
136        def onPlayBackPaused(self):
137            print( "[TodicPlayer] : paused")
138            self.reportPlaytime("paused")
139    
140        def onPlayBackResumed(self):
141            print( "[TodicPlayer] : resumed")
142            self.reportPlaytime("resumed")
143    
144    
145      def onPlayBackEnded(self):      def onPlayBackEnded(self):
146          self.stopped = True          self.stopped = True
147          print "[TodicPlayer] : ended"          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    
     def callbackLoop(self):  
         print "[Todic] startLoop"  
         while (self.stopped == False):  
             if (self.started == True):  
                 print "[todic] " + str(self.getTime())  
             xbmc.sleep(5000)  
170    
171    
172  def getText2(nodelist):  def getText2(nodelist):
# Line 144  def getText(nodelist): Line 189  def getText(nodelist):
189              return nodelist[0].childNodes[0].nodeValue              return nodelist[0].childNodes[0].nodeValue
190    
191    
192    
193  def SaveFile(path, data):  def SaveFile(path, data):
194      file = open(path, 'w')      file = open(path, 'w')
195      file.write(data)      file.write(data)
196      file.close()      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      msg = open_url(__backend__ + "&action=messages")      msg = open_url(msgurl)
225      msg = msg.strip()      msg = msg.strip()
226    
227      if msg != "":      if msg != "":
228            print("[Todic] rootMenu Dialog =" + str(msg))
229          dialog = xbmcgui.Dialog()          dialog = xbmcgui.Dialog()
230          dialog.ok('XBMC Todic', msg)          dialog.ok('XBMC Todic', msg)
231    
232      buildList(__backend__, "", False)  # call default list      buildList(__backend__, "", False)  # call default list
233    
234      # Adde xtra items to root menu      # Adde xtra items to root menu
235      listitem = xbmcgui.ListItem(      listitem = xbmcgui.ListItem(label="Søg Film ...")
236          label="Søg film ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')      listitem.setArt( { 'icon':'DefaultFolder.png', 'thumb':'DefaultFolder.png'} )
237      listitem.setProperty('Fanart_Image', fanartImage)      listitem.setProperty('Fanart_Image', fanartImage)
238    
239      u = sys.argv[0] + "?mode=10&name="      u = sys.argv[0] + "?mode=10&name="
240      ok = xbmcplugin.addDirectoryItem(      xbmcplugin.addDirectoryItem(
241          handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)          handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
242    
243      # add search series      # add search series
244      listitem = xbmcgui.ListItem(      listitem = xbmcgui.ListItem(label="Søg Serier ...")
245          label="Søg Serier ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')      listitem.setArt( { 'icon':'DefaultFolder.png', 'thumb':'DefaultFolder.png'} )
246      listitem.setProperty('Fanart_Image', fanartImage)      listitem.setProperty('Fanart_Image', fanartImage)
247    
248      u = sys.argv[0] + "?mode=11&name="      u = sys.argv[0] + "?mode=11&name="
249      ok = xbmcplugin.addDirectoryItem(      xbmcplugin.addDirectoryItem(
250          handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)          handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
251    
252      xbmcplugin.endOfDirectory(int(sys.argv[1]))      xbmcplugin.endOfDirectory(int(sys.argv[1]))
253    
254    
255  def buildList(url, title, endlist=True):  def buildList(url, title, endlist=True):
256      print '[TODIC]:' + str(url)      print( '[Todic::buildList]:' + str(url) )
257    
258      link = open_url(url)      link = open_url(url)
259      doc = parseString(link)      doc = parseString(link)
260      ty = doc.getElementsByTagName("meta")[0].getAttribute("type")      ty = doc.getElementsByTagName("meta")[0].getAttribute("type")
261      print '[TODIC]' + str(ty)      print( '[Todic]' + str(ty))
262    
263      if ty == 'clipList':      if ty == 'clipList':
264          mode = '50'          mode = '50'
# Line 207  def buildList(url, title, endlist=True): Line 269  def buildList(url, title, endlist=True):
269    
270      entries = doc.getElementsByTagName("entry")      entries = doc.getElementsByTagName("entry")
271      l = len(entries)      l = len(entries)
272      description = ''  
273      for entry in entries:      for entry in entries:
274          name = getText(entry.getElementsByTagName("title"))          name = getText(entry.getElementsByTagName("title"))
275          url = getText(entry.getElementsByTagName("url"))          url = getText(entry.getElementsByTagName("url"))
276          thumb = getText(entry.getElementsByTagName("cover"))          thumb = getText(entry.getElementsByTagName("cover"))
         description = getText(entry.getElementsByTagName("description"))  
277          playcount = getText(entry.getElementsByTagName("playcount"))          playcount = getText(entry.getElementsByTagName("playcount"))
278    
279    
280          if playcount == '':          if playcount == '':
281              playcount = '0'              playcount = '0'
282          playcount = int(playcount)          playcount = int(playcount)
283    
284  # print "name:" + name  # print "name:" + name
285  #               print "url:" + url  #               print "url:" + url
286  #               print "thumb:" + thumb  #               print "thumb:" + thumbi
287  #               print "description:" + description          listitem = xbmcgui.ListItem(label=name, label2='test')
288          listitem = xbmcgui.ListItem(          listitem.setArt( {'icon': 'DefaultFolder.png'} )
             label=name, label2='test', iconImage='DefaultFolder.png', thumbnailImage=thumb)  
289          listitem.setProperty('Fanart_Image', fanartImage)          listitem.setProperty('Fanart_Image', fanartImage)
290            listitem.addContextMenuItems([('Refresh', 'Container.Refresh')])
291            listitem.setArt( {'thumb': thumb} )
292    
293          if mode == '50':          if mode == '50':
294              infoLabels = {}              infoLabels = {}
295              infoLabels['title'] = name              infoLabels['title'] = name
             infoLabels['plot'] = description  
296              infoLabels['playcount'] = playcount              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)              listitem.setInfo('video', infoLabels)
300    
301          name = name.encode('UTF-8')          name = name.encode('UTF-8')
         description = description.encode('UTF-8')  
302    
303          u = sys.argv[0] + "?mode=" + urllib.quote(mode) + "&name=" + urllib.quote(          u = sys.argv[0] + "?mode=" + urllib.parse.quote(mode) + "&name=" + urllib.parse.quote(name) + "&url=" + urllib.parse.quote(url)
304              name) + "&url=" + urllib.quote(url) + "&description=" + urllib.quote(description)          xbmcplugin.addDirectoryItem(
         ok = xbmcplugin.addDirectoryItem(  
305              handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)              handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)
306    
307      if (endlist == True):      if (endlist == True):
308          xbmcplugin.endOfDirectory(int(sys.argv[1]))          xbmcplugin.endOfDirectory(int(sys.argv[1]))
309    
310    
311  def play_video(url, name, description):  def play_video(url, name):
312        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 == ""):      if (description == None or description == ""):
332          play_real_video(url, name)          if (savedPosition > 0):
333                dialog = xbmcgui.Dialog()
334                #yes / true -afspil fra position
335                answer = dialog.yesno(heading='Todic', message='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:      else:
342          d = TodicMovieDialog()          d = TodicMovieDialog()
343          d.setUrl(url)          d.setDetailsDoc(clipDetailsDoc)
344          d.setName(name)          d.setName(name)
345            d.setUrl(url)
346          d.setDescription(description)          d.setDescription(description)
347    
348          d.doModal()          d.doModal()
349    
350    
351  def play_real_video(url, name):  def play_real_video(url, name, position):
352      xml = open_url(url)      xml = open_url(url)
353      print 'TODIC url: ' + str(url)      print( '[Todic] url: ' + str(url) )
354      print 'TODIC xml: ' + xml      print( '[Todic] xml: ' + str(xml) )
355        print( '[Todic] pos: ' + str(position) )
356    
357      doc = parseString(xml)      doc = parseString(xml)
358      url = getText(doc.getElementsByTagName("url"))      url = getText(doc.getElementsByTagName("url"))
359    
360      subtitleurl = getText(doc.getElementsByTagName("subtitles"))      subtitleurl = getText(doc.getElementsByTagName("subtitles"))
     subtitlesfile = os.path.join(datapath, 'temp.srt')  
361    
     # if old srt file exists delete it first  
     if os.path.isfile(subtitlesfile):  
         os.unlink(subtitlesfile)  
362    
363      print '[TODIC] subs: ' + str(subtitleurl)      print( '[Todic] subs: ' + str(subtitleurl) )
     if len(subtitleurl) > 0:  
         subtitles = open_url(subtitleurl)  
         SaveFile(subtitlesfile, subtitles)  
         print 'TODIC downloaded subtitles'  
364    
365      image = xbmc.getInfoImage('ListItem.Thumb')      image = xbmc.getInfoImage('ListItem.Thumb')
366      listitem = xbmcgui.ListItem(      listitem = xbmcgui.ListItem(label=name)
367          label=name, iconImage='DefaultVideo.png', thumbnailImage=image)      listitem.setArt( {'icon': 'DefaultVideo.png', 'thumb':image} )
368      listitem.setInfo(type="Video", infoLabels={"Title": name})      listitem.setInfo(type="Video", infoLabels={"Title": name})
369    
370      player = TodicPlayer(xbmc.PLAYER_CORE_AUTO)      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)      player.play(str(url), listitem)
377    
     # kan ikke loade subtitles hvis foerend playeren koerer  
     count = 0  
     while not xbmc.Player().isPlaying():  
         xbmc.sleep(500)  
         count += 1  
         if count > 10:  
             break  
   
     if xbmc.Player().isPlaying():  
         if os.path.isfile(subtitlesfile):  
             player.setSubtitles(subtitlesfile)  
             print 'TODIC started subtitles'  
         else:  
             player.disableSubtitles()  
378    
379  #       player.callbackLoop()      #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    
387    
388    
389  def search():  def search():
# Line 309  def search(): Line 391  def search():
391    
392      if (search != None and search != ""):      if (search != None and search != ""):
393          url = __backend__ + "&action=search&search=" + \          url = __backend__ + "&action=search&search=" + \
394              urllib.quote_plus(search)              urllib.parse.quote(search)
395    
396          # print "[TODIC] Search start: " + search          # print "[Todic] Search start: " + search
397          # print "[TODIC] Search url: " + url          # print "[Todic] Search url: " + url
398    
399          buildList(url, "søgning")          buildList(url, "søgning")
400    
# Line 322  def searchSeries(): Line 404  def searchSeries():
404    
405      if (search != None and search != ""):      if (search != None and search != ""):
406          url = __backend__ + "&action=searchseries&search=" + \          url = __backend__ + "&action=searchseries&search=" + \
407              urllib.quote_plus(search)              urllib.parse.quote(search)
408    
409          # print "[TODIC] Search start: " + search          # print "[Todic] Search start: " + search
410          # print "[TODIC] Search url: " + url          # print "[Todic] Search url: " + url
411    
412          buildList(url, "serie søgning")          buildList(url, "serie søgning")
413    
# Line 333  def searchSeries(): Line 415  def searchSeries():
415  #=================================== Tool Box =======================================  #=================================== Tool Box =======================================
416  # shows a more userfriendly notification  # shows a more userfriendly notification
417  def showMessage(heading, message):  def showMessage(heading, message):
418        print( "[Todic::showMessage] " + str(message) )
419        print( message )
420      duration = 15 * 1000      duration = 15 * 1000
421      xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %      xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
422                          (heading, message, duration))                          (heading, message, duration))
# Line 381  params = get_params() Line 465  params = get_params()
465  url = None  url = None
466  name = None  name = None
467  mode = None  mode = None
468  description = None  
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  try:  
485      description = urllib.unquote_plus(params["description"])  print( "[Todic] url=" + str(url))
486  except:  print( "[Todic] name=" + str(name))
487      pass  print( "[Todic] mode=" + str(mode))
488    
489    
490  try:  try:
491      open_url("http://todic.dk")      open_url("https://todic.dk")
492  except:  except:
493      showMessage("Fejl", "Kunne ikke forbinde til todic.dk")      showMessage("Fejl", "Kunne ikke forbinde til todic.dk")
494      exit()      exit()
# Line 429  elif mode == 11: Line 516  elif mode == 11:
516    
517    
518  elif mode == 50:  elif mode == 50:
519      play_video(url, name, description)      play_video(url, name)

Legend:
Removed from v.2601  
changed lines
  Added in v.3264

  ViewVC Help
Powered by ViewVC 1.1.20