ScriptCollection 4.2.54__py3-none-any.whl → 4.2.56__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.
@@ -3,6 +3,7 @@ import json
3
3
  import binascii
4
4
  import filecmp
5
5
  import hashlib
6
+ import logging
6
7
  import multiprocessing
7
8
  import time
8
9
  from io import BytesIO
@@ -36,7 +37,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
36
37
  from .ProgramRunnerPopen import ProgramRunnerPopen
37
38
  from .SCLog import SCLog, LogLevel
38
39
 
39
- version = "4.2.54"
40
+ version = "4.2.56"
40
41
  __version__ = version
41
42
 
42
43
  class VSCodeWorkspaceShellTask:
@@ -2779,10 +2780,17 @@ OCR-content:
2779
2780
  @GeneralUtilities.check_arguments
2780
2781
  def generate_chart_diagram(self,source_file:str,target_file:str):
2781
2782
  workingfolder=os.path.dirname(source_file)
2782
- argument=f"{source_file} {target_file}"
2783
+ argument=f"\"{source_file}\" \"{target_file}\""
2784
+ loglevelMap = {
2785
+ LogLevel.Error: "error",
2786
+ LogLevel.Warning: "warn",
2787
+ LogLevel.Information: "info",
2788
+ LogLevel.Debug: "debug",
2789
+ }
2783
2790
  if self.log.loglevel==LogLevel.Debug:
2784
- argument=f"-l debug {argument}"
2785
- self.run_with_epew("vl2svg",argument,workingfolder)#this uses vega-light. to use vega "vg2svg" should be used instead.
2791
+ argument=f"-l {loglevelMap[self.log.loglevel]} {argument}"
2792
+ self.run_with_epew("vl2svg",argument,workingfolder,encode_argument_in_base64=True)
2793
+ #this uses vega-light. to use vega "vg2svg" should be used instead.
2786
2794
 
2787
2795
  @GeneralUtilities.check_arguments
2788
2796
  def inspect_container(self, container_name: str) :
@@ -3115,11 +3123,80 @@ OCR-content:
3115
3123
 
3116
3124
  #sync existing files
3117
3125
  self.__sync_xlf2_files(base_file_xml, language_files_with_content)
3118
-
3126
+
3119
3127
  @GeneralUtilities.check_arguments
3120
- def translate_messages_in_folder(self,folder:str,base_language:str, api_server:str):
3121
- pass#TODO for each file in folder: call self.translate(...)
3122
-
3128
+ def translate_xlf_files_in_folder(self, folder: str, base_language: str, libre_translate_api_server: str):
3129
+ """Translates all .xlf files directly in the given folder (non-recursive)."""
3130
+ pattern = re.compile(r'^.+\.[a-z]{2,3}\.xlf$')
3131
+ for filename in os.listdir(folder):
3132
+ if not pattern.match(filename):
3133
+ continue
3134
+ file_path = os.path.join(folder, filename)
3135
+ self.translate_xlf_file(file_path, base_language, libre_translate_api_server)
3136
+
3123
3137
  @GeneralUtilities.check_arguments
3124
- def translate(self,content:str, source_language:str, target_language:str,api_server:str)->str:
3125
- pass#TODO call libretranslate-api
3138
+ def translate_xlf_file(self, file: str, base_language: str, libre_translate_api_server: str):
3139
+ """
3140
+ Translates all segments with state='initial' in a XLIFF 2.0 file.
3141
+ The target language is extracted from the filename (e.g. 'messages.es.xlf' -> 'es').
3142
+ """
3143
+ ns_uri = "urn:oasis:names:tc:xliff:document:2.0"
3144
+ ns = {"xliff": ns_uri}
3145
+
3146
+ filename = os.path.basename(file)
3147
+ parts = filename.split(".")
3148
+ if len(parts) < 3:
3149
+ raise ValueError(f"Cannot extract language from filename: {filename}")
3150
+ target_language = parts[-2]
3151
+
3152
+ tree = ET.parse(file)
3153
+ root = tree.getroot()
3154
+
3155
+ for segment in root.findall(".//xliff:segment[@state='initial']", ns):
3156
+ source_el = segment.find("xliff:source", ns)
3157
+ if source_el is None or not source_el.text:
3158
+ continue
3159
+
3160
+ translated_text = self.translate(source_el.text, base_language, target_language, libre_translate_api_server)
3161
+
3162
+ target_el = segment.find("xliff:target", ns)
3163
+ if target_el is None:
3164
+ target_el = ET.SubElement(segment, f"{{{ns_uri}}}target")
3165
+
3166
+ target_el.text = translated_text
3167
+ segment.set("state", "translated")
3168
+
3169
+ ET.register_namespace("", ns_uri)
3170
+ xml_bytes = ET.tostring(root, encoding="utf-8", xml_declaration=True)
3171
+ with open(file, "wb") as f:
3172
+ f.write(xml_bytes)
3173
+
3174
+ @GeneralUtilities.check_arguments
3175
+ def translate(self, content: str, source_language: str, target_language: str, libre_translate_api_server: str) -> str:
3176
+ """Translates text using the LibreTranslate API."""
3177
+ url = f"{libre_translate_api_server.rstrip('/')}/translate"
3178
+ if "-" in source_language:
3179
+ source_language=source_language.split("-")[0]
3180
+ if "-" in target_language:
3181
+ target_language=target_language.split("-")[0]
3182
+ payload = {
3183
+ "q": content,
3184
+ "source": source_language,
3185
+ "target": target_language,
3186
+ "format": "text"
3187
+ }
3188
+ response = requests.post(url, json=payload)
3189
+ response.raise_for_status()
3190
+ return response.json()["translatedText"]
3191
+
3192
+ @GeneralUtilities.check_arguments
3193
+ def detect_language(self, content: str, libre_translate_api_server: str) -> str:
3194
+ """Detects the language of the given text using the LibreTranslate API."""
3195
+ url = f"{libre_translate_api_server.rstrip('/')}/detect"
3196
+ payload = {"q": content}
3197
+ response = requests.post(url, json=payload)
3198
+ response.raise_for_status()
3199
+ results = response.json()
3200
+ if not results:
3201
+ raise ValueError("Language detection returned no results.")
3202
+ return results[0]["language"]
@@ -181,8 +181,7 @@ class TFCPS_CodeUnitSpecific_NodeJS_Functions(TFCPS_CodeUnitSpecific_Base):
181
181
  angular_json_path = Path(angular_json_file)
182
182
  with angular_json_path.open(encoding="utf-8") as f:
183
183
  angular_config = json.load(f)
184
- project_name = "ConSurvFrontend"
185
- i18n_config = angular_config["projects"][project_name]["i18n"]
184
+ i18n_config = angular_config["projects"][self.get_codeunit_name()]["i18n"]
186
185
  new_locales = {
187
186
  lang: f"Other/Resources/Translations/messages.{lang}.xlf"
188
187
  for lang in languages
@@ -1430,12 +1430,20 @@ class TFCPS_Tools_General:
1430
1430
  manifest_content = GeneralUtilities.replace_variable_in_string(manifest_content, "sha256_hashvalue", GeneralUtilities.get_sha256_of_file(artifacts_file))
1431
1431
  GeneralUtilities.write_text_to_file(winget_manifest_file, manifest_content)
1432
1432
 
1433
+ def download_file(self,source:str,target:str):
1434
+ GeneralUtilities.ensure_directory_exists(os.path.dirname(target))
1435
+ GeneralUtilities.ensure_file_exists(target)
1436
+ response = requests.get(source)
1437
+ response.raise_for_status()
1438
+ with open(target, "wb") as f:
1439
+ f.write(response.content)
1440
+
1433
1441
  def try_update_basic_codeunitreference_from_examples_repository(self,codeunit_folder:str,example_codeunit_name: str):
1434
- source=f"https://github.com/anionDev/CommonProjectStructureExamples/blob/main/{example_codeunit_name}/Other/Reference/ReferenceContent/HowToBuild.md"
1442
+ source=f"https://raw.githubusercontent.com/anionDev/CommonProjectStructureExamples/refs/heads/main/{example_codeunit_name}/Other/Reference/ReferenceContent/HowToBuild.md"
1435
1443
  target=f"{codeunit_folder}/Other/Reference/ReferenceContent/HowToBuild.md"
1436
- pass#TODO copy source to target. replace entire content. create target-file if it does not exist. ignore any error but print a warning in that case.
1444
+ self.download_file(source,target)
1437
1445
 
1438
1446
  def try_update_basic_repositoryreference_from_examples_repository(self,repository_folder:str):
1439
- source=f"https://github.com/anionDev/CommonProjectStructureExamples/blob/main/Other/Reference/RepositoryStructure.md"
1447
+ source=f"https://raw.githubusercontent.com/anionDev/CommonProjectStructureExamples/refs/heads/main/Other/Reference/RepositoryStructure.mdd"
1440
1448
  target=f"{repository_folder}/Other/Reference/RepositoryStructure.md"
1441
- pass#TODO copy source to target. replace entire content. create target-file if it does not exist. ignore any error but print a warning in that case.
1449
+ self.download_file(source,target)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ScriptCollection
3
- Version: 4.2.54
3
+ Version: 4.2.56
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
@@ -9,7 +9,7 @@ ScriptCollection/ProgramRunnerMock.py,sha256=uTu-aFle1W_oKjeQEmuPsFPQpvo0kRf2FrR
9
9
  ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
10
10
  ScriptCollection/ProgramRunnerSudo.py,sha256=_khC3xuTdrPoLluBJZWfldltmmuKltABJPcbjZSFW-4,4835
11
11
  ScriptCollection/SCLog.py,sha256=8TRy1LeYMsPOIuWUcnUNNbO5pd-cNBS-3cn-kdzP8FU,4768
12
- ScriptCollection/ScriptCollectionCore.py,sha256=_IJM_ZkRGrVFEqWjj7Hpc7ZVf2k9NnJ7CLVa0yowF54,170458
12
+ ScriptCollection/ScriptCollectionCore.py,sha256=YE4yV9Vxy3RrC_Fpr0QC3tyI_OYiBAOxwZqsmGXMxU8,173731
13
13
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  ScriptCollection/OCIImages/AbstractImageHandler.py,sha256=83qDMILwxhH9DbC0sb358Vu8PXEysmJJyap_6gECZqs,1627
15
15
  ScriptCollection/OCIImages/OCIImageManager.py,sha256=aBogkSXNDyi8NO11N-s03nuFJEv7PyJ-wjHuYYeZfvs,6662
@@ -30,7 +30,7 @@ ScriptCollection/TFCPS/TFCPS_Generic.py,sha256=O-0guM_LJCcZmPZJhMgTvXD2RXUJEBWWv
30
30
  ScriptCollection/TFCPS/TFCPS_MergeToMain.py,sha256=-Ev9D3bZDlUk2WFQhcmvzQ3FCS97OdsVUd0koAdmpZc,7474
31
31
  ScriptCollection/TFCPS/TFCPS_MergeToStable.py,sha256=Ajfy2pLajTuU6UpwItHt4C2a-gLF3gPc4z6BktL3Cio,22163
32
32
  ScriptCollection/TFCPS/TFCPS_PreBuildCodeunitsScript.py,sha256=f0Uq1cA_4LvmL72cal0crrbKF6PcxL13D9wBKuQ1YBw,2328
33
- ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=e_v-YqtRW1Qe4xvuOZYq3WZJKdnOScgfHu8H-keC-gE,93779
33
+ ScriptCollection/TFCPS/TFCPS_Tools_General.py,sha256=s4DPntMzNe-hEEYeR_PAtzxb2eJM0Fp4LhK5rV_NVuE,93928
34
34
  ScriptCollection/TFCPS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  ScriptCollection/TFCPS/Docker/TFCPS_CodeUnitSpecific_Docker.py,sha256=BPJkoy2KVgB_38cAk5qjM4s4FpJvOkTp467nrvANIIU,10606
36
36
  ScriptCollection/TFCPS/Docker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -43,12 +43,12 @@ ScriptCollection/TFCPS/Flutter/TFCPS_CodeUnitSpecific_Flutter.py,sha256=U8oBAOLR
43
43
  ScriptCollection/TFCPS/Flutter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  ScriptCollection/TFCPS/Go/TFCPS_CodeUnitSpecific_Go.py,sha256=kyx26AnT1-LySFA46wfJ9yZUKYdMWTD0U2XZfSQbuB0,3497
45
45
  ScriptCollection/TFCPS/Go/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
- ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=t8HJQ0ZW8YkGoWdkLC-eDhi9dJl0ohjTEYcj8aoNSP0,11850
46
+ ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=BBWrFaAUVdmjl8qPq231aYlAENnjF1BOWXQQmOrQdxE,11816
47
47
  ScriptCollection/TFCPS/NodeJS/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  ScriptCollection/TFCPS/Python/TFCPS_CodeUnitSpecific_Python.py,sha256=nLw_eSUd_56jjgfcAvtUyzecSZ14mYmNJl0iu-1YNVk,13496
49
49
  ScriptCollection/TFCPS/Python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
- scriptcollection-4.2.54.dist-info/METADATA,sha256=j7wHIpFF0_JAn0rHeTOOeWLWxreUr42rfTpt1yelKjY,7690
51
- scriptcollection-4.2.54.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
52
- scriptcollection-4.2.54.dist-info/entry_points.txt,sha256=27XwAJEcaMEc1be0Ec1vKHCbiU4Ziu8jKL-SqsrYOIQ,4680
53
- scriptcollection-4.2.54.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
54
- scriptcollection-4.2.54.dist-info/RECORD,,
50
+ scriptcollection-4.2.56.dist-info/METADATA,sha256=Zmiu4fHdrglsMZrShG8yxyKzwqsi5RqKsW4EXESthCw,7690
51
+ scriptcollection-4.2.56.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
52
+ scriptcollection-4.2.56.dist-info/entry_points.txt,sha256=27XwAJEcaMEc1be0Ec1vKHCbiU4Ziu8jKL-SqsrYOIQ,4680
53
+ scriptcollection-4.2.56.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
54
+ scriptcollection-4.2.56.dist-info/RECORD,,