--- misc/xbmc/plugin.video.todic/default.py 2011/11/27 13:03:36 1633
+++ misc/xbmc/plugin.video.todic/default.py 2019/02/28 11:12:40 3252
@@ -1,190 +1,503 @@
+
+# This Python file uses the following encoding: utf-8
+
'''
Todic plugin for XBMC
- Version 0.0.2
+ Version 1.7.3
'''
import sys
-import cgi as urlparse
+import os
+
import xbmc
import xbmcaddon
import xbmcgui
import xbmcplugin
import urllib
-import urllib2, re
+import urllib2
+
+# import pprint
+
+from xml.dom.minidom import parseString
+from time import time
__addon__ = xbmcaddon.Addon(id='plugin.video.todic')
__key__ = __addon__.getSetting('xbmckey').lower()
-__backend__ = "http://todic.dk/xbmc.php?xbmckey=" + __key__
+__entrypoint__ = __addon__.getSetting('entrypoint').lower()
+__backend__ = "https://todic.dk/xbmc.php?xbmckey=" + __key__
+
+if __entrypoint__ == "alternative":
+ __backend__ = "https://alt.todic.dk/xbmc.php?xbmckey=" + __key__
+
+if __entrypoint__ == "testing":
+ __backend__ = "https://todic.dk/xbmc-beta.php?xbmckey=" + __key__
+
+print( "[Todic] entrypoint: " + __entrypoint__ )
+print( "[Todic] backend: " + __backend__ )
+
+
+fanartImage = os.path.join(__addon__.getAddonInfo('path'), 'movie_bg_blur.jpg')
+datapath = xbmc.translatePath(
+ 'special://profile/addon_data/plugin.video.todic/')
+
+ADDON_PATH = __addon__.getAddonInfo('path')
+SkinMasterPath = os.path.join(ADDON_PATH, 'skins') + '/'
+MySkinPath = (os.path.join(SkinMasterPath, '720p')) + '/'
+MySkin = 'main.xml'
+
+
+class TodicMovieDialog(xbmcgui.WindowXMLDialog):
+
+ def __new__(cls):
+ return super(TodicMovieDialog, cls).__new__(cls, "main.xml", ADDON_PATH)
+
+ def __init__(self):
+ super(TodicMovieDialog, self).__init__()
+ self.position = 0
+
+ def onClick(self, controlId):
+ print( "[Todic] MovieDialog OnClick: " + str(controlId) )
+
+ if (controlId == 50):
+ self.close()
+ play_real_video(self.url, self.name, 0)
+
+ if (controlId == 51):
+ self.close()
+ play_real_video(self.url, self.name, self.position)
+
+ if (controlId == 98):
+ self.close()
+
+ def onInit(self):
+
+ print( "[Todic] MovieDialog onInit" )
+ self.getControl(1).setLabel(self.name)
+ self.getControl(2).setLabel(self.moviegroups)
+ self.getControl(3).setLabel(self.description)
+ self.getControl(10).setLabel(self.playlength)
+ self.getControl(11).setLabel(self.codecdetails)
+
+ if (self.position > 0):
+ self.getControl(51).setVisible(True)
+ self.getControl(50).setPosition(100, 570)
+ self.getControl(51).setPosition(450, 570)
+ self.getControl(50).controlLeft( self.getControl(51) )
+ self.getControl(50).controlRight( self.getControl(51) )
+ else:
+ self.getControl(51).setVisible(False)
+
+ #orig_img_width = self.getControl(40).getWidth()
+ #self.starwidth = (float(self.imdbrating) / 10.0) * orig_img_width
+ #self.getControl(40).setWidth(int(self.starwidth))
+
+ def setDetailsDoc(self, detailsDoc):
+ print( "[Todic] MovieDialog setDetailsDoc:")
+ self.imdbrating = getText(detailsDoc.getElementsByTagName("imdbrating"))
+ self.moviegroups = getText(detailsDoc.getElementsByTagName("moviegroups"))
+ self.playlength = getText(detailsDoc.getElementsByTagName("playlength"))
+ self.codecdetails = getText(detailsDoc.getElementsByTagName("codecdetails"))
+ self.position = int( getText(detailsDoc.getElementsByTagName("position")) )
+
+ def setUrl(self, url):
+ self.url = url
+
+ def setName(self, name):
+ self.name = name
+
+ def setDescription(self, description):
+ self.description = description
+
+
+class TodicPlayer(xbmc.Player):
+
+ def __init__(self, *args, **kwargs):
+ # xbmc.Player.__init__(selv,*args,**kwargs)
+ xbmc.Player.__init__(self)
+ self.stopped = False
+ self.started = False
+ self.playingPosition = 0.0
+ self.lastReport = 0
+ print( "[TodicPlayer] init")
+
+ def onPlayBackStarted(self):
+ self.started = True
+ print( "[TodicPlayer] : started")
+
+ #When user presses stop, we report back the the position registered in the last call to self.tick()
+ def onPlayBackStopped(self):
+ self.stopped = True
+ print( "[TodicPlayer] : stopped")
+ self.reportPlaytime("stopped")
+
+ def onPlayBackPaused(self):
+ print( "[TodicPlayer] : paused")
+ self.reportPlaytime("paused")
+
+ def onPlayBackResumed(self):
+ print( "[TodicPlayer] : resumed")
+ self.reportPlaytime("resumed")
+
+
+ def onPlayBackEnded(self):
+ self.stopped = True
+ print( "[TodicPlayer] : ended")
+ self.reportPlaytime("ended")
+
+ def tick(self):
+ #print "[Todic] Tick: " + str( self.isPlaying() )
+ if ( self.isPlaying() ):
+ tmpTime = self.getTime()
+
+ #only report time if it has changed in the mean time
+ if tmpTime != self.playingPosition:
+ self.playingPosition = tmpTime
+ now = time()
+ #print "[Todic] tick " + str(now) + " " + str(self.lastReport) + " : " +str(now - self.lastReport)
+ if ( (now - self.lastReport) > 60.0):
+ self.lastReport = now
+ self.reportPlaytime("playing")
+
+ def reportPlaytime(self, subaction):
+ if (self.playingPosition > 60):
+ url = __backend__ + "&action=playbacktime&subaction=" + subaction + "&time=" + str( self.playingPosition )
+ print( "[Todic] reportPlaytime:" + url)
+ open_url_safe(url)
+
+
+
+def getText2(nodelist):
+ rc = []
+ for node in nodelist:
+ if node.nodeType == node.TEXT_NODE:
+ rc.append(node.data)
+ else:
+ rc.append(getText(node.childNodes))
+ return ''.join(rc)
+
+
+def getText(nodelist):
+ if nodelist.length == 0:
+ return ''
+ else:
+ if nodelist[0].childNodes.length == 0:
+ return ''
+ else:
+ return nodelist[0].childNodes[0].nodeValue
+
+
+
+def SaveFile(path, data):
+ file = open(path, 'w')
+ file.write(data)
+ file.close()
+
+
def open_url(url):
- req = urllib2.Request(url)
- content = urllib2.urlopen(req)
- data = content.read()
- content.close()
- return data
+ req = urllib2.Request(url)
+ content = urllib2.urlopen(req)
+ data = content.read()
+ content.close()
+ return data
+
+
+# wraps open url in a catch-all exception handler
+# usefull for periodic back-reporting that should not interrupt the program flow
+def open_url_safe(url):
+ try:
+ return open_url(url)
+ except:
+ print( "[Todic] Some error during open_url call to ", url)
+
+
def rootMenu():
- link = open_url(__backend__)
- m=re.compile('
(.+?)(.+?)').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('(.+?)(.+?)(.+?)').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('(.+?)(.+?)(.+?)').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]))
+ msg = open_url(__backend__ + "&action=messages")
+ msg = msg.strip()
+
+ if msg != "":
+ dialog = xbmcgui.Dialog()
+ dialog.ok('XBMC Todic', msg)
+
+ buildList(__backend__, "", False) # call default list
+
+ # Adde xtra items to root menu
+ listitem = xbmcgui.ListItem(
+ label="Søg Film ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
+ listitem.setProperty('Fanart_Image', fanartImage)
+
+ u = sys.argv[0] + "?mode=10&name="
+ xbmcplugin.addDirectoryItem(
+ handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
+
+ # add search series
+ listitem = xbmcgui.ListItem(
+ label="Søg Serier ...", iconImage='DefaultFolder.png', thumbnailImage='DefaultFolder.png')
+ listitem.setProperty('Fanart_Image', fanartImage)
+
+ u = sys.argv[0] + "?mode=11&name="
+ xbmcplugin.addDirectoryItem(
+ handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=True)
+
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
+
+
+def buildList(url, title, endlist=True):
+ print( '[Todic]:' + str(url) )
+
+ link = open_url(url)
+ doc = parseString(link)
+ ty = doc.getElementsByTagName("meta")[0].getAttribute("type")
+ print( '[Todic]' + str(ty))
+
+ if ty == 'clipList':
+ mode = '50'
+ folder = False
+ else:
+ mode = '1'
+ folder = True
+
+ entries = doc.getElementsByTagName("entry")
+ l = len(entries)
+
+ for entry in entries:
+ name = getText(entry.getElementsByTagName("title"))
+ url = getText(entry.getElementsByTagName("url"))
+ thumb = getText(entry.getElementsByTagName("cover"))
+ playcount = getText(entry.getElementsByTagName("playcount"))
+
+
+ if playcount == '':
+ playcount = '0'
+ playcount = int(playcount)
+
+# print "name:" + name
+# print "url:" + url
+# print "thumb:" + thumb
+ listitem = xbmcgui.ListItem(
+ label=name, label2='test', iconImage='DefaultFolder.png', thumbnailImage=thumb)
+ listitem.setProperty('Fanart_Image', fanartImage)
+ listitem.addContextMenuItems([('Refresh', 'Container.Refresh')])
+
+ if mode == '50':
+ infoLabels = {}
+ infoLabels['title'] = name
+ infoLabels['playcount'] = playcount
+ listitem.setInfo('video', infoLabels)
+
+ name = name.encode('UTF-8')
+
+ u = sys.argv[0] + "?mode=" + urllib.quote(mode) + "&name=" + urllib.quote(
+ name) + "&url=" + urllib.quote(url)
+ xbmcplugin.addDirectoryItem(
+ handle=int(sys.argv[1]), url=u, listitem=listitem, isFolder=folder, totalItems=l)
+
+ if (endlist == True):
+ xbmcplugin.endOfDirectory(int(sys.argv[1]))
def play_video(url, name):
- link = open_url(url)
- match=re.compile('(.+?)').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)
+ description = ""
+ playPosition = 0
+ savedPosition = 0
+ try:
+ param1 = parse_parameter_string(url)
+ clipkey = param1["clipkey"]
+
+ print( "[Todic] ClipKey:" + clipkey)
+ detailurl = __backend__ + "&action=clipdetails&clipkey=" + clipkey
+ print( "[Todic] detailURL = " + detailurl)
+
+ xml = open_url(detailurl)
+
+ clipDetailsDoc = parseString(xml)
+ savedPosition = int( getText(clipDetailsDoc.getElementsByTagName("position")) )
+ description = getText(clipDetailsDoc.getElementsByTagName("description"))
+ except:
+ print( "[Todic] Unexpected error:", sys.exc_info()[0] )
+
+ if (description == None or description == ""):
+ if (savedPosition > 0):
+ dialog = xbmcgui.Dialog()
+ #yes / true -afspil fra position
+ answer = dialog.yesno(heading='Todic', line1='Afspil fra sidste position', nolabel='Fra start', yeslabel='Fortsæt')
+ if (answer == True):
+ playPosition = savedPosition
+
+ play_real_video(url, name, playPosition)
+
+ else:
+ d = TodicMovieDialog()
+ d.setDetailsDoc(clipDetailsDoc)
+ d.setName(name)
+ d.setUrl(url)
+ d.setDescription(description)
+
+ d.doModal()
+
+
+def play_real_video(url, name, position):
+ xml = open_url(url)
+ print( '[Todic] url: ' + str(url) )
+ print( '[Todic] xml: ' + xml )
+ print( '[Todic] pos: ' + str(position) )
+
+ doc = parseString(xml)
+ url = getText(doc.getElementsByTagName("url"))
+
+ subtitleurl = getText(doc.getElementsByTagName("subtitles"))
+
+
+ print( '[Todic] subs: ' + str(subtitleurl) )
+
+ image = xbmc.getInfoImage('ListItem.Thumb')
+ listitem = xbmcgui.ListItem(
+ label=name, iconImage='DefaultVideo.png', thumbnailImage=image)
+ listitem.setInfo(type="Video", infoLabels={"Title": name})
+
+ listitem.setProperty('StartOffset', str(position) )
+
+ if len(subtitleurl) > 0:
+ listitem.setSubtitles([subtitleurl])
+
+ player = TodicPlayer()
+ player.play(str(url), listitem)
+
+
+ #Holder python kørernde indtil at det bliver bedt om at stoppe
+ while (not xbmc.abortRequested):
+ player.tick()
+ xbmc.sleep(500)
+
+
def search():
- search = getUserInput("Todic Søgning")
+ search = getUserInput("Todic Søgning")
+
+ if (search != None and search != ""):
+ url = __backend__ + "&action=search&search=" + \
+ urllib.quote_plus(search)
+
+ # print "[Todic] Search start: " + search
+ # print "[Todic] Search url: " + url
+
+ buildList(url, "søgning")
+
- url = __backend__ + "&action=search&search=" + urllib.quote_plus(search)
+def searchSeries():
+ search = getUserInput("Todic Serie Søgning")
- #print "[TODIC] Search start: " + search
- #print "[TODIC] Search url: " + url
+ if (search != None and search != ""):
+ url = __backend__ + "&action=searchseries&search=" + \
+ urllib.quote_plus(search)
- buildSubList(url, "søgning")
+ # print "[Todic] Search start: " + search
+ # print "[Todic] Search url: " + url
-
+ buildList(url, "serie søgning")
-
-#=================================== Tool Box =======================================
+#=================================== Tool Box =======================================
# shows a more userfriendly notification
def showMessage(heading, message):
- duration = 15*1000
- xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' % ( heading, message, duration) )
+ duration = 15 * 1000
+ xbmc.executebuiltin('XBMC.Notification("%s", "%s", %s)' %
+ (heading, message, duration))
# raise a keyboard for user input
-def getUserInput(title = "Input", default="", hidden=False):
- result = None
+def getUserInput(title="Input", default="", hidden=False):
+ result = None
- # Fix for when this functions is called with default=None
- if not default:
- default = ""
-
- keyboard = xbmc.Keyboard(default, title)
- keyboard.setHiddenInput(hidden)
- keyboard.doModal()
-
- if keyboard.isConfirmed():
- result = keyboard.getText()
-
- return result
+ # Fix for when this functions is called with default=None
+ if not default:
+ default = ""
+
+ keyboard = xbmc.Keyboard(default, title)
+ keyboard.setHiddenInput(hidden)
+ keyboard.doModal()
+
+ if keyboard.isConfirmed():
+ result = keyboard.getText()
+
+ return result
def get_params():
- param=[]
- paramstring=sys.argv[2]
- if len(paramstring)>=2:
- params=sys.argv[2]
- cleanedparams=params.replace('?','')
- if (params[len(params)-1]=='/'):
- params=params[0:len(params)-2]
- pairsofparams=cleanedparams.split('&')
- param={}
- for i in range(len(pairsofparams)):
- splitparams={}
- splitparams=pairsofparams[i].split('=')
- if (len(splitparams))==2:
- param[splitparams[0]]=splitparams[1]
- return param
+ return parse_parameter_string(sys.argv[2])
+
+
+def parse_parameter_string(paramstring):
+ param = []
+ if len(paramstring) >= 2:
+ params = paramstring
+ cleanedparams = params.replace('?', '')
+ if (params[len(params) - 1] == '/'):
+ params = params[0:len(params) - 2]
+ pairsofparams = cleanedparams.split('&')
+ param = {}
+ for i in range(len(pairsofparams)):
+ splitparams = {}
+ splitparams = pairsofparams[i].split('=')
+ if (len(splitparams)) == 2:
+ param[splitparams[0]] = splitparams[1]
+ return param
-params = get_params()
-url = None
-name = None
-mode = None
params = get_params()
url = None
name = None
mode = None
+
+#print params
+
try:
- url = urllib.unquote_plus(params["url"])
+ url = urllib.unquote_plus(params["url"])
except:
- pass
+ pass
try:
- name = urllib.unquote_plus(params["name"])
+ name = urllib.unquote_plus(params["name"])
except:
- pass
+ pass
try:
- mode = int(params["mode"])
+ mode = int(params["mode"])
except:
- pass
+ pass
-if mode == None:
- #build main menu
- rootMenu()
-
-elif mode == 1:
- #build list of movie starting letters
- buildList(url, name)
-elif mode == 2:
- #build list of series
- buildSubList(url, name)
-elif mode == 10:
- search()
-
+try:
+ open_url("http://todic.dk")
+except:
+ showMessage("Fejl", "Kunne ikke forbinde til todic.dk")
+ exit()
-elif mode == 50:
- play_video(url, name)
+if url == 'refresh':
+ # xbmc.output("[tvserver] Container.Refresh") #20130418 xbmc.output virker
+ # ikke med XBMC12
+ xbmc.executebuiltin("Container.Refresh")
-# xbmcplugin.endOfDirectory(int(sys.argv[1]))
+elif mode == None:
+ # build main menu
+ rootMenu()
+elif mode == 1:
+ # build list of movie starting letters
+ buildList(url, name)
+
+elif mode == 10:
+ search()
+
+elif mode == 11:
+ searchSeries()
+
+
+elif mode == 50:
+ play_video(url, name)