# This Python file uses the following encoding: utf-8 ''' Todic plugin for XBMC Version 0.1.0 ''' import sys import os import xbmc import xbmcaddon import xbmcgui import xbmcplugin import urllib 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__ = "https://todic.dk/xbmc.php?xbmckey=" + __key__ 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 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, xbmc.PLAYER_CORE_MPLAYER) 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 onPlayBackEnded(self): self.stopped = True print "[TodicPlayer] : ended" self.reportPlaytime("ended") def tick(self): if ( self.isPlaying() ): self.playingPosition = self.getTime() 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 # 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(): 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) description = '' for entry in entries: name = getText(entry.getElementsByTagName("title")) url = getText(entry.getElementsByTagName("url")) thumb = getText(entry.getElementsByTagName("cover")) description = getText(entry.getElementsByTagName("description")) playcount = getText(entry.getElementsByTagName("playcount")) if playcount == '': playcount = '0' playcount = int(playcount) # print "name:" + name # print "url:" + url # print "thumb:" + thumb # print "description:" + description listitem = xbmcgui.ListItem( label=name, label2='test', iconImage='DefaultFolder.png', thumbnailImage=thumb) listitem.setProperty('Fanart_Image', fanartImage) if mode == '50': infoLabels = {} infoLabels['title'] = name infoLabels['plot'] = description infoLabels['playcount'] = playcount listitem.setInfo('video', infoLabels) name = name.encode('UTF-8') description = description.encode('UTF-8') u = sys.argv[0] + "?mode=" + urllib.quote(mode) + "&name=" + urllib.quote( name) + "&url=" + urllib.quote(url) + "&description=" + urllib.quote(description) 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, description): 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")) ) playPosition = 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 gemt', 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.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")) subtitlesfile = os.path.join(datapath, 'temp.srt') # if old srt file exists delete it first if os.path.isfile(subtitlesfile): os.unlink(subtitlesfile) print '[TODIC] subs: ' + str(subtitleurl) if len(subtitleurl) > 0: subtitles = open_url(subtitleurl) SaveFile(subtitlesfile, subtitles) print 'TODIC downloaded subtitles' image = xbmc.getInfoImage('ListItem.Thumb') listitem = xbmcgui.ListItem( label=name, iconImage='DefaultVideo.png', thumbnailImage=image) listitem.setInfo(type="Video", infoLabels={"Title": name}) listitem.setProperty('ResumeTime', '300') listitem.setProperty('TotalTime', '3000') player = TodicPlayer(xbmc.PLAYER_CORE_AUTO) player.play(str(url), listitem) # kan ikke loade subtitles hvis foerend playeren koerer count = 0 while not xbmc.Player().isPlaying(): xbmc.sleep(250) count += 1 if count > 10: break if xbmc.Player().isPlaying(): if os.path.isfile(subtitlesfile): player.setSubtitles(subtitlesfile) print 'TODIC started subtitles' else: player.disableSubtitles() if (position > 0): while (player.getTotalTime() == 0.0): #Vent indtil vi har beregnet hvor langt klippet er xbmc.sleep(250) print "[Todic] totalTime " + str( player.getTotalTime() ) player.seekTime(position) #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") 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") def searchSeries(): search = getUserInput("Todic Serie Søgning") if (search != None and search != ""): url = __backend__ + "&action=searchseries&search=" + \ urllib.quote_plus(search) # print "[TODIC] Search start: " + search # print "[TODIC] Search url: " + url buildList(url, "serie søgning") #=================================== Tool Box ======================================= # shows a more userfriendly notification def showMessage(heading, message): 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 # 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(): 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 description = None #print params try: url = urllib.unquote_plus(params["url"]) except: pass try: name = urllib.unquote_plus(params["name"]) except: pass try: mode = int(params["mode"]) except: pass try: description = urllib.unquote_plus(params["description"]) except: pass try: open_url("http://todic.dk") except: showMessage("Fejl", "Kunne ikke forbinde til todic.dk") exit() if url == 'refresh': # xbmc.output("[tvserver] Container.Refresh") #20130418 xbmc.output virker # ikke med XBMC12 xbmc.executebuiltin("Container.Refresh") 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, description)