コード例 #1
0
ファイル: objects.py プロジェクト: vandenberghinc/dev0s
 def run(self):
     self.log(f"Starting thread {self.id}.")
     self.__status__ = "running"
     response = None
     try:
         response = self.__run__()
     except AttributeError as e:
         if "has no attribute '" in str(e):
             missing = str(e).split("has no attribute '")[1].split("'")[0]
             if missing == "__run__":
                 raise Exceptions.InvalidUsage(
                     f"Thread [{self.id}] is missing the main [__run__] function."
                 )
             else:
                 raise AttributeError(str(e))
         else:
             raise AttributeError(str(e))
     if isinstance(response, ResponseObject):
         if response.success:
             self.send_crash(response=response)
         else:
             self.send_stop(response=response)
     else:
         self.send_stop(response=response)
     return self.send_stop(f"Thread [{self.id}] has finished running.")
コード例 #2
0
    def __init__(
        self,
        # the path to the directory (str) (#1)
        path=None,
        # root permission required.
        sudo=False,
    ):

        # docs.
        DOCS = {
            "module": "dev0s.database.Database",
            "initialized": False,
            "description": [],
            "chapter": "Database",
        }

        # traceback.
        Traceback.__init__(self, traceback="Database")

        # checks.
        if path == None:
            raise Exceptions.InvalidUsage(self.__traceback__() +
                                          " Define parameter [path].")

        # args.
        self.path = gfp.clean(path)
        self.sudo = sudo

        # sys args.
        self.__cache__ = {}

        # attributes.
        self.dir = self.directory = Directory(self.path)

        # checks.
        if not self.dir.fp.exists(sudo=sudo):
            if self.sudo:
                _response_.log(
                    f"&ORANGE&Root permission&END& required to create database [{self.path}]."
                )
            Files.create(
                str(self.path),
                sudo=self.sudo,
                directory=True,
                permission=700,
                owner=defaults.vars.user,
                group=defaults.vars.group,
            )

        # copy objects.
        self.fp = self.file_path = self.dir.fp
        self.ownership = self.fp.ownership
        self.permission = self.fp.permission

        # copy functions.
        self.join = self.dir.join
        self.subpath = self.dir.subpath
        self.fullpath = self.dir.fullpath
コード例 #3
0
 def assign(self, dictionary):
     if isinstance(dictionary, (dict, Dictionary)):
         for key, value in _response_.serialize(dictionary).items():
             self[key] = value
     elif isinstance(dictionary, (tuple, list, Array)):
         for key, value in dictionary:
             self[key] = _response_.serialize(value)
     else:
         raise Exceptions.InvalidUsage(
             "The dictionary parameter must be a dict or tuple.")
     return self
コード例 #4
0
    def check(
        self,
        # the parameters (dict) (#1).
        parameters={"parameter": None},
        # the recognizer value for when the parameters are supposed to be empty.
        default=None,
        # the traceback id.
        traceback=None,
    ):

        # single.
        if isinstance(parameters, tuple):
            name, parameter = parameters
            if parameter == default:
                if traceback != None:
                    return _response_.error(
                        f"{traceback}: Define parameter [{name}].")
                else:
                    return _response_.error(f"Define parameter [{name}].")
            if ":" in name:
                name, formats = name.split(":")
                while True:
                    if " " in formats: formats = formats.replace(" ", "")
                    else: break
                formats = formats.split(",")
                param_format = Formats.get(parameter, serialize=True)
                if param_format not in formats:
                    return _response_.error(
                        f"Incorrect parameter [{name}:{param_format}] format, correct format(s): {Array(path=False, array=formats).string(joiner=', ')}."
                    )
            return _response_.success(
                f"Succesfully checked parameter [{name}].")

        # recursive.
        elif isinstance(parameters, (dict, Dictionary, ResponseObject)):
            for id, value in parameters.items():
                response = self.check(parameters=(id, value),
                                      default=default,
                                      traceback=traceback)
                if response["error"] != None: return response
            return _response_.success(
                f"Succesfully checked {len(parameters)} parameter(s).")
        # invalid.
        else:
            raise Exceptions.InstanceError(
                f"Parameter [parameters] requires to be a [dict, Dictionary, tuple] not [{parameters.__class__.__name__}]."
            )
コード例 #5
0
 def __serialize_format__(self, format):
     format = str(format).lower()
     if format in ["bytes", "Bytes", bytes, Bytes]: format = "bytes"
     elif format in ["bool", "Boolean", bool, Boolean]: format = "bool"
     elif format in ["string", "str", "String", str, String]: format = "str"
     elif format in ["int", "integer", int]: format = "int"
     elif format in ["float", float, Integer]: format = "float"
     elif format in ["list", "array", "Array", list, Array]: format = "list"
     elif format in ["dict", "dictionary", "Dictionary", dict, Dictionary]:
         format = "dict"
     if format not in [
             "bytes", "bool", "str", "int", "float", "dict", "list"
     ]:
         raise Exceptions.InvalidUsage(
             f"{self.__traceback__()}: Format [{format}] is not a valid option, options: [bool, str, int, float, dict, list]."
         )
     return format
コード例 #6
0
ファイル: objects.py プロジェクト: vandenberghinc/dev0s
 def unpack(
     self,
     # the key / keys / defaults parameter (#1).
     # str instance:
     #   unpack the str key
     # list instance:
     #   unpack all keys in the list.
     # dict instance:
     #   unpack all keys from the dict & when not present return the key's value as default.
     keys,
 ):
     defaults_ = {}
     if isinstance(keys, (dict, Files.Dictionary)):
         if isinstance(keys, dict):
             defaults_ = dict(keys)
             keys = list(keys.keys())
         else:
             defaults_ = keys.dict()
             keys = keys.keys()
     elif isinstance(keys, str):
         keys = [keys]
     unpacked = []
     for key in keys:
         value, set = None, True
         try:
             value = self[key]
         except KeyError:
             try:
                 value = defaults_[key]
             except KeyError:
                 set = False
         if not set:
             raise Exceptions.UnpackError(
                 f"Dictionary does not contain attribute [{key}].")
         unpacked.append(value)
     if len(unpacked) == 1:
         return unpacked[0]
     else:
         return unpacked
コード例 #7
0
 def __le__(self, response):
     if not isinstance(response, self.__class__):
         raise Exceptions.InstanceError(
             f"Can not compare object {self.__class__} & {response.__class__}."
         )
     return len(self) <= len(response)
コード例 #8
0
    def __init__(
        self,
        #
        # Should be initialized with response.success or response.error.
        #
        # the response attributes (dict or dict in str format).
        attributes={
            "success": False,
            "message": None,
            "error": None,
        },
    ):
        # docs.
        DOCS = {
            "module": "ResponseObject",
            "initialized": False,
            "description": [],
            "chapter": "Response",
        }

        # serialize attributes to dict.
        serialized = _response_.serialize(attributes)
        if not isinstance(serialized, (dict, Dictionary)):
            raise Exceptions.InvalidUsage(
                f"<ResponseObject.attributes>: parameter [attributes] must be a [dict, dict in str format], not [{attributes.__class__.__name__}]."
            )
        self.assign(serialized)

        # catch error so you can also init custom ResponseObjects.
        try:

            # clean message & error.
            if self.message != None:
                self.message = String(self.message).capitalized_word()
            if self.error != None:
                self.error = String(self.error).capitalized_word()
            while True:
                if self.message != None and len(
                        self.message) >= 1 and self.message[len(self.message) -
                                                            1] in [
                                                                " ", ".", ","
                                                            ]:
                    self.message = self.message[:-1]
                elif self.error != None and len(
                        self.error) >= 1 and self.error[len(self.error) -
                                                        1] in [" ", ".", ","]:
                    self.error = self.error[:-1]
                elif self.error != None and len(self.error) >= len(
                        "Error: ") and self.error[:len("Error: ")] in [
                            "Error: "
                        ]:
                    self.error = String(
                        self.error[len("Error: "):]).capitalized_word()
                elif self.error != None and len(
                        self.error) >= len("..") and String(
                            self.error).last("..") in [".."]:
                    self.error = str(String(self.error).remove_last("."))
                else:
                    break

            # add dot.
            if self.message != None and len(
                    self.message) > 0 and self.message[len(self.message) -
                                                       1] not in ["!", "?"]:
                self.message += "."
            if self.error != None and len(
                    self.error) > 0 and self.error[len(self.error) -
                                                   1] not in ["!", "?"]:
                self.error += "."

            # check error passed as success response. & reversed
            if self.message != None and len(self.message) >= len(
                    "Failed") and self.message[:len("Failed")] == "Failed":
                #_traceback_.print_exc()
                raise ValueError(
                    "A success response may not start with (failed ...). You most likely called an response.success return while you meant response.error."
                )
            if self.error != None and len(self.error) >= len(
                    "Success") and self.error[:len("Success")] == "Success":
                #_traceback_.print_exc()
                raise ValueError(
                    "An error response may not start with (success ...). You most likely called an response.error return while you meant response.success."
                )
        except AttributeError:
            a = 1
コード例 #9
0
    def get(
        self,
        # the django request (1).
        request=None,
        # the identifiers (#2).
        #	str instance: return the parameters value.
        #	list instance: return a parameters object & return an error response when a parameter is undefined.
        #	dict instance: return a parameters object & return the parameter's value from the dict as a default when undefined.
        parameters=[],
        # traceback id.
        traceback=None,
    ):
        if request == None:
            raise Exceptions.InvalidUsage(
                "<dev0s.response.paramters.get>: Define parameter: [request].")

        # single parameter.
        if isinstance(parameters, (str, String)):

            # get params & format.
            parameters = str(parameters)
            format = None
            if ":" in parameters:
                parameters, format = parameters.split(":")
                while True:
                    if " " in format: format = format.replace(" ", "")
                    else: break

            # get variable.
            if request.method in ["post", "POST"]:
                variable = request.POST.get(parameters)
            else:
                variable = request.GET.get(parameters)
            if variable in ["", None]:
                if traceback != None:
                    return variable, _response_.error(
                        f"{traceback}: Define parameter: [{parameters}].")
                else:
                    return variable, _response_.error(
                        f"Define parameter: [{parameters}].")

            # handle format.
            if format != None:
                format_options = format.split(",")
                found = False
                for format in format_options:
                    if format.lower() in ["str", "string"]:
                        try:
                            variable = str(variable)
                            found = True
                        except:
                            a = 1
                    elif format.lower() in ["int", "integer"]:
                        try:
                            variable = int(variable)
                            found = True
                        except:
                            a = 1
                    elif format.lower() in ["bool", "boolean"]:
                        try:
                            if variable in ["true", "True", "TRUE", True]:
                                variable = True
                            else:
                                variable = False
                            found = True
                        except:
                            a = 1
                    elif format.lower() in ["float", "double"]:
                        try:
                            variable = float(variable)
                            found = True
                        except:
                            a = 1
                    elif format.lower() in [
                            "array", "list", "dict", "dictionary"
                    ]:
                        try:
                            variable = ast.literal_eval(variable)
                            found = True
                        except:
                            try:
                                variable = json.loads(variable)
                                found = True
                            except:
                                a = 1
                    else:
                        raise Exceptions.InvalidUsage(
                            f"Selected format [{format}] is not a valid format option."
                        )
                    if found:
                        break
                if not found:
                    return variable, _response_.error(
                        f"Unable to parse excepted format [{Array(format_options).string(joiner=', ')}] from parameter [{parameters}:{variable}]."
                    )

            # normalize.
            if variable == "None": variable = None

            # handler.
            return variable, _response_.success(
                f"Succesfully retrieved request parameter [{parameters}].", {
                    "key": parameters,
                    "value": variable,
                })

        # list recursive.
        elif isinstance(parameters, (list, Array)):
            optional = False
            params = ResponseObject()
            for param in parameters:
                param_value, response = self.get(request,
                                                 param,
                                                 traceback=traceback)
                param = param.split(":")[0]
                if response["error"] != None:
                    if optional:
                        params[param] = None
                    else:
                        return params, response
                else:
                    params[param] = param_value
            if optional:
                for key in parameters:
                    try:
                        params[key]
                    except:
                        params[key] = None
            return params, _response_.success(
                f"Succesfully retrieved {len(params)} request parameter(s).")

        # dict recursive.
        elif isinstance(parameters, (dict, Dictionary, ResponseObject)):
            if isinstance(parameters, (ResponseObject)):
                parameters = parameters.clean()
            optional = True
            params = ResponseObject()
            for param, default in parameters.items():
                param_value, response = self.get(request,
                                                 param,
                                                 traceback=traceback)
                param = param.split(":")[0]
                if response["error"] != None:
                    if optional:
                        params[param] = default
                    else:
                        return params, response
                else:
                    params[param] = param_value
            if optional:
                for key, default in parameters.items():
                    try:
                        params[key]
                    except:
                        params[key] = default
            return params, _response_.success(
                f"Succesfully retrieved {len(params)} request parameter(s).")

        # invalid.
        else:
            raise Exceptions.InvalidUsage(
                f"The parameters parameter must be [str, String, list, Array, dict, Dictionary] not [{dictionary.__class__.__name__}]."
            )
コード例 #10
0
    def log(
        self,
        # option 1:
        # the message (#1 param).
        message=None,
        # option 2:
        # the error.
        error=None,
        # option 3:
        # the response dict (leave message None to use).
        response={},
        # print the response as json.
        json=False,
        # optionals:
        # the active log level.
        log_level=0,
        # the required log level for when printed to console (leave None to use self.log_level).
        required_log_level=None,
        # save to log file.
        save=False,
        # save errors always (for options 2 & 3 only).
        save_errors=None,
        # the log mode (leave None for default).
        mode=None,
    ):
        if mode != None:
            mode = str(mode).lower().replace("-", "").replace("_", "")
        if mode not in [None, "warning", "alert"]:
            raise Exceptions.InvalidUsage(
                f"{self.__traceback__(function='log', parameter='mode')}: Selected an invalid mode [{mode}], options: [None, warning, alert]."
            )

        def fill_message(msg, error=False):
            if mode == None:
                if error:
                    msg = f"Error: {msg}"
                else:
                    msg = msg
            elif mode == "warning":
                msg = f"&RED&Warning&END&: {msg}"
            elif mode == "alert":
                msg = f"&ORANGE&Alert&END&: {msg}"
            return msg
            #

        msg, _error_ = None, False
        if [message, error, response] == [None, None, {}]:
            raise Exceptions.InvalidUsage(
                f"{self.__traceback__(function='log')}: Define either parameter [message:str], [error:str] or [response:dict]."
            )
        if response != {}:
            if response["error"] != None:
                _error_ = True
                msg = f"Error: {response['error']}"
            else:
                if response.__class__.__name__ in ["Output"]:
                    msg = response.output
                else:
                    msg = response["message"]
        elif isinstance(error, (str, String)):
            msg = fill_message(error, error=True)
        else:
            msg = fill_message(message, error=False)
        if required_log_level == None: required_log_level = self.log_level
        try:
            required_log_level = int(required_log_level)
        except:
            required_log_level = 0
        try:
            comparison = log_level != None and log_level >= required_log_level
        except TypeError as e:
            if "not supported between instances of 'dict' and 'int'" in f"{e}":
                raise TypeError(
                    f"You most likely returned a response.error when you meant a response.success, error: {e}"
                )
            else:
                raise TypeError(e)
        if comparison:
            #print(f"{Date().seconds_timestamp} - {color.fill(msg)}")
            if json:
                if response != {}:
                    print(response.json())
                elif error != None:
                    print(self.error(error))
                else:
                    print(self.success(message))
            else:
                if self.log_timestamps:
                    print(f"{Date().seconds_timestamp} - {color.fill(msg)}")
                else:
                    print(f"{color.fill(msg)}")
        if save:
            self.log_to_file(msg)
        elif save_errors and _error_:
            self.log_to_file(msg)
コード例 #11
0
ファイル: execute.py プロジェクト: vandenberghinc/dev0s
    def expect(
        self,
        # the expected data parameter (#1).
        #	str instantce: expect a single identifier.
        #	list instance: expect one of the provided identifiers & return the found one if success.
        expect=["Password*"],
        # the optional data to send (#2).
        #	none instance: do not send anything.
        #	str instance: the data to send.
        #	list/tuple instance: send value of index from expected expect (required expect to be a list, Array & the indexes of [expect, send] be match).
        send=None,
        # the timeout (float).
        timeout=1.0,
    ):
        # check none timeout.
        if timeout == None: timeout = 1.0

        # single expect.
        if isinstance(expect, str):
            if isinstance(send, (list, Array)):
                raise Exceptions.InvalidUsage(
                    f"{self.__traceback__(function='expect', parameter='send')}: parameter [send] requires to be be a [str, String] when parameter [expect] is a [{expect.__class__.__name__}], not [{send.__class__.__name__}]."
                )
            """ add to lines to output (before) (adds nothing when empty) (do not use self.expecting before adding the output). """
            response = self.read(wait=False)
            if not response.success: return response
            """ check expect & send if provided. """
            c = 1
            try:
                #if self.async_:
                #	g = yield from self.child.expect(expect, timeout=timeout, async_=True)
                #	r = next(g)
                #else:
                r = self.child.expect(expect, timeout=timeout)
                if not isinstance(r, (int, Integer, float)):
                    return _response_.error(
                        f"Expected [{expect}] is not the child's expected input (#873465)."
                    )
                c = 2
                if self.log_level >= 8: print(f"Found expected: {expect}")
                if send != None:
                    if self.log_level >= 8:
                        print(f"Attempting to send: {send}")
                    #if self.async_:
                    #	g = yield from self.child.sendline(str(send), async_=True)
                    #	r = next(g)
                    #else:
                    r = self.child.sendline(str(send))
                    self.__secrets__.append(str(send))
                    if self.log_level >= 8:
                        print(f"Succesfully sended: {send}")
            except pexpect.exceptions.TIMEOUT:
                if c == 1:
                    return _response_.error(
                        f"Expected [{expect}] is not the child's expected input, error: Timeout (during epxecting)."
                    )
                else:
                    return _response_.error(
                        f"Failed to send expected [{expect}], error: Timeout (during sending input)."
                    )
            except pexpect.exceptions.EOF:
                if c == 1:
                    return _response_.error(
                        f"Expected [{expect}] is not the child's expected input, error: End of file (during epxecting)."
                    )
                else:
                    return _response_.error(
                        f"Failed to send expected [{expect}], error: End of file (during sending input)."
                    )
            except Exception as e:
                if c == 1:
                    return _response_.error(
                        f"Expected [{expect}] is not the child's expected input, error: {e}."
                    )
                else:
                    return _response_.error(
                        f"Failed to send expected [{expect}], error: {e}.")
            """ add to lines to output (after) (adds nothing when empty) (do not use self.expecting before adding the output). """
            response = self.read(wait=False)
            if not response.success: return response

            # handler.
            if send != None:
                return _response_.success(
                    f"Successfully send expected input ({expect}).")
            else:
                return _response_.success(
                    f"Successfully retrieved expected input ({expect}).")

        # list expect.
        elif isinstance(expect, (list, Array)):
            index = 0
            for _expect_ in expect:
                if isinstance(send, (list, Array)):
                    try:
                        _send_ = str(send[index])
                    except:
                        raise Exceptions.InvalidUsage(
                            f"{self.__traceback__(function='expect', parameter='send')}: parameter [send] and parameter [expect] do not have the same indexes."
                        )
                else:
                    _send_ = str(send)
                if self.log_level >= 8:
                    print(f"Checking optional expect: {_expect_}")
                response = self.expect(expect=_expect_,
                                       timeout=timeout,
                                       send=_send_)
                if not response.success and "is not the child's expected input" not in response.error:
                    return response
                elif response.success:
                    return _response_.success(
                        f"Successfully {Boolean(send).string(true='send', false='retrieved')} the expected input(s).",
                        {
                            "expected": _expect_,
                            "index": index,
                        })
                index += 1
            return _response_.error(
                f"None of the specified input was expected.")

        # invalid usage.
        else:
            raise Exceptions.InvalidUsage(
                f"{self.__traceback__(function='expect', parameter='expect')}: parameter [expect] requires to be be a [Dictionary], not [{config.__class__.__name__}]."
            )
コード例 #12
0
ファイル: execute.py プロジェクト: vandenberghinc/dev0s
def execute(
    # Notes:
    #   returns a dev0s.code.OutputObject object (very similair to ResponseObject).
    #
    # Mode:
    #   option 1:
    #     the command in str format, the command is saved to a script & then executed).
    command="ls .",
    #     joiner for when command is in list format.
    joiner=" ",
    #   option 2: the path to script.
    path=None,
    #
    # Executement:
    #   the executable.
    executable="sh",
    #   the arguments passed to the (saved) script.
    arguments=[],
    #
    # Options:
    #   asynchronous process.
    async_=False,
    #	await asynchronous child (sync process always awaits).
    wait=False,
    #	kill process when finished (async that is not awaited is never killed).
    kill=True,
    #   the subprocess shell parameter.
    shell=False,
    #   serialize output to dict (expect literal dictionary / json output).
    serialize=False,
    #
    # Input (sync only):
    #   send input to the command.
    #	  undefined: send no input & automatically await the process since input is always sync.
    #	  dict instance: selects "and" mode ; send expected inputs and their value & return error when one of them is missing.
    #	  list[dict] instance: send all dictionaries in the list (default dict behaviour so one of the keys in each dict is expected).
    input=None,
    #   the input timeout (float) (list with floats by index from input)
    timeout=1.0,
    #   do not throw an error when the input is missing or not expected when optional is disabled (bool).
    optional=False,
    #
    # Logging.
    # the loader (str, Loader).
    loader=None,
    # stop the loader at the end of the request (bool).
    stop_loader=True,
    #   the log level.
    log_level=defaults.options.log_level,
    #
    # System functions.
    #   add additional attributes to the spawn object.
    __spawn_attributes__={},
    #
):
    # docs.
    DOCS = {
        "module": "dev0s.code.execute",
        "initialized": False,
        "description": [],
        "chapter": "Code",
    }

    # checks,
    if input != None and not isinstance(input,
                                        (dict, Dictionary, list, Array)):
        raise Exceptions.InvalidUsage(
            f"<dev0s.code.execute>: Parameter [input] requires to be be a [dict, Dictionary, list, Array], not [{iput.__class__.__name__}]."
        )

    # loader.
    if isinstance(loader, (str, String)) and 2 > log_level >= 0:
        loader = console.Loader(loader)

    # vars.
    delete = False
    if path == None:
        delete = True
        path = f"/tmp/tmp_script_{String('').generate()}"
        if isinstance(command, list):
            command = Array(array=command).string(joiner=joiner)
        Files.save(path, command)
        response_str = f"command ({command})"
    else:
        response_str = f"script ({path})"

    # execute with input.
    #if isinstance(input, (dict, Dictionary, list, Array)):

    # checks.
    #if async_:
    #	raise Exceptions.InvalidUsage(f"<dev0s.code.execute>: Parameters [input] & [async] are not compatible, select either one.")

    # spawn.
    l = []
    for i in arguments:
        l.append(f'"{i}"')
    arguments = Array(l).string(joiner=' ')
    if log_level >= 8: print(f"Spawn: [ $ {executable} {path} {arguments}]", )
    spawn = Spawn(
        command=f"{executable} {path} {arguments}",
        #async_=async_, # does not work.
        response_str=response_str,
        log_level=log_level,
        attributes=__spawn_attributes__,
    )
    spawn.echo = False
    if isinstance(timeout, (int, float, Integer)):
        spawn.timeout = int(timeout)

    # start.
    response = spawn.start()
    if not response.success:
        if stop_loader and isinstance(loader, console.Loader):
            loader.stop(success=False)
        return OutputObject(
            error=f"Failed to start {response_str}, error: {response.error}",
            log_level=log_level)

    # check crashed
    response = spawn.crashed()
    if not response.success:
        if stop_loader and isinstance(loader, console.Loader):
            loader.stop(success=False)
        return OutputObject(error=response.error, log_level=log_level)

    # has already exited.
    elif spawn.exit_status in [0]:

        # get output.
        response = spawn.wait(timeout=1.0)
        if not response.success:
            if stop_loader and isinstance(loader, console.Loader):
                loader.stop(success=False)
            return OutputObject(error=response.error,
                                log_level=log_level)  # exit status.
        output = response.output

        #

    # proceed if already finished.
    elif spawn.exit_status not in [0]:

        # await.
        #success = False
        #for i in range(10):
        #	if spawn.running:
        #		success = True
        #		break
        #	time.sleep(1)
        #if not success:
        #	if stop_loader and isinstance(loader, console.Loader): loader.stop(success=False)
        #	return OutputObject(error=f"Unable to start {response_str}.", log_level=log_level)

        # str input.
        if isinstance(input, (list, Array)):
            if len(input) > 0:
                str_input = Array(list(input[0].keys())).string(joiner=", ")
            else:
                str_input = Array(input).string(joiner=", ")
        elif isinstance(input, (dict, Dictionary)):
            str_input = Array(list(input.keys())).string(joiner=", ")
        else:
            str_input = f"[{input}]"

        # send optional input.
        error_end_of_file = None
        if not async_ and isinstance(
                input, (list, Array, dict, Dictionary)) and len(input) > 0:

            # expect one of the keys in the dictionary.
            def process_dict_input(dictionary):

                # vars.
                expect = list(dictionary.keys())
                send = list(dictionary.values())

                # expect .
                if log_level >= 8:
                    print(f"Expecting one of the following inputs: {expect}.")
                response = spawn.expect(expect=expect,
                                        send=send,
                                        timeout=timeout)
                if not response.success:
                    if "None of the specified inputs were expected." in response.error:
                        if optional:
                            return _response_.error(
                                f"Unable to find the expected input but still success since it is optional."
                            )
                        else:
                            return _response_.error(
                                f"Specified input [{Array(expect).string(joiner=', ')}] was not expected."
                            )
                    else:
                        return response
                if log_level >= 8:
                    print("Send response message:", response.message)

                # success.
                return _response_.success("Success.")

            """ check expecting. """
            expecting = True
            if not spawn.expecting:
                expecting = False
                if not optional:
                    if stop_loader and isinstance(loader, console.Loader):
                        loader.stop(success=False)
                    if log_level >= 3:
                        return OutputObject(
                            error=
                            f"Failed to send expected input {str_input} to {response_str}, child is not expecting any input [{spawn.child}].",
                            log_level=log_level)
                    else:
                        return OutputObject(
                            error=
                            f"Failed to send expected input {str_input} to {response_str}, child is not expecting any input.",
                            log_level=log_level)

            # limit not expecting by optional.
            if expecting:

                # send all dicts in the list (list instance).
                error_end_of_file = False
                if isinstance(input, (list, Array)):
                    for _input_ in input:
                        response = process_dict_input(_input_)
                        if not response.success:
                            if "End of file" in response.error:
                                error_end_of_file = True
                            else:
                                # str input.
                                if isinstance(_input_, (list, Array)):
                                    str_input = Array(_input_).string(
                                        joiner=", ")
                                elif isinstance(_input_, (dict, Dictionary)):
                                    str_input = Array(list(
                                        _input_.keys())).string(joiner=", ")
                                else:
                                    str_input = f"[{_input_}]"
                                if optional:
                                    break
                                else:
                                    if stop_loader and isinstance(
                                            loader, console.Loader):
                                        loader.stop(success=False)
                                    return OutputObject(
                                        error=
                                        f"Failed to send one of the expected input(s) {str_input}, error: {response.error}",
                                        log_level=log_level)

                # send one of the keys (dict instance).
                elif isinstance(input, (dict, Dictionary)):
                    response = process_dict_input(input)
                    if not response.success:
                        if "End of file" in response.error:
                            error_end_of_file = True
                        elif not optional:
                            if stop_loader and isinstance(
                                    loader, console.Loader):
                                loader.stop(success=False)
                            return OutputObject(
                                error=
                                f"Failed to send one of the expected input(s) {str_input}, error: {response.error}",
                                log_level=log_level)
                """ check no input left (does not work properly).
				if not error_end_of_file and spawn.expecting:
					try: after = spawn.child.after.decode()
					except : after = spawn.child.after
					if stop_loader and isinstance(loader, console.Loader): loader.stop(success=False)
					return OutputObject(error=f"Failed to execute {response_str}, still expecting: [{after}].", log_level=log_level)
				"""

        # do not get or kill when async.
        output = None
        if not async_:

            # check crashed.
            response = spawn.crashed()
            if not response.success:
                if stop_loader and isinstance(loader, console.Loader):
                    loader.stop(success=False)
                return OutputObject(error=response.error, log_level=log_level)

            # always await sync.
            response = spawn.wait()
            if not response.success:
                if stop_loader and isinstance(loader, console.Loader):
                    loader.stop(success=False)
                return OutputObject(error=response.error, log_level=log_level)
            output = response.output
            if error_end_of_file != None and error_end_of_file:
                if stop_loader and isinstance(loader, console.Loader):
                    loader.stop(success=False)
                if log_level >= 3:
                    return OutputObject(
                        error=
                        f"Failed to send expected input {str_input} to {response_str} (#234343) (output: {output}) (child: {spawn.child}).",
                        log_level=log_level)
                else:
                    return OutputObject(
                        error=
                        f"Failed to send expected input {str_input} to {response_str} (#234343) (output: {output}).",
                        log_level=log_level)

            # check kill.
            if kill and spawn.running:
                if log_level >= 8: print(f"Killing process {response_str}.")
                response = spawn.kill()
                if not response.success:
                    if stop_loader and isinstance(loader, console.Loader):
                        loader.stop(success=False)
                    return OutputObject(
                        error=
                        f"Failed to kill {response_str}, error: {response.error}",
                        log_level=log_level)

        # async.
        elif async_:

            # check exit status.
            response = spawn.read(wait=False)
            if not response.success:
                if not response.success:
                    if stop_loader and isinstance(loader, console.Loader):
                        loader.stop(success=False)
                    return OutputObject(
                        error=
                        f"Failed to retrieve output from spawn {response_str}, error: {response.error}",
                        log_level=log_level)
            if spawn.child.exitstatus not in [0, None]:
                if stop_loader and isinstance(loader, console.Loader):
                    loader.stop(success=False)
                return OutputObject(
                    error=
                    f"{response_str} returned exit status: [{spawn.child.exitstatus}] (output: {self.read(wait=False, __safe__=True).output}).",
                    log_level=log_level)

            # await async.
            if wait:

                # await.
                response = spawn.wait()
                if not response.success:
                    if stop_loader and isinstance(loader, console.Loader):
                        loader.stop(success=False)
                    return OutputObject(error=response.error,
                                        log_level=log_level)  # exit status.
                output = response.output

                if spawn.child.exitstatus not in [0, None]:
                    if stop_loader and isinstance(loader, console.Loader):
                        loader.stop(success=False)
                    return OutputObject(
                        error=
                        f"{response_str} returned exit status: [{spawn.child.exitstatus}] (output: {self.read(wait=False, __safe__=True).output}).",
                        log_level=log_level)

                # check kill.
                if kill and spawn.running:
                    if log_level >= 8:
                        print(f"Killing process {response_str}.")
                    response = spawn.kill()
                    if not response.success:
                        if stop_loader and isinstance(loader, console.Loader):
                            loader.stop(success=False)
                        return OutputObject(
                            error=
                            f"Failed to kill {response_str}, error: {response.error}",
                            log_level=log_level)

    # handler.
    if delete: Files.delete(path)
    if serialize:
        try:
            response = _response_.ResponseObject(output)
        except Exception as e:
            if loader != None: loader.stop(success=False)
            if stop_loader and isinstance(loader, console.Loader):
                loader.stop(success=False)
            return OutputObject(
                error=f"Failed to serialize (output: {output}).",
                log_level=log_level)
        if not response.success:
            if stop_loader and isinstance(loader, console.Loader):
                loader.stop(success=False)
            return OutputObject(
                error=
                f"Encoutered an error in the serialized response, error: {response.error}",
                log_level=log_level)
    if stop_loader and isinstance(loader, console.Loader): loader.stop()
    return OutputObject(message=f"Succesfully executed {response_str}.",
                        log_level=log_level,
                        attributes={
                            "output": output,
                            "process": spawn,
                            "pid": spawn.child.pid,
                            "running": spawn.running,
                            "exit_status": spawn.exit_status,
                        })
    """
コード例 #13
0
ファイル: env.py プロジェクト: vandenberghinc/dev0s
	def export(self, 
		# the environment to export (dict).
		env=None, 
		# the export path (str) or paths (list).
		# the paths must have .json / .sh extension or be named 'json' / 'bash' when parameter [format] is undefined.
		export=None,
		# the export format (str) (leave None to be detected by parameter [export]).
		format=None,
	):
		if env == None: return _response_.error("Define parameter: env.")
		dictionary = {}
		if isinstance(env, (dict, Dictionary)):
			dictionary = env
		else: return _response_.error(f"Invalid usage, env requires to be a [str, String, FilePath, dict, Dictionary], not [{env.__class__.__name__}].")
		for key,value in dictionary.items():
			os.environ[str(key)] = str(value)
		if export != None:
			if isinstance(export, (str,String,FilePath)):
				exports = [str(export)]
			elif not isinstance(export, (list, Array)):
				raise Exceptions.InvalidUsage(f"<dev0s.system.env>: Parameter export requires to be a [str, list, FilePath], not [{export.__class__.__name__}].")
			else:
				exports = export
			c = 0
			for export in exports:
				if isinstance(format, (list, Array)):
					try:
						l_format = format[c]
					except:
						raise Exceptions.InvalidUsage(f"<dev0s.system.env>: Parameter format [list] does not contain index [{c}] for export [{export}].")
				else:
					l_format = format
				if l_format == "json" or ".json" in export or gfp.name(export) == "json":
					format = "json"
					try:
						exported = Files.load(export, format="json")
					except FileNotFoundError:
						exported = {}
				elif l_format == "bash" or ".sh" in export or gfp.name(export) == "bash":
					format = "bash"
					try:
						exported = Files.load(export, format="str")
					except FileNotFoundError:
						exported = ""
					while True:
						if "\n\n" in exported: exported = exported.replace("\n\n","\n")
						elif len(exported) > 0 and String(exported).last("\n") == "\n": exported = str(String(exported).remove_last("\n"))
						else: break
				else:
					raise Exceptions.InvalidUsage(f"Export file [{export}] must contain an .json / .sh extension or must be named 'bash' / 'json'.")
				for key,value in dictionary.items():
					if format == "json":
						exported[str(key)] = value
					elif format == "bash":
						if f'export {key.upper()}="' in exported:
							l = ""
							for line in exported.split("\n"):
								if f'export {key.upper()}="' in line:
									l += f'export {key.upper()}="{value}"\n'
								else:
									l += line+"\n"
							exported = l
						else:
							exported += '\n'+f'export {key.upper()}="{value}"\n'
				if format == "json":
					Files.save(export, exported, format="json")
				elif format == "bash":
					while True:
						if "\n\n" in exported: exported = exported.replace("\n\n","\n")
						elif len(exported) > 0 and String(exported).last("\n") == "\n": exported = str(String(exported).remove_last("\n"))
						else: break
					Files.save(export, exported, format="str")
				c += 1
		return _response_.success(f"Successfully exported {len(dictionary)} env variables.")