ScriptCollection 3.5.106__py3-none-any.whl → 3.5.108__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.
@@ -1,46 +1,53 @@
1
1
  import os
2
2
  from pathlib import Path
3
+ from datetime import datetime, timedelta
3
4
  import traceback
4
5
  from shutil import copyfile
5
- from .ScriptCollectionCore import ScriptCollectionCore
6
+ import argparse
6
7
  from .GeneralUtilities import GeneralUtilities
8
+ from .ScriptCollectionCore import ScriptCollectionCore
7
9
 
8
10
 
9
11
  class CertificateUpdater:
12
+ maximal_age_of_certificates_in_days: int = None
13
+ __domains: list[str] = None
14
+ __email: str = None
15
+ __current_folder: str = None
16
+ __last_update_timestamp_file: str = None
17
+ __repository_folder: str = None
18
+ __letsencrypt_folder: str = None
19
+ __letsencrypt_live_folder: str = None
20
+ __letsencrypt_archive_folder: str = None
21
+ __log_folder: str = None
22
+ __sc: ScriptCollectionCore = None
23
+ __arguments: ScriptCollectionCore = None
10
24
 
11
- __domains: list[str]
12
- __email: str
13
-
14
- __current_folder = os.path.dirname(os.path.abspath(__file__))
15
- __repository_folder = GeneralUtilities.resolve_relative_path(f"..{os.path.sep}..{os.path.sep}..{os.path.sep}", __current_folder)
16
- __letsencrypt_folder = GeneralUtilities.resolve_relative_path(f"..{os.path.sep}..{os.path.sep}Volumes{os.path.sep}letsencrypt", __current_folder)
17
- __letsencrypt_live_folder = os.path.join(__letsencrypt_folder, "live")
18
- __letsencrypt_archive_folder = os.path.join(__letsencrypt_folder, "archive")
19
- __log_folder = GeneralUtilities.resolve_relative_path(f"Logs{os.path.sep}Overhead", __repository_folder)
20
- __sc = ScriptCollectionCore()
21
- __line = "___________________________________________________________________"
22
-
23
- def __init__(self, domains: list[str], email: str):
25
+ def __init__(self, domains: list[str], email: str, current_file: str, arguments: list[str]):
26
+ self.__sc = ScriptCollectionCore()
27
+ self.maximal_age_of_certificates_in_days = 60
24
28
  self.__domains = domains
25
29
  self.__email = email
30
+ self.__current_folder = current_file
31
+ self.__arguments = arguments
32
+ self.__last_update_timestamp_file = GeneralUtilities.resolve_relative_path("./LastCertificateUpdate.csv", self.__current_folder)
33
+ self.__repository_folder = GeneralUtilities.resolve_relative_path("../..", self.__current_folder)
34
+ self.__sc.assert_is_git_repository(self.__repository_folder)
35
+ self.__letsencrypt_folder = f"{ self.__repository_folder}/Configuration/Volumes/letsencrypt"
36
+ self.__letsencrypt_live_folder = os.path.join(self.__letsencrypt_folder, "live")
37
+ self.__letsencrypt_archive_folder = os.path.join(self.__letsencrypt_folder, "archive")
38
+ self.__log_folder = GeneralUtilities.resolve_relative_path("Logs/Overhead", self.__repository_folder)
26
39
 
27
40
  @GeneralUtilities.check_arguments
28
41
  def __get_latest_index_by_domain(self, domain: str) -> int:
29
42
  result = self.__get_latest_index_by_filelist(GeneralUtilities.get_all_files_of_folder(os.path.join(self.__letsencrypt_archive_folder, domain)))
30
- #GeneralUtilities.write_message_to_stdout(f"Debug: Latest found existing number for domain {domain}: {result}")
43
+ GeneralUtilities.write_message_to_stdout(f"Debug: Latest found existing number for domain {domain}: {result}")
31
44
  return result
32
45
 
33
46
  @GeneralUtilities.check_arguments
34
- def __get_latest_index_by_filelist(self, filenames: list) -> int:
35
- print("files:")
36
- print(filenames)
47
+ def __get_latest_index_by_filelist(self, filenames: list[str]) -> int:
37
48
  filenames = [Path(os.path.basename(file)).stem for file in filenames]
38
- print(filenames)
39
49
  filenames = [file for file in filenames if file.startswith("privkey")]
40
- print(filenames)
41
50
  numbers = [int(file[len("privkey"):]) for file in filenames]
42
- # numbers=[]
43
- # print([os.path.basename(file) for file in filenames])
44
51
  result = max(numbers)
45
52
  return result
46
53
 
@@ -51,7 +58,7 @@ class CertificateUpdater:
51
58
  live_folder = os.path.join(self.__letsencrypt_live_folder, domain)
52
59
  live_filename = filename+".pem"
53
60
  live_file = os.path.join(live_folder, live_filename)
54
- self.__sc.run_program("rm", live_filename, live_folder)
61
+ self.__sc.run_program("rm", live_filename, live_folder, throw_exception_if_exitcode_is_not_zero=True)
55
62
  copyfile(archive_file, live_file)
56
63
 
57
64
  @GeneralUtilities.check_arguments
@@ -59,8 +66,8 @@ class CertificateUpdater:
59
66
  # new ".../live/example.com/cert.pem" is a file but should replaced by a symlink which points to ".../archive/example.com/cert42.pem"
60
67
  live_folder = os.path.join(self.__letsencrypt_live_folder, domain)
61
68
  live_filename = filename+".pem"
62
- self.__sc.run_program("rm", live_filename, live_folder)
63
- self.__sc.run_program("ln", f"-s ../../archive/{domain}/{filename+str(index)}.pem {live_filename}", live_folder)
69
+ self.__sc.run_program("rm", live_filename, live_folder, throw_exception_if_exitcode_is_not_zero=True)
70
+ self.__sc.run_program("ln", f"-s ../../archive/{domain}/{filename+str(index)}.pem {live_filename}", live_folder, throw_exception_if_exitcode_is_not_zero=True)
64
71
 
65
72
  @GeneralUtilities.check_arguments
66
73
  def __replace_symlinks_by_files(self, domain):
@@ -79,48 +86,61 @@ class CertificateUpdater:
79
86
  self.__replace_file_by_symlink(domain, "privkey", index)
80
87
 
81
88
  @GeneralUtilities.check_arguments
82
- def update_certificate_managed_by_docker_and_letsencrypt(self) -> None:
83
- GeneralUtilities.write_message_to_stdout("current_folder:")
84
- GeneralUtilities.write_message_to_stdout(self.__current_folder)
85
- GeneralUtilities.write_message_to_stdout("letsencrypt_folder:")
86
- GeneralUtilities.write_message_to_stdout(self.__letsencrypt_folder)
87
- GeneralUtilities.write_message_to_stdout("letsencrypt_live_folder:")
88
- GeneralUtilities.write_message_to_stdout(self.__letsencrypt_live_folder)
89
- GeneralUtilities.write_message_to_stdout("letsencrypt_archive_folder:")
90
- GeneralUtilities.write_message_to_stdout(self.__letsencrypt_archive_folder)
91
- GeneralUtilities.write_message_to_stdout("log_folder:")
92
- GeneralUtilities.write_message_to_stdout(self.__log_folder)
93
-
94
- GeneralUtilities.write_message_to_stdout(self.__line+self.__line)
95
- GeneralUtilities.write_message_to_stdout("Updating certificates")
96
- self.__sc.git_commit(self.__current_folder, "Saved current changes")
89
+ def __update_certificates(self) -> None:
90
+ self.__sc.git_commit(self.__repository_folder, "Saved current changes")
91
+ error_occurred = False
97
92
  for domain in self.__domains:
93
+ certbot_container_name = "certificate_updater"
98
94
  try:
99
- GeneralUtilities.write_message_to_stdout(self.__line)
95
+ GeneralUtilities.write_message_to_stdout(GeneralUtilities.get_line())
100
96
  GeneralUtilities.write_message_to_stdout(f"Process domain {domain}")
97
+ self.__sc.run_program("docker", f"container rm {certbot_container_name}", self.__current_folder, throw_exception_if_exitcode_is_not_zero=False, verbosity=0)
101
98
  certificate_for_domain_already_exists = os.path.isfile(f"{self.__letsencrypt_folder}/renewal/{domain}.conf")
102
99
  if certificate_for_domain_already_exists:
103
100
  GeneralUtilities.write_message_to_stdout(f"Update certificate for domain {domain}")
104
101
  self.__replace_files_by_symlinks(domain)
105
102
  else:
106
103
  GeneralUtilities.write_message_to_stdout(f"Create certificate for domain {domain}")
107
- certbot_container_name = "r2_updatecertificates_certbot"
108
104
  dockerargument = f"run --name {certbot_container_name} --volume {self.__letsencrypt_folder}:/etc/letsencrypt"
109
- dockerargument = dockerargument+f" --volume {self.__log_folder}:/var/log/letsencrypt -p 80:80 certbot/certbot:latest"
105
+ dockerargument = dockerargument + f" --volume {self.__log_folder}:/var/log/letsencrypt -p 80:80 certbot/certbot:latest"
110
106
  certbotargument = f"--standalone --email {self.__email} --agree-tos --force-renewal --rsa-key-size 4096 --non-interactive --no-eff-email --domain {domain}"
111
107
  if (certificate_for_domain_already_exists):
112
- self.__sc.run_program("docker", f"{dockerargument} certonly --no-random-sleep-on-renew {certbotargument}", self.__current_folder, throw_exception_if_exitcode_is_not_zero=True)
108
+ self.__sc.run_program("docker", f"{dockerargument} certonly --no-random-sleep-on-renew {certbotargument}", self.__current_folder)
113
109
  self.__replace_symlinks_by_files(domain)
114
110
  else:
115
- self.__sc.run_program("docker", f"{dockerargument} certonly --cert-name {domain} {certbotargument}", self.__current_folder, throw_exception_if_exitcode_is_not_zero=True)
111
+ self.__sc.run_program("docker", f"{dockerargument} certonly --cert-name {domain} {certbotargument}", self.__current_folder)
116
112
  except Exception as exception:
113
+ error_occurred = True
117
114
  GeneralUtilities.write_exception_to_stderr_with_traceback(exception, traceback, "Error while updating certificate")
118
115
  finally:
119
116
  try:
120
117
  self.__sc.run_program("docker", f"container rm {certbot_container_name}", self.__current_folder, throw_exception_if_exitcode_is_not_zero=True)
121
118
  except Exception as exception:
122
119
  GeneralUtilities.write_exception_to_stderr_with_traceback(exception, traceback, "Error while removing container")
123
-
124
- GeneralUtilities.write_message_to_stdout("Commit changes...")
125
120
  self.__sc.git_commit(self.__repository_folder, "Executed certificate-update-process")
126
121
  GeneralUtilities.write_message_to_stdout("Finished certificate-update-process")
122
+ if error_occurred:
123
+ raise ValueError("Certificates for at least one domain could not be added/updated.")
124
+
125
+ @GeneralUtilities.check_arguments
126
+ def __get_last_certificate_update_date(self) -> datetime:
127
+ if os.path.exists(self.__last_update_timestamp_file):
128
+ filecontent = GeneralUtilities.read_text_from_file(self.__last_update_timestamp_file)
129
+ return GeneralUtilities.string_to_datetime(filecontent.replace("\r", "").replace("\n", ""))
130
+ else:
131
+ return datetime(year=1970, month=1, day=1)
132
+
133
+ @GeneralUtilities.check_arguments
134
+ def __set_last_certificate_update_date(self, moment: datetime) -> datetime:
135
+ GeneralUtilities.ensure_file_exists(self.__last_update_timestamp_file)
136
+ GeneralUtilities.write_text_to_file(self.__last_update_timestamp_file, GeneralUtilities.datetime_to_string(moment))
137
+
138
+ @GeneralUtilities.check_arguments
139
+ def update_certificates_if_required(self) -> None:
140
+ parser = argparse.ArgumentParser(description="Updated lets-encrypt-certificates")
141
+ parser.add_argument('-f', '--force', action='store_true', required=False, default=False)
142
+ args = parser.parse_args(self.__arguments)
143
+ now = datetime.now()
144
+ if (self.__get_last_certificate_update_date()+timedelta(days=self.maximal_age_of_certificates_in_days)) < now or args.force:
145
+ self.__update_certificates()
146
+ self.__set_last_certificate_update_date(now)
@@ -12,6 +12,7 @@ import stat
12
12
  import secrets
13
13
  import string as strin
14
14
  import sys
15
+ from enum import Enum
15
16
  import traceback
16
17
  import warnings
17
18
  import functools
@@ -26,6 +27,12 @@ from defusedxml.minidom import parse
26
27
  from OpenSSL import crypto
27
28
 
28
29
 
30
+ class VersionEcholon(Enum):
31
+ Patch = 0
32
+ MinorOrPatch = 1
33
+ MajorOrMinorOrPatch = 2
34
+
35
+
29
36
  class GeneralUtilities:
30
37
 
31
38
  __datetime_format: str = "%Y-%m-%dT%H:%M:%S"
@@ -133,17 +140,17 @@ class GeneralUtilities:
133
140
 
134
141
  @staticmethod
135
142
  @check_arguments
136
- def copy_content_of_folder(source_directory: str, target_directory: str, overwrite_existing_files=False,filtertext:str=None) -> None:
137
- GeneralUtilities.__copy_or_move_content_of_folder(source_directory, target_directory, overwrite_existing_files, False,filtertext)
143
+ def copy_content_of_folder(source_directory: str, target_directory: str, overwrite_existing_files=False, filtertext: str = None) -> None:
144
+ GeneralUtilities.__copy_or_move_content_of_folder(source_directory, target_directory, overwrite_existing_files, False, filtertext)
138
145
 
139
146
  @staticmethod
140
147
  @check_arguments
141
- def move_content_of_folder(source_directory: str, target_directory: str, overwrite_existing_files=False,filtertext:str=None) -> None:
142
- GeneralUtilities.__copy_or_move_content_of_folder(source_directory, target_directory, overwrite_existing_files, True,filtertext)
148
+ def move_content_of_folder(source_directory: str, target_directory: str, overwrite_existing_files=False, filtertext: str = None) -> None:
149
+ GeneralUtilities.__copy_or_move_content_of_folder(source_directory, target_directory, overwrite_existing_files, True, filtertext)
143
150
 
144
151
  @staticmethod
145
152
  @check_arguments
146
- def __copy_or_move_content_of_folder(source_directory: str, target_directory: str, overwrite_existing_files, remove_source: bool,filtertext:str=None) -> None:
153
+ def __copy_or_move_content_of_folder(source_directory: str, target_directory: str, overwrite_existing_files, remove_source: bool, filtertext: str = None) -> None:
147
154
  srcDirFull = GeneralUtilities.resolve_relative_path_from_current_working_directory(source_directory)
148
155
  dstDirFull = GeneralUtilities.resolve_relative_path_from_current_working_directory(target_directory)
149
156
  if (os.path.isdir(source_directory)):
@@ -1032,27 +1039,25 @@ class GeneralUtilities:
1032
1039
 
1033
1040
  @staticmethod
1034
1041
  @check_arguments
1035
- def process_is_running_by_name(process_name: str) -> bool:
1042
+ def process_is_running_by_name(process_name: str) -> bool:
1036
1043
  processes: list[psutil.Process] = list(psutil.process_iter())
1037
1044
  for p in processes:
1038
1045
  if p.name() == process_name:
1039
1046
  return True
1040
1047
  return False
1041
1048
 
1042
-
1043
1049
  @staticmethod
1044
1050
  @check_arguments
1045
- def process_is_running_by_id(process_id: int) -> bool:
1051
+ def process_is_running_by_id(process_id: int) -> bool:
1046
1052
  processes: list[psutil.Process] = list(psutil.process_iter())
1047
1053
  for p in processes:
1048
1054
  if p.pid == process_id:
1049
1055
  return True
1050
1056
  return False
1051
1057
 
1052
-
1053
1058
  @staticmethod
1054
1059
  @check_arguments
1055
- def kill_process(process_id:int,include_child_processes:bool) -> bool:
1060
+ def kill_process(process_id: int, include_child_processes: bool) -> bool:
1056
1061
  if GeneralUtilities. process_is_running_by_id(process_id):
1057
1062
  GeneralUtilities.write_message_to_stdout(f"Process with id {process_id} is running. Terminating it...")
1058
1063
  process = psutil.Process(process_id)
@@ -28,12 +28,12 @@ import qrcode
28
28
  import pycdlib
29
29
  import send2trash
30
30
  from pypdf import PdfReader, PdfWriter
31
- from .GeneralUtilities import GeneralUtilities
31
+ from .GeneralUtilities import GeneralUtilities, VersionEcholon
32
32
  from .ProgramRunnerBase import ProgramRunnerBase
33
33
  from .ProgramRunnerPopen import ProgramRunnerPopen
34
34
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
35
35
 
36
- version = "3.5.106"
36
+ version = "3.5.108"
37
37
  __version__ = version
38
38
 
39
39
 
@@ -1868,8 +1868,8 @@ DNS = {domain}
1868
1868
  self.run_program_argsasarray("openssl", ['pkcs12', '-export', '-out', f'{filename}.pfx', f'-inkey', f'{filename}.key', '-in', f'{filename}.crt', '-password', f'pass:{password}'], folder)
1869
1869
 
1870
1870
  @GeneralUtilities.check_arguments
1871
- def update_dependencies_of_python_in_requirementstxt_file(self, file: str,ignored_dependencies:list[str], verbosity: int):
1872
- #TODO consider ignored_dependencies
1871
+ def update_dependencies_of_python_in_requirementstxt_file(self, file: str, ignored_dependencies: list[str], verbosity: int):
1872
+ # TODO consider ignored_dependencies
1873
1873
  lines = GeneralUtilities.read_lines_from_file(file)
1874
1874
  new_lines = []
1875
1875
  for line in lines:
@@ -1899,8 +1899,8 @@ DNS = {domain}
1899
1899
  raise ValueError(f'Unexpected line in requirements-file: "{line}"')
1900
1900
 
1901
1901
  @GeneralUtilities.check_arguments
1902
- def update_dependencies_of_python_in_setupcfg_file(self, setup_cfg_file: str,ignored_dependencies:list[str], verbosity: int):
1903
- #TODO consider ignored_dependencies
1902
+ def update_dependencies_of_python_in_setupcfg_file(self, setup_cfg_file: str, ignored_dependencies: list[str], verbosity: int):
1903
+ # TODO consider ignored_dependencies
1904
1904
  lines = GeneralUtilities.read_lines_from_file(setup_cfg_file)
1905
1905
  new_lines = []
1906
1906
  requirement_parsing_mode = False
@@ -2280,5 +2280,50 @@ TXDX
2280
2280
  ET.indent(element)
2281
2281
  GeneralUtilities.write_text_to_file(file, ET.tostring(element, encoding="unicode"), encoding)
2282
2282
 
2283
- def install_requirementstxt_file(self,requirements_txt_file: str, folder: str, verbosity: int):
2283
+ @GeneralUtilities.check_arguments
2284
+ def install_requirementstxt_file(self, requirements_txt_file: str, folder: str, verbosity: int):
2284
2285
  self.run_program_argsasarray("pip", ["install", "-r", requirements_txt_file], folder, verbosity=verbosity)
2286
+
2287
+ @GeneralUtilities.check_arguments
2288
+ def update_all_services_in_docker_compose_file(self, dockercompose_file: str, version_echolon: VersionEcholon):
2289
+ raise ValueError("not implemented yet")
2290
+
2291
+ @GeneralUtilities.check_arguments
2292
+ def update_service_in_docker_compose_file(self, dockercompose_file: str, service_name: str, version_echolon: VersionEcholon):
2293
+ raise ValueError("not implemented yet")
2294
+
2295
+ @GeneralUtilities.check_arguments
2296
+ def get_current_version_of_service_from_docker_compose_file(self, dockercompose_file: str, service_name: str):
2297
+ raise ValueError("not implemented yet")
2298
+
2299
+ @GeneralUtilities.check_arguments
2300
+ def get_services_from_docker_compose_file(self, dockercompose_file: str):
2301
+ raise ValueError("not implemented yet")
2302
+
2303
+ @GeneralUtilities.check_arguments
2304
+ def get_next_version_for_nginx(self, registry_address: str, current_version: str, version_echolon: VersionEcholon):
2305
+ raise ValueError("not implemented yet")
2306
+
2307
+ @GeneralUtilities.check_arguments
2308
+ def get_next_version_for_prometheus(self, registry_address: str, current_version: str, version_echolon: VersionEcholon):
2309
+ raise ValueError("not implemented yet")
2310
+
2311
+ @GeneralUtilities.check_arguments
2312
+ def get_next_version_for_blackbox_exporter(self, registry_address: str, current_version: str, version_echolon: VersionEcholon):
2313
+ raise ValueError("not implemented yet")
2314
+
2315
+ @GeneralUtilities.check_arguments
2316
+ def get_next_version_for_gitlab(self, registry_address: str, current_version: str, version_echolon: VersionEcholon):
2317
+ raise ValueError("not implemented yet")
2318
+
2319
+ @GeneralUtilities.check_arguments
2320
+ def get_next_version_for_nextcloud(self, registry_address: str, current_version: str, version_echolon: VersionEcholon):
2321
+ raise ValueError("not implemented yet")
2322
+
2323
+ @GeneralUtilities.check_arguments
2324
+ def get_next_version_for_genericservice(self, registry_address: str, current_version: str, version_echolon: VersionEcholon, tag_prefix: str):
2325
+ raise ValueError("not implemented yet")
2326
+
2327
+ @GeneralUtilities.check_arguments
2328
+ def get_all_available_tags(self, registry_address: str, service: str):
2329
+ raise ValueError("not implemented yet")
@@ -1025,8 +1025,9 @@ class TasksForCommonProjectStructure:
1025
1025
 
1026
1026
  if codeunit_has_testcases:
1027
1027
  source_testcoveragereport = os.path.join(other_folder_in_repository, "Artifacts", "TestCoverageReport")
1028
- target_testcoveragereport = os.path.join(target_folder, "TestCoverageReport")
1029
- shutil.copytree(source_testcoveragereport, target_testcoveragereport)
1028
+ if os.path.isdir(source_testcoveragereport): # check, because it is not a mandatory artifact. if the artifact is not available, the user gets already a warning.
1029
+ target_testcoveragereport = os.path.join(target_folder, "TestCoverageReport")
1030
+ shutil.copytree(source_testcoveragereport, target_testcoveragereport)
1030
1031
 
1031
1032
  @GeneralUtilities.check_arguments
1032
1033
  def __standardized_tasks_release_artifact(self, information: CreateReleaseInformationForProjectInCommonProjectFormat) -> None:
@@ -1560,9 +1561,9 @@ class TasksForCommonProjectStructure:
1560
1561
  combined_file = os.path.join(codeunit_folder, file)
1561
1562
  if not os.path.isfile(combined_file):
1562
1563
  raise ValueError(f'The mandatory file "{file}" does not exist in the codeunit-folder.')
1563
-
1564
- if os.path.isfile(os.path.join(codeunit_folder,"Other","requirements.txt")):
1565
- self.install_requirementstxt_for_codeunit(codeunit_folder,verbosity)
1564
+
1565
+ if os.path.isfile(os.path.join(codeunit_folder, "Other", "requirements.txt")):
1566
+ self.install_requirementstxt_for_codeunit(codeunit_folder, verbosity)
1566
1567
 
1567
1568
  # Check developer
1568
1569
  if self.validate_developers_of_repository:
@@ -2271,9 +2272,9 @@ class TasksForCommonProjectStructure:
2271
2272
  def update_dependencies_of_typical_python_repository_requirements(self, repository_folder: str, verbosity: int, cmd_args: list[str]) -> None:
2272
2273
  verbosity = self.get_verbosity_from_commandline_arguments(cmd_args, verbosity)
2273
2274
 
2274
- development_requirements_file = os.path.join(repository_folder, "Other","requirements.txt")
2275
+ development_requirements_file = os.path.join(repository_folder, "Other", "requirements.txt")
2275
2276
  if (os.path.isfile(development_requirements_file)):
2276
- self.__sc.update_dependencies_of_python_in_requirementstxt_file(development_requirements_file,[], verbosity)
2277
+ self.__sc.update_dependencies_of_python_in_requirementstxt_file(development_requirements_file, [], verbosity)
2277
2278
 
2278
2279
  @GeneralUtilities.check_arguments
2279
2280
  def update_dependencies_of_typical_python_codeunit(self, update_script_file: str, verbosity: int, cmd_args: list[str]) -> None:
@@ -2282,17 +2283,17 @@ class TasksForCommonProjectStructure:
2282
2283
  # TODO consider ignored_dependencies
2283
2284
  verbosity = self.get_verbosity_from_commandline_arguments(cmd_args, verbosity)
2284
2285
 
2285
- setup_cfg=os.path.join(codeunit_folder, "setup.cfg")
2286
+ setup_cfg = os.path.join(codeunit_folder, "setup.cfg")
2286
2287
  if (os.path.isfile(setup_cfg)):
2287
- self.__sc.update_dependencies_of_python_in_setupcfg_file(setup_cfg,ignored_dependencies, verbosity)
2288
+ self.__sc.update_dependencies_of_python_in_setupcfg_file(setup_cfg, ignored_dependencies, verbosity)
2288
2289
 
2289
- development_requirements_file = os.path.join(codeunit_folder, "requirements.txt")#required for codeunits which contain python-code which need third-party dependencies
2290
+ development_requirements_file = os.path.join(codeunit_folder, "requirements.txt") # required for codeunits which contain python-code which need third-party dependencies
2290
2291
  if (os.path.isfile(development_requirements_file)):
2291
- self.__sc.update_dependencies_of_python_in_requirementstxt_file(development_requirements_file,ignored_dependencies, verbosity)
2292
+ self.__sc.update_dependencies_of_python_in_requirementstxt_file(development_requirements_file, ignored_dependencies, verbosity)
2292
2293
 
2293
- development_requirements_file2 = os.path.join(codeunit_folder, "Other","requirements.txt")#required for codeunits which contain python-scripts which needs third-party dependencies
2294
+ development_requirements_file2 = os.path.join(codeunit_folder, "Other", "requirements.txt") # required for codeunits which contain python-scripts which needs third-party dependencies
2294
2295
  if (os.path.isfile(development_requirements_file2)):
2295
- self.__sc.update_dependencies_of_python_in_requirementstxt_file(development_requirements_file2, ignored_dependencies,verbosity)
2296
+ self.__sc.update_dependencies_of_python_in_requirementstxt_file(development_requirements_file2, ignored_dependencies, verbosity)
2296
2297
 
2297
2298
  @GeneralUtilities.check_arguments
2298
2299
  def update_dependencies_of_typical_dotnet_codeunit(self, update_script_file: str, verbosity: int, cmd_args: list[str]) -> None:
@@ -3292,15 +3293,15 @@ class TasksForCommonProjectStructure:
3292
3293
  self.__sc.git_commit(GeneralUtilities.resolve_relative_path("../..", folder_of_this_file), f"Updated content of {update_http_documentation_arguments.product_name} v{update_http_documentation_arguments.new_project_version} in {update_http_documentation_arguments.reference_repository_name}-submodule")
3293
3294
 
3294
3295
  @GeneralUtilities.check_arguments
3295
- def install_requirementstxt_for_codeunit(self,codeunit_folder:str,verbosity:int):
3296
+ def install_requirementstxt_for_codeunit(self, codeunit_folder: str, verbosity: int):
3296
3297
  self.__sc.install_requirementstxt_file(codeunit_folder+"/Other/requirements.txt", verbosity)
3297
3298
 
3298
3299
  @GeneralUtilities.check_arguments
3299
- def install_requirementstxt_for_repository(self, repository_folde: str,verbosity:int):
3300
+ def install_requirementstxt_for_repository(self, repository_folde: str, verbosity: int):
3300
3301
  self.__sc.install_requirementstxt_file(repository_folde+"/Other/requirements.txt", verbosity)
3301
3302
 
3302
3303
  @GeneralUtilities.check_arguments
3303
- def update_submodule(self, repository_folder: str, submodule_name:str):
3304
+ def update_submodule(self, repository_folder: str, submodule_name: str):
3304
3305
  submodule_folder = GeneralUtilities.resolve_relative_path("Other/Resources/Submodules/"+submodule_name, repository_folder)
3305
3306
  self.__sc.git_fetch(submodule_folder, "origin")
3306
3307
  self.__sc.git_checkout(submodule_folder, "main")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ScriptCollection
3
- Version: 3.5.106
3
+ Version: 3.5.108
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
@@ -30,7 +30,7 @@ Requires-Dist: keyboard>=0.13.5
30
30
  Requires-Dist: lcov-cobertura>=2.1.1
31
31
  Requires-Dist: lxml>=5.3.2
32
32
  Requires-Dist: ntplib>=0.4.0
33
- Requires-Dist: Pillow>=11.1.0
33
+ Requires-Dist: Pillow>=11.2.1
34
34
  Requires-Dist: pycdlib>=1.14.0
35
35
  Requires-Dist: Pygments>=2.19.1
36
36
  Requires-Dist: pylint>=3.3.6
@@ -41,7 +41,7 @@ Requires-Dist: PyYAML>=6.0.2
41
41
  Requires-Dist: qrcode>=8.1
42
42
  Requires-Dist: send2trash>=1.8.3
43
43
  Requires-Dist: twine>=6.1.0
44
- Requires-Dist: xmlschema>=3.4.5
44
+ Requires-Dist: xmlschema>=4.0.1
45
45
 
46
46
  # ScriptCollection
47
47
 
@@ -1,16 +1,16 @@
1
+ ScriptCollection/CertificateUpdater.py,sha256=pJopWFcwaLAEVljtC4O3SVrlpIpoJNUhT1V4mgiqLvE,8970
1
2
  ScriptCollection/Executables.py,sha256=HI9Pxs5Z9QxPGyqeJU2lWslEggFyGYANCqYVQZp6eJ0,30490
2
- ScriptCollection/GeneralUtilities.py,sha256=rjOHLJXHQtYCDSjjWQ45Vs7vzm9C2lEgtyYQ_91TEHU,44043
3
+ ScriptCollection/GeneralUtilities.py,sha256=VO4a7xctkjN5dcBXc32gz0x9U07DEagasjvYVKqLmdM,44173
3
4
  ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
4
5
  ScriptCollection/ProgramRunnerBase.py,sha256=2kMIAqdc65UjBAddOZkzy_aFx9h5roZ5a4bQNM6RV6Y,2480
5
6
  ScriptCollection/ProgramRunnerEpew.py,sha256=4pjEd0r9Fcz3TTDv0MdTSd5KkigYXcWUVI1X43regfU,6477
6
7
  ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
7
8
  ScriptCollection/SCLog.py,sha256=Gw27Oclcb0ten7_89PD5CdNMoO-at2hGUOYbF-x1HPQ,2296
8
- ScriptCollection/ScriptCollectionCore.py,sha256=w5AmB7nLdcgRu5kqfHls95046uRQHqLvWMsywZX4yMA,126071
9
- ScriptCollection/TasksForCommonProjectStructure.py,sha256=9rO_W6kZiy3Lgov0HeyyDhOwriorMeJXlVDvwZ3S1UE,232511
10
- ScriptCollection/UpdateCertificates.py,sha256=xRebqD2etBD7ILHL-7fg-Y-kPF0Tbmnwexv4FhwDntQ,7791
9
+ ScriptCollection/ScriptCollectionCore.py,sha256=9R--jXBBIL0wX6Cw7cq9C1UpZvIgQ_qpvf2jcXgqXY8,128371
10
+ ScriptCollection/TasksForCommonProjectStructure.py,sha256=SJ7V9HilnkCBJGCCrObWwAORSI_pXW9zC4uon1O6Xbg,232705
11
11
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- scriptcollection-3.5.106.dist-info/METADATA,sha256=n6LYf8sPb9QA50YUjdHf3Sx-ShX9J-_mjl4eJ4RZp4g,7664
13
- scriptcollection-3.5.106.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
14
- scriptcollection-3.5.106.dist-info/entry_points.txt,sha256=fYCGWGNGijBQHhFe6UAO-BEpfEOxLyNJemukt5ElSzs,3644
15
- scriptcollection-3.5.106.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
- scriptcollection-3.5.106.dist-info/RECORD,,
12
+ scriptcollection-3.5.108.dist-info/METADATA,sha256=ooO5jOZCS4o095UVS3mMveJO7BUcDqXd5Ijpid7kN_I,7664
13
+ scriptcollection-3.5.108.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
14
+ scriptcollection-3.5.108.dist-info/entry_points.txt,sha256=fYCGWGNGijBQHhFe6UAO-BEpfEOxLyNJemukt5ElSzs,3644
15
+ scriptcollection-3.5.108.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
+ scriptcollection-3.5.108.dist-info/RECORD,,