ScriptCollection 4.2.55__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.
@@ -37,7 +37,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
37
37
  from .ProgramRunnerPopen import ProgramRunnerPopen
38
38
  from .SCLog import SCLog, LogLevel
39
39
 
40
- version = "4.2.55"
40
+ version = "4.2.56"
41
41
  __version__ = version
42
42
 
43
43
  class VSCodeWorkspaceShellTask:
@@ -3123,11 +3123,80 @@ OCR-content:
3123
3123
 
3124
3124
  #sync existing files
3125
3125
  self.__sync_xlf2_files(base_file_xml, language_files_with_content)
3126
-
3126
+
3127
3127
  @GeneralUtilities.check_arguments
3128
- def translate_messages_in_folder(self,folder:str,base_language:str, api_server:str):
3129
- pass#TODO for each file in folder: call self.translate(...)
3130
-
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
+
3131
3137
  @GeneralUtilities.check_arguments
3132
- def translate(self,content:str, source_language:str, target_language:str,api_server:str)->str:
3133
- 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"]
@@ -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.55
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=RP0uhnHlZGtVxzOUjMzX0zGQ9OA7IjexFgJH6jOcI1Q,170736
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
@@ -47,8 +47,8 @@ ScriptCollection/TFCPS/NodeJS/TFCPS_CodeUnitSpecific_NodeJS.py,sha256=BBWrFaAUVd
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.55.dist-info/METADATA,sha256=4gNDfxGTvE09BqqV8gBNTLsHpqDVRywDDUSOtZfksTs,7690
51
- scriptcollection-4.2.55.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
52
- scriptcollection-4.2.55.dist-info/entry_points.txt,sha256=27XwAJEcaMEc1be0Ec1vKHCbiU4Ziu8jKL-SqsrYOIQ,4680
53
- scriptcollection-4.2.55.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
54
- scriptcollection-4.2.55.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,,