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