diff --git a/src/cubitpy/conf.py b/src/cubitpy/conf.py index 1e42953..54e14ed 100644 --- a/src/cubitpy/conf.py +++ b/src/cubitpy/conf.py @@ -84,7 +84,6 @@ def __init__(self): "/tmp/cubitpy_{}".format(getpass.getuser()), # nosec "pid_{}".format(os.getpid()), ) - self.temp_log = os.path.join(self.temp_dir, "cubitpy.log") # Check if temp path exits, if not create it. os.makedirs(self.temp_dir, exist_ok=True) diff --git a/src/cubitpy/cubit_wrapper/cubit_wrapper_client.py b/src/cubitpy/cubit_wrapper/cubit_wrapper_client.py index 608feb1..b99b436 100644 --- a/src/cubitpy/cubit_wrapper/cubit_wrapper_client.py +++ b/src/cubitpy/cubit_wrapper/cubit_wrapper_client.py @@ -38,6 +38,7 @@ import os import sys +import tempfile # Cubit constants cubit_vertex = "cubitpy_vertex" @@ -51,23 +52,6 @@ parameters = {} -def out(string): - """The print version does over different interpreters, so this function - prints strings to an active console. - - Insert the path of your console to get the - right output. - To get the current path of your console type: tty - """ - - if "tty" in parameters.keys(): - out_console = parameters["tty"] - else: - out_console = "/dev/pts/18" - escaped_string = "{}".format(string).replace('"', '\\"') - os.system('echo "{}" > {}'.format(escaped_string, out_console)) # nosec - - def is_cubit_type(obj): """Check if the object is of a cubit base.""" if ( @@ -117,9 +101,8 @@ def channel_send(argument): cubit_objects = {} -# The first call are parameters needed in this script +# The first call are parameters needed in this script and to initialize cubit. parameters = channel.receive() -channel_send(None) if not isinstance(parameters, dict): raise TypeError( "The first item should be a dictionary. Got {}!\nparameters={}".format( @@ -132,32 +115,73 @@ def channel_send(argument): if path not in sys.path: sys.path.append(path) +# Import libraries needed if this script is running on a remote system. +# Also, create a temporary directory that is accessible by Cubit. +if parameters["is_remote"]: + import platform + import subprocess # nosec B404 + import time + + temp_dir = tempfile.TemporaryDirectory(prefix="cubitpy_temp_dir") + + +if sys.version_info[0] < 3: + # On non-Coreform Cubit versions (running on python2), we check the log file to get the + # messages and errors from Cubit. This can be removed once support for python2 is + # dropped, as the message handler is the cleaner solution. + _temp_dir = "/tmp/cubitpy_temp_log" # nosec + if not os.path.exists(_temp_dir): + os.makedirs(_temp_dir) + temp_log = os.path.join(_temp_dir, "cubitpy.log") + open(temp_log, "w").close() + parameters["init_arguments"].extend(["-log", temp_log]) + + +# Import and initialize the cubit python module import cubit -# The second call is the initialization call for cubit -# init = ['init', cubit_path, [args]] -init = channel.receive() -if not init[0] == "init": - raise ValueError("The second call must be init!") -if not len(init) == 2: - raise ValueError("Two arguments must be given to init!") -cubit.init(init[1]) +cubit.init(parameters["init_arguments"]) cubit_objects[id(cubit)] = cubit channel_send(object_to_id(cubit)) -if parameters["is_remote"]: - import platform - import subprocess # nosec B404 - import tempfile - import time +# Add a custom message handler to Cubit +if sys.version_info[0] < 3: - # On remote systems, create a temporary directory. - temp_dir = tempfile.TemporaryDirectory(prefix="cubitpy_temp_dir") + class MessageHandler: + """This class intercepts messages and errors from Cubit. + + This is done by checking the log file, which is not ideal but + the only option for non-Coreform Cubit versions running on + python2. + """ + + def __init__(self): + self.setup() + + def setup(self): + """Check if the log file is empty, if it is not, empty it.""" + if os.stat(temp_log).st_size != 0: + with open(temp_log, "w"): + pass + + def pop(self): + """Return the stored log messages.""" + + with open(temp_log, "r") as log_file: + log_text = log_file.read().strip() + if log_text == "": + return_value = [[], []] + else: + # On old cubit versions, we send all messages as warnings, as they are + # not directly related to the messages on newer cubit versions. + return_value = [[log_text], []] + self.setup() + return return_value -# Try to add a custom message handler to Cubit -try: + message_handler = MessageHandler() +else: class MessageHandler(cubit.CubitMessageHandler): """This class intercepts messages and errors from Cubit.""" @@ -182,14 +206,9 @@ def print_error(self, message): """Append the error to the list of errors.""" self.errors.append(message) - message_handler_cubit = MessageHandler() - message_handler_cubit.setup() - cubit.set_cubit_message_handler(message_handler_cubit) - - # Everything worked, so overwrite the message handler with the one linked to Cubit. - message_handler = message_handler_cubit -except Exception: - pass # nosec B110 + message_handler = MessageHandler() + message_handler.setup() + cubit.set_cubit_message_handler(message_handler) # Now start an endless loop (until None is sent) and perform the cubit functions diff --git a/src/cubitpy/cubit_wrapper/cubit_wrapper_host.py b/src/cubitpy/cubit_wrapper/cubit_wrapper_host.py index 297f062..d559afd 100644 --- a/src/cubitpy/cubit_wrapper/cubit_wrapper_host.py +++ b/src/cubitpy/cubit_wrapper/cubit_wrapper_host.py @@ -23,7 +23,6 @@ interpreter and the main python interpreter.""" import atexit -import os import warnings from pathlib import Path @@ -42,18 +41,9 @@ class CubitConnect(object): receive the output. """ - def __init__(self, *, cubit_args=None): + def __init__(self): """Initialize the connection between the client (cubit) python - interpreter and this one. Also load the cubit module in the remote - interpreter. - - Args - ---- - cubit_args: [str] - List of arguments to pass to cubit.init - interpreter: str - Python interpreter to be used for running cubit. - """ + interpreter and this one.""" # Set up the gateway to the client python interpreter if cupy.is_remote(): @@ -80,52 +70,23 @@ def __init__(self, *, cubit_args=None): self.channel = self.gw.remote_exec(client_code) # Arguments for cubit - if cubit_args is None: - arguments = [ - "cubit", - # "-log", # Write the log to a file - # "dev/null", - "-information", # Do not output information of cubit - "Off", - "-nojournal", # Do write a journal file - "-noecho", # Do not output commands used in cubit - ] - else: - arguments = ["cubit"] + cubit_args + init_arguments = [ + "cubit", + "-information", # Do not output information of cubit + "Off", + "-nojournal", # Do write a journal file + "-noecho", # Do not output commands used in cubit + ] # Parameters for initialization of the client interpreter. parameters = { "additional_sys_paths": [str(cubit_lib)], "is_remote": cupy.is_remote(), + "init_arguments": init_arguments, } - # In remote mode, configure the remote Python environment and send the client code - if cupy.is_remote(): - self.log_check = False - - # Local mode – run cubit on the local machine - else: - # Check if a log file was given in the cubit arguments - for arg in arguments: - if arg.startswith("-log="): - log_given = True - break - else: - log_given = False - - self.log_check = False - - if not log_given: - # Write the log to a temporary file and check the contents after each call to cubit - arguments.extend(["-log", cupy.temp_log]) - parameters["tty"] = cupy.temp_log - self.log_check = True - - # Send the parameters to the client interpreter - self.send_and_return(parameters) - # Initialize cubit in the client and create the linking object here - cubit_id = self.send_and_return(["init", arguments]) + cubit_id = self.send_and_return(parameters) if cubit_id is None: raise RuntimeError( "Could not initialize cubit in the client! " @@ -219,12 +180,6 @@ def serialize_item(item): else: return item - if self.log_check: - # Check if the log file is empty. If it is not, empty it. - if os.stat(cupy.temp_log).st_size != 0: - with open(cupy.temp_log, "w"): - pass - # Check if there are cubit objects in the arguments arguments = serialize_item(args) @@ -233,11 +188,6 @@ def serialize_item(item): [cubit_object.cubit_id, name, arguments] ) - if self.log_check: - # Print the content of the log file - with open(cupy.temp_log, "r") as log_file: - print(log_file.read(), end="") - # Check if the return value is a cubit object if cubit_item_to_id(cubit_return) is not None: return CubitObject(self, cubit_return)