1*9f22d7c2SAndrew Rist# ************************************************************* 2*9f22d7c2SAndrew Rist# 3*9f22d7c2SAndrew Rist# Licensed to the Apache Software Foundation (ASF) under one 4*9f22d7c2SAndrew Rist# or more contributor license agreements. See the NOTICE file 5*9f22d7c2SAndrew Rist# distributed with this work for additional information 6*9f22d7c2SAndrew Rist# regarding copyright ownership. The ASF licenses this file 7*9f22d7c2SAndrew Rist# to you under the Apache License, Version 2.0 (the 8*9f22d7c2SAndrew Rist# "License"); you may not use this file except in compliance 9*9f22d7c2SAndrew Rist# with the License. You may obtain a copy of the License at 10*9f22d7c2SAndrew Rist# 11*9f22d7c2SAndrew Rist# http://www.apache.org/licenses/LICENSE-2.0 12*9f22d7c2SAndrew Rist# 13*9f22d7c2SAndrew Rist# Unless required by applicable law or agreed to in writing, 14*9f22d7c2SAndrew Rist# software distributed under the License is distributed on an 15*9f22d7c2SAndrew Rist# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9f22d7c2SAndrew Rist# KIND, either express or implied. See the License for the 17*9f22d7c2SAndrew Rist# specific language governing permissions and limitations 18*9f22d7c2SAndrew Rist# under the License. 19*9f22d7c2SAndrew Rist# 20*9f22d7c2SAndrew Rist# ************************************************************* 21*9f22d7c2SAndrew Rist 22cdf0e10cSrcweir# XScript implementation for python 23cdf0e10cSrcweirimport uno 24cdf0e10cSrcweirimport unohelper 25cdf0e10cSrcweirimport sys 26cdf0e10cSrcweirimport os 27cdf0e10cSrcweirimport imp 28cdf0e10cSrcweirimport time 29cdf0e10cSrcweirimport compiler 30cdf0e10cSrcweir 31cdf0e10cSrcweirclass LogLevel: 32cdf0e10cSrcweir NONE = 0 33cdf0e10cSrcweir ERROR = 1 34cdf0e10cSrcweir DEBUG = 2 35cdf0e10cSrcweir 36cdf0e10cSrcweir# Configuration ---------------------------------------------------- 37cdf0e10cSrcweirLogLevel.use = LogLevel.NONE # production level 38cdf0e10cSrcweir#LogLevel.use = LogLevel.ERROR # for script developers 39cdf0e10cSrcweir#LogLevel.use = LogLevel.DEBUG # for script framework developers 40cdf0e10cSrcweirLOG_STDOUT = True # True, writes to stdout (difficult on windows) 41cdf0e10cSrcweir # False, writes to user/Scripts/python/log.txt 42cdf0e10cSrcweirENABLE_EDIT_DIALOG=False # offers a minimal editor for editing. 43cdf0e10cSrcweir#------------------------------------------------------------------- 44cdf0e10cSrcweir 45cdf0e10cSrcweirdef encfile(uni): 46cdf0e10cSrcweir return uni.encode( sys.getfilesystemencoding()) 47cdf0e10cSrcweir 48cdf0e10cSrcweirdef lastException2String(): 49cdf0e10cSrcweir (excType,excInstance,excTraceback) = sys.exc_info() 50cdf0e10cSrcweir ret = str(excType) + ": "+str(excInstance) + "\n" + \ 51cdf0e10cSrcweir uno._uno_extract_printable_stacktrace( excTraceback ) 52cdf0e10cSrcweir return ret 53cdf0e10cSrcweir 54cdf0e10cSrcweirdef logLevel2String( level ): 55cdf0e10cSrcweir ret = " NONE" 56cdf0e10cSrcweir if level == LogLevel.ERROR: 57cdf0e10cSrcweir ret = "ERROR" 58cdf0e10cSrcweir elif level >= LogLevel.DEBUG: 59cdf0e10cSrcweir ret = "DEBUG" 60cdf0e10cSrcweir return ret 61cdf0e10cSrcweir 62cdf0e10cSrcweirdef getLogTarget(): 63cdf0e10cSrcweir ret = sys.stdout 64cdf0e10cSrcweir if not LOG_STDOUT: 65cdf0e10cSrcweir try: 66cdf0e10cSrcweir pathSubst = uno.getComponentContext().ServiceManager.createInstance( 67cdf0e10cSrcweir "com.sun.star.util.PathSubstitution" ) 68cdf0e10cSrcweir userInstallation = pathSubst.getSubstituteVariableValue( "user" ) 69cdf0e10cSrcweir if len( userInstallation ) > 0: 70cdf0e10cSrcweir systemPath = uno.fileUrlToSystemPath( userInstallation + "/Scripts/python/log.txt" ) 71cdf0e10cSrcweir ret = file( systemPath , "a" ) 72cdf0e10cSrcweir except Exception,e: 73cdf0e10cSrcweir print "Exception during creation of pythonscript logfile: "+ lastException2String() + "\n, delagating log to stdout\n" 74cdf0e10cSrcweir return ret 75cdf0e10cSrcweir 76cdf0e10cSrcweirclass Logger(LogLevel): 77cdf0e10cSrcweir def __init__(self , target ): 78cdf0e10cSrcweir self.target = target 79cdf0e10cSrcweir 80cdf0e10cSrcweir def isDebugLevel( self ): 81cdf0e10cSrcweir return self.use >= self.DEBUG 82cdf0e10cSrcweir 83cdf0e10cSrcweir def debug( self, msg ): 84cdf0e10cSrcweir if self.isDebugLevel(): 85cdf0e10cSrcweir self.log( self.DEBUG, msg ) 86cdf0e10cSrcweir 87cdf0e10cSrcweir def isErrorLevel( self ): 88cdf0e10cSrcweir return self.use >= self.ERROR 89cdf0e10cSrcweir 90cdf0e10cSrcweir def error( self, msg ): 91cdf0e10cSrcweir if self.isErrorLevel(): 92cdf0e10cSrcweir self.log( self.ERROR, msg ) 93cdf0e10cSrcweir 94cdf0e10cSrcweir def log( self, level, msg ): 95cdf0e10cSrcweir if self.use >= level: 96cdf0e10cSrcweir try: 97cdf0e10cSrcweir self.target.write( 98cdf0e10cSrcweir time.asctime() + 99cdf0e10cSrcweir " [" + 100cdf0e10cSrcweir logLevel2String( level ) + 101cdf0e10cSrcweir "] " + 102cdf0e10cSrcweir encfile(msg) + 103cdf0e10cSrcweir "\n" ) 104cdf0e10cSrcweir self.target.flush() 105cdf0e10cSrcweir except Exception,e: 106cdf0e10cSrcweir print "Error during writing to stdout: " +lastException2String() + "\n" 107cdf0e10cSrcweir 108cdf0e10cSrcweirlog = Logger( getLogTarget() ) 109cdf0e10cSrcweir 110cdf0e10cSrcweirlog.debug( "pythonscript loading" ) 111cdf0e10cSrcweir 112cdf0e10cSrcweir#from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider 113cdf0e10cSrcweirfrom com.sun.star.uno import RuntimeException 114cdf0e10cSrcweirfrom com.sun.star.lang import XServiceInfo 115cdf0e10cSrcweirfrom com.sun.star.io import IOException 116cdf0e10cSrcweirfrom com.sun.star.ucb import CommandAbortedException, XCommandEnvironment, XProgressHandler 117cdf0e10cSrcweirfrom com.sun.star.task import XInteractionHandler 118cdf0e10cSrcweirfrom com.sun.star.beans import XPropertySet 119cdf0e10cSrcweirfrom com.sun.star.container import XNameContainer 120cdf0e10cSrcweirfrom com.sun.star.xml.sax import XDocumentHandler, InputSource 121cdf0e10cSrcweirfrom com.sun.star.uno import Exception as UnoException 122cdf0e10cSrcweirfrom com.sun.star.script import XInvocation 123cdf0e10cSrcweirfrom com.sun.star.awt import XActionListener 124cdf0e10cSrcweir 125cdf0e10cSrcweirfrom com.sun.star.script.provider import XScriptProvider, XScript, XScriptContext, ScriptFrameworkErrorException 126cdf0e10cSrcweirfrom com.sun.star.script.browse import XBrowseNode 127cdf0e10cSrcweirfrom com.sun.star.script.browse.BrowseNodeTypes import SCRIPT, CONTAINER, ROOT 128cdf0e10cSrcweirfrom com.sun.star.util import XModifyListener 129cdf0e10cSrcweir 130cdf0e10cSrcweirLANGUAGENAME = "Python" 131cdf0e10cSrcweirGLOBAL_SCRIPTCONTEXT_NAME = "XSCRIPTCONTEXT" 132cdf0e10cSrcweirCALLABLE_CONTAINER_NAME = "g_exportedScripts" 133cdf0e10cSrcweir 134cdf0e10cSrcweir# pythonloader looks for a static g_ImplementationHelper variable 135cdf0e10cSrcweirg_ImplementationHelper = unohelper.ImplementationHelper() 136cdf0e10cSrcweirg_implName = "org.openoffice.pyuno.LanguageScriptProviderFor"+LANGUAGENAME 137cdf0e10cSrcweir 138cdf0e10cSrcweir 139cdf0e10cSrcweir 140cdf0e10cSrcweirBLOCK_SIZE = 65536 141cdf0e10cSrcweirdef readTextFromStream( inputStream ): 142cdf0e10cSrcweir # read the file 143cdf0e10cSrcweir code = uno.ByteSequence( "" ) 144cdf0e10cSrcweir while True: 145cdf0e10cSrcweir read,out = inputStream.readBytes( None , BLOCK_SIZE ) 146cdf0e10cSrcweir code = code + out 147cdf0e10cSrcweir if read < BLOCK_SIZE: 148cdf0e10cSrcweir break 149cdf0e10cSrcweir return code.value 150cdf0e10cSrcweir 151cdf0e10cSrcweirdef toIniName( str ): 152cdf0e10cSrcweir # TODO: what is the official way to get to know whether i am on the windows platform ? 153cdf0e10cSrcweir if( hasattr(sys , "dllhandle") ): 154cdf0e10cSrcweir return str + ".ini" 155cdf0e10cSrcweir return str + "rc" 156cdf0e10cSrcweir 157cdf0e10cSrcweir 158cdf0e10cSrcweir""" definition: storageURI is the system dependent, absolute file url, where the script is stored on disk 159cdf0e10cSrcweir scriptURI is the system independent uri 160cdf0e10cSrcweir""" 161cdf0e10cSrcweirclass MyUriHelper: 162cdf0e10cSrcweir 163cdf0e10cSrcweir def __init__( self, ctx, location ): 164cdf0e10cSrcweir self.s_UriMap = \ 165cdf0e10cSrcweir { "share" : "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" + toIniName( "bootstrap") + "::BaseInstallation}/share/Scripts/python" , \ 166cdf0e10cSrcweir "share:uno_packages" : "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE/uno_packages", \ 167cdf0e10cSrcweir "user" : "vnd.sun.star.expand:${$BRAND_BASE_DIR/program/" + toIniName( "bootstrap") + "::UserInstallation}/user/Scripts/python" , \ 168cdf0e10cSrcweir "user:uno_packages" : "vnd.sun.star.expand:$UNO_USER_PACKAGES_CACHE/uno_packages" } 169cdf0e10cSrcweir self.m_uriRefFac = ctx.ServiceManager.createInstanceWithContext("com.sun.star.uri.UriReferenceFactory",ctx) 170cdf0e10cSrcweir if location.startswith( "vnd.sun.star.tdoc" ): 171cdf0e10cSrcweir self.m_baseUri = location + "/Scripts/python" 172cdf0e10cSrcweir self.m_scriptUriLocation = "document" 173cdf0e10cSrcweir else: 174cdf0e10cSrcweir self.m_baseUri = expandUri( self.s_UriMap[location] ) 175cdf0e10cSrcweir self.m_scriptUriLocation = location 176cdf0e10cSrcweir log.isDebugLevel() and log.debug( "initialized urihelper with baseUri="+self.m_baseUri + ",m_scriptUriLocation="+self.m_scriptUriLocation ) 177cdf0e10cSrcweir 178cdf0e10cSrcweir def getRootStorageURI( self ): 179cdf0e10cSrcweir return self.m_baseUri 180cdf0e10cSrcweir 181cdf0e10cSrcweir def getStorageURI( self, scriptURI ): 182cdf0e10cSrcweir return self.scriptURI2StorageUri(scriptURI) 183cdf0e10cSrcweir 184cdf0e10cSrcweir def getScriptURI( self, storageURI ): 185cdf0e10cSrcweir return self.storageURI2ScriptUri(storageURI) 186cdf0e10cSrcweir 187cdf0e10cSrcweir def storageURI2ScriptUri( self, storageURI ): 188cdf0e10cSrcweir if not storageURI.startswith( self.m_baseUri ): 189cdf0e10cSrcweir message = "pythonscript: storage uri '" + storageURI + "' not in base uri '" + self.m_baseUri + "'" 190cdf0e10cSrcweir log.isDebugLevel() and log.debug( message ) 191cdf0e10cSrcweir raise RuntimeException( message ) 192cdf0e10cSrcweir 193cdf0e10cSrcweir ret = "vnd.sun.star.script:" + \ 194cdf0e10cSrcweir storageURI[len(self.m_baseUri)+1:].replace("/","|") + \ 195cdf0e10cSrcweir "?language=" + LANGUAGENAME + "&location=" + self.m_scriptUriLocation 196cdf0e10cSrcweir log.isDebugLevel() and log.debug( "converting storageURI="+storageURI + " to scriptURI=" + ret ) 197cdf0e10cSrcweir return ret 198cdf0e10cSrcweir 199cdf0e10cSrcweir def scriptURI2StorageUri( self, scriptURI ): 200cdf0e10cSrcweir try: 201cdf0e10cSrcweir myUri = self.m_uriRefFac.parse(scriptURI) 202cdf0e10cSrcweir ret = self.m_baseUri + "/" + myUri.getName().replace( "|", "/" ) 203cdf0e10cSrcweir log.isDebugLevel() and log.debug( "converting scriptURI="+scriptURI + " to storageURI=" + ret ) 204cdf0e10cSrcweir return ret 205cdf0e10cSrcweir except UnoException, e: 206cdf0e10cSrcweir log.error( "error during converting scriptURI="+scriptURI + ": " + e.Message) 207cdf0e10cSrcweir raise RuntimeException( "pythonscript:scriptURI2StorageUri: " +e.getMessage(), None ) 208cdf0e10cSrcweir except Exception, e: 209cdf0e10cSrcweir log.error( "error during converting scriptURI="+scriptURI + ": " + str(e)) 210cdf0e10cSrcweir raise RuntimeException( "pythonscript:scriptURI2StorageUri: " + str(e), None ) 211cdf0e10cSrcweir 212cdf0e10cSrcweir 213cdf0e10cSrcweirclass ModuleEntry: 214cdf0e10cSrcweir def __init__( self, lastRead, module ): 215cdf0e10cSrcweir self.lastRead = lastRead 216cdf0e10cSrcweir self.module = module 217cdf0e10cSrcweir 218cdf0e10cSrcweirdef hasChanged( oldDate, newDate ): 219cdf0e10cSrcweir return newDate.Year > oldDate.Year or \ 220cdf0e10cSrcweir newDate.Month > oldDate.Month or \ 221cdf0e10cSrcweir newDate.Day > oldDate.Day or \ 222cdf0e10cSrcweir newDate.Hours > oldDate.Hours or \ 223cdf0e10cSrcweir newDate.Minutes > oldDate.Minutes or \ 224cdf0e10cSrcweir newDate.Seconds > oldDate.Seconds or \ 225cdf0e10cSrcweir newDate.HundredthSeconds > oldDate.HundredthSeconds 226cdf0e10cSrcweir 227cdf0e10cSrcweirdef ensureSourceState( code ): 228cdf0e10cSrcweir if not code.endswith( "\n" ): 229cdf0e10cSrcweir code = code + "\n" 230cdf0e10cSrcweir code = code.replace( "\r", "" ) 231cdf0e10cSrcweir return code 232cdf0e10cSrcweir 233cdf0e10cSrcweir 234cdf0e10cSrcweirdef checkForPythonPathBesideScript( url ): 235cdf0e10cSrcweir if url.startswith( "file:" ): 236cdf0e10cSrcweir path = unohelper.fileUrlToSystemPath( url+"/pythonpath.zip" ); 237cdf0e10cSrcweir log.log( LogLevel.DEBUG, "checking for existence of " + path ) 238cdf0e10cSrcweir if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path: 239cdf0e10cSrcweir log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" ) 240cdf0e10cSrcweir sys.path.append( path ) 241cdf0e10cSrcweir 242cdf0e10cSrcweir path = unohelper.fileUrlToSystemPath( url+"/pythonpath" ); 243cdf0e10cSrcweir log.log( LogLevel.DEBUG, "checking for existence of " + path ) 244cdf0e10cSrcweir if 1 == os.access( encfile(path), os.F_OK) and not path in sys.path: 245cdf0e10cSrcweir log.log( LogLevel.DEBUG, "adding " + path + " to sys.path" ) 246cdf0e10cSrcweir sys.path.append( path ) 247cdf0e10cSrcweir 248cdf0e10cSrcweir 249cdf0e10cSrcweirclass ScriptContext(unohelper.Base): 250cdf0e10cSrcweir def __init__( self, ctx, doc ): 251cdf0e10cSrcweir self.ctx = ctx 252cdf0e10cSrcweir self.doc = doc 253cdf0e10cSrcweir 254cdf0e10cSrcweir # XScriptContext 255cdf0e10cSrcweir def getDocument(self): 256cdf0e10cSrcweir return self.getDesktop().getCurrentComponent() 257cdf0e10cSrcweir 258cdf0e10cSrcweir def getDesktop(self): 259cdf0e10cSrcweir return self.ctx.ServiceManager.createInstanceWithContext( 260cdf0e10cSrcweir "com.sun.star.frame.Desktop", self.ctx ) 261cdf0e10cSrcweir 262cdf0e10cSrcweir def getComponentContext(self): 263cdf0e10cSrcweir return self.ctx 264cdf0e10cSrcweir 265cdf0e10cSrcweir#---------------------------------- 266cdf0e10cSrcweir# Global Module Administration 267cdf0e10cSrcweir# does not fit together with script 268cdf0e10cSrcweir# engine lifetime management 269cdf0e10cSrcweir#---------------------------------- 270cdf0e10cSrcweir#g_scriptContext = ScriptContext( uno.getComponentContext(), None ) 271cdf0e10cSrcweir#g_modules = {} 272cdf0e10cSrcweir#def getModuleByUrl( url, sfa ): 273cdf0e10cSrcweir# entry = g_modules.get(url) 274cdf0e10cSrcweir# load = True 275cdf0e10cSrcweir# lastRead = sfa.getDateTimeModified( url ) 276cdf0e10cSrcweir# if entry: 277cdf0e10cSrcweir# if hasChanged( entry.lastRead, lastRead ): 278cdf0e10cSrcweir# log.isDebugLevel() and log.debug("file " + url + " has changed, reloading") 279cdf0e10cSrcweir# else: 280cdf0e10cSrcweir# load = False 281cdf0e10cSrcweir# 282cdf0e10cSrcweir# if load: 283cdf0e10cSrcweir# log.isDebugLevel() and log.debug( "opening >" + url + "<" ) 284cdf0e10cSrcweir# 285cdf0e10cSrcweir# code = readTextFromStream( sfa.openFileRead( url ) ) 286cdf0e10cSrcweir 287cdf0e10cSrcweir # execute the module 288cdf0e10cSrcweir# entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") ) 289cdf0e10cSrcweir# entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext 290cdf0e10cSrcweir# entry.module.__file__ = url 291cdf0e10cSrcweir# exec code in entry.module.__dict__ 292cdf0e10cSrcweir# g_modules[ url ] = entry 293cdf0e10cSrcweir# log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) ) 294cdf0e10cSrcweir# return entry.module 295cdf0e10cSrcweir 296cdf0e10cSrcweirclass ProviderContext: 297cdf0e10cSrcweir def __init__( self, storageType, sfa, uriHelper, scriptContext ): 298cdf0e10cSrcweir self.storageType = storageType 299cdf0e10cSrcweir self.sfa = sfa 300cdf0e10cSrcweir self.uriHelper = uriHelper 301cdf0e10cSrcweir self.scriptContext = scriptContext 302cdf0e10cSrcweir self.modules = {} 303cdf0e10cSrcweir self.rootUrl = None 304cdf0e10cSrcweir self.mapPackageName2Path = None 305cdf0e10cSrcweir 306cdf0e10cSrcweir def getTransientPartFromUrl( self, url ): 307cdf0e10cSrcweir rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1) 308cdf0e10cSrcweir return rest[0:rest.find("/")] 309cdf0e10cSrcweir 310cdf0e10cSrcweir def getPackageNameFromUrl( self, url ): 311cdf0e10cSrcweir rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1) 312cdf0e10cSrcweir start = rest.find("/") +1 313cdf0e10cSrcweir return rest[start:rest.find("/",start)] 314cdf0e10cSrcweir 315cdf0e10cSrcweir 316cdf0e10cSrcweir def removePackageByUrl( self, url ): 317cdf0e10cSrcweir items = self.mapPackageName2Path.items() 318cdf0e10cSrcweir for i in items: 319cdf0e10cSrcweir if url in i[1].pathes: 320cdf0e10cSrcweir self.mapPackageName2Path.pop(i[0]) 321cdf0e10cSrcweir break 322cdf0e10cSrcweir 323cdf0e10cSrcweir def addPackageByUrl( self, url ): 324cdf0e10cSrcweir packageName = self.getPackageNameFromUrl( url ) 325cdf0e10cSrcweir transientPart = self.getTransientPartFromUrl( url ) 326cdf0e10cSrcweir log.isDebugLevel() and log.debug( "addPackageByUrl : " + packageName + ", " + transientPart + "("+url+")" + ", rootUrl="+self.rootUrl ) 327cdf0e10cSrcweir if self.mapPackageName2Path.has_key( packageName ): 328cdf0e10cSrcweir package = self.mapPackageName2Path[ packageName ] 329cdf0e10cSrcweir package.pathes = package.pathes + (url, ) 330cdf0e10cSrcweir else: 331cdf0e10cSrcweir package = Package( (url,), transientPart) 332cdf0e10cSrcweir self.mapPackageName2Path[ packageName ] = package 333cdf0e10cSrcweir 334cdf0e10cSrcweir def isUrlInPackage( self, url ): 335cdf0e10cSrcweir values = self.mapPackageName2Path.values() 336cdf0e10cSrcweir for i in values: 337cdf0e10cSrcweir# print "checking " + url + " in " + str(i.pathes) 338cdf0e10cSrcweir if url in i.pathes: 339cdf0e10cSrcweir return True 340cdf0e10cSrcweir# print "false" 341cdf0e10cSrcweir return False 342cdf0e10cSrcweir 343cdf0e10cSrcweir def setPackageAttributes( self, mapPackageName2Path, rootUrl ): 344cdf0e10cSrcweir self.mapPackageName2Path = mapPackageName2Path 345cdf0e10cSrcweir self.rootUrl = rootUrl 346cdf0e10cSrcweir 347cdf0e10cSrcweir def getPersistentUrlFromStorageUrl( self, url ): 348cdf0e10cSrcweir # package name is the second directory 349cdf0e10cSrcweir ret = url 350cdf0e10cSrcweir if self.rootUrl: 351cdf0e10cSrcweir pos = len( self.rootUrl) +1 352cdf0e10cSrcweir ret = url[0:pos]+url[url.find("/",pos)+1:len(url)] 353cdf0e10cSrcweir log.isDebugLevel() and log.debug( "getPersistentUrlFromStorageUrl " + url + " -> "+ ret) 354cdf0e10cSrcweir return ret 355cdf0e10cSrcweir 356cdf0e10cSrcweir def getStorageUrlFromPersistentUrl( self, url): 357cdf0e10cSrcweir ret = url 358cdf0e10cSrcweir if self.rootUrl: 359cdf0e10cSrcweir pos = len(self.rootUrl)+1 360cdf0e10cSrcweir packageName = url[pos:url.find("/",pos+1)] 361cdf0e10cSrcweir package = self.mapPackageName2Path[ packageName ] 362cdf0e10cSrcweir ret = url[0:pos]+ package.transientPathElement + "/" + url[pos:len(url)] 363cdf0e10cSrcweir log.isDebugLevel() and log.debug( "getStorageUrlFromPersistentUrl " + url + " -> "+ ret) 364cdf0e10cSrcweir return ret 365cdf0e10cSrcweir 366cdf0e10cSrcweir def getFuncsByUrl( self, url ): 367cdf0e10cSrcweir src = readTextFromStream( self.sfa.openFileRead( url ) ) 368cdf0e10cSrcweir checkForPythonPathBesideScript( url[0:url.rfind('/')] ) 369cdf0e10cSrcweir src = ensureSourceState( src ) 370cdf0e10cSrcweir 371cdf0e10cSrcweir code = compiler.parse( src ) 372cdf0e10cSrcweir 373cdf0e10cSrcweir allFuncs = [] 374cdf0e10cSrcweir 375cdf0e10cSrcweir if code == None: 376cdf0e10cSrcweir return allFuncs 377cdf0e10cSrcweir 378cdf0e10cSrcweir g_exportedScripts = [] 379cdf0e10cSrcweir for node in code.node.nodes: 380cdf0e10cSrcweir if node.__class__.__name__ == 'Function': 381cdf0e10cSrcweir allFuncs.append(node.name) 382cdf0e10cSrcweir elif node.__class__.__name__ == 'Assign': 383cdf0e10cSrcweir for assignee in node.nodes: 384cdf0e10cSrcweir if assignee.name == 'g_exportedScripts': 385cdf0e10cSrcweir for item in node.expr: 386cdf0e10cSrcweir if item.__class__.__name__ == 'Name': 387cdf0e10cSrcweir g_exportedScripts.append(item.name) 388cdf0e10cSrcweir return g_exportedScripts 389cdf0e10cSrcweir 390cdf0e10cSrcweir return allFuncs 391cdf0e10cSrcweir 392cdf0e10cSrcweir def getModuleByUrl( self, url ): 393cdf0e10cSrcweir entry = self.modules.get(url) 394cdf0e10cSrcweir load = True 395cdf0e10cSrcweir lastRead = self.sfa.getDateTimeModified( url ) 396cdf0e10cSrcweir if entry: 397cdf0e10cSrcweir if hasChanged( entry.lastRead, lastRead ): 398cdf0e10cSrcweir log.isDebugLevel() and log.debug( "file " + url + " has changed, reloading" ) 399cdf0e10cSrcweir else: 400cdf0e10cSrcweir load = False 401cdf0e10cSrcweir 402cdf0e10cSrcweir if load: 403cdf0e10cSrcweir log.isDebugLevel() and log.debug( "opening >" + url + "<" ) 404cdf0e10cSrcweir 405cdf0e10cSrcweir src = readTextFromStream( self.sfa.openFileRead( url ) ) 406cdf0e10cSrcweir checkForPythonPathBesideScript( url[0:url.rfind('/')] ) 407cdf0e10cSrcweir src = ensureSourceState( src ) 408cdf0e10cSrcweir 409cdf0e10cSrcweir # execute the module 410cdf0e10cSrcweir entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") ) 411cdf0e10cSrcweir entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.scriptContext 412cdf0e10cSrcweir 413cdf0e10cSrcweir code = None 414cdf0e10cSrcweir if url.startswith( "file:" ): 415cdf0e10cSrcweir code = compile( src, encfile(uno.fileUrlToSystemPath( url ) ), "exec" ) 416cdf0e10cSrcweir else: 417cdf0e10cSrcweir code = compile( src, url, "exec" ) 418cdf0e10cSrcweir exec code in entry.module.__dict__ 419cdf0e10cSrcweir entry.module.__file__ = url 420cdf0e10cSrcweir self.modules[ url ] = entry 421cdf0e10cSrcweir log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) ) 422cdf0e10cSrcweir return entry.module 423cdf0e10cSrcweir 424cdf0e10cSrcweir#-------------------------------------------------- 425cdf0e10cSrcweirdef isScript( candidate ): 426cdf0e10cSrcweir ret = False 427cdf0e10cSrcweir if isinstance( candidate, type(isScript) ): 428cdf0e10cSrcweir ret = True 429cdf0e10cSrcweir return ret 430cdf0e10cSrcweir 431cdf0e10cSrcweir#------------------------------------------------------- 432cdf0e10cSrcweirclass ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, XActionListener ): 433cdf0e10cSrcweir def __init__( self, provCtx, uri, fileName, funcName ): 434cdf0e10cSrcweir self.fileName = fileName 435cdf0e10cSrcweir self.funcName = funcName 436cdf0e10cSrcweir self.provCtx = provCtx 437cdf0e10cSrcweir self.uri = uri 438cdf0e10cSrcweir 439cdf0e10cSrcweir def getName( self ): 440cdf0e10cSrcweir return self.funcName 441cdf0e10cSrcweir 442cdf0e10cSrcweir def getChildNodes(self): 443cdf0e10cSrcweir return () 444cdf0e10cSrcweir 445cdf0e10cSrcweir def hasChildNodes(self): 446cdf0e10cSrcweir return False 447cdf0e10cSrcweir 448cdf0e10cSrcweir def getType( self): 449cdf0e10cSrcweir return SCRIPT 450cdf0e10cSrcweir 451cdf0e10cSrcweir def getPropertyValue( self, name ): 452cdf0e10cSrcweir ret = None 453cdf0e10cSrcweir try: 454cdf0e10cSrcweir if name == "URI": 455cdf0e10cSrcweir ret = self.provCtx.uriHelper.getScriptURI( 456cdf0e10cSrcweir self.provCtx.getPersistentUrlFromStorageUrl( self.uri + "$" + self.funcName ) ) 457cdf0e10cSrcweir elif name == "Editable" and ENABLE_EDIT_DIALOG: 458cdf0e10cSrcweir ret = not self.provCtx.sfa.isReadOnly( self.uri ) 459cdf0e10cSrcweir 460cdf0e10cSrcweir log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) ) 461cdf0e10cSrcweir except Exception,e: 462cdf0e10cSrcweir log.error( "ScriptBrowseNode.getPropertyValue error " + lastException2String()) 463cdf0e10cSrcweir raise 464cdf0e10cSrcweir 465cdf0e10cSrcweir return ret 466cdf0e10cSrcweir def setPropertyValue( self, name, value ): 467cdf0e10cSrcweir log.isDebugLevel() and log.debug( "ScriptBrowseNode.setPropertyValue called " + name + "=" +str(value ) ) 468cdf0e10cSrcweir def getPropertySetInfo( self ): 469cdf0e10cSrcweir log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertySetInfo called " ) 470cdf0e10cSrcweir return None 471cdf0e10cSrcweir 472cdf0e10cSrcweir def getIntrospection( self ): 473cdf0e10cSrcweir return None 474cdf0e10cSrcweir 475cdf0e10cSrcweir def invoke( self, name, params, outparamindex, outparams ): 476cdf0e10cSrcweir if name == "Editable": 477cdf0e10cSrcweir servicename = "com.sun.star.awt.DialogProvider" 478cdf0e10cSrcweir ctx = self.provCtx.scriptContext.getComponentContext() 479cdf0e10cSrcweir dlgprov = ctx.ServiceManager.createInstanceWithContext( 480cdf0e10cSrcweir servicename, ctx ) 481cdf0e10cSrcweir 482cdf0e10cSrcweir self.editor = dlgprov.createDialog( 483cdf0e10cSrcweir "vnd.sun.star.script:" + 484cdf0e10cSrcweir "ScriptBindingLibrary.MacroEditor?location=application") 485cdf0e10cSrcweir 486cdf0e10cSrcweir code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri)) 487cdf0e10cSrcweir code = ensureSourceState( code ) 488cdf0e10cSrcweir self.editor.getControl("EditorTextField").setText(code) 489cdf0e10cSrcweir 490cdf0e10cSrcweir self.editor.getControl("RunButton").setActionCommand("Run") 491cdf0e10cSrcweir self.editor.getControl("RunButton").addActionListener(self) 492cdf0e10cSrcweir self.editor.getControl("SaveButton").setActionCommand("Save") 493cdf0e10cSrcweir self.editor.getControl("SaveButton").addActionListener(self) 494cdf0e10cSrcweir 495cdf0e10cSrcweir self.editor.execute() 496cdf0e10cSrcweir 497cdf0e10cSrcweir return None 498cdf0e10cSrcweir 499cdf0e10cSrcweir def actionPerformed( self, event ): 500cdf0e10cSrcweir try: 501cdf0e10cSrcweir if event.ActionCommand == "Run": 502cdf0e10cSrcweir code = self.editor.getControl("EditorTextField").getText() 503cdf0e10cSrcweir code = ensureSourceState( code ) 504cdf0e10cSrcweir mod = imp.new_module("ooo_script_framework") 505cdf0e10cSrcweir mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext 506cdf0e10cSrcweir exec code in mod.__dict__ 507cdf0e10cSrcweir values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None ) 508cdf0e10cSrcweir if not values: 509cdf0e10cSrcweir values = mod.__dict__.values() 510cdf0e10cSrcweir 511cdf0e10cSrcweir for i in values: 512cdf0e10cSrcweir if isScript( i ): 513cdf0e10cSrcweir i() 514cdf0e10cSrcweir break 515cdf0e10cSrcweir 516cdf0e10cSrcweir elif event.ActionCommand == "Save": 517cdf0e10cSrcweir toWrite = uno.ByteSequence( 518cdf0e10cSrcweir str( 519cdf0e10cSrcweir self.editor.getControl("EditorTextField").getText().encode( 520cdf0e10cSrcweir sys.getdefaultencoding())) ) 521cdf0e10cSrcweir copyUrl = self.uri + ".orig" 522cdf0e10cSrcweir self.provCtx.sfa.move( self.uri, copyUrl ) 523cdf0e10cSrcweir out = self.provCtx.sfa.openFileWrite( self.uri ) 524cdf0e10cSrcweir out.writeBytes( toWrite ) 525cdf0e10cSrcweir out.close() 526cdf0e10cSrcweir self.provCtx.sfa.kill( copyUrl ) 527cdf0e10cSrcweir# log.isDebugLevel() and log.debug("Save is not implemented yet") 528cdf0e10cSrcweir# text = self.editor.getControl("EditorTextField").getText() 529cdf0e10cSrcweir# log.isDebugLevel() and log.debug("Would save: " + text) 530cdf0e10cSrcweir except Exception,e: 531cdf0e10cSrcweir # TODO: add an error box here ! 532cdf0e10cSrcweir log.error( lastException2String() ) 533cdf0e10cSrcweir 534cdf0e10cSrcweir 535cdf0e10cSrcweir def setValue( self, name, value ): 536cdf0e10cSrcweir return None 537cdf0e10cSrcweir 538cdf0e10cSrcweir def getValue( self, name ): 539cdf0e10cSrcweir return None 540cdf0e10cSrcweir 541cdf0e10cSrcweir def hasMethod( self, name ): 542cdf0e10cSrcweir return False 543cdf0e10cSrcweir 544cdf0e10cSrcweir def hasProperty( self, name ): 545cdf0e10cSrcweir return False 546cdf0e10cSrcweir 547cdf0e10cSrcweir 548cdf0e10cSrcweir#------------------------------------------------------- 549cdf0e10cSrcweirclass FileBrowseNode( unohelper.Base, XBrowseNode ): 550cdf0e10cSrcweir def __init__( self, provCtx, uri , name ): 551cdf0e10cSrcweir self.provCtx = provCtx 552cdf0e10cSrcweir self.uri = uri 553cdf0e10cSrcweir self.name = name 554cdf0e10cSrcweir self.funcnames = None 555cdf0e10cSrcweir 556cdf0e10cSrcweir def getName( self ): 557cdf0e10cSrcweir return self.name 558cdf0e10cSrcweir 559cdf0e10cSrcweir def getChildNodes(self): 560cdf0e10cSrcweir ret = () 561cdf0e10cSrcweir try: 562cdf0e10cSrcweir self.funcnames = self.provCtx.getFuncsByUrl( self.uri ) 563cdf0e10cSrcweir 564cdf0e10cSrcweir scriptNodeList = [] 565cdf0e10cSrcweir for i in self.funcnames: 566cdf0e10cSrcweir scriptNodeList.append( 567cdf0e10cSrcweir ScriptBrowseNode( 568cdf0e10cSrcweir self.provCtx, self.uri, self.name, i )) 569cdf0e10cSrcweir ret = tuple( scriptNodeList ) 570cdf0e10cSrcweir log.isDebugLevel() and log.debug( "returning " +str(len(ret)) + " ScriptChildNodes on " + self.uri ) 571cdf0e10cSrcweir except Exception, e: 572cdf0e10cSrcweir text = lastException2String() 573cdf0e10cSrcweir log.error( "Error while evaluating " + self.uri + ":" + text ) 574cdf0e10cSrcweir raise 575cdf0e10cSrcweir return ret 576cdf0e10cSrcweir 577cdf0e10cSrcweir def hasChildNodes(self): 578cdf0e10cSrcweir try: 579cdf0e10cSrcweir return len(self.getChildNodes()) > 0 580cdf0e10cSrcweir except Exception, e: 581cdf0e10cSrcweir return False 582cdf0e10cSrcweir 583cdf0e10cSrcweir def getType( self): 584cdf0e10cSrcweir return CONTAINER 585cdf0e10cSrcweir 586cdf0e10cSrcweir 587cdf0e10cSrcweir 588cdf0e10cSrcweirclass DirBrowseNode( unohelper.Base, XBrowseNode ): 589cdf0e10cSrcweir def __init__( self, provCtx, name, rootUrl ): 590cdf0e10cSrcweir self.provCtx = provCtx 591cdf0e10cSrcweir self.name = name 592cdf0e10cSrcweir self.rootUrl = rootUrl 593cdf0e10cSrcweir 594cdf0e10cSrcweir def getName( self ): 595cdf0e10cSrcweir return self.name 596cdf0e10cSrcweir 597cdf0e10cSrcweir def getChildNodes( self ): 598cdf0e10cSrcweir try: 599cdf0e10cSrcweir log.isDebugLevel() and log.debug( "DirBrowseNode.getChildNodes called for " + self.rootUrl ) 600cdf0e10cSrcweir contents = self.provCtx.sfa.getFolderContents( self.rootUrl, True ) 601cdf0e10cSrcweir browseNodeList = [] 602cdf0e10cSrcweir for i in contents: 603cdf0e10cSrcweir if i.endswith( ".py" ): 604cdf0e10cSrcweir log.isDebugLevel() and log.debug( "adding filenode " + i ) 605cdf0e10cSrcweir browseNodeList.append( 606cdf0e10cSrcweir FileBrowseNode( self.provCtx, i, i[i.rfind("/")+1:len(i)-3] ) ) 607cdf0e10cSrcweir elif self.provCtx.sfa.isFolder( i ) and not i.endswith("/pythonpath"): 608cdf0e10cSrcweir log.isDebugLevel() and log.debug( "adding DirBrowseNode " + i ) 609cdf0e10cSrcweir browseNodeList.append( DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)],i)) 610cdf0e10cSrcweir return tuple( browseNodeList ) 611cdf0e10cSrcweir except Exception, e: 612cdf0e10cSrcweir text = lastException2String() 613cdf0e10cSrcweir log.error( "DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl) 614cdf0e10cSrcweir log.error( text) 615cdf0e10cSrcweir return () 616cdf0e10cSrcweir 617cdf0e10cSrcweir def hasChildNodes( self ): 618cdf0e10cSrcweir return True 619cdf0e10cSrcweir 620cdf0e10cSrcweir def getType( self ): 621cdf0e10cSrcweir return CONTAINER 622cdf0e10cSrcweir 623cdf0e10cSrcweir def getScript( self, uri ): 624cdf0e10cSrcweir log.debug( "DirBrowseNode getScript " + uri + " invoked" ) 625cdf0e10cSrcweir raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 ) 626cdf0e10cSrcweir 627cdf0e10cSrcweir 628cdf0e10cSrcweirclass ManifestHandler( XDocumentHandler, unohelper.Base ): 629cdf0e10cSrcweir def __init__( self, rootUrl ): 630cdf0e10cSrcweir self.rootUrl = rootUrl 631cdf0e10cSrcweir 632cdf0e10cSrcweir def startDocument( self ): 633cdf0e10cSrcweir self.urlList = [] 634cdf0e10cSrcweir 635cdf0e10cSrcweir def endDocument( self ): 636cdf0e10cSrcweir pass 637cdf0e10cSrcweir 638cdf0e10cSrcweir def startElement( self , name, attlist): 639cdf0e10cSrcweir if name == "manifest:file-entry": 640cdf0e10cSrcweir if attlist.getValueByName( "manifest:media-type" ) == "application/vnd.sun.star.framework-script": 641cdf0e10cSrcweir self.urlList.append( 642cdf0e10cSrcweir self.rootUrl + "/" + attlist.getValueByName( "manifest:full-path" ) ) 643cdf0e10cSrcweir 644cdf0e10cSrcweir def endElement( self, name ): 645cdf0e10cSrcweir pass 646cdf0e10cSrcweir 647cdf0e10cSrcweir def characters ( self, chars ): 648cdf0e10cSrcweir pass 649cdf0e10cSrcweir 650cdf0e10cSrcweir def ignoreableWhitespace( self, chars ): 651cdf0e10cSrcweir pass 652cdf0e10cSrcweir 653cdf0e10cSrcweir def setDocumentLocator( self, locator ): 654cdf0e10cSrcweir pass 655cdf0e10cSrcweir 656cdf0e10cSrcweirdef isPyFileInPath( sfa, path ): 657cdf0e10cSrcweir ret = False 658cdf0e10cSrcweir contents = sfa.getFolderContents( path, True ) 659cdf0e10cSrcweir for i in contents: 660cdf0e10cSrcweir if sfa.isFolder(i): 661cdf0e10cSrcweir ret = isPyFileInPath(sfa,i) 662cdf0e10cSrcweir else: 663cdf0e10cSrcweir if i.endswith(".py"): 664cdf0e10cSrcweir ret = True 665cdf0e10cSrcweir if ret: 666cdf0e10cSrcweir break 667cdf0e10cSrcweir return ret 668cdf0e10cSrcweir 669cdf0e10cSrcweir# extracts META-INF directory from 670cdf0e10cSrcweirdef getPathesFromPackage( rootUrl, sfa ): 671cdf0e10cSrcweir ret = () 672cdf0e10cSrcweir try: 673cdf0e10cSrcweir fileUrl = rootUrl + "/META-INF/manifest.xml" 674cdf0e10cSrcweir inputStream = sfa.openFileRead( fileUrl ) 675cdf0e10cSrcweir parser = uno.getComponentContext().ServiceManager.createInstance( "com.sun.star.xml.sax.Parser" ) 676cdf0e10cSrcweir handler = ManifestHandler( rootUrl ) 677cdf0e10cSrcweir parser.setDocumentHandler( handler ) 678cdf0e10cSrcweir parser.parseStream( InputSource( inputStream , "", fileUrl, fileUrl ) ) 679cdf0e10cSrcweir for i in tuple(handler.urlList): 680cdf0e10cSrcweir if not isPyFileInPath( sfa, i ): 681cdf0e10cSrcweir handler.urlList.remove(i) 682cdf0e10cSrcweir ret = tuple( handler.urlList ) 683cdf0e10cSrcweir except UnoException, e: 684cdf0e10cSrcweir text = lastException2String() 685cdf0e10cSrcweir log.debug( "getPathesFromPackage " + fileUrl + " Exception: " +text ) 686cdf0e10cSrcweir pass 687cdf0e10cSrcweir return ret 688cdf0e10cSrcweir 689cdf0e10cSrcweir 690cdf0e10cSrcweirclass Package: 691cdf0e10cSrcweir def __init__( self, pathes, transientPathElement ): 692cdf0e10cSrcweir self.pathes = pathes 693cdf0e10cSrcweir self.transientPathElement = transientPathElement 694cdf0e10cSrcweir 695cdf0e10cSrcweirclass DummyInteractionHandler( unohelper.Base, XInteractionHandler ): 696cdf0e10cSrcweir def __init__( self ): 697cdf0e10cSrcweir pass 698cdf0e10cSrcweir def handle( self, event): 699cdf0e10cSrcweir log.isDebugLevel() and log.debug( "pythonscript: DummyInteractionHandler.handle " + str( event ) ) 700cdf0e10cSrcweir 701cdf0e10cSrcweirclass DummyProgressHandler( unohelper.Base, XProgressHandler ): 702cdf0e10cSrcweir def __init__( self ): 703cdf0e10cSrcweir pass 704cdf0e10cSrcweir 705cdf0e10cSrcweir def push( self,status ): 706cdf0e10cSrcweir log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.push " + str( status ) ) 707cdf0e10cSrcweir def update( self,status ): 708cdf0e10cSrcweir log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.update " + str( status ) ) 709cdf0e10cSrcweir def pop( self ): 710cdf0e10cSrcweir log.isDebugLevel() and log.debug( "pythonscript: DummyProgressHandler.push " + str( event ) ) 711cdf0e10cSrcweir 712cdf0e10cSrcweirclass CommandEnvironment(unohelper.Base, XCommandEnvironment): 713cdf0e10cSrcweir def __init__( self ): 714cdf0e10cSrcweir self.progressHandler = DummyProgressHandler() 715cdf0e10cSrcweir self.interactionHandler = DummyInteractionHandler() 716cdf0e10cSrcweir def getInteractionHandler( self ): 717cdf0e10cSrcweir return self.interactionHandler 718cdf0e10cSrcweir def getProgressHandler( self ): 719cdf0e10cSrcweir return self.progressHandler 720cdf0e10cSrcweir 721cdf0e10cSrcweir#maybe useful for debugging purposes 722cdf0e10cSrcweir#class ModifyListener( unohelper.Base, XModifyListener ): 723cdf0e10cSrcweir# def __init__( self ): 724cdf0e10cSrcweir# pass 725cdf0e10cSrcweir# def modified( self, event ): 726cdf0e10cSrcweir# log.isDebugLevel() and log.debug( "pythonscript: ModifyListener.modified " + str( event ) ) 727cdf0e10cSrcweir# def disposing( self, event ): 728cdf0e10cSrcweir# log.isDebugLevel() and log.debug( "pythonscript: ModifyListener.disposing " + str( event ) ) 729cdf0e10cSrcweir 730cdf0e10cSrcweirdef mapStorageType2PackageContext( storageType ): 731cdf0e10cSrcweir ret = storageType 732cdf0e10cSrcweir if( storageType == "share:uno_packages" ): 733cdf0e10cSrcweir ret = "shared" 734cdf0e10cSrcweir if( storageType == "user:uno_packages" ): 735cdf0e10cSrcweir ret = "user" 736cdf0e10cSrcweir return ret 737cdf0e10cSrcweir 738cdf0e10cSrcweirdef getPackageName2PathMap( sfa, storageType ): 739cdf0e10cSrcweir ret = {} 740cdf0e10cSrcweir packageManagerFactory = uno.getComponentContext().getValueByName( 741cdf0e10cSrcweir "/singletons/com.sun.star.deployment.thePackageManagerFactory" ) 742cdf0e10cSrcweir packageManager = packageManagerFactory.getPackageManager( 743cdf0e10cSrcweir mapStorageType2PackageContext(storageType)) 744cdf0e10cSrcweir# packageManager.addModifyListener( ModifyListener() ) 745cdf0e10cSrcweir log.isDebugLevel() and log.debug( "pythonscript: getPackageName2PathMap start getDeployedPackages" ) 746cdf0e10cSrcweir packages = packageManager.getDeployedPackages( 747cdf0e10cSrcweir packageManager.createAbortChannel(), CommandEnvironment( ) ) 748cdf0e10cSrcweir log.isDebugLevel() and log.debug( "pythonscript: getPackageName2PathMap end getDeployedPackages (" + str(len(packages))+")" ) 749cdf0e10cSrcweir 750cdf0e10cSrcweir for i in packages: 751cdf0e10cSrcweir log.isDebugLevel() and log.debug( "inspecting package " + i.Name + "("+i.Identifier.Value+")" ) 752cdf0e10cSrcweir transientPathElement = penultimateElement( i.URL ) 753cdf0e10cSrcweir j = expandUri( i.URL ) 754cdf0e10cSrcweir pathes = getPathesFromPackage( j, sfa ) 755cdf0e10cSrcweir if len( pathes ) > 0: 756cdf0e10cSrcweir # map package name to url, we need this later 757cdf0e10cSrcweir log.isErrorLevel() and log.error( "adding Package " + transientPathElement + " " + str( pathes ) ) 758cdf0e10cSrcweir ret[ lastElement( j ) ] = Package( pathes, transientPathElement ) 759cdf0e10cSrcweir return ret 760cdf0e10cSrcweir 761cdf0e10cSrcweirdef penultimateElement( aStr ): 762cdf0e10cSrcweir lastSlash = aStr.rindex("/") 763cdf0e10cSrcweir penultimateSlash = aStr.rindex("/",0,lastSlash-1) 764cdf0e10cSrcweir return aStr[ penultimateSlash+1:lastSlash ] 765cdf0e10cSrcweir 766cdf0e10cSrcweirdef lastElement( aStr): 767cdf0e10cSrcweir return aStr[ aStr.rfind( "/" )+1:len(aStr)] 768cdf0e10cSrcweir 769cdf0e10cSrcweirclass PackageBrowseNode( unohelper.Base, XBrowseNode ): 770cdf0e10cSrcweir def __init__( self, provCtx, name, rootUrl ): 771cdf0e10cSrcweir self.provCtx = provCtx 772cdf0e10cSrcweir self.name = name 773cdf0e10cSrcweir self.rootUrl = rootUrl 774cdf0e10cSrcweir 775cdf0e10cSrcweir def getName( self ): 776cdf0e10cSrcweir return self.name 777cdf0e10cSrcweir 778cdf0e10cSrcweir def getChildNodes( self ): 779cdf0e10cSrcweir items = self.provCtx.mapPackageName2Path.items() 780cdf0e10cSrcweir browseNodeList = [] 781cdf0e10cSrcweir for i in items: 782cdf0e10cSrcweir if len( i[1].pathes ) == 1: 783cdf0e10cSrcweir browseNodeList.append( 784cdf0e10cSrcweir DirBrowseNode( self.provCtx, i[0], i[1].pathes[0] )) 785cdf0e10cSrcweir else: 786cdf0e10cSrcweir for j in i[1].pathes: 787cdf0e10cSrcweir browseNodeList.append( 788cdf0e10cSrcweir DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j), j ) ) 789cdf0e10cSrcweir return tuple( browseNodeList ) 790cdf0e10cSrcweir 791cdf0e10cSrcweir def hasChildNodes( self ): 792cdf0e10cSrcweir return len( self.mapPackageName2Path ) > 0 793cdf0e10cSrcweir 794cdf0e10cSrcweir def getType( self ): 795cdf0e10cSrcweir return CONTAINER 796cdf0e10cSrcweir 797cdf0e10cSrcweir def getScript( self, uri ): 798cdf0e10cSrcweir log.debug( "DirBrowseNode getScript " + uri + " invoked" ) 799cdf0e10cSrcweir raise IllegalArgumentException( "PackageBrowseNode couldn't instantiate script " + uri , self , 0 ) 800cdf0e10cSrcweir 801cdf0e10cSrcweir 802cdf0e10cSrcweir 803cdf0e10cSrcweir 804cdf0e10cSrcweirclass PythonScript( unohelper.Base, XScript ): 805cdf0e10cSrcweir def __init__( self, func, mod ): 806cdf0e10cSrcweir self.func = func 807cdf0e10cSrcweir self.mod = mod 808cdf0e10cSrcweir def invoke(self, args, out, outindex ): 809cdf0e10cSrcweir log.isDebugLevel() and log.debug( "PythonScript.invoke " + str( args ) ) 810cdf0e10cSrcweir try: 811cdf0e10cSrcweir ret = self.func( *args ) 812cdf0e10cSrcweir except UnoException,e: 813cdf0e10cSrcweir # UNO Exception continue to fly ... 814cdf0e10cSrcweir text = lastException2String() 815cdf0e10cSrcweir complete = "Error during invoking function " + \ 816cdf0e10cSrcweir str(self.func.__name__) + " in module " + \ 817cdf0e10cSrcweir self.mod.__file__ + " (" + text + ")" 818cdf0e10cSrcweir log.isDebugLevel() and log.debug( complete ) 819cdf0e10cSrcweir # some people may beat me up for modifying the exception text, 820cdf0e10cSrcweir # but otherwise office just shows 821cdf0e10cSrcweir # the type name and message text with no more information, 822cdf0e10cSrcweir # this is really bad for most users. 823cdf0e10cSrcweir e.Message = e.Message + " (" + complete + ")" 824cdf0e10cSrcweir raise 825cdf0e10cSrcweir except Exception,e: 826cdf0e10cSrcweir # General python exception are converted to uno RuntimeException 827cdf0e10cSrcweir text = lastException2String() 828cdf0e10cSrcweir complete = "Error during invoking function " + \ 829cdf0e10cSrcweir str(self.func.__name__) + " in module " + \ 830cdf0e10cSrcweir self.mod.__file__ + " (" + text + ")" 831cdf0e10cSrcweir log.isDebugLevel() and log.debug( complete ) 832cdf0e10cSrcweir raise RuntimeException( complete , self ) 833cdf0e10cSrcweir log.isDebugLevel() and log.debug( "PythonScript.invoke ret = " + str( ret ) ) 834cdf0e10cSrcweir return ret, (), () 835cdf0e10cSrcweir 836cdf0e10cSrcweirdef expandUri( uri ): 837cdf0e10cSrcweir if uri.startswith( "vnd.sun.star.expand:" ): 838cdf0e10cSrcweir uri = uri.replace( "vnd.sun.star.expand:", "",1) 839cdf0e10cSrcweir uri = uno.getComponentContext().getByName( 840cdf0e10cSrcweir "/singletons/com.sun.star.util.theMacroExpander" ).expandMacros( uri ) 841cdf0e10cSrcweir if uri.startswith( "file:" ): 842cdf0e10cSrcweir uri = uno.absolutize("",uri) # necessary to get rid of .. in uri 843cdf0e10cSrcweir return uri 844cdf0e10cSrcweir 845cdf0e10cSrcweir#-------------------------------------------------------------- 846cdf0e10cSrcweirclass PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer): 847cdf0e10cSrcweir def __init__( self, ctx, *args ): 848cdf0e10cSrcweir if log.isDebugLevel(): 849cdf0e10cSrcweir mystr = "" 850cdf0e10cSrcweir for i in args: 851cdf0e10cSrcweir if len(mystr) > 0: 852cdf0e10cSrcweir mystr = mystr +"," 853cdf0e10cSrcweir mystr = mystr + str(i) 854cdf0e10cSrcweir log.debug( "Entering PythonScriptProvider.ctor" + mystr ) 855cdf0e10cSrcweir 856cdf0e10cSrcweir storageType = "" 857cdf0e10cSrcweir if isinstance(args[0],unicode ): 858cdf0e10cSrcweir storageType = args[0] 859cdf0e10cSrcweir else: 860cdf0e10cSrcweir storageType = args[0].SCRIPTING_DOC_URI 861cdf0e10cSrcweir isPackage = storageType.endswith( ":uno_packages" ) 862cdf0e10cSrcweir 863cdf0e10cSrcweir try: 864cdf0e10cSrcweir# urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext( 865cdf0e10cSrcweir# "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx) 866cdf0e10cSrcweir urlHelper = MyUriHelper( ctx, storageType ) 867cdf0e10cSrcweir log.isDebugLevel() and log.debug( "got urlHelper " + str( urlHelper ) ) 868cdf0e10cSrcweir 869cdf0e10cSrcweir rootUrl = expandUri( urlHelper.getRootStorageURI() ) 870cdf0e10cSrcweir log.isDebugLevel() and log.debug( storageType + " transformed to " + rootUrl ) 871cdf0e10cSrcweir 872cdf0e10cSrcweir ucbService = "com.sun.star.ucb.SimpleFileAccess" 873cdf0e10cSrcweir sfa = ctx.ServiceManager.createInstanceWithContext( ucbService, ctx ) 874cdf0e10cSrcweir if not sfa: 875cdf0e10cSrcweir log.debug("PythonScriptProvider couldn't instantiate " +ucbService) 876cdf0e10cSrcweir raise RuntimeException( 877cdf0e10cSrcweir "PythonScriptProvider couldn't instantiate " +ucbService, self) 878cdf0e10cSrcweir self.provCtx = ProviderContext( 879cdf0e10cSrcweir storageType, sfa, urlHelper, ScriptContext( uno.getComponentContext(), None ) ) 880cdf0e10cSrcweir if isPackage: 881cdf0e10cSrcweir mapPackageName2Path = getPackageName2PathMap( sfa, storageType ) 882cdf0e10cSrcweir self.provCtx.setPackageAttributes( mapPackageName2Path , rootUrl ) 883cdf0e10cSrcweir self.dirBrowseNode = PackageBrowseNode( self.provCtx, LANGUAGENAME, rootUrl ) 884cdf0e10cSrcweir else: 885cdf0e10cSrcweir self.dirBrowseNode = DirBrowseNode( self.provCtx, LANGUAGENAME, rootUrl ) 886cdf0e10cSrcweir 887cdf0e10cSrcweir except Exception, e: 888cdf0e10cSrcweir text = lastException2String() 889cdf0e10cSrcweir log.debug( "PythonScriptProvider could not be instantiated because of : " + text ) 890cdf0e10cSrcweir raise e 891cdf0e10cSrcweir 892cdf0e10cSrcweir def getName( self ): 893cdf0e10cSrcweir return self.dirBrowseNode.getName() 894cdf0e10cSrcweir 895cdf0e10cSrcweir def getChildNodes( self ): 896cdf0e10cSrcweir return self.dirBrowseNode.getChildNodes() 897cdf0e10cSrcweir 898cdf0e10cSrcweir def hasChildNodes( self ): 899cdf0e10cSrcweir return self.dirBrowseNode.hasChildNodes() 900cdf0e10cSrcweir 901cdf0e10cSrcweir def getType( self ): 902cdf0e10cSrcweir return self.dirBrowseNode.getType() 903cdf0e10cSrcweir 904cdf0e10cSrcweir def getScript( self, uri ): 905cdf0e10cSrcweir log.debug( "DirBrowseNode getScript " + uri + " invoked" ) 906cdf0e10cSrcweir 907cdf0e10cSrcweir raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 ) 908cdf0e10cSrcweir 909cdf0e10cSrcweir def getScript( self, scriptUri ): 910cdf0e10cSrcweir try: 911cdf0e10cSrcweir log.isDebugLevel() and log.debug( "getScript " + scriptUri + " invoked") 912cdf0e10cSrcweir 913cdf0e10cSrcweir storageUri = self.provCtx.getStorageUrlFromPersistentUrl( 914cdf0e10cSrcweir self.provCtx.uriHelper.getStorageURI(scriptUri) ); 915cdf0e10cSrcweir log.isDebugLevel() and log.debug( "getScript: storageUri = " + storageUri) 916cdf0e10cSrcweir fileUri = storageUri[0:storageUri.find( "$" )] 917cdf0e10cSrcweir funcName = storageUri[storageUri.find( "$" )+1:len(storageUri)] 918cdf0e10cSrcweir 919cdf0e10cSrcweir mod = self.provCtx.getModuleByUrl( fileUri ) 920cdf0e10cSrcweir log.isDebugLevel() and log.debug( " got mod " + str(mod) ) 921cdf0e10cSrcweir 922cdf0e10cSrcweir func = mod.__dict__[ funcName ] 923cdf0e10cSrcweir 924cdf0e10cSrcweir log.isDebugLevel() and log.debug( "got func " + str( func ) ) 925cdf0e10cSrcweir return PythonScript( func, mod ) 926cdf0e10cSrcweir except Exception, e: 927cdf0e10cSrcweir text = lastException2String() 928cdf0e10cSrcweir log.error( text ) 929cdf0e10cSrcweir raise ScriptFrameworkErrorException( text, self, scriptUri, LANGUAGENAME, 0 ) 930cdf0e10cSrcweir 931cdf0e10cSrcweir 932cdf0e10cSrcweir # XServiceInfo 933cdf0e10cSrcweir def getSupportedServices( self ): 934cdf0e10cSrcweir return g_ImplementationHelper.getSupportedServices(g_implName) 935cdf0e10cSrcweir 936cdf0e10cSrcweir def supportsService( self, ServiceName ): 937cdf0e10cSrcweir return g_ImplementationHelper.supportsService( g_implName, ServiceName ) 938cdf0e10cSrcweir 939cdf0e10cSrcweir def getImplementationName(self): 940cdf0e10cSrcweir return g_implName 941cdf0e10cSrcweir 942cdf0e10cSrcweir def getByName( self, name ): 943cdf0e10cSrcweir log.debug( "getByName called" + str( name )) 944cdf0e10cSrcweir return None 945cdf0e10cSrcweir 946cdf0e10cSrcweir 947cdf0e10cSrcweir def getElementNames( self ): 948cdf0e10cSrcweir log.debug( "getElementNames called") 949cdf0e10cSrcweir return () 950cdf0e10cSrcweir 951cdf0e10cSrcweir def hasByName( self, name ): 952cdf0e10cSrcweir try: 953cdf0e10cSrcweir log.debug( "hasByName called " + str( name )) 954cdf0e10cSrcweir uri = expandUri(name) 955cdf0e10cSrcweir ret = self.provCtx.isUrlInPackage( uri ) 956cdf0e10cSrcweir log.debug( "hasByName " + uri + " " +str( ret ) ) 957cdf0e10cSrcweir return ret 958cdf0e10cSrcweir except Exception, e: 959cdf0e10cSrcweir text = lastException2String() 960cdf0e10cSrcweir log.debug( "Error in hasByName:" + text ) 961cdf0e10cSrcweir return False 962cdf0e10cSrcweir 963cdf0e10cSrcweir def removeByName( self, name ): 964cdf0e10cSrcweir log.debug( "removeByName called" + str( name )) 965cdf0e10cSrcweir uri = expandUri( name ) 966cdf0e10cSrcweir if self.provCtx.isUrlInPackage( uri ): 967cdf0e10cSrcweir self.provCtx.removePackageByUrl( uri ) 968cdf0e10cSrcweir else: 969cdf0e10cSrcweir log.debug( "removeByName unknown uri " + str( name ) + ", ignoring" ) 970cdf0e10cSrcweir raise NoSuchElementException( uri + "is not in package" , self ) 971cdf0e10cSrcweir log.debug( "removeByName called" + str( uri ) + " successful" ) 972cdf0e10cSrcweir 973cdf0e10cSrcweir def insertByName( self, name, value ): 974cdf0e10cSrcweir log.debug( "insertByName called " + str( name ) + " " + str( value )) 975cdf0e10cSrcweir uri = expandUri( name ) 976cdf0e10cSrcweir if isPyFileInPath( self.provCtx.sfa, uri ): 977cdf0e10cSrcweir self.provCtx.addPackageByUrl( uri ) 978cdf0e10cSrcweir else: 979cdf0e10cSrcweir # package is no python package ... 980cdf0e10cSrcweir log.debug( "insertByName: no python files in " + str( uri ) + ", ignoring" ) 981cdf0e10cSrcweir raise IllegalArgumentException( uri + " does not contain .py files", self, 1 ) 982cdf0e10cSrcweir log.debug( "insertByName called " + str( uri ) + " successful" ) 983cdf0e10cSrcweir 984cdf0e10cSrcweir def replaceByName( self, name, value ): 985cdf0e10cSrcweir log.debug( "replaceByName called " + str( name ) + " " + str( value )) 986cdf0e10cSrcweir removeByName( name ) 987cdf0e10cSrcweir insertByName( name ) 988cdf0e10cSrcweir log.debug( "replaceByName called" + str( uri ) + " successful" ) 989cdf0e10cSrcweir 990cdf0e10cSrcweir def getElementType( self ): 991cdf0e10cSrcweir log.debug( "getElementType called" ) 992cdf0e10cSrcweir return uno.getTypeByName( "void" ) 993cdf0e10cSrcweir 994cdf0e10cSrcweir def hasElements( self ): 995cdf0e10cSrcweir log.debug( "hasElements got called") 996cdf0e10cSrcweir return False 997cdf0e10cSrcweir 998cdf0e10cSrcweirg_ImplementationHelper.addImplementation( \ 999cdf0e10cSrcweir PythonScriptProvider,g_implName, \ 1000cdf0e10cSrcweir ("com.sun.star.script.provider.LanguageScriptProvider", 1001cdf0e10cSrcweir "com.sun.star.script.provider.ScriptProviderFor"+ LANGUAGENAME,),) 1002cdf0e10cSrcweir 1003cdf0e10cSrcweir 1004cdf0e10cSrcweirlog.debug( "pythonscript finished intializing" ) 1005cdf0e10cSrcweir 1006