/[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 3154 by torben, Mon Nov 28 17:34:42 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.1
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    
123    
124        def onPlayBackEnded(self):
125            self.stopped = True
126            print "[TodicPlayer] : ended"
127            self.reportPlaytime("ended")
128    
129        def tick(self):
130            if ( self.isPlaying() ):
131                self.playingPosition = self.getTime()
132                now = time()
133                #print "[Todic] tick " + str(now) + " " + str(self.lastReport) + " : " +str(now - self.lastReport)
134                if ( (now - self.lastReport) > 60.0):
135                    self.lastReport = now
136                    self.reportPlaytime("playing")
137    
138        def reportPlaytime(self, subaction):
139            if (self.playingPosition > 60):
140                url = __backend__ + "&action=playbacktime&subaction=" + subaction + "&time=" + str( self.playingPosition )
141                print "[Todic] reportPlaytime:" + url
142                open_url_safe(url)
143    
144    
145    
146    def getText2(nodelist):
147        rc = []
148        for node in nodelist:
149            if node.nodeType == node.TEXT_NODE:
150                rc.append(node.data)
151            else:
152                rc.append(getText(node.childNodes))
153        return ''.join(rc)
154    
155    
156    def getText(nodelist):
157        if nodelist.length == 0:
158            return ''
159        else:
160            if nodelist[0].childNodes.length == 0:
161                return ''
162            else:
163                return nodelist[0].childNodes[0].nodeValue
164    
165    
166    
167    def SaveFile(path, data):
168        file = open(path, 'w')
169        file.write(data)
170        file.close()
171    
172    
173    
174  def open_url(url):  def open_url(url):
175          req = urllib2.Request(url)      req = urllib2.Request(url)
176          content = urllib2.urlopen(req)      content = urllib2.urlopen(req)
177          data = content.read()      data = content.read()
178          content.close()      content.close()
179          return data      return data
180    
181    
182    # wraps open url in a catch-all exception handler
183    # usefull for periodic back-reporting that should not interrupt the program flow
184    def open_url_safe(url):
185        try:
186            return open_url(url)
187        except:
188            print "[Todic ]Some error during open_url call to ", url
189    
190    
191    
192  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]))  
193    
194        msg = open_url(__backend__ + "&action=messages")
195        msg = msg.strip()
196    
197        if msg != "":
198            dialog = xbmcgui.Dialog()
199            dialog.ok('XBMC Todic', msg)
200    
201        buildList(__backend__, "", False)  # call default list
202    
203        # Adde xtra items to root menu
204        listitem = xbmcgui.ListItem(
205            label="Søg film ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
206        listitem.setProperty('Fanart_Image', fanartImage)
207    
208        u = sys.argv[0] + "?mode=10&name="
209        xbmcplugin.addDirectoryItem(
210            handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
211    
212        # add search series
213        listitem = xbmcgui.ListItem(
214            label="Søg Serier ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
215        listitem.setProperty('Fanart_Image', fanartImage)
216    
217        u = sys.argv[0] + "?mode=11&name="
218        xbmcplugin.addDirectoryItem(
219            handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
220    
221        xbmcplugin.endOfDirectory(int(sys.argv[1]))
222    
223    
224    def buildList(url, title, endlist=True):
225        print '[TODIC]:' + str(url)
226    
227        link = open_url(url)
228        doc = parseString(link)
229        ty = doc.getElementsByTagName("meta")[0].getAttribute("type")
230        print '[TODIC]' + str(ty)
231    
232        if ty == 'clipList':
233            mode = '50'
234            folder = False
235        else:
236            mode = '1'
237            folder = True
238    
239        entries = doc.getElementsByTagName("entry")
240        l = len(entries)
241        description = ''
242        for entry in entries:
243            name = getText(entry.getElementsByTagName("title"))
244            url = getText(entry.getElementsByTagName("url"))
245            thumb = getText(entry.getElementsByTagName("cover"))
246            description = getText(entry.getElementsByTagName("description"))
247            playcount = getText(entry.getElementsByTagName("playcount"))
248    
249    
250            if playcount == '':
251                playcount = '0'
252            playcount = int(playcount)
253    
254    # print "name:" + name
255    #               print "url:" + url
256    #               print "thumb:" + thumb
257    #               print "description:" + description
258            listitem = xbmcgui.ListItem(
259                label=name, label2='test', iconImage='DefaultFolder.png', thumbnailImage=thumb)
260            listitem.setProperty('Fanart_Image', fanartImage)
261            if mode == '50':
262                infoLabels = {}
263                infoLabels['title'] = name
264                infoLabels['plot'] = description
265                infoLabels['playcount'] = playcount
266                listitem.setInfo('video', infoLabels)
267    
268            name = name.encode('UTF-8')
269            description = description.encode('UTF-8')
270    
271            u = sys.argv[0] + "?mode=" + urllib.quote(mode) + "&name=" + urllib.quote(
272                name) + "&url=" + urllib.quote(url) + "&description=" + urllib.quote(description)
273            xbmcplugin.addDirectoryItem(
274                handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)
275    
276        if (endlist == True):
277            xbmcplugin.endOfDirectory(int(sys.argv[1]))
278    
279    
280    def play_video(url, name, description):
281        param1 = parse_parameter_string(url)
282        clipkey = param1["clipkey"]
283    
284        print "[Todic] ClipKey:" + clipkey
285        detailurl = __backend__ + "&action=clipdetails&clipkey=" + clipkey
286        print "[Todic] detailURL = " + detailurl
287    
288        xml = open_url(detailurl)
289    
290        clipDetailsDoc = parseString(xml)
291        savedPosition = int( getText(clipDetailsDoc.getElementsByTagName("position")) )
292        playPosition = 0
293    
294        if (description == None or description == ""):
295            if (savedPosition > 0):
296                dialog = xbmcgui.Dialog()
297                #yes / true -afspil fra position
298                answer = dialog.yesno(heading='Todic', line1='Afspil fra gemt', nolabel='Fra start', yeslabel='Fortsæt')
299                if (answer == True):
300                    playPosition = savedPosition
301            
302            play_real_video(url, name, playPosition)
303    
304        else:
305            d = TodicMovieDialog()
306            d.setDetailsDoc(clipDetailsDoc)
307            d.setName(name)
308            d.setUrl(url)
309            d.setDescription(description)
310    
311            d.doModal()
312    
313    
314    def play_real_video(url, name, position):
315        xml = open_url(url)
316        print '[Todic] url: ' + str(url)
317        print '[Todic] xml: ' + xml
318        print '[Todic] pos: ' + str(position)
319    
320        doc = parseString(xml)
321        url = getText(doc.getElementsByTagName("url"))
322    
323        subtitleurl = getText(doc.getElementsByTagName("subtitles"))
324        subtitlesfile = os.path.join(datapath, 'temp.srt')
325    
326        # if old srt file exists delete it first
327        if os.path.isfile(subtitlesfile):
328            os.unlink(subtitlesfile)
329    
330        print '[TODIC] subs: ' + str(subtitleurl)
331        if len(subtitleurl) > 0:
332            subtitles = open_url(subtitleurl)
333            SaveFile(subtitlesfile, subtitles)
334            print 'TODIC downloaded subtitles'
335    
336        image = xbmc.getInfoImage('ListItem.Thumb')
337        listitem = xbmcgui.ListItem(
338            label=name, iconImage='DefaultVideo.png', thumbnailImage=image)
339        listitem.setInfo(type="Video", infoLabels={"Title": name})
340        listitem.setProperty('ResumeTime', '300')
341        listitem.setProperty('TotalTime', '3000')
342    
343        player = TodicPlayer(xbmc.PLAYER_CORE_AUTO)
344        player.play(str(url), listitem)
345    
346        # kan ikke loade subtitles hvis foerend playeren koerer
347        count = 0
348        while not xbmc.Player().isPlaying():
349            xbmc.sleep(250)
350            count += 1
351            if count > 10:
352                break
353    
354    
355    
356        if xbmc.Player().isPlaying():
357            if os.path.isfile(subtitlesfile):
358                player.setSubtitles(subtitlesfile)
359                print 'TODIC started subtitles'
360            else:
361                player.disableSubtitles()
362    
363    
364            if (position > 0):
365                while (player.getTotalTime() == 0.0): #Vent indtil vi har beregnet hvor langt klippet er
366                    xbmc.sleep(250)
367    
368                print "[Todic] totalTime " +  str( player.getTotalTime() )
369                player.seekTime(position)
370    
371    
372        #Holder python kørernde indtil at det bliver bedt om at stoppe
373        while (not xbmc.abortRequested):
374            player.tick()
375            xbmc.sleep(500)
376    
377    
 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)  
378    
379  def search():  def search():
380          search = getUserInput("Todic Søgning")      search = getUserInput("Todic Søgning")
381    
382        if (search != None and search != ""):
383            url = __backend__ + "&action=search&search=" + \
384                urllib.quote_plus(search)
385    
386            # print "[TODIC] Search start: " + search
387            # print "[TODIC] Search url: " + url
388    
389            buildList(url, "søgning")
390    
391    
392          url = __backend__ + "&action=search&search=" + urllib.quote_plus(search)  def searchSeries():
393        search = getUserInput("Todic Serie Søgning")
394    
395          print "[TODIC] Search start: " + search      if (search != None and search != ""):
396          print "[TODIC] Search url: " + url          url = __backend__ + "&action=searchseries&search=" + \
397                urllib.quote_plus(search)
398    
399          buildSubList(url, "søgning")          # print "[TODIC] Search start: " + search
400            # print "[TODIC] Search url: " + url
401    
402                    buildList(url, "serie søgning")
403    
404    
405                    #=================================== Tool Box =======================================
 #=================================== Tool Box =======================================  
406  # shows a more userfriendly notification  # shows a more userfriendly notification
407  def showMessage(heading, message):  def showMessage(heading, message):
408          duration = 15*1000      duration = 15 * 1000
409          xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( heading, message, duration) )      xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
410                            (heading, message, duration))
411    
412    
413  # raise a keyboard for user input  # raise a keyboard for user input
414  def getUserInput(title = "Input", default="", hidden=False):  def getUserInput(title="Input", default="", hidden=False):
415          result = None      result = None
416    
417          # Fix for when this functions is called with default=None      # Fix for when this functions is called with default=None
418          if not default:      if not default:
419                  default = ""          default = ""
420                            
421          keyboard = xbmc.Keyboard(default, title)      keyboard = xbmc.Keyboard(default, title)
422          keyboard.setHiddenInput(hidden)      keyboard.setHiddenInput(hidden)
423          keyboard.doModal()      keyboard.doModal()
424                    
425          if keyboard.isConfirmed():      if keyboard.isConfirmed():
426                  result = keyboard.getText()          result = keyboard.getText()
427                    
428          return result      return result
429    
430    
431  def get_params():  def get_params():
432          param=[]      return parse_parameter_string(sys.argv[2])
433          paramstring=sys.argv[2]  
434          if len(paramstring)>=2:  
435                  params=sys.argv[2]  def parse_parameter_string(paramstring):
436                  cleanedparams=params.replace('?','')      param = []
437                  if (params[len(params)-1]=='/'):      if len(paramstring) >= 2:
438                          params=params[0:len(params)-2]          params = paramstring
439                  pairsofparams=cleanedparams.split('&')          cleanedparams = params.replace('?', '')
440                  param={}          if (params[len(params) - 1] == '/'):
441                  for i in range(len(pairsofparams)):              params = params[0:len(params) - 2]
442                          splitparams={}          pairsofparams = cleanedparams.split('&')
443                          splitparams=pairsofparams[i].split('=')          param = {}
444                          if (len(splitparams))==2:          for i in range(len(pairsofparams)):
445                                  param[splitparams[0]]=splitparams[1]                                                  splitparams = {}
446          return param              splitparams = pairsofparams[i].split('=')
447                if (len(splitparams)) == 2:
448                    param[splitparams[0]] = splitparams[1]
449        return param
450    
 params = get_params()  
 url = None  
 name = None  
 mode = None  
451    
452  params = get_params()  params = get_params()
453  url = None  url = None
454  name = None  name = None
455  mode = None  mode = None
456    description = None
457    
458    
459    #print params
460    
461    try:
462        url = urllib.unquote_plus(params["url"])
463    except:
464        pass
465  try:  try:
466          url = urllib.unquote_plus(params["url"])      name = urllib.unquote_plus(params["name"])
467  except:  except:
468          pass      pass
469  try:  try:
470          name = urllib.unquote_plus(params["name"])      mode = int(params["mode"])
471  except:  except:
472          pass      pass
473  try:  try:
474          mode = int(params["mode"])      description = urllib.unquote_plus(params["description"])
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 == 10:  try:
482          search()      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    
 elif mode == 50:  
         play_video(url, name)  
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, description)

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

  ViewVC Help
Powered by ViewVC 1.1.20