ScriptCollection 4.2.51__py3-none-any.whl → 4.2.53__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.
@@ -21,8 +21,9 @@ class CertificateUpdater:
21
21
  __log_folder: str = None
22
22
  __sc: ScriptCollectionCore = None
23
23
  __arguments: ScriptCollectionCore = None
24
+ __certbot_image_address_with_tag:str=None
24
25
 
25
- def __init__(self, domains: list[str], email: str, current_file: str, arguments: list[str]):
26
+ def __init__(self, domains: list[str], email: str, current_file: str, arguments: list[str],certbot_image_address_with_tag:str=None):
26
27
  self.__sc = ScriptCollectionCore()
27
28
  self.maximal_age_of_certificates_in_days = 15
28
29
  self.__domains = domains
@@ -36,6 +37,9 @@ class CertificateUpdater:
36
37
  self.__letsencrypt_live_folder = os.path.join(self.__letsencrypt_folder, "live")
37
38
  self.__letsencrypt_archive_folder = os.path.join(self.__letsencrypt_folder, "archive")
38
39
  self.__log_folder = GeneralUtilities.resolve_relative_path("Logs/Overhead", self.__repository_folder)
40
+ if certbot_image_address_with_tag is None:
41
+ certbot_image_address_with_tag="docker.io/certbot/certbot:latest"
42
+ self.__certbot_image_address_with_tag=certbot_image_address_with_tag
39
43
 
40
44
  @GeneralUtilities.check_arguments
41
45
  def __get_latest_index_by_domain(self, domain: str) -> int:
@@ -102,7 +106,7 @@ class CertificateUpdater:
102
106
  else:
103
107
  GeneralUtilities.write_message_to_stdout(f"Create certificate for domain {domain}")
104
108
  dockerargument = f"run --rm --name {certbot_container_name} --volume {self.__letsencrypt_folder}:/etc/letsencrypt"
105
- dockerargument = dockerargument + f" --volume {self.__log_folder}:/var/log/letsencrypt -p 80:80 "+"docker.io/certbot/certbot"#TODO make this replaceable
109
+ dockerargument = dockerargument + f" --volume {self.__log_folder}:/var/log/letsencrypt -p 80:80 "+self.__certbot_image_address_with_tag
106
110
  certbotargument = f"--standalone --email {self.__email} --agree-tos --force-renewal --rsa-key-size 4096 --non-interactive --no-eff-email --domain {domain}"
107
111
  if (certificate_for_domain_already_exists):
108
112
  self.__sc.run_program("docker", f"{dockerargument} certonly --no-random-sleep-on-renew {certbotargument}", self.__current_folder)
@@ -113,13 +117,6 @@ class CertificateUpdater:
113
117
  except Exception as exception:
114
118
  error_occurred = True
115
119
  GeneralUtilities.write_exception_to_stderr_with_traceback(exception, traceback, "Error while updating certificate")
116
- finally:
117
- enabled=False#disabled because docker run has now the --rm argument
118
- if enabled:
119
- try:
120
- self.__sc.run_program("docker", f"container rm {certbot_container_name}", self.__current_folder, throw_exception_if_exitcode_is_not_zero=True)
121
- except Exception as exception:
122
- GeneralUtilities.write_exception_to_stderr_with_traceback(exception, traceback, "Error while removing container")
123
120
  self.__sc.git_commit(self.__repository_folder, "Executed certificate-update-process")
124
121
  GeneralUtilities.write_message_to_stdout("Finished certificate-update-process")
125
122
  if error_occurred:
@@ -8,7 +8,6 @@ import keyboard
8
8
  from .ScriptCollectionCore import ScriptCollectionCore
9
9
  from .GeneralUtilities import GeneralUtilities
10
10
  from .SCLog import LogLevel, SCLog
11
- from .ImageUpdater import ImageUpdater, VersionEcholon
12
11
  from .TFCPS.TFCPS_CodeUnit_BuildCodeUnits import TFCPS_CodeUnit_BuildCodeUnits
13
12
  from .TFCPS.TFCPS_Tools_General import TFCPS_Tools_General
14
13
 
@@ -282,7 +281,7 @@ def BuildCodeUnitsC() -> int:
282
281
  parser.add_argument('--ispremerge', required=False, default=False, action='store_true')
283
282
  parser.add_argument('--image', required=False, default="scbuilder:latest")
284
283
  args = parser.parse_args()
285
- GeneralUtilities.reconfigure_standrd_input_and_outputs()
284
+ GeneralUtilities.reconfigure_standard_input_and_outputs()
286
285
  repo:str=GeneralUtilities.resolve_relative_path(args.repositoryfolder,os.getcwd())
287
286
  verbosity=LogLevel(int(args.verbosity))
288
287
  t:TFCPS_CodeUnit_BuildCodeUnits=TFCPS_CodeUnit_BuildCodeUnits(repo,verbosity,args.targetenvironment,args.additionalargumentsfile,not args.nocache,args.ispremerge)
@@ -704,66 +703,52 @@ def ConvertGitRepositoryToBareRepository() -> int:
704
703
  def OCRAnalysisOfFolder() -> int:
705
704
  parser = argparse.ArgumentParser()
706
705
  parser.add_argument('-s', '--serviceaddress', required=False, default=None)
707
- parser.add_argument('-e', '--extensions', required=False, default=None)
708
- parser.add_argument('-l', '--languages', required=False, default="en")
706
+ parser.add_argument('-e', '--extensions', required=False, default="pdf,docx,jpg,png,xlsx")
707
+ parser.add_argument('-l', '--languages', required=False, default="eng")
709
708
  parser.add_argument('-f', '--folder', required=False, default=None)
709
+ parser.add_argument('-d', '--datafolder', required=False, default=None)
710
710
  args = parser.parse_args()
711
711
  sc = ScriptCollectionCore()
712
712
  if args.folder is None:
713
713
  args.folder = os.getcwd()
714
- extensions_value: str = None
715
- if args.extensions is not None:
716
- if "," in args.extensions:
717
- extensions_value = args.extensions.split(",")
718
- else:
719
- extensions_value = [args.extensions]
720
- sc.ocr_analysis_of_folder(args.folder, args.serviceaddress, extensions_value, args.languages)
714
+ languages=args.languages.split(",")
715
+ extensions=args.extensions.split(",")
716
+ sc.ocr_analysis_of_folder(args.folder, args.serviceaddress, extensions, languages,args.datafolder,args.folder,[])
721
717
  return 0
722
718
 
723
719
 
724
720
  def OCRAnalysisOfFile() -> int:
725
721
  parser = argparse.ArgumentParser()
726
722
  parser.add_argument('-s', '--serviceaddress', required=False, default=None)
727
- parser.add_argument('-l', '--languages', required=False, default="en")
723
+ parser.add_argument('-l', '--languages', required=False, default="eng")
728
724
  parser.add_argument('-f', '--file', required=True)
725
+ parser.add_argument('-d', '--datafolder', required=False, default=None)
729
726
  args = parser.parse_args()
730
727
  sc = ScriptCollectionCore()
731
- sc.ocr_analysis_of_file(args.file, args.serviceaddress, args.languages)
728
+ languages=args.languages.split(",")
729
+ sc.ocr_analysis_of_file(args.file, args.serviceaddress, languages,args.datafolder,".")
732
730
  return 0
733
731
 
734
732
 
735
733
  def OCRAnalysisOfRepository() -> int:
736
734
  parser = argparse.ArgumentParser()
737
735
  parser.add_argument('-s', '--serviceaddress', required=False, default=None)
738
- parser.add_argument('-e', '--extensions', required=False, default=None)
739
- parser.add_argument('-l', '--languages', required=False, default="en")
736
+ parser.add_argument('-e', '--extensions', required=False, default="pdf,docx,jpg,png,xlsx")
737
+ parser.add_argument('-l', '--languages', required=False, default="eng")
740
738
  parser.add_argument('-f', '--folder', required=False, default=None)
739
+ parser.add_argument('-d', '--datafolder', required=False, default=None)
741
740
  args = parser.parse_args()
742
741
  sc = ScriptCollectionCore()
743
742
  if args.folder is None:
744
743
  args.folder = os.getcwd()
745
- extensions_value: str = None
746
- if args.extensions is not None:
747
- if "," in args.extensions:
748
- extensions_value = args.extensions.split(",")
749
- else:
750
- extensions_value = [args.extensions]
751
- sc.ocr_analysis_of_repository(args.folder, args.serviceaddress, extensions_value, args.languages)
744
+ languages=args.languages.split(",")
745
+ extensions=args.extensions.split(",")
746
+ sc.ocr_analysis_of_repository(args.folder, args.serviceaddress, extensions, languages,args.datafolder)
752
747
  return 0
753
748
 
754
749
 
755
750
  def UpdateImagesInDockerComposeFile() -> int:
756
- iu: ImageUpdater = ImageUpdater()
757
- parser = argparse.ArgumentParser()
758
- parser.add_argument('-f', '--file', required=False, default=None)
759
- parser.add_argument('-v', '--versionecholon', required=False, default=VersionEcholon.LatestVersion.name, dest="Possible values are: " + ", ".join([e.name for e in VersionEcholon]))
760
- parser.add_argument("-s", "--servicename", required=True, default=None)
761
- parser.add_argument("-u", "--updatertype", required=True, default=None)
762
- args = parser.parse_args()
763
- if args.file is None:
764
- args.file = os.path.join(os.getcwd(), "docker-compose.yml")
765
- versionecholonTyped = VersionEcholon[args.versionecholon]
766
- iu.update_services_in_docker_compose_file(args.file, [args.servicename], versionecholonTyped, args.updatertype)
751
+ #TODO use OCIImageUpdater
767
752
  return 0
768
753
 
769
754
 
@@ -910,9 +895,22 @@ def AddImageToCustomRegistry()->int:
910
895
  parser.add_argument('-p', '--password', required=False,default=None)
911
896
  verbosity_values = ", ".join(f"{lvl.value}={lvl.name}" for lvl in LogLevel)
912
897
  parser.add_argument('-v', '--verbosity', required=False, default=3, help=f"Sets the loglevel. Possible values: {verbosity_values}")
898
+ parser.add_argument('-r', '--removeimagelocally', action='store_true', default=False)
913
899
  args = parser.parse_args()
914
900
  sc:ScriptCollectionCore=ScriptCollectionCore()
915
901
  verbosity=int(args.verbosity)
916
902
  sc.log.loglevel=LogLevel(verbosity)
917
- sc.add_image_to_custom_docker_image_registry(args.remotehub,args.imagenameonremotehub,args.ownregistryaddress,args.imagenameonownregistry,args.tag,args.username,args.password)
903
+ sc.add_image_to_custom_docker_image_registry(args.remotehub,args.imagenameonremotehub,args.ownregistryaddress,args.imagenameonownregistry,args.tag,args.username,args.password,args.removeimagelocally)
918
904
  return 0
905
+
906
+ def SyncXlfFiles()->int:
907
+ parser = argparse.ArgumentParser(description="This function syncs the content of xlf-files in a folder. This is useful to keep the content of xlf-files in sync which are used for translations in software projects.")
908
+ parser.add_argument('-p', '--prefix', required=True, help="File prefix. Example: 'message' when the files are named 'message.xlf', 'message.fr.xlf', etc.")
909
+ parser.add_argument('-l', '--languages', required=True, help="Comma-separated list of languages. Example: 'en,fr,de'")
910
+ parser.add_argument('-f', '--folder', required=False)
911
+ args = parser.parse_args()
912
+ sc:ScriptCollectionCore=ScriptCollectionCore()
913
+ languages=str(args.languages).split(",")
914
+ folder=GeneralUtilities.resolve_relative_path(args.folder, os.getcwd())
915
+ sc.sync_xlf2_files(args.prefix, languages, folder)
916
+ return 0
@@ -235,8 +235,8 @@ class GeneralUtilities:
235
235
  @staticmethod
236
236
  @check_arguments
237
237
  def is_ignored_by_glob_pattern(source_directory:str,path:str, ignored_glob_patterms: list[str]) -> bool:
238
- source_directory=source_directory.replace("\\","/")
239
- path=path.replace("\\","/")
238
+ source_directory=GeneralUtilities.normalize_path(source_directory)
239
+ path=GeneralUtilities.normalize_path(path)
240
240
  GeneralUtilities.assert_condition(path.startswith(source_directory), f"Path '{path}' is not located in source directory '{source_directory}'.")
241
241
  if ignored_glob_patterms is None:
242
242
  return False
@@ -380,7 +380,7 @@ class GeneralUtilities:
380
380
 
381
381
  @staticmethod
382
382
  @check_arguments
383
- def reconfigure_standrd_input_and_outputs():
383
+ def reconfigure_standard_input_and_outputs():
384
384
  sys.stdin.reconfigure(encoding='utf-8')
385
385
  sys.stderr.reconfigure(encoding='utf-8')
386
386
  sys.stdout.reconfigure(encoding='utf-8')
@@ -542,7 +542,7 @@ class GeneralUtilities:
542
542
  @staticmethod
543
543
  @check_arguments
544
544
  def file_ends_with_newline(file: str) -> bool:
545
- file=GeneralUtilities.normaliza_path(file)
545
+ file=GeneralUtilities.normalize_path(file)
546
546
  with open(file, "rb") as file_object:
547
547
  return GeneralUtilities.ends_with_newline_character(file_object.read())
548
548
 
@@ -575,13 +575,13 @@ class GeneralUtilities:
575
575
  @staticmethod
576
576
  @check_arguments
577
577
  def append_line_to_file(file: str, line: str, encoding: str = "utf-8") -> None:
578
- file=GeneralUtilities.normaliza_path(file)
578
+ file=GeneralUtilities.normalize_path(file)
579
579
  GeneralUtilities.append_lines_to_file(file, [line], encoding)
580
580
 
581
581
  @staticmethod
582
582
  @check_arguments
583
583
  def append_lines_to_file(file: str, lines: list[str], encoding: str = "utf-8") -> None:
584
- file=GeneralUtilities.normaliza_path(file)
584
+ file=GeneralUtilities.normalize_path(file)
585
585
  if len(lines) == 0:
586
586
  return
587
587
  is_first_line = True
@@ -604,7 +604,7 @@ class GeneralUtilities:
604
604
  @staticmethod
605
605
  @check_arguments
606
606
  def append_to_file(file: str, content: str, encoding: str = "utf-8") -> None:
607
- file=GeneralUtilities.normaliza_path(file)
607
+ file=GeneralUtilities.normalize_path(file)
608
608
  GeneralUtilities.assert_condition(not "\n" in content, "Appending multiple lines is not allowed. Use append_lines_to_file instead.")
609
609
  with open(file, "a", encoding=encoding) as fileObject:
610
610
  fileObject.write(content)
@@ -612,14 +612,14 @@ class GeneralUtilities:
612
612
  @staticmethod
613
613
  @check_arguments
614
614
  def ensure_directory_exists(path: str) -> None:
615
- path=GeneralUtilities.normaliza_path(path)
615
+ path=GeneralUtilities.normalize_path(path)
616
616
  if not os.path.isdir(path):
617
617
  os.makedirs(path)
618
618
 
619
619
  @staticmethod
620
620
  @check_arguments
621
621
  def ensure_file_exists(path: str) -> None:
622
- path=GeneralUtilities.normaliza_path(path)
622
+ path=GeneralUtilities.normalize_path(path)
623
623
  if (not os.path.isfile(path)):
624
624
  with open(path, "a+", encoding="utf-8"):
625
625
  pass
@@ -786,7 +786,7 @@ class GeneralUtilities:
786
786
  @staticmethod
787
787
  @check_arguments
788
788
  def read_binary_from_file(file: str) -> bytes:
789
- file=GeneralUtilities.normaliza_path(file)
789
+ file=GeneralUtilities.normalize_path(file)
790
790
  with open(file, "rb") as file_object:
791
791
  return file_object.read()
792
792
 
@@ -1281,7 +1281,7 @@ class GeneralUtilities:
1281
1281
 
1282
1282
  @staticmethod
1283
1283
  @check_arguments
1284
- def normaliza_path(path)->str:
1284
+ def normalize_path(path)->str:
1285
1285
  path=str(path)
1286
1286
  if GeneralUtilities.current_system_is_windows():
1287
1287
  path=path.replace("/","\\")
@@ -10,7 +10,7 @@ class AbstractImageHandler(ABC):
10
10
 
11
11
  def _protected_get_credentials_for_registry(self,registry_address:str,username_str:str)->tuple[str,str]:
12
12
  """return (username, password) for basic auth.
13
- Data will be taken from "~/.scriptcollection/GlobalCache/RegistryCredentials.csv" if available.
13
+ Data will be taken from "~/.ScriptCollection/GlobalCache/RegistryCredentials.csv" if available.
14
14
  If no credentials are available then None will be returned for the missing values."""
15
15
  raise NotImplementedError()
16
16
 
@@ -2,7 +2,7 @@ import os
2
2
  from packaging.version import Version
3
3
  from ..GeneralUtilities import GeneralUtilities
4
4
  from ..ScriptCollectionCore import ScriptCollectionCore
5
- from ..ImageUpdater import VersionEcholon
5
+ from ..GeneralUtilities import VersionEcholon
6
6
  from .AbstractImageHandler import AbstractImageHandler
7
7
  from .ConcreteImageHandlers.ImageHandlerDebianSlim import ImageHandlerDebianSlim
8
8
 
@@ -52,30 +52,21 @@ class OCIImageManager:
52
52
  result.append(line[0])
53
53
  return result
54
54
 
55
- def custom_registry_is_defined(self,image_name:str)->str:
55
+ def custom_registry_is_defined(self,image_name:str)->bool:
56
56
  global_docker_image_registries_file=self.get_global_docker_image_registries_file()
57
57
  for line in GeneralUtilities.read_nonempty_lines_from_file(global_docker_image_registries_file)[1:]:
58
58
  splitted_line=line.split(";")
59
59
  if image_name==splitted_line[0]:
60
- GeneralUtilities.assert_condition( GeneralUtilities.string_has_content(splitted_line[1]),f"No registry defined for image {image_name}.")
60
+ GeneralUtilities.assert_condition(GeneralUtilities.string_has_content(splitted_line[1]),f"No registry defined for image {image_name}.")
61
61
  return True
62
62
  return False
63
63
 
64
- def get_default_tag(self,repository:str,image_name:str,strict_mode:bool)->str:
65
- """this functions returns a string like "17.7" or "latest"."""
66
- if self.custom_registry_is_defined(image_name):
67
- repository_image_definition_file=self.get_repository_image_definition_file(repository)
68
- for line in [f.split(";") for f in GeneralUtilities.read_nonempty_lines_from_file(repository_image_definition_file)[1:]]:
69
- if image_name==line[0]:
70
- GeneralUtilities.assert_condition( GeneralUtilities.string_has_content(line[2]),f"No default-tag defined for image {image_name}.")
71
- return line[2]
72
- else:
73
- if strict_mode:
74
- raise ValueError(f"No default-tag is defined for image \"{image_name}\".")
75
- else:
76
- return "latest"
77
-
78
- raise ValueError(f"No registry defined for image \"{image_name}\".")
64
+ def get_tag_for_image(self,repository:str,image_name:str,strict_mode:bool)->str:
65
+ repository_image_definition_file=self.get_repository_image_definition_file(repository)
66
+ for line in [f.split(";") for f in GeneralUtilities.read_nonempty_lines_from_file(repository_image_definition_file)[1:]]:
67
+ if image_name==line[0]:
68
+ return line[2]
69
+ raise ValueError(f"No tag defined for image \"{image_name}\".")
79
70
 
80
71
  def get_registry_address_for_image(self,repository:str,image_name:str)->str:
81
72
  """if image_name==Debian this function returns something like "myregistry.example.com/debian", always without tag."""
@@ -91,11 +82,10 @@ class OCIImageManager:
91
82
  for line in [f.split(";") for f in GeneralUtilities.read_nonempty_lines_from_file(repository_image_definition_file)[1:]]:
92
83
  if image_name==line[0]:
93
84
  return line[1]
94
-
95
85
  raise ValueError(f"No registry defined for image \"{image_name}\".")
96
86
 
97
87
  def get_registry_address_for_image_with_default_tag(self,repository:str,image_name:str,strict_mode:bool=True)->str:
98
- return f"{self.get_registry_address_for_image(repository,image_name)}:{self.get_default_tag(repository,image_name,strict_mode)}"
88
+ return f"{self.get_registry_address_for_image(repository,image_name)}:{self.get_tag_for_image(repository,image_name,strict_mode)}"
99
89
 
100
90
  def update_default_tag_for_image(self,repository:str,image_name:str,echolon:VersionEcholon,search_in_custom_registry_only_if_available:bool)->None:
101
91
  pass#TODO update in ImageDefinition.csv using get_available_versions_of_image_which_are_newer
@@ -116,4 +106,4 @@ class OCIImageManager:
116
106
  """registry_address must have one of theese formats: "myregistry.example.com/debian" or "docker.io/debian" or "docker.io/myuser/debian".
117
107
  returns something like "13.3-slim".
118
108
  If there are multiple tags available for a certain version then the image-handler decides which one will be returned."""
119
- return self.get_image_handler(image_name).version_to_tag(image_name,registry_address,version)#
109
+ return self.get_image_handler(image_name).version_to_tag(image_name,registry_address,version)