3 # Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE
5 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
6 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 # See https://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
25 # File : extension_utilities.py
26 # Author : Konstantin Leontev, Open Cascade
28 # @package SalomeOnDemandTK
29 # @brief Set of utility functions those help to build SALOME python extensions.
32 Utilities and constants those help deal with salome extension files.
38 from traceback import format_exc
40 # Setup logger's output
41 FORMAT = '%(funcName)s():%(lineno)s: %(message)s'
42 logging.basicConfig(format=FORMAT, level=logging.DEBUG)
43 logger = logging.getLogger()
45 SALOME_EXTDIR = '__SALOME_EXT__'
46 ARCFILE_EXT = 'salomex'
47 BFILE_EXT = 'salomexb'
48 CFILE_EXT = 'salomexc'
49 DFILE_EXT = 'salomexd'
53 EXTDESCR_KEY = 'descr'
54 EXTDEPENDSON_KEY = 'depends_on'
55 EXTAUTHOR_KEY = 'author'
56 EXTCOMPONENT_KEY = 'components'
59 def create_salomexd(name, descr='', depends_on=None, author='', components=None):
61 Create a basic salomexd file from provided args.
62 Current version is a json file with function args as the keys.
65 name - the name of the corresponding salome extension.
66 depends_on - list of the modules that current extension depends on.
67 author - an author of the extension.
68 components - the names of the modules those current extension was built from.
71 Raises OSError exception.
77 logger.debug('Create salomexd file...')
79 if depends_on is None:
82 if components is None:
85 json_string = json.dumps(
89 EXTDEPENDSON_KEY: depends_on,
90 EXTAUTHOR_KEY: author,
91 EXTCOMPONENT_KEY: components
97 with open(name + '.' + DFILE_EXT, "w", encoding="utf-8") as file:
98 file.write(json_string)
101 logger.error(format_exc())
104 def read_salomexd(file_path):
106 Reads a content of a salomexd file. Current version is a json file.
107 There's no check if the file_path is a valid salomexd file name.
108 It's expected that user call isvalid_filename() in advance.
111 file_path - the path to the salomexd file.
114 Raises OSError exception.
117 A dictionary that represents the content of the salomexd file.
120 logger.debug('Read salomexd file %s', file_path)
123 with open(file_path, 'r', encoding='UTF-8') as file:
124 return json.load(file)
127 logger.error(format_exc())
131 def create_salomexb(name, included):
133 Create a salomexb file from a list of included file names.
140 name - the name of the corresponding salome extension.
141 included - list of the directories those must be included inside a salomex.
144 Raises OSError exception.
150 logger.debug('Create salomexb file...')
153 with open(name + '.' + BFILE_EXT, "w", encoding="utf-8") as file:
154 file.write('\n'.join(included[0:]))
157 logger.error(format_exc())
160 def read_salomexb(file_path):
162 Returns a content af a salomexb file as a list of strings.
163 There's no check if the file_path is a valid salomexb file name.
164 It's expected that user call isvalid_filename() in advance.
167 file_path - the path to the salomexb file.
170 Raises OSError exception.
173 List of strings - paths to the directories those must be included in
174 corresponding salomex archive file.
177 logger.debug('Read salomexb file %s', file_path)
180 with open(file_path, 'r', encoding='UTF-8') as file:
181 return [line.rstrip() for line in file]
184 logger.error(format_exc())
188 def list_files(dir_path):
190 Returns the recursive list of relative paths to files as strings
191 in the dir_path root directory and all subdirectories.
194 dir_path - the path to the directory where you search for files.
197 Raises OSError exception.
200 A list of relative paths to files inside the given directory.
204 for root, _, files in os.walk(dir_path):
206 files_list += os.path.relpath(os.path.join(root, file), dir_path)
211 def list_files_filter(dir_path, filter_patterns):
213 Returns the recursive list of relative paths to files as strings
214 in the dir_path root directory and all subdirectories.
217 dir_path - the path to the directory where you search for files.
218 filter_patterns - list of expressions for matching file names.
221 files_abs - a list of absolute paths to selected files.
222 files_rel - a list of relative paths to selected files.
225 logger.debug('Get list of files to add into archive...')
230 for root, _, files in os.walk(dir_path):
232 for pattern in filter_patterns:
233 filename_abs = os.path.join(root, file)
234 filename_rel = os.path.relpath(filename_abs, dir_path)
236 if filename_rel.startswith(pattern):
237 logger.debug('File name %s matches pattern %s', filename_rel, pattern)
238 files_abs.append(filename_abs)
239 files_rel.append(filename_rel)
241 return files_abs, files_rel
244 def list_tonewline_str(str_list):
246 Converts the given list of strings to a newline separated string.
249 dir_path - the path to the directory where you search for files.
252 A newline separated string.
254 return '\n'.join(file for file in str_list)
257 def isvalid_filename(filename, extension):
259 Checks if a given filename is valid in a sense that it exists and have a given extension.
262 filename - the name of the file to check.
263 extension - expected file name extension.
266 True if the given filename is valid for given extension.
269 logger.debug('Check if the filename %s exists and has an extension %s', filename, extension)
271 # First do we even have something to check here
272 if filename == '' or extension == '':
273 logger.error('A filename and extension cannot be empty! Args: filename=%s, extension=%s',
277 # Check if the filename matchs the provided extension
278 _, ext = os.path.splitext(filename)
279 ext = ext.lstrip('.')
281 logger.error('The filename %s doesnt have a valid extension! \
282 The valid extension must be: %s, but get: %s',
283 filename, extension, ext)
286 # Check if the file base name is not empty
287 base_name = os.path.basename(filename)
289 logger.error('The file name %s has an empty base name!', filename)
292 # Check if a file with given filename exists
293 if not os.path.isfile(filename):
294 logger.error('The filename %s is not an existing regular file!', filename)
297 logger.debug('Filename %s exists and has an extension %s', filename, extension)
301 def isvalid_dirname(dirname):
303 Checks if a given directory name exists.
306 dirname - the name of the directory to check.
309 True if the given dirname is valid.
312 logger.debug('Check if the dirname %s exists', dirname)
314 # First do we even have something to check here
316 logger.error('A dirname argument cannot be empty! dirname=%s', dirname)
319 # Check if a file with given filename exists
320 if not os.path.isdir(dirname):
321 logger.error('The dirname %s is not an existing regular file!', dirname)
324 logger.debug('Directory %s exists', dirname)