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

Legend:
Removed from v.1631  
changed lines
  Added in v.3157

  ViewVC Help
Powered by ViewVC 1.1.20