--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+"""
+import sys,os,shutil,glob,socket
+import optparse
+
+import getAppliPath
+appli_local=os.path.realpath(os.path.dirname(__file__))
+APPLI=getAppliPath.relpath(appli_local,os.path.realpath(os.getenv('HOME')))
+
+usage="""usage: %prog [options]
+Typical use is:
+ python update_catalogs.py
+
+You need to have a well installed SALOME application with a CatalogResources.base.xml file.
+This file is used (parsed) to collect all module catalogs from distant resources and
+put them in the directory "remote_catalogs" with sub-directories with same name as the distant resource.
+Distant resources are all the resources except the main SALOME application.
+Module catalogs from distant resources are copied by the remote protocol declared in the catalog (rcp or rsh)
+except for the user resources on the local machine (local copy: cp).
+
+In a second time, this procedure generates a ready to use CatalogResources.xml with all available components
+for each resource.
+"""
+
+try:
+ # cElementTree from Python 2.5+
+ import xml.etree.cElementTree as etree_
+except ImportError:
+ try:
+ import xml.etree.ElementTree as etree_
+ except ImportError:
+ try:
+ import cElementTree as etree_
+ except ImportError:
+ try:
+ # normal ElementTree install
+ import elementtree.ElementTree as etree_
+ except ImportError:
+ raise
+
+class ParseError(Exception):
+ pass
+
+catalog_file_base=os.path.join(appli_local,"CatalogResources.base.xml")
+catalog_file=os.path.join(appli_local,"CatalogResources.xml")
+
+cata_dir=os.path.join(appli_local,"remote_catalogs")
+cata_dir_bak=os.path.join(appli_local,"remote_catalogs.bak")
+
+SEP=":"
+if sys.platform == "win32":SEP=";"
+
+def get_hostname():
+ return socket.gethostname().split('.')[0]
+
+class Component:
+ """Define a SALOME component
+ - name : component name
+ - moduleName : module name
+ """
+ def __init__(self,name,moduleName):
+ self.name=name
+ self.moduleName=moduleName
+
+class Resource:
+ """Define a SALOME resource
+ - components : the list of available components of the resource
+ """
+ def __init__(self,node):
+ self.node=node
+ self.components=[]
+ self.resource_dir=None
+ self.build()
+
+ def build(self):
+ self.attrs=self.node.attrib
+ #remove all children (components and modules)
+ for child in list(self.node):
+ self.node.remove(child)
+
+ def update(self):
+ for compo in self.components:
+ child=etree_.Element("component",name=compo.name,moduleName=compo.moduleName)
+ child.tail="\n"
+ self.node.append(child)
+
+ def get_rcp(self):
+ protocol= self.node.get("protocol")
+ if protocol and protocol[0]=='s':return "scp"
+ else:return "rcp"
+
+ def get_user(self):
+ userName= self.node.get("userName")
+ if not userName:
+ userName=os.getenv('USER')
+ return userName
+
+ def get_host(self):
+ hostname= self.node.get("hostname")
+ return hostname
+
+ def get_name(self):
+ name= self.node.get("name")
+ if name:return name
+ return self.get_host()
+
+ def get_appliPath(self):
+ appliPath= self.node.get("appliPath")
+ if appliPath is None:
+ appliPath=APPLI
+ return appliPath
+
+ def get_catalogs(self):
+ """Get module catalogs file from the resource and copy them locally in remote_catalogs/<resource name>"""
+ hostname=self.get_host()
+ appliPath= self.get_appliPath()
+ userName = self.get_user()
+ rcopy=self.get_rcp()
+
+ resource_dir=os.path.join(cata_dir,self.get_name())
+
+ if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
+ #local machine, use cp
+ if appliPath[0]!='/':
+ #relative path
+ appliPath=os.path.join(os.getenv("HOME"),appliPath)
+
+ if appliPath == appli_local:
+ return
+ os.mkdir(resource_dir)
+ cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
+ cmd="cp %s %s" % (cata_path,resource_dir)
+ print cmd
+ os.system(cmd)
+ cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
+ cmd="cp %s %s" % (cata_path,resource_dir)
+ print cmd
+ os.system(cmd)
+ else:
+ #remote machine, use rcopy
+ os.mkdir(resource_dir)
+ cata_path=os.path.join(appliPath,"share","salome","resources","*Catalog.xml")
+ cmd="%s %s@%s:%s %s"
+ cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
+ print cmd
+ os.system(cmd)
+ cata_path=os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml")
+ cmd="%s %s@%s:%s %s"
+ cmd= cmd%(rcopy,userName,hostname,cata_path,resource_dir)
+ print cmd
+ os.system(cmd)
+
+ schema_cata=os.path.join(resource_dir,"*SchemaCatalog.xml")
+ os.system("rm %s"% schema_cata)
+
+ self.resource_dir=os.path.abspath(resource_dir)
+
+ def get_components(self):
+ """Retrieve all components declared in module catalogs of the resource"""
+ appliPath= self.get_appliPath()
+ userName = self.get_user()
+ hostname=self.get_host()
+ resource_dir=os.path.join(cata_dir,self.get_name())
+ catalogs_list=glob.glob(os.path.join(resource_dir,"*Catalog.xml"))
+
+ if hostname == "localhost" or hostname == get_hostname() and userName == os.getenv("USER"):
+ #user local resource
+ if appliPath[0]!='/':
+ appliPath=os.path.join(os.getenv("HOME"),appliPath)
+ if appliPath == appli_local:
+ #main local resource: get catalogs in share/salome/resources
+ catalogs_list=glob.glob(os.path.join(appliPath,"share","salome","resources","*","*Catalog.xml"))
+ catalogs_list=catalogs_list + glob.glob(os.path.join(appliPath,"share","salome","resources","*Catalog.xml"))
+
+ for cata in catalogs_list:
+ moduleName= os.path.basename(cata)[:-11]
+ #Parse module catalog
+ doc = etree_.parse(cata)
+ rootNode = doc.getroot()
+ for componentName in rootNode.findall("component-list/component/component-name"):
+ self.components.append(Component(componentName.text,moduleName))
+
+
+def main():
+ parser = optparse.OptionParser(usage=usage)
+
+ options, args = parser.parse_args()
+
+ if not os.path.exists(catalog_file_base):
+ print "ERROR: the base catalog file %s is mandatory" % catalog_file_base
+ sys.exit(1)
+
+ #Parse CatalogResource.xml
+ doc = etree_.parse(catalog_file_base)
+
+ rootNode = doc.getroot()
+ if rootNode.tag != "resources":
+ raise ParseError("First level tag must be resources not %s" % rootNode.tag)
+
+ resources=[]
+
+ #Extract resources
+ for child in rootNode:
+ if child.tag != "machine":
+ raise ParseError("Second level tag must be machine not %s" % child.tag)
+ resources.append(Resource(child))
+
+ # Remove remote_catalogs directory and create a new empty one
+ if os.path.exists(cata_dir):
+ if os.path.exists(cata_dir_bak):
+ shutil.rmtree(cata_dir_bak)
+ os.rename(cata_dir,cata_dir_bak)
+
+ os.mkdir(cata_dir)
+
+ #Get catalogs from remote resources and copy them in remote_catalogs
+ for mach in resources:
+ mach.get_catalogs()
+
+ #Get the list of SALOME components that are defined in catalogs
+ for mach in resources:
+ mach.get_components()
+
+ #Update the resource catalog dom object for further dump
+ for mach in resources:
+ mach.update()
+
+ #dump new CatalogResources.xml
+ f=open(catalog_file,'w')
+ f.write('<?xml version="1.0" ?>\n')
+ doc.write(f)
+ f.write('\n')
+ f.close()
+ print "%s updated" % catalog_file
+
+ #update configRemote.sh in env.d directory (environment variable SALOME_CATALOGS_PATH)
+ path=[]
+ for mach in resources:
+ if mach.resource_dir:
+ path.append(mach.resource_dir)
+
+ f=open(os.path.join(appli_local,"env.d","configRemote.sh"),'w')
+ f.write("export SALOME_CATALOGS_PATH=%s\n" % SEP.join(path))
+ f.close()
+
+
+if __name__ == '__main__':
+ main()
+