syntax corrections and version bump

This commit is contained in:
desolat 2012-10-06 12:21:30 +02:00
parent dab2624c88
commit ad4637f4cf
15 changed files with 1960 additions and 1950 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
*.pyo *.pyo
*.pyc *.pyc
.*

View file

@ -1,17 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.makemkvbluray" name="BluRay Player with MakeMKV" <addon
version="1.1.0" provider-name="Magnetism"> id="plugin.makemkvbluray"
<requires> name="BluRay Player with MakeMKV"
<import addon="xbmc.python" version="2.0" /> version="1.1.1"
</requires> provider-name="desolat">
<extension point="xbmc.python.pluginsource" library="default.py"> <requires>
<provides>video</provides> <import addon="xbmc.python" version="2.0" />
</extension> </requires>
<extension point="xbmc.service" library="service.py"> <extension point="xbmc.python.pluginsource" library="default.py">
</extension> <provides>video</provides>
<extension point="xbmc.addon.metadata"> </extension>
<summary>Play BluRays from XBMC with MakeMKV</summary> <extension point="xbmc.service" library="service.py">
<description>Awesomeness </description> </extension>
<platform>all</platform> <extension point="xbmc.addon.metadata">
</extension> <summary>Play BluRays from XBMC with MakeMKV</summary>
</addon> <description>Uses MakeMKV streaming ability to play BlueRay Discs</description>
<platform>all</platform>
</extension>
</addon>

View file

@ -1,194 +1,194 @@
import xbmc, xbmcgui, subprocess, os, time, sys, urllib, re import xbmc, xbmcgui, subprocess, os, time, sys, urllib, re
import xbmcplugin, xbmcaddon import xbmcplugin, xbmcaddon
__scriptname__ = "MakeMKV BluRay Watch Plugin" __scriptname__ = "MakeMKV BluRay Watch Plugin"
__scriptID__ = "plugin.makemkvbluray" __scriptID__ = "plugin.makemkvbluray"
__author__ = "Magnetism" __author__ = "Magnetism"
__url__ = "http://bultsblog.com/arne" __url__ = "http://bultsblog.com/arne"
__credits__ = "" __credits__ = ""
__version__ = "0.1" __version__ = "0.1"
__addon__ = xbmcaddon.Addon(__scriptID__) __addon__ = xbmcaddon.Addon(__scriptID__)
# Shared resources # Shared resources
BASE_RESOURCE_PATH = os.path.join( __addon__.getAddonInfo('path'), "resources" ) BASE_RESOURCE_PATH = os.path.join( __addon__.getAddonInfo('path'), "resources" )
sys.path.append( os.path.join( BASE_RESOURCE_PATH, "lib" ) ) sys.path.append( os.path.join( BASE_RESOURCE_PATH, "lib" ) )
__language__ = __addon__.getLocalizedString __language__ = __addon__.getLocalizedString
_ = sys.modules[ "__main__" ].__language__ _ = sys.modules[ "__main__" ].__language__
import settings, file, mkvparser, brlog, makemkv import settings, file, mkvparser, brlog, makemkv
_log = brlog.BrLog() _log = brlog.BrLog()
_log.info('Starting the BluRay script') _log.info('Starting the BluRay script')
class BluRayStarter: class BluRayStarter:
def __init__(self): def __init__(self):
_log.info('Staring') _log.info('Staring')
self.settings = settings.BluRaySettings() self.settings = settings.BluRaySettings()
self.makemkv = makemkv.MakeMkvInteraction() self.makemkv = makemkv.MakeMkvInteraction()
def killAndStart(self, mkvStart): def killAndStart(self, mkvStart):
if self.settings.local: if self.settings.local:
_log.info('Running makemkvcon locally') _log.info('Running makemkvcon locally')
self.killMkv() self.killMkv()
# Determine if we're doing the disc or if we're browsing.. # Determine if we're doing the disc or if we're browsing..
_log.info(mkvStart) _log.info(mkvStart)
return subprocess.Popen(mkvStart, shell=True) return subprocess.Popen(mkvStart, shell=True)
else: else:
_log.info('connecting to remote stream, returning fake file browse class..') _log.info('connecting to remote stream, returning fake file browse class..')
return file.FakeFile() return file.FakeFile()
def killMkv(self): def killMkv(self):
# Linux # Linux
try : try :
_log.info('attempting linux kill of makemkvcon') _log.info('attempting linux kill of makemkvcon')
subprocess.call('killall -9 makemkvcon', shell=True) subprocess.call('killall -9 makemkvcon', shell=True)
_log.info('Linux call successful') _log.info('Linux call successful')
except: except:
pass pass
#Windows. #Windows.
try : try :
_log.info('attempting windows kill of makemkvcon') _log.info('attempting windows kill of makemkvcon')
subprocess.call('taskkill /F /IM makemkvcon.exe', shell=True) subprocess.call('taskkill /F /IM makemkvcon.exe', shell=True)
_log.info('Windows call successful') _log.info('Windows call successful')
except: except:
pass pass
def browse(self, url) : def browse(self, url) :
_log.info('starting browser handler') _log.info('starting browser handler')
h = mkvparser.BrowseHandler() h = mkvparser.BrowseHandler()
h.start(url) h.start(url)
for k,v in h.titleMap.iteritems() : #@UnusedVariable for k,v in h.titleMap.iteritems() : #@UnusedVariable
self.addLink("%s %s, %s %s" %(_(50005), v['duration'], _(50006), v['chaptercount']),v['file']) self.addLink("%s %s, %s %s" %(_(50005), v['duration'], _(50006), v['chaptercount']),v['file'])
def getMainFeatureTitle(self, url): def getMainFeatureTitle(self, url):
h = mkvparser.BrowseHandler() h = mkvparser.BrowseHandler()
h.start(url) h.start(url)
# Play the longest feature on the disc: # Play the longest feature on the disc:
largest = 0 largest = 0
largestTitle = '' largestTitle = ''
for k,v in h.titleMap.iteritems() : #@UnusedVariable for k,v in h.titleMap.iteritems() : #@UnusedVariable
m = re.search('(\d+):(\d+):(\d+)', v['duration']) m = re.search('(\d+):(\d+):(\d+)', v['duration'])
length = int(m.group(1)) * 3600 + int(m.group(2)) * 60 + int(m.group(3)) length = int(m.group(1)) * 3600 + int(m.group(2)) * 60 + int(m.group(3))
if length > largest : if length > largest :
largest = length largest = length
largestTitle = v['file'] largestTitle = v['file']
_log.info('largest: %d, %s' %(largest,largestTitle)) _log.info('largest: %d, %s' %(largest,largestTitle))
return largestTitle return largestTitle
def handleListing(self): def handleListing(self):
mode = self.settings.paramMode mode = self.settings.paramMode
_log.info( 'mode: ' + str(mode)) _log.info( 'mode: ' + str(mode))
if mode ==None: if mode == None:
_log.info('Showing categories') _log.info('Showing categories')
self.CATEGORIES() self.CATEGORIES()
_log.info('Showing categories done') _log.info('Showing categories done')
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
if mode == 1 : if mode == 1 :
_log.info( 'Entering Disc mode') _log.info( 'Entering Disc mode')
self.process(self.makemkv.startStream(self.settings.disc)) self.process(self.makemkv.startStream(self.settings.disc))
elif mode == 3 : elif mode == 3 :
_log.info( 'Entering Remote mode') _log.info( 'Entering Remote mode')
mystarter = BluRayStarter() mystarter = BluRayStarter()
mystarter.process('') mystarter.process('')
elif mode == 2: elif mode == 2:
_log.info( 'Entering Browse mode') _log.info( 'Entering Browse mode')
d = xbmcgui.Dialog() d = xbmcgui.Dialog()
choice = d.browse(1, 'Select folder', 'video', 'index.bdmv|.iso|.isoRenamedMeansSkip!|.MDS|.CUE|.CDI|.CCD', False, False, '') choice = d.browse(1, 'Select folder', 'video', 'index.bdmv|.iso|.isoRenamedMeansSkip!|.MDS|.CUE|.CDI|.CCD', False, False, '')
if choice <> '': if choice <> '':
self.process(self.makemkv.startFileStream(choice)) self.process(self.makemkv.startFileStream(choice))
if mode == 20: if mode == 20:
self.settings.showSettings() self.settings.showSettings()
def process(self, ready): def process(self, ready):
try : try :
if ready: if ready:
_log.info( 'Stream ready. ') _log.info( 'Stream ready. ')
# the Stream has started, start auto playback? # the Stream has started, start auto playback?
if self.settings.autoPlay: if self.settings.autoPlay:
_log.info( 'Autoplay selected') _log.info( 'Autoplay selected')
title = self.getMainFeatureTitle(self.settings.rootURL) title = self.getMainFeatureTitle(self.settings.rootURL)
_log.info( 'Main feature determined to be : ' + title) _log.info( 'Main feature determined to be : ' + title)
opener = urllib.URLopener() opener = urllib.URLopener()
testfile = '' testfile = ''
try: try:
testfile = title testfile = title
opener.open(testfile) opener.open(testfile)
except IOError: except IOError:
testfile = '' testfile = ''
del opener del opener
if testfile<>'': if testfile<>'':
_log.info( 'Playing file ' + testfile) _log.info( 'Playing file ' + testfile)
li = xbmcgui.ListItem(path = testfile) li = xbmcgui.ListItem(path = testfile)
li.setProperty('IsPlayable', 'true') li.setProperty('IsPlayable', 'true')
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, li) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, li)
else: else:
self.message(_(50071)) self.message(_(50071))
xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem()) xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem())
else: else:
# Add the selections as selectable files. # Add the selections as selectable files.
self.browse(self.settings.rootURL) self.browse(self.settings.rootURL)
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
except : except :
self.message(_(50072)) self.message(_(50072))
self.pDialog.close() self.pDialog.close()
xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem()) xbmcplugin.setResolvedUrl(int(sys.argv[1]), False, xbmcgui.ListItem())
raise raise
def CATEGORIES(self): def CATEGORIES(self):
# Disc # Disc
if self.settings.enableDisc: if self.settings.enableDisc:
disclist = self.makemkv.discList() disclist = self.makemkv.discList()
for disc in disclist: for disc in disclist:
self.addDir(_(50061) %(disc[0], disc[1]),1, True, disc[0], disc[1]) self.addDir(_(50061) %(disc[0], disc[1]),1, True, disc[0], disc[1])
for disc in disclist: for disc in disclist:
self.addDir(_(50062) %(disc[0], disc[1]),1, False, disc[0], disc[1]) self.addDir(_(50062) %(disc[0], disc[1]),1, False, disc[0], disc[1])
# Filelocation # Filelocation
if self.settings.enableFile: if self.settings.enableFile:
self.addDir(_(50063),2, True) self.addDir(_(50063),2, True)
self.addDir(_(50064),2, False) self.addDir(_(50064),2, False)
self.addDir(_(50060),20, True, '0', 'settings', False) self.addDir(_(50060),20, True, '0', 'settings', False)
xbmcplugin.endOfDirectory(int(sys.argv[1])) xbmcplugin.endOfDirectory(int(sys.argv[1]))
def addDir(self, name,mode, autoplay, disc = '0', disc_title ='idontknow', isPlayable = True): def addDir(self, name,mode, autoplay, disc = '0', disc_title ='idontknow', isPlayable = True):
u=sys.argv[0]+"?mode="+str(mode)+"&autoplay="+urllib.quote_plus(str(autoplay)) + "&disc=" + disc u=sys.argv[0]+"?mode="+str(mode)+"&autoplay="+urllib.quote_plus(str(autoplay)) + "&disc=" + disc
_log.info(u) _log.info(u)
icon = "DefaultVideoPlaylists.png" icon = "DefaultVideoPlaylists.png"
if autoplay: if autoplay:
icon= "DefaultVideo.png" icon= "DefaultVideo.png"
liz=xbmcgui.ListItem(name, iconImage=icon, thumbnailImage='') liz=xbmcgui.ListItem(name, iconImage=icon, thumbnailImage='')
if autoplay and isPlayable: if autoplay and isPlayable:
liz.setProperty("IsPlayable", "true") liz.setProperty("IsPlayable", "true")
liz.setInfo( type="Video", infoLabels={ "Title": name } ) liz.setInfo( type="Video", infoLabels={ "Title": name } )
_log.info(name) _log.info(name)
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz, isFolder= not autoplay) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=liz, isFolder= not autoplay)
def addLink(self, name,url): def addLink(self, name,url):
liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png", thumbnailImage='') liz=xbmcgui.ListItem(name, iconImage="DefaultVideo.png", thumbnailImage='')
liz.setInfo( type="Video", infoLabels={ "Title": name } ) liz.setInfo( type="Video", infoLabels={ "Title": name } )
liz.setProperty("IsPlayable" , "true") liz.setProperty("IsPlayable" , "true")
xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=liz) xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=url,listitem=liz)
def message(self, messageText): def message(self, messageText):
dialog = xbmcgui.Dialog() dialog = xbmcgui.Dialog()
dialog.ok("Info", messageText) dialog.ok("Info", messageText)
_log.info("args") _log.info("args")
for arg in sys.argv: for arg in sys.argv:
_log.info(arg) _log.info(arg)
_log.info("done args") _log.info("done args")
mydisplay = BluRayStarter() mydisplay = BluRayStarter()
mydisplay.handleListing() mydisplay.handleListing()

View file

@ -1,41 +1,41 @@
<strings> <strings>
<string id="50001">MakeMKV location</string> <string id="50001">MakeMKV location</string>
<string id="50002">Autoplay main feature</string> <string id="50002">Autoplay main feature</string>
<string id="51000">Remote Setup</string> <string id="51000">Remote Setup</string>
<string id="51001">Remote IP address</string> <string id="51001">Remote IP address</string>
<string id="51002">Local Port number</string> <string id="51002">Local Port number</string>
<string id="51003">Seconds to wait for stream</string> <string id="51003">Seconds to wait for stream</string>
<string id="51004">General Settings</string> <string id="51004">General Settings</string>
<string id="51005">Browseable Options</string> <string id="51005">Browseable Options</string>
<string id="51006">Enable Disc support</string> <string id="51006">Enable Disc support</string>
<string id="51007">Enable File location support</string> <string id="51007">Enable File location support</string>
<string id="51008">Enable Remote location support</string> <string id="51008">Enable Remote location support</string>
<string id="51009">Remote Port number</string> <string id="51009">Remote Port number</string>
<!-- Chapter browse --> <!-- Chapter browse -->
<string id="50005">duration</string> <string id="50005">duration</string>
<string id="50006">chapters</string> <string id="50006">chapters</string>
<!-- Progress Dialog --> <!-- Progress Dialog -->
<string id="50050">Starting BluRay script</string> <string id="50050">Starting BluRay script</string>
<string id="50051">Initializing</string> <string id="50051">Initializing</string>
<string id="50052">Waiting for BluRay to be prepared</string> <string id="50052">Waiting for BluRay to be prepared</string>
<string id="50053">Starting Disc</string> <string id="50053">Starting Disc</string>
<string id="50054">Starting Image</string> <string id="50054">Starting Image</string>
<string id="50055">Starting Directory</string> <string id="50055">Starting Directory</string>
<string id="50056">Waiting for stream</string> <string id="50056">Waiting for stream</string>
<!-- Plugin strings --> <!-- Plugin strings -->
<string id="50060">Settings</string> <string id="50060">Settings</string>
<string id="50061">Play Disc %s: %s</string> <string id="50061">Play Disc %s: %s</string>
<string id="50062">Browse Disc %s: %s</string> <string id="50062">Browse Disc %s: %s</string>
<string id="50063">Play Filelocation</string> <string id="50063">Play Filelocation</string>
<string id="50064">Browse Filelocation</string> <string id="50064">Browse Filelocation</string>
<string id="50065">Play Remote location</string> <string id="50065">Play Remote location</string>
<string id="50066">Browse Remote location</string> <string id="50066">Browse Remote location</string>
<!-- Error messages --> <!-- Error messages -->
<string id="50070">Running MakeMKV ended abnormally. Is it installed?</string> <string id="50070">Running MakeMKV ended abnormally. Is it installed?</string>
<string id="50071">unable to find autoplay stream</string> <string id="50071">unable to find autoplay stream</string>
<string id="50072">Error trying to open makemkv stream</string> <string id="50072">Error trying to open makemkv stream</string>
<string id="50073">The file you've selected cannot be accessed by the filesystem</string> <string id="50073">The file you've selected cannot be accessed by the filesystem</string>
</strings> </strings>

View file

@ -0,0 +1,5 @@
'''
Created on 06.10.2012
@author: desolat
'''

View file

@ -1,32 +1,32 @@
class BrLog: class BrLog:
__DEBUG = 0 __DEBUG = 0
__INFO = 1 __INFO = 1
__WARN = 2 __WARN = 2
__ERROR = 3 __ERROR = 3
def __init__(self, prefix = ''): def __init__(self, prefix = ''):
self.logLevel = self.__INFO self.logLevel = self.__INFO
if prefix <> '': if prefix <> '':
prefix = '-' + prefix prefix = '-' + prefix
self.prefix = prefix self.prefix = prefix
def setLevel(self, level): def setLevel(self, level):
if level >= 0 and level <= 3: if level >= 0 and level <= 3:
self.logLevel = level self.logLevel = level
def info(self, message): def info(self, message):
self.log(message, self.__INFO) self.log(message, self.__INFO)
def debug(self, message): def debug(self, message):
self.log(message, self.__DEBUG) self.log(message, self.__DEBUG)
def error(self, message): def error(self, message):
self.log(message, self.__ERROR) self.log(message, self.__ERROR)
def warn(self, message): def warn(self, message):
self.log(message, self.__WARN) self.log(message, self.__WARN)
def log(self, message, level): def log(self, message, level):
if self.logLevel <= level: if self.logLevel <= level:
print '[BR%s %d] %s' %(self.prefix, level, message) print '[BR%s %d] %s' %(self.prefix, level, message)

View file

@ -1,196 +1,196 @@
# #
# ElementTree # ElementTree
# $Id: ElementPath.py 1858 2004-06-17 21:31:41Z Fredrik $ # $Id: ElementPath.py 1858 2004-06-17 21:31:41Z Fredrik $
# #
# limited xpath support for element trees # limited xpath support for element trees
# #
# history: # history:
# 2003-05-23 fl created # 2003-05-23 fl created
# 2003-05-28 fl added support for // etc # 2003-05-28 fl added support for // etc
# 2003-08-27 fl fixed parsing of periods in element names # 2003-08-27 fl fixed parsing of periods in element names
# #
# Copyright (c) 2003-2004 by Fredrik Lundh. All rights reserved. # Copyright (c) 2003-2004 by Fredrik Lundh. All rights reserved.
# #
# fredrik@pythonware.com # fredrik@pythonware.com
# http://www.pythonware.com # http://www.pythonware.com
# #
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# The ElementTree toolkit is # The ElementTree toolkit is
# #
# Copyright (c) 1999-2004 by Fredrik Lundh # Copyright (c) 1999-2004 by Fredrik Lundh
# #
# By obtaining, using, and/or copying this software and/or its # By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood, # associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions: # and will comply with the following terms and conditions:
# #
# Permission to use, copy, modify, and distribute this software and # Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is # its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in # hereby granted, provided that the above copyright notice appears in
# all copies, and that both that copyright notice and this permission # all copies, and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of # notice appear in supporting documentation, and that the name of
# Secret Labs AB or the author not be used in advertising or publicity # Secret Labs AB or the author not be used in advertising or publicity
# pertaining to distribution of the software without specific, written # pertaining to distribution of the software without specific, written
# prior permission. # prior permission.
# #
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE. # OF THIS SOFTWARE.
# -------------------------------------------------------------------- # --------------------------------------------------------------------
## ##
# Implementation module for XPath support. There's usually no reason # Implementation module for XPath support. There's usually no reason
# to import this module directly; the <b>ElementTree</b> does this for # to import this module directly; the <b>ElementTree</b> does this for
# you, if needed. # you, if needed.
## ##
import re import re
xpath_tokenizer = re.compile( xpath_tokenizer = re.compile(
"(::|\.\.|\(\)|[/.*:\[\]\(\)@=])|((?:\{[^}]+\})?[^/:\[\]\(\)@=\s]+)|\s+" "(::|\.\.|\(\)|[/.*:\[\]\(\)@=])|((?:\{[^}]+\})?[^/:\[\]\(\)@=\s]+)|\s+"
).findall ).findall
class xpath_descendant_or_self: class xpath_descendant_or_self:
pass pass
## ##
# Wrapper for a compiled XPath. # Wrapper for a compiled XPath.
class Path: class Path:
## ##
# Create an Path instance from an XPath expression. # Create an Path instance from an XPath expression.
def __init__(self, path): def __init__(self, path):
tokens = xpath_tokenizer(path) tokens = xpath_tokenizer(path)
# the current version supports 'path/path'-style expressions only # the current version supports 'path/path'-style expressions only
self.path = [] self.path = []
self.tag = None self.tag = None
if tokens and tokens[0][0] == "/": if tokens and tokens[0][0] == "/":
raise SyntaxError("cannot use absolute path on element") raise SyntaxError("cannot use absolute path on element")
while tokens: while tokens:
op, tag = tokens.pop(0) op, tag = tokens.pop(0)
if tag or op == "*": if tag or op == "*":
self.path.append(tag or op) self.path.append(tag or op)
elif op == ".": elif op == ".":
pass pass
elif op == "/": elif op == "/":
self.path.append(xpath_descendant_or_self()) self.path.append(xpath_descendant_or_self())
continue continue
else: else:
raise SyntaxError("unsupported path syntax (%s)" % op) raise SyntaxError("unsupported path syntax (%s)" % op)
if tokens: if tokens:
op, tag = tokens.pop(0) op, tag = tokens.pop(0)
if op != "/": if op != "/":
raise SyntaxError( raise SyntaxError(
"expected path separator (%s)" % (op or tag) "expected path separator (%s)" % (op or tag)
) )
if self.path and isinstance(self.path[-1], xpath_descendant_or_self): if self.path and isinstance(self.path[-1], xpath_descendant_or_self):
raise SyntaxError("path cannot end with //") raise SyntaxError("path cannot end with //")
if len(self.path) == 1 and isinstance(self.path[0], type("")): if len(self.path) == 1 and isinstance(self.path[0], type("")):
self.tag = self.path[0] self.tag = self.path[0]
## ##
# Find first matching object. # Find first matching object.
def find(self, element): def find(self, element):
tag = self.tag tag = self.tag
if tag is None: if tag is None:
nodeset = self.findall(element) nodeset = self.findall(element)
if not nodeset: if not nodeset:
return None return None
return nodeset[0] return nodeset[0]
for elem in element: for elem in element:
if elem.tag == tag: if elem.tag == tag:
return elem return elem
return None return None
## ##
# Find text for first matching object. # Find text for first matching object.
def findtext(self, element, default=None): def findtext(self, element, default=None):
tag = self.tag tag = self.tag
if tag is None: if tag is None:
nodeset = self.findall(element) nodeset = self.findall(element)
if not nodeset: if not nodeset:
return default return default
return nodeset[0].text or "" return nodeset[0].text or ""
for elem in element: for elem in element:
if elem.tag == tag: if elem.tag == tag:
return elem.text or "" return elem.text or ""
return default return default
## ##
# Find all matching objects. # Find all matching objects.
def findall(self, element): def findall(self, element):
nodeset = [element] nodeset = [element]
index = 0 index = 0
while 1: while 1:
try: try:
path = self.path[index] path = self.path[index]
index = index + 1 index = index + 1
except IndexError: except IndexError:
return nodeset return nodeset
set = [] set = []
if isinstance(path, xpath_descendant_or_self): if isinstance(path, xpath_descendant_or_self):
try: try:
tag = self.path[index] tag = self.path[index]
if not isinstance(tag, type("")): if not isinstance(tag, type("")):
tag = None tag = None
else: else:
index = index + 1 index = index + 1
except IndexError: except IndexError:
tag = None # invalid path tag = None # invalid path
for node in nodeset: for node in nodeset:
new = list(node.getiterator(tag)) new = list(node.getiterator(tag))
if new and new[0] is node: if new and new[0] is node:
set.extend(new[1:]) set.extend(new[1:])
else: else:
set.extend(new) set.extend(new)
else: else:
for node in nodeset: for node in nodeset:
for node in node: for node in node:
if path == "*" or node.tag == path: if path == "*" or node.tag == path:
set.append(node) set.append(node)
if not set: if not set:
return [] return []
nodeset = set nodeset = set
_cache = {} _cache = {}
## ##
# (Internal) Compile path. # (Internal) Compile path.
def _compile(path): def _compile(path):
p = _cache.get(path) p = _cache.get(path)
if p is not None: if p is not None:
return p return p
p = Path(path) p = Path(path)
if len(_cache) >= 100: if len(_cache) >= 100:
_cache.clear() _cache.clear()
_cache[path] = p _cache[path] = p
return p return p
## ##
# Find first matching object. # Find first matching object.
def find(element, path): def find(element, path):
return _compile(path).find(element) return _compile(path).find(element)
## ##
# Find text for first matching object. # Find text for first matching object.
def findtext(element, path, default=None): def findtext(element, path, default=None):
return _compile(path).findtext(element, default) return _compile(path).findtext(element, default)
## ##
# Find all matching objects. # Find all matching objects.
def findall(element, path): def findall(element, path):
return _compile(path).findall(element) return _compile(path).findall(element)

File diff suppressed because it is too large Load diff

View file

@ -1,30 +1,30 @@
# $Id: __init__.py 1821 2004-06-03 16:57:49Z fredrik $ # $Id: __init__.py 1821 2004-06-03 16:57:49Z fredrik $
# elementtree package # elementtree package
# -------------------------------------------------------------------- # --------------------------------------------------------------------
# The ElementTree toolkit is # The ElementTree toolkit is
# #
# Copyright (c) 1999-2004 by Fredrik Lundh # Copyright (c) 1999-2004 by Fredrik Lundh
# #
# By obtaining, using, and/or copying this software and/or its # By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood, # associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions: # and will comply with the following terms and conditions:
# #
# Permission to use, copy, modify, and distribute this software and # Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is # its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in # hereby granted, provided that the above copyright notice appears in
# all copies, and that both that copyright notice and this permission # all copies, and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of # notice appear in supporting documentation, and that the name of
# Secret Labs AB or the author not be used in advertising or publicity # Secret Labs AB or the author not be used in advertising or publicity
# pertaining to distribution of the software without specific, written # pertaining to distribution of the software without specific, written
# prior permission. # prior permission.
# #
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD # SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR # ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE. # OF THIS SOFTWARE.
# -------------------------------------------------------------------- # --------------------------------------------------------------------

View file

@ -1,6 +1,6 @@
class FakeFile: class FakeFile:
def poll(self): def poll(self):
return False return False
def communicate(self): def communicate(self):
return '', '' return '', ''

View file

@ -67,37 +67,37 @@ class MakeMkvInteraction:
proc = subprocess.Popen(mkvStart, shell=True) proc = subprocess.Popen(mkvStart, shell=True)
# Then wait for the stream to come up # Then wait for the stream to come up
while True: while True:
try: try:
urllib.urlretrieve(self.settings.rootURL) urllib.urlretrieve(self.settings.rootURL)
return proc.pid return proc.pid
except IOError: except IOError:
pass pass
if proc.poll() : if proc.poll() :
if proc.proc != 0 : if proc.proc != 0 :
self.message(_(50070)) self.message(_(50070))
return -1 return -1
xbmc.sleep(1000) xbmc.sleep(1000)
timeSlept = timeSlept + 1 timeSlept = timeSlept + 1
if timeSlept > self.settings.waitTimeOut : if timeSlept > self.settings.waitTimeOut :
return -1 return -1
def killMkv(self): def killMkv(self):
# Linux # Linux
try : try :
self.log.info('attempting linux kill of makemkvcon') self.log.info('attempting linux kill of makemkvcon')
subprocess.call('killall -9 makemkvcon', shell=True) subprocess.call('killall -9 makemkvcon', shell=True)
self.log.info('Linux call successful') self.log.info('Linux call successful')
except: except:
pass pass
#Windows. #Windows.
try : try :
self.log.info('attempting windows kill of makemkvcon') self.log.info('attempting windows kill of makemkvcon')
subprocess.call('taskkill /F /IM makemkvcon.exe', shell=True) subprocess.call('taskkill /F /IM makemkvcon.exe', shell=True)
self.log.info('Windows call successful') self.log.info('Windows call successful')
except: except:
pass pass
def makeMkvExists(self): def makeMkvExists(self):
(fin, fout) = os.popen4('%s -r' %(self.settings.mkvLocation)) (fin, fout) = os.popen4('%s -r' %(self.settings.mkvLocation))
@ -107,7 +107,7 @@ class MakeMkvInteraction:
self.log.info("MakeMkvCon found!") self.log.info("MakeMkvCon found!")
return True return True
else: else:
self.log.info('MakeMkvcon seems not to be configured properly : %s' %(self.settings.mkvLocation)) self.log.info('MakeMkvcon seems not to be configured properly : %s'
% (self.settings.mkvLocation))
return False return False

View file

@ -1,56 +1,56 @@
import urllib, re, elementtree.ElementTree as ET import urllib, re, elementtree.ElementTree as ET
class BrowseHandler: class BrowseHandler:
def __init__(self) : def __init__(self) :
self.catchCharData = False self.catchCharData = False
self.keyColumn = False self.keyColumn = False
self.map = {} self.map = {}
self.lastKey = '' self.lastKey = ''
self.lastVal = '' self.lastVal = ''
self.titleMap = {} self.titleMap = {}
def start(self, url, title = 'none'): def start(self, url, title = 'none'):
# Initialize all locals # Initialize all locals
self.catchCharData = False self.catchCharData = False
self.keyColumn = False self.keyColumn = False
self.map[url] = {} self.map[url] = {}
self.currMap = self.map[url] self.currMap = self.map[url]
self.lastKey = '' self.lastKey = ''
self.lastVal = '' self.lastVal = ''
filename, headers = urllib.urlretrieve(url) filename, headers = urllib.urlretrieve(url)
del headers del headers
XML = ET.parse(filename) XML = ET.parse(filename)
elems = XML.getiterator(tag='{http://www.w3.org/1999/xhtml}td') elems = XML.getiterator(tag='{http://www.w3.org/1999/xhtml}td')
for each in elems: for each in elems:
self.keyColumn = not self.keyColumn self.keyColumn = not self.keyColumn
if self.keyColumn: if self.keyColumn:
self.lastKey = each.text self.lastKey = each.text
else: else:
txt = '' txt = ''
# Check for href: # Check for href:
refs = each.getiterator(tag='{http://www.w3.org/1999/xhtml}a') refs = each.getiterator(tag='{http://www.w3.org/1999/xhtml}a')
for ref in refs: for ref in refs:
txt = ref.get('href') txt = ref.get('href')
if txt == '' : if txt == '' :
txt = each.text txt = each.text
self.currMap[self.lastKey] = txt self.currMap[self.lastKey] = txt
# Now do some processing: # Now do some processing:
for k, v in self.map[url].iteritems() : for k, v in self.map[url].iteritems() :
if k == 'titles': if k == 'titles':
# go straight ahead and parse some more: # go straight ahead and parse some more:
self.start(v) self.start(v)
if re.search('title\d+', k) : if re.search('title\d+', k) :
self.titleMap[k] = {} self.titleMap[k] = {}
self.start(v, k) self.start(v, k)
if title != 'none': if title != 'none':
if k == 'duration': if k == 'duration':
self.titleMap[title]['duration'] = v self.titleMap[title]['duration'] = v
elif k == 'file0': elif k == 'file0':
self.titleMap[title]['file'] = v self.titleMap[title]['file'] = v
elif k == 'chaptercount': elif k == 'chaptercount':
self.titleMap[title]['chaptercount'] = v self.titleMap[title]['chaptercount'] = v

View file

@ -1,81 +1,81 @@
import xbmcplugin, xbmcaddon import xbmcplugin, xbmcaddon
import sys import sys
import urllib import urllib
import brlog import brlog
__scriptID__ = sys.modules[ "__main__" ].__scriptID__ __scriptID__ = sys.modules[ "__main__" ].__scriptID__
class BluRaySettings: class BluRaySettings:
def __init__(self): def __init__(self):
addon = xbmcaddon.Addon(__scriptID__) addon = xbmcaddon.Addon(__scriptID__)
self.log = brlog.BrLog('settings') self.log = brlog.BrLog('settings')
self.log.info('reading settings') self.log.info('reading settings')
params = self.getParams() params = self.getParams()
if len(sys.argv) >= 2: if len(sys.argv) >= 2:
self.handle = int(sys.argv[1]) self.handle = int(sys.argv[1])
self.paramUrl = self.getParam(params, 'url') self.paramUrl = self.getParam(params, 'url')
self.paramName = self.getParam(params, "name") self.paramName = self.getParam(params, "name")
self.paramMode = self.getIntParam(params, "mode") self.paramMode = self.getIntParam(params, "mode")
self.autoPlay = self.getBoolParam(params, "autoplay") self.autoPlay = self.getBoolParam(params, "autoplay")
self.disc = self.getParam(params, "disc") self.disc = self.getParam(params, "disc")
self.local = True self.local = True
self.portNumber = addon.getSetting('port_number') self.portNumber = addon.getSetting('port_number')
self.ipAddress = '127.0.0.1' self.ipAddress = '127.0.0.1'
self.mkvLocation = addon.getSetting('mkvlocation') self.mkvLocation = addon.getSetting('mkvlocation')
self.rootURL = 'http://%s:%s/' % (self.ipAddress, self.portNumber) self.rootURL = 'http://%s:%s/' % (self.ipAddress, self.portNumber)
self.waitTimeOut = int(addon.getSetting('wait_timeout')) self.waitTimeOut = int(addon.getSetting('wait_timeout'))
# Sections: # Sections:
self.enableDisc = addon.getSetting('support_disc') == "true" self.enableDisc = addon.getSetting('support_disc') == "true"
self.enableFile = addon.getSetting('support_fileselect') == "true" self.enableFile = addon.getSetting('support_fileselect') == "true"
def getParam(self, params, name): def getParam(self, params, name):
try: try:
result = params[name] result = params[name]
result = urllib.unquote_plus(result) result = urllib.unquote_plus(result)
return result return result
except: except:
return None return None
def getIntParam (self, params, name): def getIntParam (self, params, name):
try: try:
param = self.getParam(params,name) param = self.getParam(params,name)
self.log.debug(name + ' = ' + param) self.log.debug(name + ' = ' + param)
return int(param) return int(param)
except: except:
return None return None
def getBoolParam (self, params, name): def getBoolParam (self, params, name):
try: try:
param = self.getParam(params,name) param = self.getParam(params,name)
self.log.debug(name + ' = ' + param) self.log.debug(name + ' = ' + param)
return 'True' == param return 'True' == param
except: except:
return None return None
def getParams(self): def getParams(self):
try: try:
param=[] param=[]
paramstring=sys.argv[2] paramstring=sys.argv[2]
self.log.info('raw param string: ' + paramstring) self.log.info('raw param string: ' + paramstring)
if len(paramstring)>=2: if len(paramstring)>=2:
params=sys.argv[2] params=sys.argv[2]
cleanedparams=params.replace('?','') cleanedparams=params.replace('?','')
if (params[len(params)-1]=='/'): if (params[len(params)-1]=='/'):
params=params[0:len(params)-2] params=params[0:len(params)-2]
pairsofparams=cleanedparams.split('&') pairsofparams=cleanedparams.split('&')
param={} param={}
for i in range(len(pairsofparams)): for i in range(len(pairsofparams)):
splitparams={} splitparams={}
splitparams=pairsofparams[i].split('=') splitparams=pairsofparams[i].split('=')
if (len(splitparams))==2: if (len(splitparams))==2:
param[splitparams[0]]=splitparams[1] param[splitparams[0]]=splitparams[1]
return param return param
except: except:
return [] return []
def showSettings(self): def showSettings(self):
xbmcaddon.Addon(__scriptID__).openSettings(sys.argv[ 0 ]) xbmcaddon.Addon(__scriptID__).openSettings(sys.argv[ 0 ])

View file

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<settings> <settings>
<setting type="lsep" label="51004"/> <setting type="lsep" label="51004"/>
<setting id="mkvlocation" type="file" label="50001" default="makemkvcon"/> <setting id="mkvlocation" type="file" label="50001" default="makemkvcon"/>
<setting id="wait_timeout" type="number" label="51003" default="120" /> <setting id="wait_timeout" type="number" label="51003" default="120" />
<setting id="port_number" type="number" label="51002" default="51000" /> <setting id="port_number" type="number" label="51002" default="51000" />
<setting type="lsep" label="51005"/> <setting type="lsep" label="51005"/>
<setting id="support_disc" type="bool" label="51006" default="true" /> <setting id="support_disc" type="bool" label="51006" default="true" />
<setting id="support_fileselect" type="bool" label="51007" default="true"/> <setting id="support_fileselect" type="bool" label="51007" default="true"/>
</settings> </settings>

View file

@ -20,6 +20,7 @@ _log = brlog.BrLog('tracker service')
_log.info('Starting the BluRay tracker service') _log.info('Starting the BluRay tracker service')
class MyPlayer(xbmc.Player): class MyPlayer(xbmc.Player):
def __init__(self): def __init__(self):
xbmc.Player.__init__(self) xbmc.Player.__init__(self)
@ -37,7 +38,7 @@ class MyPlayer(xbmc.Player):
myPlayer = MyPlayer() myPlayer = MyPlayer()
xbmc.sleep(4) xbmc.sleep(4)
if not makemkv.MakeMkvInteraction().makeMkvExists(): if not makemkv.MakeMkvInteraction().makeMkvExists():
imagePath = os.path.join(__addon__.getAddonInfo('path'),'resources','images', 'alerticon.png') imagePath = os.path.join(__addon__.getAddonInfo('path'), 'resources', 'images', 'alerticon.png')
xbmc.executebuiltin('Notification("MakeMkv", "The MakeMKV bluray plugin cannot find MakeMkv. Please configure the plugin to point to it", "15000", "%s")' % (imagePath)) xbmc.executebuiltin('Notification("MakeMkv", "The MakeMKV bluray plugin cannot find MakeMkv. Please configure the plugin to point to it", "15000", "%s")' % (imagePath))
while (not xbmc.abortRequested): while (not xbmc.abortRequested):