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

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

  ViewVC Help
Powered by ViewVC 1.1.20