pyuno/source/loader/pythonloader.py | 125 ++-- scripting/source/pyprov/pythonscript.py | 965 ++++++++++++++++---------------- 2 files changed, 574 insertions(+), 516 deletions(-)
New commits: commit b0ed190986fab0c57d5933b4d4a41a9be72e3f1b Author: Chenxiong Qi <qcxh...@gmail.com> AuthorDate: Fri Dec 27 09:14:34 2024 +0800 Commit: Ilmari Lauhakangas <ilmari.lauhakan...@libreoffice.org> CommitDate: Sun Dec 29 15:22:47 2024 +0100 Format pythonloader.py and pythonscript.py The goal is to make the script more readable. The format is done with command: black --line-length 120 <filename> No manual modification to these files. Change-Id: I8ebbac936924277308fc011b20cba60849fa9c45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179438 Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakan...@libreoffice.org> Tested-by: Jenkins diff --git a/pyuno/source/loader/pythonloader.py b/pyuno/source/loader/pythonloader.py index bd389d438a5d..bb139a1196b9 100644 --- a/pyuno/source/loader/pythonloader.py +++ b/pyuno/source/loader/pythonloader.py @@ -22,55 +22,61 @@ import sys import types import os from urllib.parse import unquote -from com.sun.star.uno import Exception,RuntimeException +from com.sun.star.uno import Exception, RuntimeException from com.sun.star.loader import XImplementationLoader from com.sun.star.lang import XServiceInfo MODULE_PROTOCOL = "vnd.openoffice.pymodule:" DEBUG = 0 -g_supportedServices = "com.sun.star.loader.Python", # referenced by the native C++ loader ! -g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! +g_supportedServices = ("com.sun.star.loader.Python",) # referenced by the native C++ loader ! +g_implementationName = "org.openoffice.comp.pyuno.Loader" # referenced by the native C++ loader ! -def splitUrl( url ): - nColon = url.find( ":" ) + +def splitUrl(url): + nColon = url.find(":") if -1 == nColon: - raise RuntimeException( "PythonLoader: No protocol in url " + url, None ) - return url[0:nColon], url[nColon+1:len(url)] + raise RuntimeException("PythonLoader: No protocol in url " + url, None) + return url[0:nColon], url[nColon + 1 : len(url)] + g_loadedComponents = {} -def checkForPythonPathBesideComponent( url ): - path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ) + + +def checkForPythonPathBesideComponent(url): + path = unohelper.fileUrlToSystemPath(url + "/pythonpath.zip") if DEBUG == 1: - print(b"checking for existence of " + encfile( path )) - if 1 == os.access( encfile( path ), os.F_OK) and path not in sys.path: + print(b"checking for existence of " + encfile(path)) + if 1 == os.access(encfile(path), os.F_OK) and path not in sys.path: if DEBUG == 1: - print(b"adding " + encfile( path ) + b" to sys.path") - sys.path.append( path ) + print(b"adding " + encfile(path) + b" to sys.path") + sys.path.append(path) - path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ) - if 1 == os.access( encfile( path ), os.F_OK) and path not in sys.path: + path = unohelper.fileUrlToSystemPath(url + "/pythonpath") + if 1 == os.access(encfile(path), os.F_OK) and path not in sys.path: if DEBUG == 1: - print(b"adding " + encfile( path ) + b" to sys.path") - sys.path.append( path ) + print(b"adding " + encfile(path) + b" to sys.path") + sys.path.append(path) + def encfile(uni): - return uni.encode( sys.getfilesystemencoding()) + return uni.encode(sys.getfilesystemencoding()) + -class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): - def __init__(self, ctx ): +class Loader(XImplementationLoader, XServiceInfo, unohelper.Base): + def __init__(self, ctx): if DEBUG: print("pythonloader.Loader ctor") self.ctx = ctx - def getModuleFromUrl( self, url ): + def getModuleFromUrl(self, url): if DEBUG: print("pythonloader: interpreting url " + url) - protocol, dependent = splitUrl( url ) + protocol, dependent = splitUrl(url) if "vnd.sun.star.expand" == protocol: - exp = self.ctx.getValueByName( "/singletons/com.sun.star.util.theMacroExpander" ) + exp = self.ctx.getValueByName("/singletons/com.sun.star.util.theMacroExpander") url = exp.expandMacros(unquote(dependent)) - protocol,dependent = splitUrl( url ) + protocol, dependent = splitUrl(url) if DEBUG: print("pythonloader: after expansion " + protocol + ":" + dependent) @@ -78,86 +84,85 @@ class Loader( XImplementationLoader, XServiceInfo, unohelper.Base ): try: if "file" == protocol: # remove \..\ sequence, which may be useful e.g. in the build env - url = unohelper.absolutize( url, url ) + url = unohelper.absolutize(url, url) # did we load the module already ? - mod = g_loadedComponents.get( url ) + mod = g_loadedComponents.get(url) if not mod: mod = types.ModuleType("uno_component") # check for pythonpath.zip beside .py files - checkForPythonPathBesideComponent( url[0:url.rfind('/')] ) + checkForPythonPathBesideComponent(url[0 : url.rfind("/")]) # read the file - filename = unohelper.fileUrlToSystemPath( url ) + filename = unohelper.fileUrlToSystemPath(url) - with open( filename, encoding='utf_8' ) as fileHandle: - src = fileHandle.read().replace(" ","") - if not src.endswith( " " ): + with open(filename, encoding="utf_8") as fileHandle: + src = fileHandle.read().replace(" ", "") + if not src.endswith(" "): src = src + " " # compile and execute the module - codeobject = compile( src, encfile(filename), "exec" ) + codeobject = compile(src, encfile(filename), "exec") mod.__file__ = filename exec(codeobject, mod.__dict__) g_loadedComponents[url] = mod return mod elif "vnd.openoffice.pymodule" == protocol: - nSlash = dependent.rfind('/') + nSlash = dependent.rfind("/") if -1 != nSlash: - path = unohelper.fileUrlToSystemPath( dependent[0:nSlash] ) - dependent = dependent[nSlash+1:len(dependent)] + path = unohelper.fileUrlToSystemPath(dependent[0:nSlash]) + dependent = dependent[nSlash + 1 : len(dependent)] if path not in sys.path: - sys.path.append( path ) - mod = __import__( dependent ) - path_component, dot, rest = dependent.partition('.') - while dot == '.': - path_component, dot, rest = rest.partition('.') + sys.path.append(path) + mod = __import__(dependent) + path_component, dot, rest = dependent.partition(".") + while dot == ".": + path_component, dot, rest = rest.partition(".") mod = getattr(mod, path_component) return mod else: if DEBUG: print("Unknown protocol '" + protocol + "'") - raise RuntimeException( "PythonLoader: Unknown protocol " + - protocol + " in url " +url, self ) + raise RuntimeException("PythonLoader: Unknown protocol " + protocol + " in url " + url, self) except Exception as e: if DEBUG: - print ("Python import exception " + str(type(e)) + - " message " + str(e) + " args " + str(e.args)) - raise RuntimeException( "Couldn't load " + url + " for reason " + str(e), None ) + print("Python import exception " + str(type(e)) + " message " + str(e) + " args " + str(e.args)) + raise RuntimeException("Couldn't load " + url + " for reason " + str(e), None) return None - def activate( self, implementationName, dummy, locationUrl, regKey ): + def activate(self, implementationName, dummy, locationUrl, regKey): if DEBUG: print("pythonloader.Loader.activate") - mod = self.getModuleFromUrl( locationUrl ) - implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) + mod = self.getModuleFromUrl(locationUrl) + implHelper = mod.__dict__.get("g_ImplementationHelper", None) if DEBUG: - print ("Fetched ImplHelper as " + str(implHelper)) + print("Fetched ImplHelper as " + str(implHelper)) if implHelper is None: - return mod.getComponentFactory( implementationName, self.ctx.ServiceManager, regKey ) + return mod.getComponentFactory(implementationName, self.ctx.ServiceManager, regKey) else: - return implHelper.getComponentFactory( implementationName,regKey,self.ctx.ServiceManager) + return implHelper.getComponentFactory(implementationName, regKey, self.ctx.ServiceManager) - def writeRegistryInfo( self, regKey, dummy, locationUrl ): + def writeRegistryInfo(self, regKey, dummy, locationUrl): if DEBUG: - print( "pythonloader.Loader.writeRegistryInfo" ) + print("pythonloader.Loader.writeRegistryInfo") - mod = self.getModuleFromUrl( locationUrl ) - implHelper = mod.__dict__.get( "g_ImplementationHelper" , None ) + mod = self.getModuleFromUrl(locationUrl) + implHelper = mod.__dict__.get("g_ImplementationHelper", None) if implHelper is None: - return mod.writeRegistryInfo( self.ctx.ServiceManager, regKey ) + return mod.writeRegistryInfo(self.ctx.ServiceManager, regKey) else: - return implHelper.writeRegistryInfo( regKey, self.ctx.ServiceManager ) + return implHelper.writeRegistryInfo(regKey, self.ctx.ServiceManager) - def getImplementationName( self ): + def getImplementationName(self): return g_implementationName - def supportsService( self, ServiceName ): + def supportsService(self, ServiceName): return ServiceName in self.getSupportedServiceNames() - def getSupportedServiceNames( self ): + def getSupportedServiceNames(self): return g_supportedServices + # vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/scripting/source/pyprov/pythonscript.py b/scripting/source/pyprov/pythonscript.py index 6d5d81e5df65..93aff0331984 100644 --- a/scripting/source/pyprov/pythonscript.py +++ b/scripting/source/pyprov/pythonscript.py @@ -28,11 +28,13 @@ import platform from com.sun.star.uri.RelativeUriExcessParentSegments import RETAIN from urllib.parse import unquote + class LogLevel: - NONE = 0 # production level + NONE = 0 # production level ERROR = 1 # for script developers DEBUG = 2 # for script framework developers + PYSCRIPT_LOG_ENV = "PYSCRIPT_LOG_LEVEL" PYSCRIPT_LOG_STDOUT_ENV = "PYSCRIPT_LOG_STDOUT" @@ -47,19 +49,21 @@ elif os.environ.get(PYSCRIPT_LOG_ENV) == "DEBUG": # False, writes to user/Scripts/python/log.txt LOG_STDOUT = os.environ.get(PYSCRIPT_LOG_STDOUT_ENV, "1") != "0" -ENABLE_EDIT_DIALOG=False # offers a minimal editor for editing. -#------------------------------------------------------------------- +ENABLE_EDIT_DIALOG = False # offers a minimal editor for editing. +# ------------------------------------------------------------------- + def encfile(uni): - return uni.encode( sys.getfilesystemencoding()) + return uni.encode(sys.getfilesystemencoding()) + def lastException2String(): - (excType,excInstance,excTraceback) = sys.exc_info() - ret = str(excType) + ": "+str(excInstance) + " " + \ - uno._uno_extract_printable_stacktrace( excTraceback ) + (excType, excInstance, excTraceback) = sys.exc_info() + ret = str(excType) + ": " + str(excInstance) + " " + uno._uno_extract_printable_stacktrace(excTraceback) return ret -def logLevel2String( level ): + +def logLevel2String(level): ret = " NONE" if level == LogLevel.ERROR: ret = "ERROR" @@ -67,57 +71,57 @@ def logLevel2String( level ): ret = "DEBUG" return ret + def getLogTarget(): ret = sys.stdout if not LOG_STDOUT: try: - pathSubst = uno.getComponentContext().ServiceManager.createInstance( - "com.sun.star.util.PathSubstitution" ) - userInstallation = pathSubst.getSubstituteVariableValue( "user" ) - if len( userInstallation ) > 0: - systemPath = uno.fileUrlToSystemPath( userInstallation + "/Scripts/python/log.txt" ) - ret = open( systemPath , "a" ) + pathSubst = uno.getComponentContext().ServiceManager.createInstance("com.sun.star.util.PathSubstitution") + userInstallation = pathSubst.getSubstituteVariableValue("user") + if len(userInstallation) > 0: + systemPath = uno.fileUrlToSystemPath(userInstallation + "/Scripts/python/log.txt") + ret = open(systemPath, "a") except Exception: - print("Exception during creation of pythonscript logfile: "+ lastException2String() + " , delegating log to stdout ") + print( + "Exception during creation of pythonscript logfile: " + + lastException2String() + + " , delegating log to stdout " + ) return ret + class Logger(LogLevel): - def __init__(self , target ): + def __init__(self, target): self.target = target - def isDebugLevel( self ): + def isDebugLevel(self): return self.use >= self.DEBUG - def debug( self, msg ): + def debug(self, msg): if self.isDebugLevel(): - self.log( self.DEBUG, msg ) + self.log(self.DEBUG, msg) - def isErrorLevel( self ): + def isErrorLevel(self): return self.use >= self.ERROR - def error( self, msg ): + def error(self, msg): if self.isErrorLevel(): - self.log( self.ERROR, msg ) + self.log(self.ERROR, msg) - def log( self, level, msg ): + def log(self, level, msg): if self.use >= level: try: - self.target.write( - time.asctime() + - " [" + - logLevel2String( level ) + - "] " + - msg + - " " ) + self.target.write(time.asctime() + " [" + logLevel2String(level) + "] " + msg + " ") self.target.flush() except Exception: - print("Error during writing to stdout: " +lastException2String() + " ") + print("Error during writing to stdout: " + lastException2String() + " ") + -log = Logger( getLogTarget() ) +log = Logger(getLogTarget()) -log.debug( "pythonscript loading" ) +log.debug("pythonscript loading") -#from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider +# from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider from com.sun.star.uno import RuntimeException from com.sun.star.lang import IllegalArgumentException from com.sun.star.container import NoSuchElementException @@ -136,26 +140,28 @@ from com.sun.star.script.browse.BrowseNodeTypes import SCRIPT, CONTAINER LANGUAGENAME = "Python" GLOBAL_SCRIPTCONTEXT_NAME = "XSCRIPTCONTEXT" -CALLABLE_CONTAINER_NAME = "g_exportedScripts" +CALLABLE_CONTAINER_NAME = "g_exportedScripts" # pythonloader looks for a static g_ImplementationHelper variable g_ImplementationHelper = unohelper.ImplementationHelper() -g_implName = "org.libreoffice.pyuno.LanguageScriptProviderFor"+LANGUAGENAME - +g_implName = "org.libreoffice.pyuno.LanguageScriptProviderFor" + LANGUAGENAME BLOCK_SIZE = 65536 -def readTextFromStream( inputStream ): + + +def readTextFromStream(inputStream): # read the file - code = uno.ByteSequence( b"" ) + code = uno.ByteSequence(b"") while True: - read,out = inputStream.readBytes( None , BLOCK_SIZE ) + read, out = inputStream.readBytes(None, BLOCK_SIZE) code = code + out if read < BLOCK_SIZE: - break + break return code.value -def toIniName( str ): + +def toIniName(str): if platform.system() == "Windows": return str + ".ini" else: @@ -165,46 +171,58 @@ def toIniName( str ): """ definition: storageURI is the system dependent, absolute file url, where the script is stored on disk scriptURI is the system independent uri """ + + class MyUriHelper: - def __init__( self, ctx, location ): + def __init__(self, ctx, location): self.ctx = ctx - self.s_UriMap = \ - { "share" : "vnd.sun.star.expand:$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/Scripts/python" , \ - "share:uno_packages" : "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages", \ - "user" : "vnd.sun.star.expand:${$BRAND_INI_DIR/" + toIniName( "bootstrap") + "::UserInstallation}/user/Scripts/python" , \ - "user:uno_packages" : "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages" } - self.m_uriRefFac = ctx.ServiceManager.createInstanceWithContext("com.sun.star.uri.UriReferenceFactory",ctx) - if location.startswith( "vnd.sun.star.tdoc" ): + self.s_UriMap = { + "share": "vnd.sun.star.expand:$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/Scripts/python", + "share:uno_packages": "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages", + "user": "vnd.sun.star.expand:${$BRAND_INI_DIR/" + + toIniName("bootstrap") + + "::UserInstallation}/user/Scripts/python", + "user:uno_packages": "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages", + } + self.m_uriRefFac = ctx.ServiceManager.createInstanceWithContext("com.sun.star.uri.UriReferenceFactory", ctx) + if location.startswith("vnd.sun.star.tdoc"): self.m_baseUri = location + "/Scripts/python" self.m_scriptUriLocation = "document" else: - self.m_baseUri = expandUri( self.s_UriMap[location] ) + self.m_baseUri = expandUri(self.s_UriMap[location]) self.m_scriptUriLocation = location - log.debug( "initialized urihelper with baseUri="+self.m_baseUri + ",m_scriptUriLocation="+self.m_scriptUriLocation ) + log.debug( + "initialized urihelper with baseUri=" + self.m_baseUri + ",m_scriptUriLocation=" + self.m_scriptUriLocation + ) - def getRootStorageURI( self ): + def getRootStorageURI(self): return self.m_baseUri - def getStorageURI( self, scriptURI ): + def getStorageURI(self, scriptURI): return self.scriptURI2StorageUri(scriptURI) - def getScriptURI( self, storageURI ): + def getScriptURI(self, storageURI): return self.storageURI2ScriptUri(storageURI) - def storageURI2ScriptUri( self, storageURI ): - if not storageURI.startswith( self.m_baseUri ): + def storageURI2ScriptUri(self, storageURI): + if not storageURI.startswith(self.m_baseUri): message = "pythonscript: storage uri '" + storageURI + "' not in base uri '" + self.m_baseUri + "'" - log.debug( message ) - raise RuntimeException( message, self.ctx ) - - ret = "vnd.sun.star.script:" + \ - storageURI[len(self.m_baseUri)+1:].replace("/","|") + \ - "?language=" + LANGUAGENAME + "&location=" + self.m_scriptUriLocation - log.debug( "converting storageURI="+storageURI + " to scriptURI=" + ret ) + log.debug(message) + raise RuntimeException(message, self.ctx) + + ret = ( + "vnd.sun.star.script:" + + storageURI[len(self.m_baseUri) + 1 :].replace("/", "|") + + "?language=" + + LANGUAGENAME + + "&location=" + + self.m_scriptUriLocation + ) + log.debug("converting storageURI=" + storageURI + " to scriptURI=" + ret) return ret - def scriptURI2StorageUri( self, scriptURI ): + def scriptURI2StorageUri(self, scriptURI): try: # base path to the python script location sBaseUri = self.m_baseUri + "/" @@ -214,26 +232,26 @@ class MyUriHelper: xStorageUri = self.m_uriRefFac.parse(scriptURI) # getName will apply url-decoding to the name, so encode back sStorageUri = xStorageUri.getName().replace("%", "%25") - sStorageUri = sStorageUri.replace( "|", "/" ) + sStorageUri = sStorageUri.replace("|", "/") # path to the .py file, relative to the base funcNameStart = sStorageUri.find("$") if funcNameStart != -1: sFileUri = sStorageUri[0:funcNameStart] - sFuncName = sStorageUri[funcNameStart+1:] + sFuncName = sStorageUri[funcNameStart + 1 :] else: sFileUri = sStorageUri xFileUri = self.m_uriRefFac.parse(sFileUri) if not xFileUri: - message = "pythonscript: invalid relative uri '" + sFileUri+ "'" - log.debug( message ) - raise RuntimeException( message, self.ctx ) + message = "pythonscript: invalid relative uri '" + sFileUri + "'" + log.debug(message) + raise RuntimeException(message, self.ctx) if not xFileUri.hasRelativePath(): - message = "pythonscript: an absolute uri is invalid '" + sFileUri+ "'" - log.debug( message ) - raise RuntimeException( message, self.ctx ) + message = "pythonscript: an absolute uri is invalid '" + sFileUri + "'" + log.debug(message) + raise RuntimeException(message, self.ctx) # absolute path to the .py file xAbsScriptUri = self.m_uriRefFac.makeAbsolute(xBaseUri, xFileUri, True, RETAIN) @@ -242,73 +260,76 @@ class MyUriHelper: # ensure py file is under the base path if not sAbsScriptUri.startswith(sBaseUri): message = "pythonscript: storage uri '" + sAbsScriptUri + "' not in base uri '" + self.m_baseUri + "'" - log.debug( message ) - raise RuntimeException( message, self.ctx ) + log.debug(message) + raise RuntimeException(message, self.ctx) ret = sAbsScriptUri if funcNameStart != -1: ret = ret + "$" + sFuncName - log.debug( "converting scriptURI="+scriptURI + " to storageURI=" + ret ) + log.debug("converting scriptURI=" + scriptURI + " to storageURI=" + ret) return ret except UnoException as e: - log.error( "error during converting scriptURI="+scriptURI + ": " + e.Message) - raise RuntimeException( "pythonscript:scriptURI2StorageUri: " + e.Message, self.ctx ) + log.error("error during converting scriptURI=" + scriptURI + ": " + e.Message) + raise RuntimeException("pythonscript:scriptURI2StorageUri: " + e.Message, self.ctx) except Exception as e: - log.error( "error during converting scriptURI="+scriptURI + ": " + str(e)) - raise RuntimeException( "pythonscript:scriptURI2StorageUri: " + str(e), self.ctx ) + log.error("error during converting scriptURI=" + scriptURI + ": " + str(e)) + raise RuntimeException("pythonscript:scriptURI2StorageUri: " + str(e), self.ctx) class ModuleEntry: - def __init__( self, lastRead, module ): + def __init__(self, lastRead, module): self.lastRead = lastRead self.module = module -def hasChanged( oldDate, newDate ): - return newDate.Year > oldDate.Year or \ - newDate.Month > oldDate.Month or \ - newDate.Day > oldDate.Day or \ - newDate.Hours > oldDate.Hours or \ - newDate.Minutes > oldDate.Minutes or \ - newDate.Seconds > oldDate.Seconds or \ - newDate.NanoSeconds > oldDate.NanoSeconds -def ensureSourceState( code ): +def hasChanged(oldDate, newDate): + return ( + newDate.Year > oldDate.Year + or newDate.Month > oldDate.Month + or newDate.Day > oldDate.Day + or newDate.Hours > oldDate.Hours + or newDate.Minutes > oldDate.Minutes + or newDate.Seconds > oldDate.Seconds + or newDate.NanoSeconds > oldDate.NanoSeconds + ) + + +def ensureSourceState(code): if code.endswith(b" "): code = code + b" " code = code.replace(b" ", b"") return code -def checkForPythonPathBesideScript( url ): - if url.startswith( "file:" ): - path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ) - log.log( LogLevel.DEBUG, "checking for existence of " + path ) - if 1 == os.access( encfile(path), os.F_OK) and path not in sys.path: - log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" ) - sys.path.append( path ) +def checkForPythonPathBesideScript(url): + if url.startswith("file:"): + path = unohelper.fileUrlToSystemPath(url + "/pythonpath.zip") + log.log(LogLevel.DEBUG, "checking for existence of " + path) + if 1 == os.access(encfile(path), os.F_OK) and path not in sys.path: + log.log(LogLevel.DEBUG, "adding " + path + " to sys.path") + sys.path.append(path) - path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ) - log.log( LogLevel.DEBUG, "checking for existence of " + path ) - if 1 == os.access( encfile(path), os.F_OK) and path not in sys.path: - log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" ) - sys.path.append( path ) + path = unohelper.fileUrlToSystemPath(url + "/pythonpath") + log.log(LogLevel.DEBUG, "checking for existence of " + path) + if 1 == os.access(encfile(path), os.F_OK) and path not in sys.path: + log.log(LogLevel.DEBUG, "adding " + path + " to sys.path") + sys.path.append(path) class ScriptContext(unohelper.Base): - def __init__( self, ctx, doc, inv ): + def __init__(self, ctx, doc, inv): self.ctx = ctx self.doc = doc self.inv = inv - # XScriptContext + # XScriptContext def getDocument(self): if self.doc: return self.doc return self.getDesktop().getCurrentComponent() def getDesktop(self): - return self.ctx.ServiceManager.createInstanceWithContext( - "com.sun.star.frame.Desktop", self.ctx ) + return self.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", self.ctx) def getComponentContext(self): return self.ctx @@ -316,14 +337,15 @@ class ScriptContext(unohelper.Base): def getInvocationContext(self): return self.inv -#---------------------------------- + +# ---------------------------------- # Global Module Administration # does not fit together with script # engine lifetime management -#---------------------------------- -#g_scriptContext = ScriptContext( uno.getComponentContext(), None ) -#g_modules = {} -#def getModuleByUrl( url, sfa ): +# ---------------------------------- +# g_scriptContext = ScriptContext( uno.getComponentContext(), None ) +# g_modules = {} +# def getModuleByUrl( url, sfa ): # entry = g_modules.get(url) # load = True # lastRead = sfa.getDateTimeModified( url ) @@ -338,7 +360,7 @@ class ScriptContext(unohelper.Base): # # code = readTextFromStream( sfa.openFileRead( url ) ) - # execute the module +# execute the module # entry = ModuleEntry( lastRead, types.ModuleType("ooo_script_framework") ) # entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext # entry.module.__file__ = url @@ -347,8 +369,9 @@ class ScriptContext(unohelper.Base): # log.debug( "mapped " + url + " to " + str( entry.module ) ) # return entry.module + class ProviderContext: - def __init__( self, storageType, sfa, uriHelper, scriptContext ): + def __init__(self, storageType, sfa, uriHelper, scriptContext): self.storageType = storageType self.sfa = sfa self.uriHelper = uriHelper @@ -357,75 +380,78 @@ class ProviderContext: self.rootUrl = None self.mapPackageName2Path = None - def getTransientPartFromUrl( self, url ): - rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1) - return rest[0:rest.find("/")] - - def getPackageNameFromUrl( self, url ): - rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1) - start = rest.find("/") +1 - return rest[start:rest.find("/",start)] + def getTransientPartFromUrl(self, url): + rest = url.replace(self.rootUrl, "", 1).replace("/", "", 1) + return rest[0 : rest.find("/")] + def getPackageNameFromUrl(self, url): + rest = url.replace(self.rootUrl, "", 1).replace("/", "", 1) + start = rest.find("/") + 1 + return rest[start : rest.find("/", start)] - def removePackageByUrl( self, url ): + def removePackageByUrl(self, url): items = self.mapPackageName2Path.items() for i in items: if url in i[1].paths: self.mapPackageName2Path.pop(i[0]) break - def addPackageByUrl( self, url ): - packageName = self.getPackageNameFromUrl( url ) - transientPart = self.getTransientPartFromUrl( url ) - log.debug( "addPackageByUrl : " + packageName + ", " + transientPart + "("+url+")" + ", rootUrl="+self.rootUrl ) + def addPackageByUrl(self, url): + packageName = self.getPackageNameFromUrl(url) + transientPart = self.getTransientPartFromUrl(url) + log.debug( + "addPackageByUrl : " + packageName + ", " + transientPart + "(" + url + ")" + ", rootUrl=" + self.rootUrl + ) if packageName in self.mapPackageName2Path: - package = self.mapPackageName2Path[ packageName ] - package.paths = package.paths + (url, ) + package = self.mapPackageName2Path[packageName] + package.paths = package.paths + (url,) else: - package = Package( (url,), transientPart) - self.mapPackageName2Path[ packageName ] = package + package = Package((url,), transientPart) + self.mapPackageName2Path[packageName] = package - def isUrlInPackage( self, url ): + def isUrlInPackage(self, url): values = self.mapPackageName2Path.values() for i in values: -# print ("checking " + url + " in " + str(i.paths)) + # print ("checking " + url + " in " + str(i.paths)) if url in i.paths: - return True -# print ("false") + return True + # print ("false") return False - def setPackageAttributes( self, mapPackageName2Path, rootUrl ): + def setPackageAttributes(self, mapPackageName2Path, rootUrl): self.mapPackageName2Path = mapPackageName2Path self.rootUrl = rootUrl - def getPersistentUrlFromStorageUrl( self, url ): + def getPersistentUrlFromStorageUrl(self, url): # package name is the second directory ret = url if self.rootUrl: - pos = len( self.rootUrl) +1 - ret = url[0:pos]+url[url.find("/",pos)+1:len(url)] - log.debug( "getPersistentUrlFromStorageUrl " + url + " -> "+ ret) + pos = len(self.rootUrl) + 1 + ret = url[0:pos] + url[url.find("/", pos) + 1 : len(url)] + log.debug("getPersistentUrlFromStorageUrl " + url + " -> " + ret) return ret - def getStorageUrlFromPersistentUrl( self, url): + def getStorageUrlFromPersistentUrl(self, url): ret = url if self.rootUrl: - pos = len(self.rootUrl)+1 - packageName = url[pos:url.find("/",pos+1)] - package = self.mapPackageName2Path[ packageName ] - ret = url[0:pos]+ package.transientPathElement + "/" + url[pos:len(url)] - log.debug( "getStorageUrlFromPersistentUrl " + url + " -> "+ ret) + pos = len(self.rootUrl) + 1 + packageName = url[pos : url.find("/", pos + 1)] + package = self.mapPackageName2Path[packageName] + ret = url[0:pos] + package.transientPathElement + "/" + url[pos : len(url)] + log.debug("getStorageUrlFromPersistentUrl " + url + " -> " + ret) return ret - def getFuncsByUrl( self, url ): - src = readTextFromStream( self.sfa.openFileRead( url ) ) - checkForPythonPathBesideScript( url[0:url.rfind('/')] ) - src = ensureSourceState( src ) + def getFuncsByUrl(self, url): + src = readTextFromStream(self.sfa.openFileRead(url)) + checkForPythonPathBesideScript(url[0 : url.rfind("/")]) + src = ensureSourceState(src) try: - code = ast.parse( src ) + code = ast.parse(src) except Exception: - log.isDebugLevel() and log.debug( "pythonscript: getFuncsByUrl: exception while parsing: " + lastException2String()) + log.isDebugLevel() and log.debug( + "pythonscript: getFuncsByUrl: exception while parsing: " + lastException2String() + ) raise allFuncs = [] @@ -449,68 +475,70 @@ class ProviderContext: g_exportedScripts.append(value.id) return g_exportedScripts -# Python 2 only -# for node in code.node.nodes: -# if node.__class__.__name__ == 'Function': -# allFuncs.append(node.name) -# elif node.__class__.__name__ == 'Assign': -# for assignee in node.nodes: -# if assignee.name == 'g_exportedScripts': -# for item in node.expr.nodes: -# if item.__class__.__name__ == 'Name': -# g_exportedScripts.append(item.name) -# return g_exportedScripts + # Python 2 only + # for node in code.node.nodes: + # if node.__class__.__name__ == 'Function': + # allFuncs.append(node.name) + # elif node.__class__.__name__ == 'Assign': + # for assignee in node.nodes: + # if assignee.name == 'g_exportedScripts': + # for item in node.expr.nodes: + # if item.__class__.__name__ == 'Name': + # g_exportedScripts.append(item.name) + # return g_exportedScripts return allFuncs - def getModuleByUrl( self, url ): - entry = self.modules.get(url) + def getModuleByUrl(self, url): + entry = self.modules.get(url) load = True - lastRead = self.sfa.getDateTimeModified( url ) + lastRead = self.sfa.getDateTimeModified(url) if entry: - if hasChanged( entry.lastRead, lastRead ): - log.debug( "file " + url + " has changed, reloading" ) + if hasChanged(entry.lastRead, lastRead): + log.debug("file " + url + " has changed, reloading") else: load = False if load: - log.debug( "opening >" + url + "<" ) + log.debug("opening >" + url + "<") - src = readTextFromStream( self.sfa.openFileRead( url ) ) - checkForPythonPathBesideScript( url[0:url.rfind('/')] ) - src = ensureSourceState( src ) + src = readTextFromStream(self.sfa.openFileRead(url)) + checkForPythonPathBesideScript(url[0 : url.rfind("/")]) + src = ensureSourceState(src) # execute the module - entry = ModuleEntry( lastRead, types.ModuleType("ooo_script_framework") ) + entry = ModuleEntry(lastRead, types.ModuleType("ooo_script_framework")) entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.scriptContext code = None - if url.startswith( "file:" ): - code = compile( src, encfile(uno.fileUrlToSystemPath( url ) ), "exec" ) + if url.startswith("file:"): + code = compile(src, encfile(uno.fileUrlToSystemPath(url)), "exec") else: - code = compile( src, url, "exec" ) + code = compile(src, url, "exec") exec(code, entry.module.__dict__) entry.module.__file__ = url - self.modules[ url ] = entry - log.debug( "mapped " + url + " to " + str( entry.module ) ) - return entry.module + self.modules[url] = entry + log.debug("mapped " + url + " to " + str(entry.module)) + return entry.module -#-------------------------------------------------- -def isScript( candidate ): + +# -------------------------------------------------- +def isScript(candidate): ret = False - if isinstance( candidate, type(isScript) ): + if isinstance(candidate, type(isScript)): ret = True return ret -#------------------------------------------------------- -class ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, XActionListener ): - def __init__( self, provCtx, uri, fileName, funcName ): + +# ------------------------------------------------------- +class ScriptBrowseNode(unohelper.Base, XBrowseNode, XPropertySet, XInvocation, XActionListener): + def __init__(self, provCtx, uri, fileName, funcName): self.fileName = fileName self.funcName = funcName self.provCtx = provCtx self.uri = uri - def getName( self ): + def getName(self): return self.funcName def getChildNodes(self): @@ -519,46 +547,48 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, def hasChildNodes(self): return False - def getType( self): + def getType(self): return SCRIPT - def getPropertyValue( self, name ): + def getPropertyValue(self, name): ret = None try: if name == "URI": ret = self.provCtx.uriHelper.getScriptURI( - self.provCtx.getPersistentUrlFromStorageUrl( self.uri + "$" + self.funcName ) ) + self.provCtx.getPersistentUrlFromStorageUrl(self.uri + "$" + self.funcName) + ) elif name == "Editable" and ENABLE_EDIT_DIALOG: - ret = not self.provCtx.sfa.isReadOnly( self.uri ) + ret = not self.provCtx.sfa.isReadOnly(self.uri) - log.debug( "ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) ) + log.debug("ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret)) except Exception: - log.error( "ScriptBrowseNode.getPropertyValue error " + lastException2String()) + log.error("ScriptBrowseNode.getPropertyValue error " + lastException2String()) raise return ret - def setPropertyValue( self, name, value ): - log.debug( "ScriptBrowseNode.setPropertyValue called " + name + "=" +str(value ) ) - def getPropertySetInfo( self ): - log.debug( "ScriptBrowseNode.getPropertySetInfo called " ) + + def setPropertyValue(self, name, value): + log.debug("ScriptBrowseNode.setPropertyValue called " + name + "=" + str(value)) + + def getPropertySetInfo(self): + log.debug("ScriptBrowseNode.getPropertySetInfo called ") return None - def getIntrospection( self ): + def getIntrospection(self): return None - def invoke( self, name, params, outparamindex, outparams ): + def invoke(self, name, params, outparamindex, outparams): if name == "Editable": servicename = "com.sun.star.awt.DialogProvider" ctx = self.provCtx.scriptContext.getComponentContext() - dlgprov = ctx.ServiceManager.createInstanceWithContext( - servicename, ctx ) + dlgprov = ctx.ServiceManager.createInstanceWithContext(servicename, ctx) self.editor = dlgprov.createDialog( - "vnd.sun.star.script:" + - "ScriptBindingLibrary.MacroEditor?location=application") + "vnd.sun.star.script:" + "ScriptBindingLibrary.MacroEditor?location=application" + ) code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri)) - code = ensureSourceState( code ) + code = ensureSourceState(code) self.editor.getControl("EditorTextField").setText(code) self.editor.getControl("RunButton").setActionCommand("Run") @@ -570,80 +600,77 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, return None - def actionPerformed( self, event ): + def actionPerformed(self, event): try: if event.ActionCommand == "Run": code = self.editor.getControl("EditorTextField").getText() - code = ensureSourceState( code ) + code = ensureSourceState(code) mod = types.ModuleType("ooo_script_framework") mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext exec(code, mod.__dict__) - values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None ) + values = mod.__dict__.get(CALLABLE_CONTAINER_NAME, None) if not values: values = mod.__dict__.values() for i in values: - if isScript( i ): + if isScript(i): i() break elif event.ActionCommand == "Save": toWrite = uno.ByteSequence( - self.editor.getControl("EditorTextField").getText().encode( - sys.getdefaultencoding()) ) + self.editor.getControl("EditorTextField").getText().encode(sys.getdefaultencoding()) + ) copyUrl = self.uri + ".orig" - self.provCtx.sfa.move( self.uri, copyUrl ) - out = self.provCtx.sfa.openFileWrite( self.uri ) - out.writeBytes( toWrite ) + self.provCtx.sfa.move(self.uri, copyUrl) + out = self.provCtx.sfa.openFileWrite(self.uri) + out.writeBytes(toWrite) out.close() - self.provCtx.sfa.kill( copyUrl ) -# log.debug("Save is not implemented yet") -# text = self.editor.getControl("EditorTextField").getText() -# log.debug("Would save: " + text) + self.provCtx.sfa.kill(copyUrl) + # log.debug("Save is not implemented yet") + # text = self.editor.getControl("EditorTextField").getText() + # log.debug("Would save: " + text) except Exception: # TODO: add an error box here! - log.error( lastException2String() ) + log.error(lastException2String()) - - def setValue( self, name, value ): + def setValue(self, name, value): return None - def getValue( self, name ): + def getValue(self, name): return None - def hasMethod( self, name ): + def hasMethod(self, name): return False - def hasProperty( self, name ): + def hasProperty(self, name): return False -#------------------------------------------------------- -class FileBrowseNode( unohelper.Base, XBrowseNode ): - def __init__( self, provCtx, uri , name ): +# ------------------------------------------------------- +class FileBrowseNode(unohelper.Base, XBrowseNode): + def __init__(self, provCtx, uri, name): self.provCtx = provCtx self.uri = uri self.name = name self.funcnames = None - def getName( self ): + def getName(self): return self.name def getChildNodes(self): ret = () try: - self.funcnames = self.provCtx.getFuncsByUrl( self.uri ) + self.funcnames = self.provCtx.getFuncsByUrl(self.uri) scriptNodeList = [] for i in self.funcnames: - scriptNodeList.append( - ScriptBrowseNode( - self.provCtx, self.uri, self.name, i )) - ret = tuple( scriptNodeList ) - log.debug( "returning " +str(len(ret)) + " ScriptChildNodes on " + self.uri ) + scriptNodeList.append(ScriptBrowseNode(self.provCtx, self.uri, self.name, i)) + ret = tuple(scriptNodeList) + log.debug("returning " + str(len(ret)) + " ScriptChildNodes on " + self.uri) except Exception: text = lastException2String() - log.error( "Error while evaluating " + self.uri + ":" + text ) + log.error("Error while evaluating " + self.uri + ":" + text) raise return ret @@ -653,85 +680,83 @@ class FileBrowseNode( unohelper.Base, XBrowseNode ): except Exception: return False - def getType( self): + def getType(self): return CONTAINER - -class DirBrowseNode( unohelper.Base, XBrowseNode ): - def __init__( self, provCtx, name, rootUrl ): +class DirBrowseNode(unohelper.Base, XBrowseNode): + def __init__(self, provCtx, name, rootUrl): self.provCtx = provCtx self.name = name self.rootUrl = rootUrl - def getName( self ): + def getName(self): return self.name - def getChildNodes( self ): + def getChildNodes(self): try: - log.debug( "DirBrowseNode.getChildNodes called for " + self.rootUrl ) - contents = self.provCtx.sfa.getFolderContents( self.rootUrl, True ) + log.debug("DirBrowseNode.getChildNodes called for " + self.rootUrl) + contents = self.provCtx.sfa.getFolderContents(self.rootUrl, True) browseNodeList = [] for i in contents: - if i.endswith( ".py" ): - log.debug( "adding filenode " + i ) - browseNodeList.append( - FileBrowseNode( self.provCtx, i, i[i.rfind("/")+1:len(i)-3] ) ) - elif self.provCtx.sfa.isFolder( i ) and not i.endswith("/pythonpath"): - log.debug( "adding DirBrowseNode " + i ) - browseNodeList.append( DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)],i)) - return tuple( browseNodeList ) + if i.endswith(".py"): + log.debug("adding filenode " + i) + browseNodeList.append(FileBrowseNode(self.provCtx, i, i[i.rfind("/") + 1 : len(i) - 3])) + elif self.provCtx.sfa.isFolder(i) and not i.endswith("/pythonpath"): + log.debug("adding DirBrowseNode " + i) + browseNodeList.append(DirBrowseNode(self.provCtx, i[i.rfind("/") + 1 : len(i)], i)) + return tuple(browseNodeList) except Exception as e: text = lastException2String() - log.error( "DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl) - log.error( text) + log.error("DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl) + log.error(text) return () - def hasChildNodes( self ): + def hasChildNodes(self): return True - def getType( self ): + def getType(self): return CONTAINER - def getScript( self, uri ): - log.debug( "DirBrowseNode getScript " + uri + " invoked" ) - raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 ) + def getScript(self, uri): + log.debug("DirBrowseNode getScript " + uri + " invoked") + raise IllegalArgumentException("DirBrowseNode couldn't instantiate script " + uri, self, 0) -class ManifestHandler( XDocumentHandler, unohelper.Base ): - def __init__( self, rootUrl ): +class ManifestHandler(XDocumentHandler, unohelper.Base): + def __init__(self, rootUrl): self.rootUrl = rootUrl - def startDocument( self ): + def startDocument(self): self.urlList = [] - def endDocument( self ): + def endDocument(self): pass - def startElement( self , name, attlist): + def startElement(self, name, attlist): if name == "manifest:file-entry": - if attlist.getValueByName( "manifest:media-type" ) == "application/vnd.sun.star.framework-script": - self.urlList.append( - self.rootUrl + "/" + attlist.getValueByName( "manifest:full-path" ) ) + if attlist.getValueByName("manifest:media-type") == "application/vnd.sun.star.framework-script": + self.urlList.append(self.rootUrl + "/" + attlist.getValueByName("manifest:full-path")) - def endElement( self, name ): + def endElement(self, name): pass - def characters ( self, chars ): + def characters(self, chars): pass - def ignoreableWhitespace( self, chars ): + def ignoreableWhitespace(self, chars): pass - def setDocumentLocator( self, locator ): + def setDocumentLocator(self, locator): pass -def isPyFileInPath( sfa, path ): + +def isPyFileInPath(sfa, path): ret = False - contents = sfa.getFolderContents( path, True ) + contents = sfa.getFolderContents(path, True) for i in contents: if sfa.isFolder(i): - ret = isPyFileInPath(sfa,i) + ret = isPyFileInPath(sfa, i) else: if i.endswith(".py"): ret = True @@ -739,60 +764,70 @@ def isPyFileInPath( sfa, path ): break return ret + # extracts META-INF directory from -def getPathsFromPackage( rootUrl, sfa ): +def getPathsFromPackage(rootUrl, sfa): ret = () try: fileUrl = rootUrl + "/META-INF/manifest.xml" - inputStream = sfa.openFileRead( fileUrl ) - parser = uno.getComponentContext().ServiceManager.createInstance( "com.sun.star.xml.sax.Parser" ) - handler = ManifestHandler( rootUrl ) - parser.setDocumentHandler( handler ) - parser.parseStream( InputSource( inputStream , "", fileUrl, fileUrl ) ) + inputStream = sfa.openFileRead(fileUrl) + parser = uno.getComponentContext().ServiceManager.createInstance("com.sun.star.xml.sax.Parser") + handler = ManifestHandler(rootUrl) + parser.setDocumentHandler(handler) + parser.parseStream(InputSource(inputStream, "", fileUrl, fileUrl)) for i in tuple(handler.urlList): - if not isPyFileInPath( sfa, i ): + if not isPyFileInPath(sfa, i): handler.urlList.remove(i) - ret = tuple( handler.urlList ) + ret = tuple(handler.urlList) except UnoException: text = lastException2String() - log.debug( "getPathsFromPackage " + fileUrl + " Exception: " +text ) + log.debug("getPathsFromPackage " + fileUrl + " Exception: " + text) pass return ret class Package: - def __init__( self, paths, transientPathElement ): + def __init__(self, paths, transientPathElement): self.paths = paths self.transientPathElement = transientPathElement -class DummyInteractionHandler( unohelper.Base, XInteractionHandler ): - def __init__( self ): + +class DummyInteractionHandler(unohelper.Base, XInteractionHandler): + def __init__(self): pass - def handle( self, event): - log.debug( "pythonscript: DummyInteractionHandler.handle " + str( event ) ) -class DummyProgressHandler( unohelper.Base, XProgressHandler ): - def __init__( self ): + def handle(self, event): + log.debug("pythonscript: DummyInteractionHandler.handle " + str(event)) + + +class DummyProgressHandler(unohelper.Base, XProgressHandler): + def __init__(self): pass - def push( self,status ): - log.debug( "pythonscript: DummyProgressHandler.push " + str( status ) ) - def update( self,status ): - log.debug( "pythonscript: DummyProgressHandler.update " + str( status ) ) - def pop( self, event ): - log.debug( "pythonscript: DummyProgressHandler.push " + str( event ) ) + def push(self, status): + log.debug("pythonscript: DummyProgressHandler.push " + str(status)) + + def update(self, status): + log.debug("pythonscript: DummyProgressHandler.update " + str(status)) + + def pop(self, event): + log.debug("pythonscript: DummyProgressHandler.push " + str(event)) + class CommandEnvironment(unohelper.Base, XCommandEnvironment): - def __init__( self ): + def __init__(self): self.progressHandler = DummyProgressHandler() self.interactionHandler = DummyInteractionHandler() - def getInteractionHandler( self ): + + def getInteractionHandler(self): return self.interactionHandler - def getProgressHandler( self ): + + def getProgressHandler(self): return self.progressHandler -#maybe useful for debugging purposes -#class ModifyListener( unohelper.Base, XModifyListener ): + +# maybe useful for debugging purposes +# class ModifyListener( unohelper.Base, XModifyListener ): # def __init__( self ): # pass # def modified( self, event ): @@ -800,12 +835,14 @@ class CommandEnvironment(unohelper.Base, XCommandEnvironment): # def disposing( self, event ): # log.debug( "pythonscript: ModifyListener.disposing " + str( event ) ) + def getModelFromDocUrl(ctx, url): """Get document model from document url.""" doc = None args = ("Local", "Office") ucb = ctx.getServiceManager().createInstanceWithArgumentsAndContext( - "com.sun.star.ucb.UniversalContentBroker", args, ctx) + "com.sun.star.ucb.UniversalContentBroker", args, ctx + ) identifier = ucb.createContentIdentifier(url) content = ucb.queryContent(identifier) p = Property() @@ -825,20 +862,20 @@ def getModelFromDocUrl(ctx, url): log.isErrorLevel() and log.error("getModelFromDocUrl: %s" % url) return doc -def mapStorageType2PackageContext( storageType ): + +def mapStorageType2PackageContext(storageType): ret = storageType - if( storageType == "share:uno_packages" ): + if storageType == "share:uno_packages": ret = "shared" - if( storageType == "user:uno_packages" ): + if storageType == "user:uno_packages": ret = "user" return ret + def getPackageName2PathMap(sfa, storageType): ret = {} - ext_mgr = uno.getComponentContext().getValueByName( - "/singletons/com.sun.star.deployment.ExtensionManager" - ) + ext_mgr = uno.getComponentContext().getValueByName("/singletons/com.sun.star.deployment.ExtensionManager") log.debug("pythonscript: getPackageName2PathMap start getDeployedPackages") packages = ext_mgr.getDeployedExtensions( @@ -847,11 +884,7 @@ def getPackageName2PathMap(sfa, storageType): CommandEnvironment(), ) - log.debug( - "pythonscript: getPackageName2PathMap end getDeployedPackages (" - + str(len(packages)) - + ")" - ) + log.debug("pythonscript: getPackageName2PathMap end getDeployedPackages (" + str(len(packages)) + ")") for pkg in packages: log.debug("inspecting package " + pkg.Name + "(" + pkg.Identifier.Value + ")") # type: ignore @@ -864,68 +897,73 @@ def getPackageName2PathMap(sfa, storageType): ret[lastElement(exp_uri)] = Package(paths, transientPathElement) return ret -def penultimateElement( aStr ): + +def penultimateElement(aStr): lastSlash = aStr.rindex("/") - penultimateSlash = aStr.rindex("/",0,lastSlash-1) - return aStr[ penultimateSlash+1:lastSlash ] + penultimateSlash = aStr.rindex("/", 0, lastSlash - 1) + return aStr[penultimateSlash + 1 : lastSlash] + + +def lastElement(aStr): + return aStr[aStr.rfind("/") + 1 : len(aStr)] -def lastElement( aStr): - return aStr[ aStr.rfind( "/" )+1:len(aStr)] -class PackageBrowseNode( unohelper.Base, XBrowseNode ): - def __init__( self, provCtx, name, rootUrl ): +class PackageBrowseNode(unohelper.Base, XBrowseNode): + def __init__(self, provCtx, name, rootUrl): self.provCtx = provCtx self.name = name self.rootUrl = rootUrl - def getName( self ): + def getName(self): return self.name - def getChildNodes( self ): + def getChildNodes(self): items = self.provCtx.mapPackageName2Path.items() browseNodeList = [] for i in items: - if len( i[1].paths ) == 1: - browseNodeList.append( - DirBrowseNode( self.provCtx, i[0], i[1].paths[0] )) + if len(i[1].paths) == 1: + browseNodeList.append(DirBrowseNode(self.provCtx, i[0], i[1].paths[0])) else: for j in i[1].paths: - browseNodeList.append( - DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j), j ) ) - return tuple( browseNodeList ) + browseNodeList.append(DirBrowseNode(self.provCtx, i[0] + "." + lastElement(j), j)) + return tuple(browseNodeList) - def hasChildNodes( self ): - return len( self.provCtx.mapPackageName2Path ) > 0 + def hasChildNodes(self): + return len(self.provCtx.mapPackageName2Path) > 0 - def getType( self ): + def getType(self): return CONTAINER - def getScript( self, uri ): - log.debug( "PackageBrowseNode getScript " + uri + " invoked" ) - raise IllegalArgumentException( "PackageBrowseNode couldn't instantiate script " + uri , self , 0 ) - - + def getScript(self, uri): + log.debug("PackageBrowseNode getScript " + uri + " invoked") + raise IllegalArgumentException("PackageBrowseNode couldn't instantiate script " + uri, self, 0) -class PythonScript( unohelper.Base, XScript ): - def __init__( self, func, mod, args ): +class PythonScript(unohelper.Base, XScript): + def __init__(self, func, mod, args): self.func = func self.mod = mod self.args = args - def invoke(self, args, out, outindex ): - log.debug( "PythonScript.invoke " + str( args ) ) + def invoke(self, args, out, outindex): + log.debug("PythonScript.invoke " + str(args)) try: - if (self.args): + if self.args: args += self.args - ret = self.func( *args ) + ret = self.func(*args) except UnoException as e: # UNO Exception continue to fly ... text = lastException2String() - complete = "Error during invoking function " + \ - str(self.func.__name__) + " in module " + \ - self.mod.__file__ + " (" + text + ")" - log.debug( complete ) + complete = ( + "Error during invoking function " + + str(self.func.__name__) + + " in module " + + self.mod.__file__ + + " (" + + text + + ")" + ) + log.debug(complete) # some people may beat me up for modifying the exception text, # but otherwise office just shows # the type name and message text with no more information, @@ -935,33 +973,44 @@ class PythonScript( unohelper.Base, XScript ): except Exception: # General python exception are converted to uno RuntimeException text = lastException2String() - complete = "Error during invoking function " + \ - str(self.func.__name__) + " in module " + \ - self.mod.__file__ + " (" + text + ")" - log.debug( complete ) - raise RuntimeException( complete , self ) - log.debug( "PythonScript.invoke ret = " + str( ret ) ) + complete = ( + "Error during invoking function " + + str(self.func.__name__) + + " in module " + + self.mod.__file__ + + " (" + + text + + ")" + ) + log.debug(complete) + raise RuntimeException(complete, self) + log.debug("PythonScript.invoke ret = " + str(ret)) return ret, (), () -def expandUri( uri ): - if uri.startswith( "vnd.sun.star.expand:" ): - uri = uri.replace( "vnd.sun.star.expand:", "",1) - uri = uno.getComponentContext().getByName( - "/singletons/com.sun.star.util.theMacroExpander" ).expandMacros( unquote(uri) ) - if uri.startswith( "file:" ): - uri = uno.absolutize("",uri) # necessary to get rid of .. in uri + +def expandUri(uri): + if uri.startswith("vnd.sun.star.expand:"): + uri = uri.replace("vnd.sun.star.expand:", "", 1) + uri = ( + uno.getComponentContext() + .getByName("/singletons/com.sun.star.util.theMacroExpander") + .expandMacros(unquote(uri)) + ) + if uri.startswith("file:"): + uri = uno.absolutize("", uri) # necessary to get rid of .. in uri return uri -#-------------------------------------------------------------- -class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer): - def __init__( self, ctx, *args ): + +# -------------------------------------------------------------- +class PythonScriptProvider(unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer): + def __init__(self, ctx, *args): if log.isDebugLevel(): mystr = "" for i in args: if len(mystr) > 0: - mystr = mystr +"," + mystr = mystr + "," mystr = mystr + str(i) - log.debug( "Entering PythonScriptProvider.ctor" + mystr ) + log.debug("Entering PythonScriptProvider.ctor" + mystr) doc = None inv = None @@ -969,75 +1018,77 @@ class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameC if isinstance(args[0], str): storageType = args[0] - if storageType.startswith( "vnd.sun.star.tdoc" ): + if storageType.startswith("vnd.sun.star.tdoc"): doc = getModelFromDocUrl(ctx, storageType) else: inv = args[0] try: doc = inv.ScriptContainer - content = ctx.getServiceManager().createInstanceWithContext( - "com.sun.star.frame.TransientDocumentsDocumentContentFactory", - ctx).createDocumentContent(doc) + content = ( + ctx.getServiceManager() + .createInstanceWithContext("com.sun.star.frame.TransientDocumentsDocumentContentFactory", ctx) + .createDocumentContent(doc) + ) storageType = content.getIdentifier().getContentIdentifier() except Exception: text = lastException2String() - log.error( text ) + log.error(text) - isPackage = storageType.endswith( ":uno_packages" ) + isPackage = storageType.endswith(":uno_packages") try: -# urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext( -# "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx) - urlHelper = MyUriHelper( ctx, storageType ) - log.debug( "got urlHelper " + str( urlHelper ) ) + # urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext( + # "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx) + urlHelper = MyUriHelper(ctx, storageType) + log.debug("got urlHelper " + str(urlHelper)) - rootUrl = expandUri( urlHelper.getRootStorageURI() ) - log.debug( storageType + " transformed to " + rootUrl ) + rootUrl = expandUri(urlHelper.getRootStorageURI()) + log.debug(storageType + " transformed to " + rootUrl) ucbService = "com.sun.star.ucb.SimpleFileAccess" - sfa = ctx.ServiceManager.createInstanceWithContext( ucbService, ctx ) + sfa = ctx.ServiceManager.createInstanceWithContext(ucbService, ctx) if not sfa: - log.debug("PythonScriptProvider couldn't instantiate " +ucbService) - raise RuntimeException( - "PythonScriptProvider couldn't instantiate " +ucbService, self) + log.debug("PythonScriptProvider couldn't instantiate " + ucbService) + raise RuntimeException("PythonScriptProvider couldn't instantiate " + ucbService, self) self.provCtx = ProviderContext( - storageType, sfa, urlHelper, ScriptContext( uno.getComponentContext(), doc, inv ) ) + storageType, sfa, urlHelper, ScriptContext(uno.getComponentContext(), doc, inv) + ) if isPackage: - mapPackageName2Path = getPackageName2PathMap( sfa, storageType ) - self.provCtx.setPackageAttributes( mapPackageName2Path , rootUrl ) - self.dirBrowseNode = PackageBrowseNode( self.provCtx, LANGUAGENAME, rootUrl ) + mapPackageName2Path = getPackageName2PathMap(sfa, storageType) + self.provCtx.setPackageAttributes(mapPackageName2Path, rootUrl) + self.dirBrowseNode = PackageBrowseNode(self.provCtx, LANGUAGENAME, rootUrl) else: - self.dirBrowseNode = DirBrowseNode( self.provCtx, LANGUAGENAME, rootUrl ) + self.dirBrowseNode = DirBrowseNode(self.provCtx, LANGUAGENAME, rootUrl) except Exception as e: text = lastException2String() - log.debug( "PythonScriptProvider could not be instantiated because of : " + text ) + log.debug("PythonScriptProvider could not be instantiated because of : " + text) raise e - def getName( self ): + def getName(self): return self.dirBrowseNode.getName() - def getChildNodes( self ): + def getChildNodes(self): return self.dirBrowseNode.getChildNodes() - def hasChildNodes( self ): + def hasChildNodes(self): return self.dirBrowseNode.hasChildNodes() - def getType( self ): + def getType(self): return self.dirBrowseNode.getType() # retrieve function args in parenthesis def getFunctionArguments(self, func_signature): - nOpenParenthesis = func_signature.find( "(" ) + nOpenParenthesis = func_signature.find("(") if -1 == nOpenParenthesis: function_name = func_signature arguments = None else: function_name = func_signature[0:nOpenParenthesis] - arg_part = func_signature[nOpenParenthesis+1:len(func_signature)] - nCloseParenthesis = arg_part.find( ")" ) + arg_part = func_signature[nOpenParenthesis + 1 : len(func_signature)] + nCloseParenthesis = arg_part.find(")") if -1 == nCloseParenthesis: - raise IllegalArgumentException( "PythonLoader: mismatch parenthesis " + func_signature, self, 0 ) + raise IllegalArgumentException("PythonLoader: mismatch parenthesis " + func_signature, self, 0) arguments = arg_part[0:nCloseParenthesis].strip() if arguments == "": arguments = None @@ -1045,107 +1096,109 @@ class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameC arguments = tuple([x.strip().strip('"') for x in arguments.split(",")]) return function_name, arguments - def getScript( self, scriptUri ): + def getScript(self, scriptUri): try: - log.debug( "getScript " + scriptUri + " invoked") + log.debug("getScript " + scriptUri + " invoked") - storageUri = self.provCtx.getStorageUrlFromPersistentUrl( - self.provCtx.uriHelper.getStorageURI(scriptUri) ) - log.debug( "getScript: storageUri = " + storageUri) - fileUri = storageUri[0:storageUri.find( "$" )] - funcName = storageUri[storageUri.find( "$" )+1:len(storageUri)] + storageUri = self.provCtx.getStorageUrlFromPersistentUrl(self.provCtx.uriHelper.getStorageURI(scriptUri)) + log.debug("getScript: storageUri = " + storageUri) + fileUri = storageUri[0 : storageUri.find("$")] + funcName = storageUri[storageUri.find("$") + 1 : len(storageUri)] # retrieve arguments in parenthesis funcName, funcArgs = self.getFunctionArguments(funcName) - log.debug( " getScript : parsed funcname " + str(funcName) ) - log.debug( " getScript : func args " + str(funcArgs) ) + log.debug(" getScript : parsed funcname " + str(funcName)) + log.debug(" getScript : func args " + str(funcArgs)) - mod = self.provCtx.getModuleByUrl( fileUri ) - log.debug( " got mod " + str(mod) ) + mod = self.provCtx.getModuleByUrl(fileUri) + log.debug(" got mod " + str(mod)) - func = mod.__dict__[ funcName ] + func = mod.__dict__[funcName] - log.debug( "got func " + str( func ) ) - return PythonScript( func, mod, funcArgs ) + log.debug("got func " + str(func)) + return PythonScript(func, mod, funcArgs) except Exception: text = lastException2String() - log.error( text ) - raise ScriptFrameworkErrorException( text, self, scriptUri, LANGUAGENAME, 0 ) - + log.error(text) + raise ScriptFrameworkErrorException(text, self, scriptUri, LANGUAGENAME, 0) # XServiceInfo - def getSupportedServices( self ): + def getSupportedServices(self): return g_ImplementationHelper.getSupportedServices(g_implName) - def supportsService( self, ServiceName ): - return g_ImplementationHelper.supportsService( g_implName, ServiceName ) + def supportsService(self, ServiceName): + return g_ImplementationHelper.supportsService(g_implName, ServiceName) def getImplementationName(self): return g_implName - def getByName( self, name ): - log.debug( "getByName called" + str( name )) + def getByName(self, name): + log.debug("getByName called" + str(name)) return None - - def getElementNames( self ): - log.debug( "getElementNames called") + def getElementNames(self): + log.debug("getElementNames called") return () - def hasByName( self, name ): + def hasByName(self, name): try: - log.debug( "hasByName called " + str( name )) + log.debug("hasByName called " + str(name)) uri = expandUri(name) - ret = self.provCtx.isUrlInPackage( uri ) - log.debug( "hasByName " + uri + " " +str( ret ) ) + ret = self.provCtx.isUrlInPackage(uri) + log.debug("hasByName " + uri + " " + str(ret)) return ret except Exception: text = lastException2String() - log.debug( "Error in hasByName:" + text ) + log.debug("Error in hasByName:" + text) return False - def removeByName( self, name ): - log.debug( "removeByName called" + str( name )) - uri = expandUri( name ) - if self.provCtx.isUrlInPackage( uri ): - self.provCtx.removePackageByUrl( uri ) + def removeByName(self, name): + log.debug("removeByName called" + str(name)) + uri = expandUri(name) + if self.provCtx.isUrlInPackage(uri): + self.provCtx.removePackageByUrl(uri) else: - log.debug( "removeByName unknown uri " + str( name ) + ", ignoring" ) - raise NoSuchElementException( uri + "is not in package" , self ) - log.debug( "removeByName called" + str( uri ) + " successful" ) - - def insertByName( self, name, value ): - log.debug( "insertByName called " + str( name ) + " " + str( value )) - uri = expandUri( name ) - if isPyFileInPath( self.provCtx.sfa, uri ): - self.provCtx.addPackageByUrl( uri ) + log.debug("removeByName unknown uri " + str(name) + ", ignoring") + raise NoSuchElementException(uri + "is not in package", self) + log.debug("removeByName called" + str(uri) + " successful") + + def insertByName(self, name, value): + log.debug("insertByName called " + str(name) + " " + str(value)) + uri = expandUri(name) + if isPyFileInPath(self.provCtx.sfa, uri): + self.provCtx.addPackageByUrl(uri) else: # package is no python package ... - log.debug( "insertByName: no python files in " + str( uri ) + ", ignoring" ) - raise IllegalArgumentException( uri + " does not contain .py files", self, 1 ) - log.debug( "insertByName called " + str( uri ) + " successful" ) - - def replaceByName( self, name, value ): - log.debug( "replaceByName called " + str( name ) + " " + str( value )) - uri = expandUri( name ) - self.removeByName( name ) - self.insertByName( name, value ) - log.debug( "replaceByName called" + str( uri ) + " successful" ) - - def getElementType( self ): - log.debug( "getElementType called" ) - return uno.getTypeByName( "void" ) - - def hasElements( self ): - log.debug( "hasElements got called") + log.debug("insertByName: no python files in " + str(uri) + ", ignoring") + raise IllegalArgumentException(uri + " does not contain .py files", self, 1) + log.debug("insertByName called " + str(uri) + " successful") + + def replaceByName(self, name, value): + log.debug("replaceByName called " + str(name) + " " + str(value)) + uri = expandUri(name) + self.removeByName(name) + self.insertByName(name, value) + log.debug("replaceByName called" + str(uri) + " successful") + + def getElementType(self): + log.debug("getElementType called") + return uno.getTypeByName("void") + + def hasElements(self): + log.debug("hasElements got called") return False -g_ImplementationHelper.addImplementation( \ - PythonScriptProvider,g_implName, \ - ("com.sun.star.script.provider.LanguageScriptProvider", - "com.sun.star.script.provider.ScriptProviderFor"+ LANGUAGENAME,),) + +g_ImplementationHelper.addImplementation( + PythonScriptProvider, + g_implName, + ( + "com.sun.star.script.provider.LanguageScriptProvider", + "com.sun.star.script.provider.ScriptProviderFor" + LANGUAGENAME, + ), +) -log.debug( "pythonscript finished initializing" ) +log.debug("pythonscript finished initializing") # vim: set shiftwidth=4 softtabstop=4 expandtab: