# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import os
+import sys
import platform
import datetime
import shutil
import gettext
-import sys
+import pprint as PP
import src
+import src.logger as LOG
import src.debug as DBG
+import src.callerName as CALN
+
+logger = LOG.getDefaultLogger()
+
+verbose = False # True for debug
# internationalization
satdir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
_("Optional: synthetic list of all properties used in the application"))
parser.add_option('c', 'copy', 'boolean', 'copy',
_("""Optional: copy a config file to the personal config files directory.
-\tWARNING the included files are not copied.
-\tIf a name is given the new config file takes the given name."""))
+WARNING: the included files are not copied.
+If a name is given the new config file takes the given name."""))
parser.add_option('n', 'no_label', 'boolean', 'no_label',
_("Internal use: do not print labels, Works only with --value and --list."))
parser.add_option('', 'completion', 'boolean', 'completion',
parser.add_option('s', 'schema', 'boolean', 'schema',
_("Internal use."))
+def osJoin(*args):
+ """
+ shortcut wrapper to os.path.join
+ plus optionaly print for debug
+ """
+ res = os.path.realpath(os.path.join(*args))
+ if verbose:
+ if True: # ".pyconf" in res:
+ logger.info("osJoin %-80s in %s" % (res, CALN.caller_name()))
+ return res
+
class ConfigOpener:
'''Class that helps to find an application pyconf
in all the possible directories (pathList)
:param pathList list: The list of paths where to search a pyconf.
'''
self.pathList = pathList
+ if verbose:
+ for path in pathList:
+ if not os.path.isdir(path):
+ logger.warning("ConfigOpener inexisting directory: %s" % path)
def __call__(self, name):
if os.path.isabs(name):
return src.pyconf.ConfigInputStream(open(name, 'rb'))
else:
- return src.pyconf.ConfigInputStream(
- open(os.path.join( self.get_path(name), name ), 'rb') )
+ return src.pyconf.ConfigInputStream(open(osJoin(self.get_path(name), name), 'rb'))
raise IOError(_("Configuration file '%s' not found") % name)
def get_path( self, name ):
'''The method that returns the entire path of the pyconf searched
+ returns first found in self.pathList directories
+
:param name str: The name of the searched pyconf.
'''
for path in self.pathList:
- if os.path.exists(os.path.join(path, name)):
+ if os.path.exists(osJoin(path, name)):
return path
raise IOError(_("Configuration file '%s' not found") % name)
'''
var = {}
var['user'] = src.architecture.get_user()
- var['salometoolsway'] = os.path.dirname(
- os.path.dirname(os.path.abspath(__file__)))
- var['srcDir'] = os.path.join(var['salometoolsway'], 'src')
- var['internal_dir'] = os.path.join(var['srcDir'], 'internal_config')
+ var['salometoolsway'] = os.path.dirname( os.path.dirname(os.path.abspath(__file__)))
+ var['srcDir'] = osJoin(var['salometoolsway'], 'src')
+ var['internal_dir'] = osJoin(var['srcDir'], 'internal_config')
var['sep']= os.path.sep
# datadir has a default location
- var['datadir'] = os.path.join(var['salometoolsway'], 'data')
+ var['datadir'] = osJoin(var['salometoolsway'], 'data')
if datadir is not None:
var['datadir'] = datadir
- var['personalDir'] = os.path.join(os.path.expanduser('~'),
- '.salomeTools')
+ var['personalDir'] = osJoin(os.path.expanduser('~'), '.salomeTools')
src.ensure_path_exists(var['personalDir'])
- var['personal_applications_dir'] = os.path.join(var['personalDir'],
- "Applications")
+ var['personal_applications_dir'] = osJoin(var['personalDir'], "Applications")
src.ensure_path_exists(var['personal_applications_dir'])
- var['personal_products_dir'] = os.path.join(var['personalDir'],
- "products")
+ var['personal_products_dir'] = osJoin(var['personalDir'], "products")
src.ensure_path_exists(var['personal_products_dir'])
- var['personal_archives_dir'] = os.path.join(var['personalDir'],
- "Archives")
+ var['personal_archives_dir'] = osJoin(var['personalDir'], "Archives")
src.ensure_path_exists(var['personal_archives_dir'])
- var['personal_jobs_dir'] = os.path.join(var['personalDir'],
- "Jobs")
+ var['personal_jobs_dir'] = osJoin(var['personalDir'], "Jobs")
src.ensure_path_exists(var['personal_jobs_dir'])
- var['personal_machines_dir'] = os.path.join(var['personalDir'],
- "Machines")
+ var['personal_machines_dir'] = osJoin(var['personalDir'], "Machines")
src.ensure_path_exists(var['personal_machines_dir'])
# read linux distributions dictionary
- distrib_cfg = src.pyconf.Config(os.path.join(var['srcDir'],
- 'internal_config',
- 'distrib.pyconf'))
+ distrib_cfg = src.pyconf.Config( osJoin(var['srcDir'], 'internal_config', 'distrib.pyconf'))
# set platform parameters
- dist_name = src.architecture.get_distribution(
- codes=distrib_cfg.DISTRIBUTIONS)
- dist_version = src.architecture.get_distrib_version(dist_name,
- codes=distrib_cfg.VERSIONS)
+ dist_name = src.architecture.get_distribution(codes=distrib_cfg.DISTRIBUTIONS)
+ dist_version = src.architecture.get_distrib_version(dist_name, codes=distrib_cfg.VERSIONS)
+ dist_version_full = src.architecture.get_infosys()
dist = dist_name + dist_version
var['dist_name'] = dist_name
var['dist_version'] = dist_version
var['dist'] = dist
+ var['dist_ref'] = dist_name + dist_version_full
var['python'] = src.architecture.get_python_version()
var['nb_proc'] = src.architecture.get_nb_proc()
# =====================================================================
# create VARS section
- var = self._create_vars(application=application, command=command,
- datadir=datadir)
+ var = self._create_vars(application=application, command=command, datadir=datadir)
+ # DBG.write("create_vars", var, DBG.isDeveloper())
+
# add VARS to config
cfg.VARS = src.pyconf.Mapping(cfg)
for variable in var:
# Load INTERNAL config
# read src/internal_config/salomeTools.pyconf
src.pyconf.streamOpener = ConfigOpener([
- os.path.join(cfg.VARS.srcDir, 'internal_config')])
+ osJoin(cfg.VARS.srcDir, 'internal_config')])
try:
- internal_cfg = src.pyconf.Config(open(os.path.join(cfg.VARS.srcDir,
+ internal_cfg = src.pyconf.Config(open( osJoin(cfg.VARS.srcDir,
'internal_config', 'salomeTools.pyconf')))
except src.pyconf.ConfigError as e:
raise src.SatException(_("Error in configuration file:"
# search only in the data directory
src.pyconf.streamOpener = ConfigOpener([cfg.VARS.datadir])
try:
- local_cfg = src.pyconf.Config(open(os.path.join(cfg.VARS.datadir,
+ local_cfg = src.pyconf.Config(open( osJoin(cfg.VARS.datadir,
'local.pyconf')),
PWD = ('LOCAL', cfg.VARS.datadir) )
except src.pyconf.ConfigError as e:
# When the key is "default", put the default value
if cfg.LOCAL.base == "default":
- cfg.LOCAL.base = os.path.abspath(
- os.path.join(cfg.VARS.salometoolsway,
- "..",
- "BASE"))
+ cfg.LOCAL.base = os.path.abspath(osJoin(cfg.VARS.salometoolsway, "..", "BASE"))
if cfg.LOCAL.workdir == "default":
- cfg.LOCAL.workdir = os.path.abspath(
- os.path.join(cfg.VARS.salometoolsway,
- ".."))
+ cfg.LOCAL.workdir = os.path.abspath(osJoin(cfg.VARS.salometoolsway, ".."))
if cfg.LOCAL.log_dir == "default":
- cfg.LOCAL.log_dir = os.path.abspath(
- os.path.join(cfg.VARS.salometoolsway,
- "..",
- "LOGS"))
+ cfg.LOCAL.log_dir = os.path.abspath(osJoin(cfg.VARS.salometoolsway, "..", "LOGS"))
if cfg.LOCAL.archive_dir == "default":
- cfg.LOCAL.archive_dir = os.path.abspath(
- os.path.join(cfg.VARS.salometoolsway,
- "..",
- "ARCHIVES"))
+ cfg.LOCAL.archive_dir = os.path.abspath( osJoin(cfg.VARS.salometoolsway, "..", "ARCHIVES"))
# apply overwrite from command line if needed
for rule in self.get_command_line_overrides(options, ["LOCAL"]):
cfg.PATHS.PRODUCTPATH.append(cfg.VARS.personal_products_dir, "")
cfg.PATHS["ARCHIVEPATH"] = src.pyconf.Sequence(cfg.PATHS)
cfg.PATHS.ARCHIVEPATH.append(cfg.VARS.personal_archives_dir, "")
+ cfg.PATHS["ARCHIVEFTP"] = src.pyconf.Sequence(cfg.PATHS)
cfg.PATHS["JOBPATH"] = src.pyconf.Sequence(cfg.PATHS)
cfg.PATHS.JOBPATH.append(cfg.VARS.personal_jobs_dir, "")
cfg.PATHS["MACHINEPATH"] = src.pyconf.Sequence(cfg.PATHS)
for PATH in ["APPLICATIONPATH",
"PRODUCTPATH",
"ARCHIVEPATH", #comment this for default archive #8646
+ "ARCHIVEFTP",
"JOBPATH",
"MACHINEPATH"]:
if PATH not in cfg.PROJECTS.projects[project]:
exec('cfg.' + rule) # this cannot be factorized because of the exec
# AT END append APPLI_TEST directory in APPLICATIONPATH, for unittest
- appli_test_dir = os.path.join(satdir, "test", "APPLI_TEST")
+ appli_test_dir = osJoin(satdir, "test", "APPLI_TEST")
if appli_test_dir not in cfg.PATHS.APPLICATIONPATH:
cfg.PATHS.APPLICATIONPATH.append(appli_test_dir, "unittest APPLI_TEST path")
'''
# get the expected name and path of the file
self.config_file_name = 'SAT.pyconf'
- self.user_config_file_path = os.path.join(config.VARS.personalDir,
- self.config_file_name)
+ self.user_config_file_path = osJoin(config.VARS.personalDir, self.config_file_name)
# if pyconf does not exist, create it from scratch
if not os.path.isfile(self.user_config_file_path):
"This is the default output_verbose_level you want."
" 0=>no output, 5=>debug.\n")
user_cfg.USER.addMapping('publish_dir',
- os.path.join(os.path.expanduser('~'),
+ osJoin(os.path.expanduser('~'),
'websupport',
'satreport'),
"")
# "The products installation base (could be "
# "ignored if this key exists in the local.pyconf"
# " file of salomTools).\n")
-
- #
+
src.ensure_path_exists(config.VARS.personalDir)
- src.ensure_path_exists(os.path.join(config.VARS.personalDir,
+ src.ensure_path_exists( osJoin(config.VARS.personalDir,
'Applications'))
f = open(cfg_name, 'w')
pinfo = src.product.get_product_config(config, name)
if "depend" in pinfo:
- src.printcolors.print_value(logger,
- "depends on",
- ', '.join(pinfo.depend), 2)
+ src.printcolors.print_value(logger, "depends on", sorted(pinfo.depend), 2)
if "opt_depend" in pinfo:
- src.printcolors.print_value(logger,
- "optional",
- ', '.join(pinfo.opt_depend), 2)
+ src.printcolors.print_value(logger, "optional", sorted(pinfo.opt_depend), 2)
# information on pyconf
logger.write("\n", 2)
logger.write(src.printcolors.printcLabel("configuration:") + "\n", 2)
if "from_file" in pinfo:
- src.printcolors.print_value(logger,
- "pyconf file path",
- pinfo.from_file,
+ src.printcolors.print_value(logger,
+ "pyconf file path",
+ pinfo.from_file,
2)
if "section" in pinfo:
- src.printcolors.print_value(logger,
- "section",
- pinfo.section,
+ src.printcolors.print_value(logger,
+ "section",
+ pinfo.section,
2)
# information on prepare
src.printcolors.print_value(logger, "tag", pinfo.git_info.tag, 2)
elif method == 'archive':
- src.printcolors.print_value(logger,
- "get from",
- check_path(pinfo.archive_info.archive_name),
+ src.printcolors.print_value(logger,
+ "get from",
+ check_path(pinfo.archive_info.archive_name),
2)
if 'patches' in pinfo:
src.printcolors.print_value(logger, "patch", check_path(patch), 2)
if src.product.product_is_fixed(pinfo):
- src.printcolors.print_value(logger, "install_dir",
+ src.printcolors.print_value(logger, "install_dir",
check_path(pinfo.install_dir), 2)
if src.product.product_is_native(pinfo) or src.product.product_is_fixed(pinfo):
if src.product.product_compiles(pinfo):
logger.write("\n", 2)
logger.write(src.printcolors.printcLabel("compile:") + "\n", 2)
- src.printcolors.print_value(logger,
- "compilation method",
- pinfo.build_source,
+ src.printcolors.print_value(logger,
+ "compilation method",
+ pinfo.build_source,
2)
if pinfo.build_source == "script" and "compil_script" in pinfo:
check_path(pinfo.environ.env_script),
2)
- zz = src.environment.SalomeEnviron(config,
+ zz = src.environment.SalomeEnviron(config,
src.fileEnviron.ScreenEnviron(logger),
False)
zz.set_python_libdirs()
od = options.debug[1:]
else:
od = options.debug
- exec("a = runner.cfg.%s" % od)
- res = DBG.indent(DBG.getStrConfigDbg(a))
- logger.write("\nConfig.%s of application %s:\n\n%s\n" % (od, runner.cfg.VARS.application, res))
+ try:
+ aCode = "a = runner.cfg.%s" % od
+ # https://stackoverflow.com/questions/15086040/behavior-of-exec-function-in-python-2-and-python-3
+ aDict = {"runner": runner}
+ exec(aCode, globals(), aDict)
+ # DBG.write("globals()", globals(), True)
+ # DBG.write("aDict", aDict, True)
+ res = DBG.indent(DBG.getStrConfigDbg(aDict["a"]))
+ logger.write("\nConfig.%s of application %s:\n\n%s\n" % (od, runner.cfg.VARS.application, res))
+ except Exception as e:
+ msg = "\nConfig.%s of application %s: Unknown pyconf key\n" % (od, runner.cfg.VARS.application)
+ logger.write(src.printcolors.printcError(msg), 1)
# case : edit user pyconf file or application file
editor = runner.cfg.USER.editor
if ('APPLICATION' not in runner.cfg and
'open_application' not in runner.cfg): # edit user pyconf
- usercfg = os.path.join(runner.cfg.VARS.personalDir,
+ usercfg = osJoin(runner.cfg.VARS.personalDir,
'SAT.pyconf')
logger.write(_("Opening %s\n" % usercfg), 3)
src.system.show_in_editor(editor, usercfg, logger)
else:
# search for file <application>.pyconf and open it
for path in runner.cfg.PATHS.APPLICATIONPATH:
- pyconf_path = os.path.join(path,
+ pyconf_path = osJoin(path,
runner.cfg.VARS.application + ".pyconf")
if os.path.exists(pyconf_path):
logger.write(_("Opening %s\n" % pyconf_path), 3)
if path == runner.cfg.VARS.personalDir:
continue
# loop on all directories that can have pyconf applications
- zz = os.path.join(path, source)
+ zz = osJoin(path, source)
if os.path.exists(zz):
source_full_path = zz
break
dest = runner.cfg.VARS.application
# the full path
- dest_file = os.path.join(runner.cfg.VARS.personalDir,
+ dest_file = osJoin(runner.cfg.VARS.personalDir,
'Applications', dest + '.pyconf')
if os.path.exists(dest_file):
raise src.SatException(_("A personal application"
for name in names:
# display information
- len_points = max_len - len(name)
+ len_points = max_len - len(name) + 3
local_path, archive_path = d_content[name]
in_archive = os.path.join(name_archive, archive_path)
logger.write(name + " " + len_points * "." + " "+ in_archive + " ", 3)
bin_kernel_install_dir = os.path.join(kernel_root_dir,"bin","salome")
# check if the application contains an application module
- l_product_info = src.product.get_products_infos(config.APPLICATION.products.keys(),
- config)
+ l_product_info = src.product.get_products_infos(config.APPLICATION.products.keys(), config)
salome_application_name="Not defined"
for prod_name, prod_info in l_product_info:
# look for a salome application
l_not_installed = []
l_sources_not_present = []
generate_mesa_launcher = False # a flag to know if we generate a mesa launcher
+ if ("APPLICATION" in config and
+ "properties" in config.APPLICATION and
+ "mesa_launcher_in_package" in config.APPLICATION.properties and
+ config.APPLICATION.properties.mesa_launcher_in_package == "yes") :
+ generate_mesa_launcher=True
+
for prod_name, prod_info in l_product_info:
# skip product with property not_in_package set to yes
if src.get_property_in_product_cfg(prod_info, "not_in_package") == "yes":
else:
l_sources_not_present.append(prod_name)
- # if at least one of the application products has the "is_mesa" property
- if src.get_property_in_product_cfg(prod_info, "is_mesa") == "yes":
- generate_mesa_launcher = True # we will generate a mesa launcher
-
# ignore the native and fixed products for install directories
if (src.product.product_is_native(prod_info)
or src.product.product_is_fixed(prod_info)
runner.cfg.VARS.application), 1)
# Get the default directory where to put the packages
- package_default_path = os.path.join(runner.cfg.APPLICATION.workdir,
- "PACKAGE")
+ package_default_path = os.path.join(runner.cfg.APPLICATION.workdir, "PACKAGE")
src.ensure_path_exists(package_default_path)
# if the package contains a project:
break
if foundProject is None:
- local_path = os.path.join(runner.cfg.VARS.salometoolsway,
- "data",
- "local.pyconf")
+ local_path = os.path.join(runner.cfg.VARS.salometoolsway, "data", "local.pyconf")
msg = _("""ERROR: the project %(1)s is not visible by salomeTools.
known projects are:
%(2)s
d_files_to_add[file_name] = (file_path, file_name)
logger.write("\n", 2)
-
logger.write(src.printcolors.printcLabel(_("Actually do the package")), 2)
logger.write("\n", 2)
+ logger.write("\nfiles and directories to add:\n%s\n\n" % PP.pformat(d_files_to_add), 5)
res = 0
try:
logger.write(_("\n"), 1)
return 1
+ # case if no application, only package sat as 'sat package -t'
+ try:
+ app = runner.cfg.APPLICATION
+ except:
+ app = None
+
# unconditionaly remove the tmp_local_working_dir
- tmp_local_working_dir = os.path.join(runner.cfg.APPLICATION.workdir, "tmp_package")
- if os.path.isdir(tmp_local_working_dir):
- shutil.rmtree(tmp_local_working_dir)
+ if app is not None:
+ tmp_local_working_dir = os.path.join(app.workdir, "tmp_package")
+ if os.path.isdir(tmp_local_working_dir):
+ shutil.rmtree(tmp_local_working_dir)
# have to decide some time
DBG.tofix("make shutil.rmtree('%s') effective" % tmp_working_dir, "", DBG.isDeveloper())
--- /dev/null
- if not moduleDesktop.has_key( studyID ):
+ # Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+ #
+ # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+ # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+ #
+ # This library is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU Lesser General Public
+ # License as published by the Free Software Foundation; either
+ # version 2.1 of the License.
+ #
+ # This library is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ # Lesser General Public License for more details.
+ #
+ # You should have received a copy of the GNU Lesser General Public
+ # License along with this library; if not, write to the Free Software
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ #
+ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+ #
+
+ # ---
+ # File : :sat:{PYCMP}GUI.py
+ # Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+ # ---
+ #
+ import traceback
+ import string
+ import os
+ import sys
+ from qtsalome import *
+
+ #from :sat:{PYCMP}_utils import *
+
+ import salome
+ from Controller import Controller
+ from TreeWidget import TreeWidget
+ from :sat:{PYCMP}Desktop import :sat:{PYCMP}Desktop
+
+ # Get SALOME PyQt interface
+ import SalomePyQt
+ import libSALOME_Swig
+
+ ########################################################
+ # Global variables
+ ########################################################
+
+ sgPyQt = SalomePyQt.SalomePyQt()
+ sg = libSALOME_Swig.SALOMEGUI_Swig()
+ sgDesktop = sgPyQt.getDesktop()
+ widgetDialogBox = None
+
+ objectsManager = Controller( None )
+ moduleDesktop = {}
+ currentDesktop = None
+
+ CURVE_MENU_ID = 1000
+ ADVANCED_MENU_ID = 1001
+ POLYLINE_ID = 1002
+ CIRCLE_ID = 1003
+ DEL_ALL_ID = 1004
+
+ ########################################################
+ # Internal methods
+ ########################################################
+
+ def getStudyId():
+ """This method returns the active study ID"""
+ return sgPyQt.getStudyId()
+
+ def getStudy():
+ """This method returns the active study"""
+
+ studyId = _getStudyId()
+ study = getStudyManager().GetStudyByID( studyId )
+ return study
+
+ def getDesktop():
+ """This method returns the current :sat:{PYCMP} desktop"""
+
+ global currentDesktop
+ return currentDesktop
+
+ def setDesktop( studyID ):
+ """This method sets and returns :sat:{PYCMP} desktop"""
+
+ global moduleDesktop, currentDesktop, objectsManager
+
- if dict_command.has_key( commandID ):
++ if not studyID in moduleDesktop:
+ moduleDesktop[studyID] = :sat:{PYCMP}Desktop( sgPyQt, sg )
+ objectsManager = Controller( moduleDesktop[studyID] )
+ moduleDesktop[studyID].setController( objectsManager )
+ pass
+ currentDesktop = moduleDesktop[studyID]
+ return currentDesktop
+
+ def incObjToMap( m, id ):
+ """This method incrementes the object counter in the map"""
+
+ if id not in m: m[id] = 0
+ m[id] += 1
+ pass
+
+ def getSelection():
+ """This method analyses selection"""
+
+ selcount = sg.SelectedCount()
+ seltypes = {}
+ for i in range( selcount ):
+ incObjToMap( seltypes, getObjectID( getStudy(), sg.getSelected( i ) ) )
+ pass
+ return selcount, seltypes
+
+ ################################################
+ # Callback functions
+ ################################################
+
+ def initialize():
+ """This method is called when module is initialized. It performs initialization actions"""
+
+ setDesktop( getStudyId() )
+ pass
+
+ def windows():
+ """This method is called when module is initialized. It returns a map of popup windows to be used by the module"""
+
+ wm = {}
+ wm[SalomePyQt.WT_ObjectBrowser] = Qt.LeftDockWidgetArea
+ wm[SalomePyQt.WT_PyConsole] = Qt.BottomDockWidgetArea
+ return wm
+
+ def views():
+ """This method is called when module is initialized. It returns a list of 2D/3D views to be used by the module"""
+ return []
+
+ def createPreferences():
+ """This method is called when module is initialized. It exports module preferences"""
+ pass
+
+ def activate():
+ """This method is called when module is initialized. It returns True if activating is successfull, False otherwise"""
+
+ global moduleDesktop, sgPyQt, widgetDialogBox
+
+ widgetDialogBox = QDockWidget( sgDesktop )
+ moduleDesktop[getStudyId()].createActions()
+ moduleDesktop[getStudyId()].createMenus()
+ moduleDesktop[getStudyId()].createToolBars()
+ moduleDesktop[getStudyId()].createPopups()
+ moduleDesktop[getStudyId()].getDockGlobalTree().show()
+ moduleDesktop[getStudyId()].getGlobalGraphicsView().show()
+ sgPyQt.activateView( moduleDesktop[getStudyId()].getGlobalGraphicsViewID() )
+ return True
+
+ def viewTryClose( wid ):
+ sgPyQt.setViewClosable(wid, True)
+ pass
+
+ def deactivate():
+ """This method is called when module is deactivated"""
+
+ global moduleDesktop, widgetDialogBox
+
+ widgetDialogBox.close()
+ moduleDesktop[getStudyId()].getDockGlobalTree().hide()
+ moduleDesktop[getStudyId()].updateGlobalGraphicsView( None )
+ moduleDesktop[getStudyId()].getGlobalGraphicsView().hide()
+ pass
+
+ def activeStudyChanged( studyID ):
+ """This method is called when active study is changed"""
+
+ setDesktop( getStudyId() )
+ pass
+
+ def createPopupMenu( popup, context ):
+ """This method is called when popup menu is invocked"""
+ pass
+
+ def OnGUIEvent( commandID ):
+ """This method is called when a GUI action is activated"""
+
++ if commandID in dict_command:
+ dict_command[commandID]()
+ pass
+ pass
+
+ def preferenceChanged( section, setting ):
+ """This method is called when module's preferences are changed"""
+ pass
+
+ def activeViewChanged( viewID ):
+ """This method is called when active view is changed"""
+ pass
+
+ def viewCloned( viewID ):
+ """This method is called when active view is cloned"""
+ pass
+
+ def viewClosed( viewID ):
+ """This method is called when active view viewClosed"""
+ pass
+
+ def engineIOR():
+ """This method is called when study is opened. It returns engine IOR"""
+ return getEngineIOR()
+
+
+ ################################################
+ # GUI actions implementation
+ ################################################
+
+ def showCreatePolylineDialog() :
+ from CreatePolylineDialog import CreatePolylineDialog
+
+ global widgetDialogBox
+ widgetDialogBox = QDockWidget( sgDesktop )
+ myDialog = CreatePolylineDialog( "www.cea.fr", objectsManager, widgetDialogBox )
+ widgetDialogBox.setWidget( myDialog )
+ widgetDialogBox.setWindowTitle( "Polyline definition" )
+ sgDesktop.addDockWidget(Qt.LeftDockWidgetArea, widgetDialogBox)
+ pass
+
+ def showCreateCircleDialog() :
+ from CreateCircleDialog import CreateCircleDialog
+
+ global widgetDialogBox
+ widgetDialogBox = QDockWidget( sgDesktop )
+ myDialog = CreateCircleDialog( "www.cea.fr", objectsManager, widgetDialogBox )
+ widgetDialogBox.setWidget( myDialog )
+ widgetDialogBox.setWindowTitle( "Circle definition" )
+ sgDesktop.addDockWidget(Qt.LeftDockWidgetArea, widgetDialogBox)
+ pass
+
+ def deleteAll() :
+ models = moduleDesktop[getStudyId()].getController().getModels()
+ if len( models ) == 0 : return
+ answer = QMessageBox.question( moduleDesktop[getStudyId()], 'Confirmation', 'Do you really want to delete all the existing objects ?' , QMessageBox.Yes | QMessageBox.No )
+ if answer == QMessageBox.Yes :
+ for model in models :
+ moduleDesktop[getStudyId()].getController().removeModel( model )
+ pass
+ pass
+ pass
+
+ ########################################################
+ # Commands dictionary
+ ########################################################
+
+ dict_command = { POLYLINE_ID : showCreatePolylineDialog,
+ CIRCLE_ID : showCreateCircleDialog,
+ DEL_ALL_ID : deleteAll
+ }
+
+ ########################################################
import errno
import stat
import fnmatch
+import pprint as PP
+ from ftplib import FTP
from . import pyconf
from . import architecture
return config[param_name]
return default
+def strSplitN(aList, nb, skip="\n "):
+ """
+ example
+ aStr = 'this-is-a-string'
+ splitN(aStr, 2, '-')
+ split it by every 2nd '-' rather than every '-'
+ """
+ strValue = ""
+ i = 0
+ for v in aList:
+ strValue += "%15s, " % str(v)
+ i += 1
+ if i >= nb:
+ strValue += skip
+ i = 0
+ if len(aList) > nb:
+ strValue = skip + strValue
+ return strValue
def getProductNames(cfg, wildcards, logger):
"""get products names using * or ? as wildcards like shell Linux"""
wilds = wildcards
else:
wilds = [wildcards]
+ notFound = {}
products = cfg.APPLICATION.products.keys()
- for prod in products:
- for wild in wildcards:
+ for wild in wildcards:
+ ok = False
+ for prod in products:
filtered = fnmatch.filter([prod], wild)
# print("filtered", prod, wild, filtered)
if len(filtered) > 0:
res.append(prod)
+ ok = True
break
+ if not ok:
+ notFound[wild] = None
if len(res) == 0:
logger.warning("Empty list of products, from %s" % wilds)
+ if len(notFound.keys()) > 0:
+ strProd = strSplitN( sorted(products), 5)
+ logger.warning("products not found: %s\n availables products are:\n%s" % \
+ (sorted(notFound.keys()), strProd) )
return res
return os.path.join(dir_complete, file_name)
return False
+ def find_file_in_ftppath(file_name, ftppath, installation_dir, logger):
+ """\
+ Find in all ftp servers in ftppath the file called file_name
+ If it is found then return the destination path of the file
+ (the place where the file was downloaded"
+ else return False.
+
+ :param file_name str: The file name to search
+ :param ftppath, List: The list of ftp servers where to search
+ :param installation_dir str: The name of the installation directory
+ :return: the full path of the file or False if not found
+ :param logger Logger: The logging instance to use for the prints.
+ :rtype: str
+ """
+ destination=os.path.join(installation_dir, file_name)
+ for ftp_archive in ftppath:
+ try:
+ # ftp_archive has the form ftp.xxx.yyy/dir1/dir2/...
+ ftp_archive_split=ftp_archive.split("/")
+ ftp_server=ftp_archive_split[0]
+ ftp = FTP(ftp_server)
+ logger.write(" Connect to ftp server %s\n" % ftp_server, 3)
+ ftp.login()
+ for directory in ftp_archive_split[1:]:
+ logger.write(" Change directory to %s\n" % directory, 3)
+ ftp.cwd(directory)
+ except:
+ logger.error("while connecting to ftp server %s\n" % ftp_server)
+
+ try:
+ if ftp.size(file_name) > 0:
+ # if file exists and is non empty
+ with open(destination,'wb') as dest_file:
+ ftp.retrbinary("RETR "+file_name, dest_file.write)
+ logger.write(" Archive %s was retrieved and stored in %s\n" % (file_name, destination), 3)
+ return destination
+ except:
+ logger.error("File not found in ftp_archive %s\n" % ftp_server)
+ pass
+
+ return False
+
def handleRemoveReadonly(func, path, exc):
excvalue = exc[1]
if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
prod_info.addMapping("archive_info",
src.pyconf.Mapping(prod_info),
"")
- if "archive_name" not in prod_info.archive_info:
+ if "archive_name" in prod_info.archive_info:
+ arch_name = prod_info.archive_info.archive_name
+ else:
+ # standard name
arch_name = product_name + "-" + version + ".tar.gz"
- arch_path = src.find_file_in_lpath(arch_name,
- config.PATHS.ARCHIVEPATH)
- if not arch_path:
- msg = _("Archive %(1)s for %(2)s not found in config.PATHS.ARCHIVEPATH") % \
- {"1" : arch_name, "2" : prod_info.name}
- DBG.tofix(msg, config.PATHS.ARCHIVEPATH)
- prod_info.archive_info.archive_name = arch_name #without path
- # raise src.SatException(msg) #may be a warning, continue #8646
- else:
- prod_info.archive_info.archive_name = arch_path
+
+ arch_path = src.find_file_in_lpath(arch_name,
+ config.PATHS.ARCHIVEPATH)
+ if not arch_path:
+ # arch_path is not found. It may generate an error in sat source,
+ # unless the archive is found in ftp serveur
+ msg = _("Archive %(1)s for %(2)s not found in config.PATHS.ARCHIVEPATH") % \
+ {"1" : arch_name, "2" : prod_info.name}
+ DBG.tofix(msg, config.PATHS.ARCHIVEPATH)
+ prod_info.archive_info.archive_name = arch_name #without path
else:
- if (os.path.basename(prod_info.archive_info.archive_name) ==
- prod_info.archive_info.archive_name):
- arch_name = prod_info.archive_info.archive_name
- arch_path = src.find_file_in_lpath(
- arch_name,
- config.PATHS.ARCHIVEPATH)
- if not arch_path:
- msg = _("Archive %(1)s for %(2)s not found in config.PATHS.ARCHIVEPATH") % \
- {"1" : arch_name, "2" : prod_info.name}
- DBG.tofix(msg, config.PATHS.ARCHIVEPATH) #avoid 2 messages in compile
- prod_info.archive_info.archive_name = arch_name #without path
- # raise src.SatException(msg) #may be a warning, continue #8646
- else:
- prod_info.archive_info.archive_name = arch_path
+ prod_info.archive_info.archive_name = arch_path
# If the product compiles with a script, check the script existence
with open(aFile, 'w') as f:
res.__save__(f)
- # this file is for human eye reading
+ # this file is not mandatory, is for human eye reading
aFile = os.path.join(p_info.install_dir, PRODUCT_FILENAME)
- with open(aFile, 'w') as f:
- # f.write(DBG.getStrConfigDbg(p_info)) # debug mode
- try:
- p_info.__save__(f, evaluated=True) # evaluated expressions mode
- except:
- # the second file is not mandatory. In the context of non VCS archives, p_info cannot be evaluated
- # because information on git server is not available. In this case, we skip the writing without raising an error.
- #DBG.write("cannot evaluate product info - do not write ", PRODUCT_FILENAME, True)
- pass
-
-
+ try:
+ with open(aFile, 'w') as f:
+ p_info.__save__(f, evaluated=True) # evaluated expressions mode
+ except:
+ DBG.write("cannot evaluate product info - problem in file %s" % aFile, p_info, True)
+ # write DBG mode, as no problem if evaluation not possible
+ msg = """\
+# Some informations cannot be evaluated.
+# for example:
+# In the context of non VCS archives, information on git server is not available.
+
+"""
+ with open(aFile, 'w') as f:
+ f.write(msg)
+ f.write(DBG.getStrConfigDbg(p_info))
def check_config_exists(config, prod_dir, prod_info, verbose=False):
"""\