/[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 1629 by torben, Sun Nov 27 11:01:27 2011 UTC revision 3256 by torben, Tue Mar 5 10:58:04 2019 UTC
# Line 1  Line 1 
1    
2    # This Python file uses the following encoding: utf-8
3    
4  '''  '''
5      Todic plugin for XBMC      Todic plugin for XBMC
6      Version 0.0.2      Version 1.7.3
7  '''  '''
8    
9  import sys  import sys
10  import cgi as urlparse  import os
11    
12    
13  import xbmc  import xbmc
14  import xbmcaddon  import xbmcaddon
15  import xbmcgui  import xbmcgui
16  import xbmcplugin  import xbmcplugin
17  import urllib  import urllib
18  import urllib2, re  import urllib2
19    
20    # import pprint
21    
22    from xml.dom.minidom import parseString
23    from time import time
24    
25  __addon__ = xbmcaddon.Addon(id='plugin.video.todic')  __addon__ = xbmcaddon.Addon(id='plugin.video.todic')
26  __key__ = __addon__.getSetting('xbmckey').lower()  __key__ = __addon__.getSetting('xbmckey').lower()
27  __backend__ = "http://todic.dk/xbmc.php?xbmckey=" + __key__  __entrypoint__ = __addon__.getSetting('entrypoint').lower()
28    __backend__ = "https://todic.dk/xbmc.php?xbmckey=" + __key__
29    
30    
31    if __entrypoint__ == "alternative":
32        __backend__ = "https://alt.todic.dk/xbmc.php?xbmckey=" + __key__
33    
34    if __entrypoint__ == "testing":
35        __backend__ = "https://todic.dk/xbmc-beta.php?xbmckey=" + __key__
36    
37    print( "[Todic] entrypoint: " + __entrypoint__ )
38    print( "[Todic] backend: " + __backend__ )
39    
40    
41    fanartImage = os.path.join(__addon__.getAddonInfo('path'), 'movie_bg_blur.jpg')
42    datapath = xbmc.translatePath(
43        'special://profile/addon_data/plugin.video.todic/')
44    
45    ADDON_PATH = __addon__.getAddonInfo('path')
46    SkinMasterPath = os.path.join(ADDON_PATH, 'skins') + '/'
47    MySkinPath = (os.path.join(SkinMasterPath, '720p')) + '/'
48    MySkin = 'main.xml'
49    
50    
51    class TodicMovieDialog(xbmcgui.WindowXMLDialog):
52    
53        def __new__(cls):
54            return super(TodicMovieDialog, cls).__new__(cls, "main.xml", ADDON_PATH)
55    
56        def __init__(self):
57            super(TodicMovieDialog, self).__init__()
58            self.position = 0
59    
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:
90                self.getControl(51).setVisible(False)
91    
92            #orig_img_width = self.getControl(40).getWidth()
93            #self.starwidth = (float(self.imdbrating) / 10.0) * orig_img_width
94            #self.getControl(40).setWidth(int(self.starwidth))
95    
96        def setDetailsDoc(self, detailsDoc):
97            print( "[Todic] MovieDialog setDetailsDoc:")
98            self.imdbrating = getText(detailsDoc.getElementsByTagName("imdbrating"))
99            self.moviegroups = getText(detailsDoc.getElementsByTagName("moviegroups"))
100            self.playlength = getText(detailsDoc.getElementsByTagName("playlength"))
101            self.codecdetails = getText(detailsDoc.getElementsByTagName("codecdetails"))
102            self.position = int( getText(detailsDoc.getElementsByTagName("position")) )
103    
104        def setUrl(self, url):
105            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):  def open_url(url):
200          req = urllib2.Request(url)      req = urllib2.Request(url)
201          content = urllib2.urlopen(req)      content = urllib2.urlopen(req)
202          data = content.read()      data = content.read()
203          content.close()      content.close()
204          return data      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():  def rootMenu():
218          link = open_url(__backend__)      kodi_ver = xbmc.getInfoLabel('System.BuildVersion')
219          m=re.compile('<title>(.+?)</title><url>(.+?)</url>').findall(link)      plugin_ver = __addon__.getAddonInfo('version')
220          for name,url in m:      msgurl = __backend__ + "&action=messages&kodi=" + urllib.quote_plus(kodi_ver) + "&todicplugin=" + urllib.quote_plus(plugin_ver)
221                  listitem = xbmcgui.ListItem(label = name, iconImage = 'DefaultFolder.png', thumbnailImage = 'DefaultFolder.png')  
222                  u = sys.argv[0] + "?mode=1&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(url)      msg = open_url(msgurl)
223                  ok = xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = u, listitem = listitem, isFolder = True)      msg = msg.strip()
224          xbmcplugin.endOfDirectory(int(sys.argv[1]))  
225        if msg != "":
226            dialog = xbmcgui.Dialog()
227  def buildList(url,title):          dialog.ok('XBMC Todic', msg)
228          print '[TODIC]:'+str(url)          
229          link = open_url(url)      buildList(__backend__, "", False)  # call default list
230          ty=re.compile('<meta type=\'(.+?)\'').findall(link)  
231          print '[TOD]'+str(ty[0])      # Adde xtra items to root menu
232          m=re.compile('<title>(.+?)</title><url>(.+?)</url><cover>(.+?)</cover>').findall(link)      listitem = xbmcgui.ListItem(
233          for name,url,thumb in m:          label="Søg Film ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
234                  if ty[0] == 'clipList':      listitem.setProperty('Fanart_Image', fanartImage)
235                          mode = '50'  
236                          folder = False      u = sys.argv[0] + "?mode=10&name="
237                  else:      xbmcplugin.addDirectoryItem(
238                          mode = '2'          handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
239                          folder = True  
240                                # add search series
241                  listitem = xbmcgui.ListItem(label = name, iconImage = 'DefaultFolder.png', thumbnailImage = thumb)      listitem = xbmcgui.ListItem(
242                  u = sys.argv[0] + "?mode=" + urllib.quote_plus(mode) + "&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(url)          label="Søg Serier ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
243                  ok = xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = u, listitem = listitem, isFolder = folder)      listitem.setProperty('Fanart_Image', fanartImage)
244          xbmcplugin.endOfDirectory(int(sys.argv[1]))  
245        u = sys.argv[0] + "?mode=11&name="
246  def buildSubList(url,title):      xbmcplugin.addDirectoryItem(
247          print '[TODIC]:'+str(url)          handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
248          link = open_url(url)  
249          m=re.compile('<title>(.+?)</title><url>(.+?)</url><cover>(.+?)</cover>').findall(link)      xbmcplugin.endOfDirectory(int(sys.argv[1]))
250          for name,url,thumb in m:  
251                  listitem = xbmcgui.ListItem(label = name, iconImage = 'DefaultFolder.png', thumbnailImage = thumb)  
252                  u = sys.argv[0] + "?mode=50&name=" + urllib.quote_plus(name) + "&url=" + urllib.quote_plus(url)  def buildList(url, title, endlist=True):
253                  ok = xbmcplugin.addDirectoryItem(handle = int(sys.argv[1]), url = u, listitem = listitem, isFolder = False)      print( '[Todic]:' + str(url) )
254          xbmcplugin.endOfDirectory(int(sys.argv[1]))  
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():
385        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            buildList(url, "søgning")
395    
396    
397    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    
409    
410    #=================================== Tool Box =======================================
411    # shows a more userfriendly notification
412    def showMessage(heading, message):
413        duration = 15 * 1000
414        xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
415                            (heading, message, duration))
416    
417    
418    # raise a keyboard for user input
419    def getUserInput(title="Input", default="", hidden=False):
420        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        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 == 2:  
         #build list of series          
         buildSubList(url, name)  
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  xbmcplugin.endOfDirectory(int(sys.argv[1]))  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    elif mode == 11:
506        searchSeries()
507    
508    
509    elif mode == 50:
510        play_video(url, name)

Legend:
Removed from v.1629  
changed lines
  Added in v.3256

  ViewVC Help
Powered by ViewVC 1.1.20