ScriptCollection 4.0.51__py3-none-any.whl → 4.0.52__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,108 @@
1
+ from subprocess import Popen
2
+ from .GeneralUtilities import GeneralUtilities
3
+ from .ProgramRunnerBase import ProgramRunnerBase
4
+ from .ScriptCollectionCore import ScriptCollectionCore
5
+
6
+
7
+ class SudoPopenReader:
8
+ content: bytes = None
9
+
10
+ def __init__(self, content: bytes):
11
+ self.content = content
12
+
13
+ def readable(self) -> bool:
14
+ return True
15
+
16
+ def read(self) -> bytes:
17
+ return self.content
18
+
19
+
20
+ class SudoPopen:
21
+ returncode: int = None
22
+ stdout_str: str = None
23
+ stderr_str: str = None
24
+ pid: int = None
25
+ stdout: bytes = None
26
+ stderr: bytes = None
27
+
28
+ def __init__(self, exitcode: int, stdout: str, stderr: str, pid: int):
29
+ self.returncode: int = exitcode
30
+ self.stdout_str: str = stdout
31
+ self.stdout = str.encode(self.stdout_str)
32
+ self.stderr_str: str = stderr
33
+ self.stderr = str.encode(self.stderr_str)
34
+ self.pid = pid
35
+
36
+ def communicate(self):
37
+ return (self.stdout, self.stderr)
38
+
39
+ def wait(self):
40
+ return self.returncode
41
+
42
+ def poll(self) -> object:
43
+ return self.returncode
44
+
45
+ def __enter__(self):
46
+ return self
47
+
48
+ def __exit__(self, exc_type, exc_value, traceback):
49
+ pass
50
+
51
+
52
+ class ProgramRunnerSudo(ProgramRunnerBase):
53
+ __sc: ScriptCollectionCore
54
+ __password: str
55
+
56
+ @GeneralUtilities.check_arguments
57
+ def __init__(self,user_password:str):
58
+ GeneralUtilities.assert_condition(GeneralUtilities.current_system_is_linux(), "SudoRunner can only be only executed on Linux.")
59
+ self.__sc = ScriptCollectionCore()
60
+ self.__password = user_password
61
+
62
+ @GeneralUtilities.check_arguments
63
+ def will_be_executed_locally(self) -> bool:
64
+ return True
65
+
66
+ @GeneralUtilities.check_arguments
67
+ def run_program_internal(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None) -> tuple[int, str, str, int]:
68
+ argument = program+" " + ' '.join(GeneralUtilities.args_array_surround_with_quotes_if_required(arguments_as_array))
69
+ argument = f"echo {self.__password} | sudo -k -S {argument}" # TODO maybe add "exit" somewhere before argument or before sudo to correctly return the exit-code"
70
+ result = self.__sc.run_program_argsasarray("sh", ["-c", argument], working_directory)
71
+ return result
72
+
73
+ @GeneralUtilities.check_arguments
74
+ def run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> Popen:
75
+ if interactive:
76
+ raise ValueError("Interactive execution is not supported in Sudo-runner")
77
+ r: tuple[int, str, str, int] = self.run_program_internal(program, arguments_as_array, working_directory, custom_argument)
78
+ popen: SudoPopen = SudoPopen(r[0], r[1], r[2], r[3])
79
+ return popen
80
+
81
+ # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
82
+ @GeneralUtilities.check_arguments
83
+ def wait(self, process: Popen, custom_argument: object) -> tuple[int, str, str, int]:
84
+ raise ValueError("Wait is not supported in Sudo-runner")
85
+
86
+ # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
87
+ @GeneralUtilities.check_arguments
88
+ def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
89
+ if interactive:
90
+ raise ValueError("Interactive execution is not supported in Sudo-runner")
91
+ return self.run_program_internal(program, arguments_as_array, working_directory, custom_argument)
92
+
93
+ # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
94
+ @GeneralUtilities.check_arguments
95
+ def run_program(self, program: str, arguments: str = "", working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
96
+ if interactive:
97
+ raise ValueError("Interactive execution is not supported in Sudo-runner")
98
+ return self.run_program_internal(program, arguments.split(" "), working_directory, custom_argument)
99
+
100
+ # Return-values program_runner: Pid
101
+ @GeneralUtilities.check_arguments
102
+ def run_program_argsasarray_async(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> int:
103
+ raise ValueError("Async execution is not supported in Sudo-runner")
104
+
105
+ # Return-values program_runner: Pid
106
+ @GeneralUtilities.check_arguments
107
+ def run_program_async(self, program: str, arguments: str, working_directory: str, custom_argument: object, interactive: bool = False) -> int:
108
+ raise ValueError("Async execution is not supported in Sudo-runner")
@@ -34,10 +34,9 @@ from pypdf import PdfReader, PdfWriter
34
34
  from .GeneralUtilities import GeneralUtilities
35
35
  from .ProgramRunnerBase import ProgramRunnerBase
36
36
  from .ProgramRunnerPopen import ProgramRunnerPopen
37
- from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
38
37
  from .SCLog import SCLog, LogLevel
39
38
 
40
- version = "4.0.51"
39
+ version = "4.0.52"
41
40
  __version__ = version
42
41
 
43
42
 
@@ -1549,8 +1548,6 @@ class ScriptCollectionCore:
1549
1548
 
1550
1549
  @GeneralUtilities.check_arguments
1551
1550
  def __run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, custom_argument: object = None, interactive: bool = False) -> Popen:
1552
- if isinstance(self.program_runner, ProgramRunnerEpew):
1553
- custom_argument = CustomEpewArgument(print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace,self.log.loglevel, arguments_for_log)
1554
1551
  popen: Popen = self.program_runner.run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, custom_argument, interactive)
1555
1552
  return popen
1556
1553
 
@@ -1833,10 +1830,14 @@ class ScriptCollectionCore:
1833
1830
  pid: int
1834
1831
 
1835
1832
  @GeneralUtilities.check_arguments
1836
- def run_with_epew(self, program: str, argument: str = "", working_directory: str = None, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False,print_live_output:bool=False) -> tuple[int, str, str, int]:
1837
- sc: ScriptCollectionCore = ScriptCollectionCore()
1838
- sc.program_runner = ProgramRunnerEpew()
1839
- return sc.run_program(program, argument, working_directory, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, throw_exception_if_exitcode_is_not_zero, custom_argument, interactive,print_live_output=print_live_output)
1833
+ def run_with_epew(self, program: str, argument: str = "", working_directory: str = None, print_errors_as_information: bool = False, log_file: str = None, timeoutInSeconds: int = 600, addLogOverhead: bool = False, title: str = None, log_namespace: str = "", arguments_for_log: list[str] = None, throw_exception_if_exitcode_is_not_zero: bool = True, custom_argument: object = None, interactive: bool = False,print_live_output:bool=False,encode_argument_in_base64:bool=False) -> tuple[int, str, str, int]:
1834
+ epew_argument=f"-p {program} -a {argument} -w {working_directory}"
1835
+ if encode_argument_in_base64:
1836
+ base64_bytes = base64.b64encode(argument)
1837
+ base64_string = base64_bytes.decode('utf-8')
1838
+ argument=base64.b64decode(base64_string)
1839
+ epew_argument=epew_argument+" -b"
1840
+ return self.run_program("epew", epew_argument, working_directory, print_errors_as_information, log_file, timeoutInSeconds, addLogOverhead, title, log_namespace, arguments_for_log, throw_exception_if_exitcode_is_not_zero, custom_argument, interactive,print_live_output=print_live_output)
1840
1841
 
1841
1842
 
1842
1843
  # </run programs>
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ScriptCollection
3
- Version: 4.0.51
3
+ Version: 4.0.52
4
4
  Summary: The ScriptCollection is the place for reusable scripts.
5
5
  Home-page: https://github.com/anionDev/ScriptCollection
6
6
  Author: Marius Göcke
@@ -5,11 +5,11 @@ ScriptCollection/GeneralUtilities.py,sha256=9Xd9aKPj3TkpVtdHXzFMILrRoXAfJCph69XR
5
5
  ScriptCollection/ImageUpdater.py,sha256=qTe3yoqzQJY7LZdXBbjbWvrsSQaeHy1VwmOxaRzU2ig,29305
6
6
  ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
7
7
  ScriptCollection/ProgramRunnerBase.py,sha256=4A2eQgSg_rRgQcgSi-LYtUlM-uSQEpS7qFWn0tWt4uo,2171
8
- ScriptCollection/ProgramRunnerEpew.py,sha256=TJdDx9zIMSiCaXh8X-ekrMlbXfGtmd0Mmyxj-tV_gHg,7338
9
8
  ScriptCollection/ProgramRunnerMock.py,sha256=uTu-aFle1W_oKjeQEmuPsFPQpvo0kRf2FrRjAPIwT5Y,37
10
9
  ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
10
+ ScriptCollection/ProgramRunnerSudo.py,sha256=_khC3xuTdrPoLluBJZWfldltmmuKltABJPcbjZSFW-4,4835
11
11
  ScriptCollection/SCLog.py,sha256=dxGOI4E9lG5v9jk_LajXCkM5nghliCDV8YB8Ihn160s,4541
12
- ScriptCollection/ScriptCollectionCore.py,sha256=n-QprUwKp_hE2W9jPHzktCEDurVVcvkH4Sz8EIcyV0M,142178
12
+ ScriptCollection/ScriptCollectionCore.py,sha256=2EqLxmuiBYobgKIjQ2yBYZYkHmu1g3QsZykfhvU1SbI,142125
13
13
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  ScriptCollection/TFCPS/TFCPS_CodeUnitSpecific_Base.py,sha256=H9ampfCfJ4-ohN33VkYWTKwYaTV-y3AelZAiTduwHzw,25442
15
15
  ScriptCollection/TFCPS/TFCPS_CodeUnit_BuildCodeUnit.py,sha256=4rYKgTAga11NiDx8YUqz3K_Q4eX_n3kC6lvNdXEa24s,7389
@@ -35,8 +35,8 @@ ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=e2bvR_zzAr
35
35
  ScriptCollection/TFCPS/NodeJS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py,sha256=q7msAxCb5VIZ-xhFg1MfzUvWomQRKYldqmW42KFhyMU,6868
37
37
  ScriptCollection/TFCPS/Python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- scriptcollection-4.0.51.dist-info/METADATA,sha256=IAPmwcVuxRDd8BqNGVtKq5bZyU9gwBJzD4N1k6jiby8,7688
39
- scriptcollection-4.0.51.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
- scriptcollection-4.0.51.dist-info/entry_points.txt,sha256=_izhaQEyHiyBIfM2zTYDaJ7qvgsP1WntkVChFnkWymE,4431
41
- scriptcollection-4.0.51.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
42
- scriptcollection-4.0.51.dist-info/RECORD,,
38
+ scriptcollection-4.0.52.dist-info/METADATA,sha256=5SNVHNlcuIWhu4ufQyC648iLMrNWuaMTHtSE7d6toQM,7688
39
+ scriptcollection-4.0.52.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
40
+ scriptcollection-4.0.52.dist-info/entry_points.txt,sha256=_izhaQEyHiyBIfM2zTYDaJ7qvgsP1WntkVChFnkWymE,4431
41
+ scriptcollection-4.0.52.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
42
+ scriptcollection-4.0.52.dist-info/RECORD,,
@@ -1,148 +0,0 @@
1
- import os
2
- import base64
3
- import tempfile
4
- from subprocess import Popen
5
- from uuid import uuid4
6
-
7
- from .GeneralUtilities import GeneralUtilities
8
- from .ProgramRunnerBase import ProgramRunnerBase
9
- from .ProgramRunnerPopen import ProgramRunnerPopen
10
- from .SCLog import LogLevel
11
-
12
-
13
- class CustomEpewArgument:
14
-
15
- print_errors_as_information: bool
16
- log_file: str
17
- timeoutInSeconds: int
18
- addLogOverhead: bool
19
- title: str
20
- log_namespace: str
21
- verbosity: LogLevel
22
- arguments_for_log: list[str]
23
- tempdir = os.path.join(tempfile.gettempdir(), str(uuid4()))
24
- stdoutfile = tempdir + ".epew.stdout.txt"
25
- stderrfile = tempdir + ".epew.stderr.txt"
26
- exitcodefile = tempdir + ".epew.exitcode.txt"
27
- pidfile = tempdir + ".epew.pid.txt"
28
-
29
- def __init__(self, print_errors_as_information: bool, log_file: str, timeoutInSeconds: int, addLogOverhead: bool, title: str, log_namespace: str, verbosity: LogLevel, arguments_for_log: list[str]):
30
- self.print_errors_as_information = print_errors_as_information
31
- self.log_file = log_file
32
- self.timeoutInSeconds = timeoutInSeconds
33
- self.addLogOverhead = addLogOverhead
34
- self.title = title
35
- self.log_namespace = log_namespace
36
- self.verbosity = verbosity
37
- self.arguments_for_log = arguments_for_log
38
-
39
-
40
- class ProgramRunnerEpew(ProgramRunnerBase):
41
-
42
- @GeneralUtilities.check_arguments
43
- def run_program_argsasarray_async_helper(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> Popen:
44
- if GeneralUtilities.epew_is_available():
45
- custom_argument: CustomEpewArgument = custom_argument
46
- args = []
47
-
48
- base64argument = base64.b64encode(' '.join(arguments_as_array).encode('utf-8')).decode('utf-8')
49
- args.append(f'-p "{program}"')
50
- args.append(f'-a {base64argument}')
51
- args.append('-b')
52
- args.append(f'-w "{working_directory}"')
53
- if custom_argument.stdoutfile is not None:
54
- args.append(f'-o {custom_argument.stdoutfile}')
55
- if custom_argument.stderrfile is not None:
56
- args.append(f'-e {custom_argument.stderrfile}')
57
- if custom_argument.exitcodefile is not None:
58
- args.append(f'-x {custom_argument.exitcodefile}')
59
- if custom_argument.pidfile is not None:
60
- args.append(f'-r {custom_argument.pidfile}')
61
- args.append(f'-d {str(custom_argument.timeoutInSeconds*1000)}')
62
- if GeneralUtilities.string_has_content(custom_argument.title):
63
- args.append(f'-t "{custom_argument.title}"')
64
- if GeneralUtilities.string_has_content(custom_argument.log_namespace):
65
- args.append(f'-l "{custom_argument.log_namespace}"')
66
- if not GeneralUtilities.string_is_none_or_whitespace(custom_argument.log_file):
67
- args.append(f'-f "{custom_argument.log_file}"')
68
- if custom_argument.print_errors_as_information:
69
- args.append("-i")
70
- if custom_argument.addLogOverhead:
71
- args.append("-g")
72
- args.append("-v "+str(self.__get_microsoft_loglevel()))
73
- return ProgramRunnerPopen().run_program_argsasarray_async_helper("epew", args, working_directory, custom_argument, interactive)
74
- else:
75
- raise ValueError("Epew is not available.")
76
-
77
- def __get_microsoft_loglevel(self):
78
- #see https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel
79
- #match self.verbosity:
80
- # case LogLevel.Quiet:
81
- # return 6
82
- # case LogLevel.Error:
83
- # return 4
84
- # case LogLevel.Warning:
85
- # return 3
86
- # case LogLevel.Information:
87
- # return 5
88
- # case LogLevel.Debug:
89
- # return 1
90
- # case LogLevel.Diagnostig:
91
- # return 0
92
- # case _:
93
- # raise ValueError(f"Unhandled log level: {level}")
94
- return 2#TODO
95
-
96
- # Return-values program_runner: Exitcode, StdOut, StdErr, Pid
97
- @GeneralUtilities.check_arguments
98
- def wait(self, process: Popen, custom_argument: object = None) -> tuple[int, str, str, int]:
99
- process.wait()
100
- custom_argument: CustomEpewArgument = custom_argument
101
- stdout = self.__load_text(custom_argument.output_file_for_stdout)
102
- stderr = self.__load_text(custom_argument.output_file_for_stderr)
103
- exit_code = self.__get_number_from_filecontent(self.__load_text(custom_argument.output_file_for_exit_code))
104
- pid = self.__get_number_from_filecontent(self.__load_text(custom_argument.output_file_for_pid))
105
- GeneralUtilities.ensure_directory_does_not_exist(custom_argument.tempdir)
106
- result = (exit_code, stdout, stderr, pid)
107
- return result
108
-
109
- @GeneralUtilities.check_arguments
110
- def run_program_argsasarray(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
111
- process: Popen = self.run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, custom_argument, interactive)
112
- return self.wait(process, custom_argument)
113
-
114
- @GeneralUtilities.check_arguments
115
- def run_program(self, program: str, arguments: str = "", working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> tuple[int, str, str, int]:
116
- return self.run_program_argsasarray(program, GeneralUtilities.arguments_to_array(arguments), working_directory, custom_argument, interactive)
117
-
118
- @GeneralUtilities.check_arguments
119
- def run_program_argsasarray_async(self, program: str, arguments_as_array: list[str] = [], working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> int:
120
- return self.run_program_argsasarray_async_helper(program, arguments_as_array, working_directory, custom_argument, interactive).pid
121
-
122
- @GeneralUtilities.check_arguments
123
- def run_program_async(self, program: str, arguments: str = "", working_directory: str = None, custom_argument: object = None, interactive: bool = False) -> int:
124
- return self.run_program_argsasarray_async(program, GeneralUtilities.arguments_to_array(arguments), working_directory, custom_argument, interactive)
125
-
126
- @GeneralUtilities.check_arguments
127
- def __get_number_from_filecontent(self, filecontent: str) -> int:
128
- for line in filecontent.splitlines():
129
- try:
130
- striped_line = GeneralUtilities.strip_new_line_character(line)
131
- result = int(striped_line)
132
- return result
133
- except:
134
- pass
135
- raise ValueError(f"'{filecontent}' does not containe an int-line")
136
-
137
- @GeneralUtilities.check_arguments
138
- def __load_text(self, file: str) -> str:
139
- if os.path.isfile(file):
140
- content = GeneralUtilities.read_text_from_file(file).replace('\r', '')
141
- os.remove(file)
142
- return content
143
- else:
144
- raise ValueError(f"File '{file}' does not exist")
145
-
146
- @GeneralUtilities.check_arguments
147
- def will_be_executed_locally(self) -> bool:
148
- return True