ScriptCollection 3.5.138__py3-none-any.whl → 3.5.140__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.
- ScriptCollection/Executables.py +68 -3
- ScriptCollection/ImageUpdater.py +78 -33
- ScriptCollection/ScriptCollectionCore.py +88 -10
- ScriptCollection/TasksForCommonProjectStructure.py +25 -8
- {scriptcollection-3.5.138.dist-info → scriptcollection-3.5.140.dist-info}/METADATA +4 -4
- {scriptcollection-3.5.138.dist-info → scriptcollection-3.5.140.dist-info}/RECORD +9 -9
- {scriptcollection-3.5.138.dist-info → scriptcollection-3.5.140.dist-info}/entry_points.txt +4 -0
- {scriptcollection-3.5.138.dist-info → scriptcollection-3.5.140.dist-info}/WHEEL +0 -0
- {scriptcollection-3.5.138.dist-info → scriptcollection-3.5.140.dist-info}/top_level.txt +0 -0
ScriptCollection/Executables.py
CHANGED
@@ -8,6 +8,7 @@ import keyboard
|
|
8
8
|
from .TasksForCommonProjectStructure import TasksForCommonProjectStructure
|
9
9
|
from .ScriptCollectionCore import ScriptCollectionCore
|
10
10
|
from .GeneralUtilities import GeneralUtilities
|
11
|
+
from .ImageUpdater import ImageUpdater, VersionEcholon
|
11
12
|
|
12
13
|
|
13
14
|
def FilenameObfuscator() -> int:
|
@@ -635,7 +636,7 @@ def Espoc() -> int:
|
|
635
636
|
parser.add_argument('-p', '--processid', required=True)
|
636
637
|
parser.add_argument('-f', '--file', required=True, help='Specifies the file where the process-ids of the started processes are stored (line by line). This file will be deleted when all started processes are terminated.')
|
637
638
|
args = parser.parse_args()
|
638
|
-
process_id =int(args.processid)
|
639
|
+
process_id = int(args.processid)
|
639
640
|
process_list_file: str = args.file
|
640
641
|
if not os.path.isabs(process_list_file):
|
641
642
|
process_list_file = GeneralUtilities.resolve_relative_path(process_list_file, os.getcwd())
|
@@ -654,10 +655,74 @@ def Espoc() -> int:
|
|
654
655
|
GeneralUtilities.write_message_to_stdout(f"File '{process_list_file}' does not exist. No processes to terminate.")
|
655
656
|
return 0
|
656
657
|
|
657
|
-
|
658
|
+
|
659
|
+
def ConvertGitRepositoryToBareRepository() -> int:
|
658
660
|
parser = argparse.ArgumentParser(description="Converts a local git-repository to a bare repository.")
|
659
661
|
parser.add_argument('-f', '--folder', required=True, help='Git-repository-folder which should be converted.')
|
660
662
|
args = parser.parse_args()
|
661
|
-
sc=ScriptCollectionCore()
|
663
|
+
sc = ScriptCollectionCore()
|
662
664
|
sc.convert_git_repository_to_bare_repository(args.folder)
|
663
665
|
return 0
|
666
|
+
|
667
|
+
|
668
|
+
def OCRAnalysisOfFolder() -> int:
|
669
|
+
parser = argparse.ArgumentParser()
|
670
|
+
parser.add_argument('-s', '--serviceaddress', required=False, default=None)
|
671
|
+
parser.add_argument('-e', '--extensions', required=False, default=None)
|
672
|
+
parser.add_argument('-l', '--languages', required=False, default="en")
|
673
|
+
parser.add_argument('-f', '--folder', required=False, default=None)
|
674
|
+
args = parser.parse_args()
|
675
|
+
sc = ScriptCollectionCore()
|
676
|
+
if args.folder is None:
|
677
|
+
args.folder = os.getcwd()
|
678
|
+
extensions_value: str = None
|
679
|
+
if args.extensions is not None:
|
680
|
+
if "," in args.extensions:
|
681
|
+
extensions_value = args.extensions.split(",")
|
682
|
+
else:
|
683
|
+
extensions_value = [args.extensions]
|
684
|
+
sc.ocr_analysis_of_folder(args.folder, args.serviceaddress, extensions_value, args.languages)
|
685
|
+
return 0
|
686
|
+
|
687
|
+
|
688
|
+
def OCRAnalysisOfFile() -> int:
|
689
|
+
parser = argparse.ArgumentParser()
|
690
|
+
parser.add_argument('-s', '--serviceaddress', required=False, default=None)
|
691
|
+
parser.add_argument('-l', '--languages', required=False, default="en")
|
692
|
+
parser.add_argument('-f', '--file', required=True)
|
693
|
+
args = parser.parse_args()
|
694
|
+
sc = ScriptCollectionCore()
|
695
|
+
sc.ocr_analysis_of_file(args.file, args.serviceaddress, args.languages)
|
696
|
+
return 0
|
697
|
+
|
698
|
+
|
699
|
+
def OCRAnalysisOfRepository() -> int:
|
700
|
+
parser = argparse.ArgumentParser()
|
701
|
+
parser.add_argument('-s', '--serviceaddress', required=False, default=None)
|
702
|
+
parser.add_argument('-e', '--extensions', required=False, default=None)
|
703
|
+
parser.add_argument('-l', '--languages', required=False, default="en")
|
704
|
+
parser.add_argument('-f', '--folder', required=False, default=None)
|
705
|
+
args = parser.parse_args()
|
706
|
+
sc = ScriptCollectionCore()
|
707
|
+
if args.folder is None:
|
708
|
+
args.folder = os.getcwd()
|
709
|
+
extensions_value: str = None
|
710
|
+
if args.extensions is not None:
|
711
|
+
if "," in args.extensions:
|
712
|
+
extensions_value = args.extensions.split(",")
|
713
|
+
else:
|
714
|
+
extensions_value = [args.extensions]
|
715
|
+
sc.ocr_analysis_of_repository(args.folder, args.serviceaddress, extensions_value, args.languages)
|
716
|
+
return 0
|
717
|
+
|
718
|
+
|
719
|
+
def UpdateImagesInDockerComposeFile() -> int:
|
720
|
+
iu: ImageUpdater = ImageUpdater()
|
721
|
+
parser = argparse.ArgumentParser()
|
722
|
+
parser.add_argument('-f', '--file', required=False, default=None)
|
723
|
+
# TODO add option to specify ignored services and versionecholon
|
724
|
+
args = parser.parse_args()
|
725
|
+
if args.file is None:
|
726
|
+
args.file = os.path.join(os.getcwd(), "docker-compose.yml")
|
727
|
+
iu.update_all_services_in_docker_compose_file(args.file, VersionEcholon.LatestPatch, [])
|
728
|
+
return 0
|
ScriptCollection/ImageUpdater.py
CHANGED
@@ -11,7 +11,7 @@ from .GeneralUtilities import GeneralUtilities
|
|
11
11
|
|
12
12
|
|
13
13
|
class VersionEcholon(Enum):
|
14
|
-
|
14
|
+
LatestPatch = 0
|
15
15
|
LatestPatchOrLatestMinor = 1
|
16
16
|
LatestPatchOrLatestMinorOrNextMajor = 2
|
17
17
|
Newest = 3
|
@@ -63,8 +63,8 @@ class ImageUpdaterHelper:
|
|
63
63
|
|
64
64
|
@staticmethod
|
65
65
|
@GeneralUtilities.check_arguments
|
66
|
-
def
|
67
|
-
if version_echolon == VersionEcholon.
|
66
|
+
def filter_considering_echolon(newer_versions: list[Version], current_version: Version, version_echolon: VersionEcholon) -> Version:
|
67
|
+
if version_echolon == VersionEcholon.LatestPatch:
|
68
68
|
return ImageUpdaterHelper._internal_get_latest_patch_version(newer_versions, current_version)
|
69
69
|
elif version_echolon == VersionEcholon.LatestPatchOrLatestMinor:
|
70
70
|
return ImageUpdaterHelper._internal_get_latest_patch_or_latest_minor_version(newer_versions, current_version)
|
@@ -137,11 +137,14 @@ class ConcreteImageUpdaterForNginx(ConcreteImageUpdater):
|
|
137
137
|
|
138
138
|
@GeneralUtilities.check_arguments
|
139
139
|
def version_to_tag(self, version: Version) -> str:
|
140
|
-
|
140
|
+
return f"{version.major}.{version.minor}.{version.micro}"
|
141
141
|
|
142
142
|
@GeneralUtilities.check_arguments
|
143
143
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
144
|
-
|
144
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^\\d+\\.\\d+\\.\\d+$", 999)
|
145
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
146
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
147
|
+
return result
|
145
148
|
|
146
149
|
@GeneralUtilities.check_arguments
|
147
150
|
def get_supported_images(self) -> list[str]:
|
@@ -149,14 +152,36 @@ class ConcreteImageUpdaterForNginx(ConcreteImageUpdater):
|
|
149
152
|
|
150
153
|
@GeneralUtilities.check_arguments
|
151
154
|
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
152
|
-
|
155
|
+
return ve.parse(tag)
|
156
|
+
|
157
|
+
|
158
|
+
class ConcreteImageUpdaterForWordpress(ConcreteImageUpdater):
|
159
|
+
|
160
|
+
@GeneralUtilities.check_arguments
|
161
|
+
def version_to_tag(self, version: Version) -> str:
|
162
|
+
return f"{version.major}.{version.minor}.{version.micro}"
|
163
|
+
|
164
|
+
@GeneralUtilities.check_arguments
|
165
|
+
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
166
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^\\d+\\.\\d+\\.\\d+$", 999)
|
167
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
168
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
169
|
+
return result
|
170
|
+
|
171
|
+
@GeneralUtilities.check_arguments
|
172
|
+
def get_supported_images(self) -> list[str]:
|
173
|
+
return ["wordpress"]
|
174
|
+
|
175
|
+
@GeneralUtilities.check_arguments
|
176
|
+
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
177
|
+
return ve.parse(tag)
|
153
178
|
|
154
179
|
|
155
180
|
class ConcreteImageUpdaterForGitLab(ConcreteImageUpdater):
|
156
181
|
|
157
182
|
@GeneralUtilities.check_arguments
|
158
183
|
def version_to_tag(self, version: Version) -> str:
|
159
|
-
|
184
|
+
return f"{version.major}.{version.minor}.{version.micro}-ce.0"
|
160
185
|
|
161
186
|
@GeneralUtilities.check_arguments
|
162
187
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
@@ -175,96 +200,111 @@ class ConcreteImageUpdaterForRegistry(ConcreteImageUpdater):
|
|
175
200
|
|
176
201
|
@GeneralUtilities.check_arguments
|
177
202
|
def version_to_tag(self, version: Version) -> str:
|
178
|
-
|
203
|
+
return f"{version.major}.{version.minor}.{version.micro}"
|
179
204
|
|
180
205
|
@GeneralUtilities.check_arguments
|
181
206
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
182
|
-
|
207
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^\\d+\\.\\d+\\.\\d+$", 999)
|
208
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
209
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
210
|
+
return result
|
183
211
|
|
184
212
|
@abstractmethod
|
185
213
|
@GeneralUtilities.check_arguments
|
186
214
|
def get_supported_images(self) -> list[str]:
|
187
|
-
return []
|
215
|
+
return ["registry"]
|
188
216
|
|
189
217
|
@GeneralUtilities.check_arguments
|
190
218
|
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
191
|
-
|
219
|
+
return ve.parse(tag)
|
192
220
|
|
193
221
|
|
194
222
|
class ConcreteImageUpdaterForPrometheus(ConcreteImageUpdater):
|
195
223
|
|
196
224
|
@GeneralUtilities.check_arguments
|
197
225
|
def version_to_tag(self, version: Version) -> str:
|
198
|
-
|
226
|
+
return f"v{version.major}.{version.minor}.{version.micro}"
|
199
227
|
|
200
228
|
@GeneralUtilities.check_arguments
|
201
229
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
202
|
-
|
230
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^v\\d+\\.\\d+\\.\\d+$", 999)
|
231
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
232
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
233
|
+
return result
|
203
234
|
|
204
235
|
@GeneralUtilities.check_arguments
|
205
236
|
def get_supported_images(self) -> list[str]:
|
206
|
-
return []
|
237
|
+
return ["prom/prometheus"]
|
207
238
|
|
208
239
|
@GeneralUtilities.check_arguments
|
209
240
|
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
210
|
-
|
241
|
+
return ve.parse(tag[1:])
|
211
242
|
|
212
243
|
|
213
244
|
class ConcreteImageUpdaterForPrometheusBlackboxExporter(ConcreteImageUpdater):
|
214
245
|
|
215
246
|
@GeneralUtilities.check_arguments
|
216
247
|
def version_to_tag(self, version: Version) -> str:
|
217
|
-
|
248
|
+
return f"v{version.major}.{version.minor}.{version.micro}"
|
218
249
|
|
219
250
|
@GeneralUtilities.check_arguments
|
220
251
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
221
|
-
|
252
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^v\\d+\\.\\d+\\.\\d+$", 999)
|
253
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
254
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
255
|
+
return result
|
222
256
|
|
223
257
|
@GeneralUtilities.check_arguments
|
224
258
|
def get_supported_images(self) -> list[str]:
|
225
|
-
return []
|
259
|
+
return ["prom/blackbox-exporter"]
|
226
260
|
|
227
261
|
@GeneralUtilities.check_arguments
|
228
262
|
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
229
|
-
|
263
|
+
return ve.parse(tag[1:])
|
230
264
|
|
231
265
|
|
232
266
|
class ConcreteImageUpdaterForPrometheusNginxExporter(ConcreteImageUpdater):
|
233
267
|
|
234
268
|
@GeneralUtilities.check_arguments
|
235
269
|
def version_to_tag(self, version: Version) -> str:
|
236
|
-
|
270
|
+
return f"v{version.major}.{version.minor}.{version.micro}"
|
237
271
|
|
238
272
|
@GeneralUtilities.check_arguments
|
239
273
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
240
|
-
|
274
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^v\\d+\\.\\d+\\.\\d+$", 999)
|
275
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
276
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
277
|
+
return result
|
241
278
|
|
242
279
|
@GeneralUtilities.check_arguments
|
243
280
|
def get_supported_images(self) -> list[str]:
|
244
|
-
return []
|
281
|
+
return ["prom/nginx-prometheus-exporter"]
|
245
282
|
|
246
283
|
@GeneralUtilities.check_arguments
|
247
284
|
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
248
|
-
|
285
|
+
return ve.parse(tag[1:])
|
249
286
|
|
250
287
|
|
251
288
|
class ConcreteImageUpdaterForPrometheusNodeExporter(ConcreteImageUpdater):
|
252
289
|
|
253
290
|
@GeneralUtilities.check_arguments
|
254
291
|
def version_to_tag(self, version: Version) -> str:
|
255
|
-
|
292
|
+
return f"v{version.major}.{version.minor}.{version.micro}"
|
256
293
|
|
257
294
|
@GeneralUtilities.check_arguments
|
258
295
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
259
|
-
|
296
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^v\\d+\\.\\d+\\.\\d+$", 999)
|
297
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
298
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
299
|
+
return result
|
260
300
|
|
261
301
|
@GeneralUtilities.check_arguments
|
262
302
|
def get_supported_images(self) -> list[str]:
|
263
|
-
return []
|
303
|
+
return ["prom/node-exporter"]
|
264
304
|
|
265
305
|
@GeneralUtilities.check_arguments
|
266
306
|
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
267
|
-
|
307
|
+
return ve.parse(tag[1:])
|
268
308
|
|
269
309
|
|
270
310
|
class ConcreteImageUpdaterForKeycloak(ConcreteImageUpdater):
|
@@ -296,7 +336,7 @@ class ConcreteImageUpdaterForMariaDB(ConcreteImageUpdater):
|
|
296
336
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
297
337
|
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^\\d+\\.\\d+\\.\\d+$", 999)
|
298
338
|
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
299
|
-
result = ImageUpdaterHelper.
|
339
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
300
340
|
return result
|
301
341
|
|
302
342
|
@GeneralUtilities.check_arguments
|
@@ -312,19 +352,22 @@ class ConcreteImageUpdaterForPostgreSQL(ConcreteImageUpdater):
|
|
312
352
|
|
313
353
|
@GeneralUtilities.check_arguments
|
314
354
|
def version_to_tag(self, version: Version) -> str:
|
315
|
-
|
355
|
+
return f"{version.major}.{version.minor}"
|
316
356
|
|
317
357
|
@GeneralUtilities.check_arguments
|
318
358
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
319
|
-
|
359
|
+
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^\\d+\\.\\d+$", 999)
|
360
|
+
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
361
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
362
|
+
return result
|
320
363
|
|
321
364
|
@GeneralUtilities.check_arguments
|
322
365
|
def get_supported_images(self) -> list[str]:
|
323
|
-
return []
|
366
|
+
return ["postgres"]
|
324
367
|
|
325
368
|
@GeneralUtilities.check_arguments
|
326
369
|
def get_version_from_tag(self, image: str, tag: str) -> Version:
|
327
|
-
|
370
|
+
return ve.parse(tag+".0")
|
328
371
|
|
329
372
|
|
330
373
|
class ConcreteImageUpdaterForAdminer(ConcreteImageUpdater):
|
@@ -337,7 +380,7 @@ class ConcreteImageUpdaterForAdminer(ConcreteImageUpdater):
|
|
337
380
|
def get_latest_version_of_image(self, image: str, version_echolon: VersionEcholon, current_version: Version) -> Version:
|
338
381
|
versions = ImageUpdaterHelper.get_versions_in_docker_hub(image, ".", "^\\d+\\.\\d+\\.\\d+$", 999)
|
339
382
|
newer_versions = ImageUpdaterHelper.filter_for_newer_versions(current_version, versions)
|
340
|
-
result = ImageUpdaterHelper.
|
383
|
+
result = ImageUpdaterHelper.filter_considering_echolon(newer_versions, current_version, version_echolon)
|
341
384
|
return result
|
342
385
|
|
343
386
|
@GeneralUtilities.check_arguments
|
@@ -358,6 +401,7 @@ class ImageUpdater:
|
|
358
401
|
|
359
402
|
def add_default_mapper(self) -> None:
|
360
403
|
self.updater.append(ConcreteImageUpdaterForNginx())
|
404
|
+
self.updater.append(ConcreteImageUpdaterForWordpress())
|
361
405
|
self.updater.append(ConcreteImageUpdaterForGitLab())
|
362
406
|
self.updater.append(ConcreteImageUpdaterForRegistry())
|
363
407
|
self.updater.append(ConcreteImageUpdaterForPrometheus())
|
@@ -415,6 +459,7 @@ class ImageUpdater:
|
|
415
459
|
result = self.get_latest_version_of_image(imagename, version_echolon, existing_version)
|
416
460
|
newest_version = result[0]
|
417
461
|
newest_tag = result[1]
|
462
|
+
# TODO write info to console if there is a newwer version available if versionecoholon==latest would have been chosen
|
418
463
|
if existing_version < newest_version:
|
419
464
|
|
420
465
|
with open(dockercompose_file, 'r', encoding="utf-8") as f:
|
@@ -33,7 +33,7 @@ from .ProgramRunnerPopen import ProgramRunnerPopen
|
|
33
33
|
from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
|
34
34
|
from .SCLog import SCLog, LogLevel
|
35
35
|
|
36
|
-
version = "3.5.
|
36
|
+
version = "3.5.140"
|
37
37
|
__version__ = version
|
38
38
|
|
39
39
|
|
@@ -309,7 +309,7 @@ class ScriptCollectionCore:
|
|
309
309
|
|
310
310
|
@GeneralUtilities.check_arguments
|
311
311
|
def git_pull_with_retry(self, folder: str, remote: str, localbranchname: str, remotebranchname: str, force: bool = False, amount_of_attempts: int = 5) -> None:
|
312
|
-
GeneralUtilities.retry_action(lambda: self.
|
312
|
+
GeneralUtilities.retry_action(lambda: self.git_pull(folder, remote, localbranchname, remotebranchname), amount_of_attempts)
|
313
313
|
|
314
314
|
@GeneralUtilities.check_arguments
|
315
315
|
def git_pull(self, folder: str, remote: str, localbranchname: str, remotebranchname: str, force: bool = False) -> None:
|
@@ -688,7 +688,7 @@ class ScriptCollectionCore:
|
|
688
688
|
raise ValueError(f"Folder '{folder}' does not exist.")
|
689
689
|
git_folder_path = f"{folder}/.git"
|
690
690
|
return self.is_folder(git_folder_path) or self.is_file(git_folder_path)
|
691
|
-
|
691
|
+
|
692
692
|
@GeneralUtilities.check_arguments
|
693
693
|
def is_bare_git_repository(self, folder: str) -> bool:
|
694
694
|
"""This function works platform-independent also for non-local-executions if the ScriptCollection commandline-commands are available as global command on the target-system."""
|
@@ -697,26 +697,25 @@ class ScriptCollectionCore:
|
|
697
697
|
if not self.is_folder(folder):
|
698
698
|
raise ValueError(f"Folder '{folder}' does not exist.")
|
699
699
|
return folder.endswith(".git")
|
700
|
-
|
700
|
+
|
701
701
|
@GeneralUtilities.check_arguments
|
702
702
|
def is_git_or_bare_git_repository(self, folder: str) -> bool:
|
703
703
|
"""This function works platform-independent also for non-local-executions if the ScriptCollection commandline-commands are available as global command on the target-system."""
|
704
|
-
return self.is_git_repository(folder) or self.is_bare_git_repository(folder)
|
704
|
+
return self.is_git_repository(folder) or self.is_bare_git_repository(folder)
|
705
705
|
|
706
706
|
@GeneralUtilities.check_arguments
|
707
707
|
def assert_is_git_repository(self, folder: str) -> str:
|
708
708
|
"""This function works platform-independent also for non-local-executions if the ScriptCollection commandline-commands are available as global command on the target-system."""
|
709
709
|
GeneralUtilities.assert_condition(self.is_git_repository(folder), f"'{folder}' is not a git-repository.")
|
710
710
|
|
711
|
-
|
712
711
|
@GeneralUtilities.check_arguments
|
713
|
-
def convert_git_repository_to_bare_repository(self,repository_folder:str):
|
714
|
-
repository_folder=repository_folder.replace("\\", "/")
|
712
|
+
def convert_git_repository_to_bare_repository(self, repository_folder: str):
|
713
|
+
repository_folder = repository_folder.replace("\\", "/")
|
715
714
|
self.assert_is_git_repository(repository_folder)
|
716
|
-
git_folder=repository_folder+ "/.git"
|
715
|
+
git_folder = repository_folder + "/.git"
|
717
716
|
if not self.is_folder(git_folder):
|
718
717
|
raise ValueError(f"Converting '{repository_folder}' to a bare repository not possible. The folder '{git_folder}' does not exist. Converting is currently only supported when the git-folder is a direct folder in a repository and not a reference to another location.")
|
719
|
-
target_folder:str = repository_folder + ".git"
|
718
|
+
target_folder: str = repository_folder + ".git"
|
720
719
|
GeneralUtilities.ensure_directory_exists(target_folder)
|
721
720
|
GeneralUtilities.move_content_of_folder(git_folder, target_folder)
|
722
721
|
GeneralUtilities.ensure_directory_does_not_exist(repository_folder)
|
@@ -2336,3 +2335,82 @@ TXDX
|
|
2336
2335
|
@GeneralUtilities.check_arguments
|
2337
2336
|
def install_requirementstxt_file(self, requirements_txt_file: str, folder: str, verbosity: int):
|
2338
2337
|
self.run_program_argsasarray("pip", ["install", "-r", requirements_txt_file], folder, verbosity=verbosity)
|
2338
|
+
|
2339
|
+
@GeneralUtilities.check_arguments
|
2340
|
+
def ocr_analysis_of_folder(self, folder: str, serviceaddress: str, extensions: list[str], languages: list[str]) -> list[str]: # Returns a list of changed files due to ocr-analysis.
|
2341
|
+
GeneralUtilities.write_message_to_stdout("Starting OCR analysis of folder " + folder)
|
2342
|
+
supported_extensions = ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'gif', 'pdf', 'docx', 'doc', 'xlsx', 'xls', 'pptx', 'ppt']
|
2343
|
+
changes_files: list[str] = []
|
2344
|
+
if extensions is None:
|
2345
|
+
extensions = supported_extensions
|
2346
|
+
for file in GeneralUtilities.get_direct_files_of_folder(folder):
|
2347
|
+
file_lower = file.lower()
|
2348
|
+
for extension in extensions:
|
2349
|
+
if file_lower.endswith("."+extension):
|
2350
|
+
if self.ocr_analysis_of_file(file, serviceaddress, languages):
|
2351
|
+
changes_files.append(file)
|
2352
|
+
break
|
2353
|
+
for subfolder in GeneralUtilities.get_direct_folders_of_folder(folder):
|
2354
|
+
for file in self.ocr_analysis_of_folder(subfolder, serviceaddress, extensions, languages):
|
2355
|
+
changes_files.append(file)
|
2356
|
+
return changes_files
|
2357
|
+
|
2358
|
+
@GeneralUtilities.check_arguments
|
2359
|
+
def ocr_analysis_of_file(self, file: str, serviceaddress: str, languages: list[str]) -> bool: # Returns true if the ocr-file was generated or updated. Returns false if the existing ocr-file was not changed.
|
2360
|
+
GeneralUtilities.write_message_to_stdout("Do OCR analysis of file " + file)
|
2361
|
+
supported_extensions = ['png', 'jpg', 'jpeg', 'tiff', 'bmp', 'webp', 'gif', 'pdf', 'rtf', 'docx', 'doc', 'odt', 'xlsx', 'xls', 'ods', 'pptx', 'ppt', 'odp']
|
2362
|
+
for extension in supported_extensions:
|
2363
|
+
if file.lower().endswith("."+extension):
|
2364
|
+
raise ValueError(f"Extension '{extension}' is not supported. Supported extensions are: {', '.join(supported_extensions)}")
|
2365
|
+
target_file = file+".ocr.txt"
|
2366
|
+
hash_of_current_file: str = GeneralUtilities. get_sha256_of_file(file)
|
2367
|
+
if os.path.isfile(target_file):
|
2368
|
+
lines = GeneralUtilities.read_lines_from_file(target_file)
|
2369
|
+
previous_hash_of_current_file: str = lines[1].split(":")[1].strip()
|
2370
|
+
if hash_of_current_file == previous_hash_of_current_file:
|
2371
|
+
return False
|
2372
|
+
ocr_content = self.get_ocr_content_of_file(file, serviceaddress, languages)
|
2373
|
+
GeneralUtilities.ensure_file_exists(target_file)
|
2374
|
+
GeneralUtilities.write_text_to_file(file, f"""Name of file: \"{os.path.basename(file)}\""
|
2375
|
+
Hash of file: {hash_of_current_file}
|
2376
|
+
OCR-content:
|
2377
|
+
\"{ocr_content}\"""")
|
2378
|
+
return True
|
2379
|
+
|
2380
|
+
@GeneralUtilities.check_arguments
|
2381
|
+
def get_ocr_content_of_file(self, file: str, serviceaddress: str, languages: list[str]) -> str: # serviceaddress = None means local executable
|
2382
|
+
result: str = None
|
2383
|
+
extension = Path(file).suffix
|
2384
|
+
if serviceaddress is None:
|
2385
|
+
program_result = self.run_program_argsasarray("simpleocr", ["--File", file, "--Languages", "+".join(languages)] + languages)
|
2386
|
+
result = program_result[1]
|
2387
|
+
else:
|
2388
|
+
languages_for_url = '%2B'.join(languages)
|
2389
|
+
package_url: str = f"https://{serviceaddress}/GetOCRContent?languages={languages_for_url}&fileType={extension}"
|
2390
|
+
headers = {'Cache-Control': 'no-cache'}
|
2391
|
+
r = requests.put(package_url, timeout=5, headers=headers, data=GeneralUtilities.read_binary_from_file(file))
|
2392
|
+
if r.status_code != 200:
|
2393
|
+
raise ValueError(f"Checking for latest tor package resulted in HTTP-response-code {r.status_code}.")
|
2394
|
+
result = GeneralUtilities.bytes_to_string(r.content)
|
2395
|
+
return result
|
2396
|
+
|
2397
|
+
@GeneralUtilities.check_arguments
|
2398
|
+
def ocr_analysis_of_repository(self, folder: str, serviceaddress: str, extensions: list[str], languages: list[str]) -> None:
|
2399
|
+
self.assert_is_git_repository(folder)
|
2400
|
+
changed_files = self.ocr_analysis_of_folder(folder, serviceaddress, extensions, languages)
|
2401
|
+
for changed_ocr_file in changed_files:
|
2402
|
+
GeneralUtilities.assert_condition(changed_ocr_file.endswith(".ocr.txt"), f"File '{changed_ocr_file}' is not an OCR-file. It should end with '.ocr.txt'.")
|
2403
|
+
base_file = changed_ocr_file[:-len(".ocr.txt")]
|
2404
|
+
GeneralUtilities.assert_condition(os.path.isfile(base_file), f"Base file '{base_file}' does not exist. The OCR-file '{changed_ocr_file}' is not valid.")
|
2405
|
+
base_file_relative_path = os.path.relpath(base_file, folder)
|
2406
|
+
base_file_diff_program_result = self.run_program("git", f"diff --quiet -- \"{base_file_relative_path}\"", folder, throw_exception_if_exitcode_is_not_zero=False)
|
2407
|
+
has_staged_changes: bool = None
|
2408
|
+
if base_file_diff_program_result[0] == 0:
|
2409
|
+
has_staged_changes = False
|
2410
|
+
elif base_file_diff_program_result[0] == 1:
|
2411
|
+
has_staged_changes = True
|
2412
|
+
else:
|
2413
|
+
raise RuntimeError(f"Unexpected exit code {base_file_diff_program_result[0]} when checking for staged changes of file '{base_file_relative_path}'.")
|
2414
|
+
if has_staged_changes:
|
2415
|
+
changed_ocr_file_relative_path = os.path.relpath(changed_ocr_file, folder)
|
2416
|
+
self.run_program_argsasarray("git", ["add", changed_ocr_file_relative_path], folder)
|
@@ -2360,6 +2360,7 @@ class TasksForCommonProjectStructure:
|
|
2360
2360
|
tasks.sort(key=lambda x: x["label"].split("/")[-1], reverse=False) # sort by the label of the task
|
2361
2361
|
for task in tasks:
|
2362
2362
|
if task["type"] == "shell":
|
2363
|
+
|
2363
2364
|
description: str = task["label"]
|
2364
2365
|
name: str = GeneralUtilities.to_pascal_case(description)
|
2365
2366
|
command = task["command"]
|
@@ -2381,11 +2382,18 @@ class TasksForCommonProjectStructure:
|
|
2381
2382
|
if len(args) > 1:
|
2382
2383
|
command_with_args = f"{command_with_args} {' '.join(args)}"
|
2383
2384
|
|
2385
|
+
if "description" in task:
|
2386
|
+
additional_description = task["description"]
|
2387
|
+
description = f"{description} ({additional_description})"
|
2388
|
+
|
2384
2389
|
if append_cli_args_at_end:
|
2385
2390
|
command_with_args = f"{command_with_args} {{{{.CLI_ARGS}}}}"
|
2386
|
-
|
2391
|
+
|
2392
|
+
cwd_literal = cwd.replace("\\", "\\\\").replace('"', '\\"') # escape backslashes and double quotes for YAML
|
2393
|
+
description_literal = description.replace("\\", "\\\\").replace('"', '\\"') # escape backslashes and double quotes for YAML
|
2394
|
+
|
2387
2395
|
lines.append(f" {name}:")
|
2388
|
-
lines.append(f' desc: "{
|
2396
|
+
lines.append(f' desc: "{description_literal}"')
|
2389
2397
|
lines.append(' silent: true')
|
2390
2398
|
lines.append(f' dir: "{cwd_literal}"')
|
2391
2399
|
lines.append(" cmds:")
|
@@ -2397,6 +2405,7 @@ class TasksForCommonProjectStructure:
|
|
2397
2405
|
for alias in aliases:
|
2398
2406
|
lines.append(f' - {alias}')
|
2399
2407
|
lines.append(GeneralUtilities.empty_string)
|
2408
|
+
|
2400
2409
|
GeneralUtilities.write_lines_to_file(task_file, lines)
|
2401
2410
|
|
2402
2411
|
@GeneralUtilities.check_arguments
|
@@ -2560,6 +2569,14 @@ class TasksForCommonProjectStructure:
|
|
2560
2569
|
from_day = datetime(now.year, now.month, now.day, 0, 0, 0)
|
2561
2570
|
self.mark_current_version_as_supported(repository_folder, project_version, from_day, until_day)
|
2562
2571
|
|
2572
|
+
package_json_file = os.path.join(repository_folder, "package.json")
|
2573
|
+
if os.path.isfile(package_json_file):
|
2574
|
+
with open(package_json_file, "r", encoding="utf-8") as f1:
|
2575
|
+
package_json_data = json.load(f1)
|
2576
|
+
package_json_data["version"] = project_version
|
2577
|
+
with open(package_json_file, "w", encoding="utf-8") as f2:
|
2578
|
+
json.dump(package_json_data, f2, indent=2)
|
2579
|
+
|
2563
2580
|
project_resources_folder = os.path.join(repository_folder, "Other", "Scripts")
|
2564
2581
|
PrepareBuildCodeunits_script_name = "PrepareBuildCodeunits.py"
|
2565
2582
|
prepare_build_codeunits_scripts = os.path.join(project_resources_folder, PrepareBuildCodeunits_script_name)
|
@@ -3115,7 +3132,7 @@ class TasksForCommonProjectStructure:
|
|
3115
3132
|
# TODO validate artifactsinformation_file against xsd
|
3116
3133
|
GeneralUtilities.write_message_to_stdout(f"Finished building codeunit {codeunit_name} without errors.")
|
3117
3134
|
|
3118
|
-
def
|
3135
|
+
def __ensure_changelog_file_is_added(self, repository_folder: str, version_of_project: str):
|
3119
3136
|
changelog_file = os.path.join(repository_folder, "Other", "Resources", "Changelog", f"v{version_of_project}.md")
|
3120
3137
|
if not os.path.isfile(changelog_file):
|
3121
3138
|
GeneralUtilities.ensure_file_exists(changelog_file)
|
@@ -3136,16 +3153,16 @@ class TasksForCommonProjectStructure:
|
|
3136
3153
|
target_environmenttype = "QualityCheck"
|
3137
3154
|
project_name: str = os.path.basename(repository_folder)
|
3138
3155
|
GeneralUtilities.assert_condition(not self.__sc.git_repository_has_uncommitted_changes(repository_folder), "There are uncommitted changes in the repository.")
|
3156
|
+
self.build_codeunits(repository_folder, target_environmenttype=target_environmenttype, do_git_clean_when_no_changes=True, note="Prepare dependency-update") # Required because update dependencies is not always possible for not-buildet codeunits (depends on the programming language or package manager)
|
3139
3157
|
|
3140
3158
|
# update dependencies of resources
|
3141
3159
|
global_scripts_folder = os.path.join(repository_folder, "Other", "Scripts")
|
3142
3160
|
if os.path.isfile(os.path.join(global_scripts_folder, update_dependencies_script_filename)):
|
3143
|
-
self.build_codeunits(repository_folder, target_environmenttype=target_environmenttype, do_git_clean_when_no_changes=True, note="Prepare dependency-update") # Required because update dependencies is not always possible for not-buildet codeunits (depends on the programming language or package manager)
|
3144
3161
|
self.__sc.run_program("python", update_dependencies_script_filename, global_scripts_folder, print_live_output=True)
|
3145
3162
|
version_of_project = self.get_version_of_project(repository_folder)
|
3146
|
-
self.
|
3163
|
+
self.__ensure_changelog_file_is_added(repository_folder, version_of_project)
|
3147
3164
|
GeneralUtilities.write_message_to_stdout(f"Updated global dependencies of {project_name}.")
|
3148
|
-
self.build_codeunits(repository_folder, verbosity, "QualityCheck", None, False, None, [], False, "Build codeunits due to updated dependencies")
|
3165
|
+
self.build_codeunits(repository_folder, verbosity, "QualityCheck", None, False, None, [], False, "Build codeunits due to updated product-wide dependencies")
|
3149
3166
|
|
3150
3167
|
# update dependencies of codeunits
|
3151
3168
|
for codeunit in codeunits:
|
@@ -3160,10 +3177,10 @@ class TasksForCommonProjectStructure:
|
|
3160
3177
|
self.__sc.run_program("python", update_dependencies_script_filename, update_dependencies_script_folder, verbosity, print_live_output=True)
|
3161
3178
|
if self.__sc.git_repository_has_uncommitted_changes(repository_folder):
|
3162
3179
|
version_of_project = self.get_version_of_project(repository_folder)
|
3163
|
-
self.
|
3180
|
+
self.__ensure_changelog_file_is_added(repository_folder, version_of_project)
|
3164
3181
|
GeneralUtilities.write_message_to_stdout(f"Updated dependencies in codeunit {codeunit}.")
|
3165
3182
|
|
3166
|
-
self.build_codeunits(repository_folder, verbosity, "QualityCheck", None, False, None, [], False, "Build codeunits due to updated dependencies")
|
3183
|
+
self.build_codeunits(repository_folder, verbosity, "QualityCheck", None, False, None, [], False, "Build all codeunits due to updated dependencies")
|
3167
3184
|
self.__sc.git_commit(repository_folder, "Updated dependencies")
|
3168
3185
|
|
3169
3186
|
class GenericPrepareNewReleaseArguments:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: ScriptCollection
|
3
|
-
Version: 3.5.
|
3
|
+
Version: 3.5.140
|
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
|
@@ -23,7 +23,7 @@ Classifier: Topic :: Utilities
|
|
23
23
|
Requires-Python: >=3.10
|
24
24
|
Description-Content-Type: text/markdown
|
25
25
|
Requires-Dist: build>=1.2.2.post1
|
26
|
-
Requires-Dist: coverage>=7.
|
26
|
+
Requires-Dist: coverage>=7.9.1
|
27
27
|
Requires-Dist: cyclonedx-bom>=6.1.1
|
28
28
|
Requires-Dist: defusedxml>=0.7.1
|
29
29
|
Requires-Dist: keyboard>=0.13.5
|
@@ -37,12 +37,12 @@ Requires-Dist: Pygments>=2.19.1
|
|
37
37
|
Requires-Dist: pylint>=3.3.7
|
38
38
|
Requires-Dist: pyOpenSSL>=25.1.0
|
39
39
|
Requires-Dist: PyPDF>=5.6.0
|
40
|
-
Requires-Dist: pytest>=8.4.
|
40
|
+
Requires-Dist: pytest>=8.4.1
|
41
41
|
Requires-Dist: PyYAML>=6.0.2
|
42
42
|
Requires-Dist: qrcode>=8.2
|
43
43
|
Requires-Dist: send2trash>=1.8.3
|
44
44
|
Requires-Dist: twine>=6.1.0
|
45
|
-
Requires-Dist: xmlschema>=4.0
|
45
|
+
Requires-Dist: xmlschema>=4.1.0
|
46
46
|
|
47
47
|
# ScriptCollection
|
48
48
|
|
@@ -1,17 +1,17 @@
|
|
1
1
|
ScriptCollection/CertificateUpdater.py,sha256=OAxrG21k_o3W3niOOGNSZzUPJlvolOWc1lRB2dMhc3g,9212
|
2
|
-
ScriptCollection/Executables.py,sha256=
|
2
|
+
ScriptCollection/Executables.py,sha256=d9QkQuaS0nxTwNUGxtqKUk9dJqT5gS670LNuCz2YMw0,35349
|
3
3
|
ScriptCollection/GeneralUtilities.py,sha256=PKdzq382RYVSWeSG_6z6FiHu-SiTOi2BavJKvP-0slU,47308
|
4
|
-
ScriptCollection/ImageUpdater.py,sha256=
|
4
|
+
ScriptCollection/ImageUpdater.py,sha256=3B5pgAMnyne3ZogWz-suqglZGIB9FAKyWn31P9E1ST0,24491
|
5
5
|
ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
|
6
6
|
ScriptCollection/ProgramRunnerBase.py,sha256=2kMIAqdc65UjBAddOZkzy_aFx9h5roZ5a4bQNM6RV6Y,2480
|
7
7
|
ScriptCollection/ProgramRunnerEpew.py,sha256=4pjEd0r9Fcz3TTDv0MdTSd5KkigYXcWUVI1X43regfU,6477
|
8
8
|
ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
|
9
9
|
ScriptCollection/SCLog.py,sha256=Dd2P8vH2PA830wAv6bchlMHHdGE_7At-F4WQY5w4XdA,4016
|
10
|
-
ScriptCollection/ScriptCollectionCore.py,sha256=
|
11
|
-
ScriptCollection/TasksForCommonProjectStructure.py,sha256=
|
10
|
+
ScriptCollection/ScriptCollectionCore.py,sha256=RRwHiyjOKelBW0a52t4goDjm0Nm5yOz-r3grzkEPZRc,136482
|
11
|
+
ScriptCollection/TasksForCommonProjectStructure.py,sha256=Aln85JyVrspQmluNyNSFT4gPycVt42W_4dM21qys13c,236756
|
12
12
|
ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
-
scriptcollection-3.5.
|
14
|
-
scriptcollection-3.5.
|
15
|
-
scriptcollection-3.5.
|
16
|
-
scriptcollection-3.5.
|
17
|
-
scriptcollection-3.5.
|
13
|
+
scriptcollection-3.5.140.dist-info/METADATA,sha256=h47YkJZXJr_B_LQt2qF2bEJnHxtoc6Us-cKkxiVxBts,7694
|
14
|
+
scriptcollection-3.5.140.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
15
|
+
scriptcollection-3.5.140.dist-info/entry_points.txt,sha256=AvmVO9iyWImExpvzL3YYQ9AOEiUIN9guPRRG_W_VNWY,4116
|
16
|
+
scriptcollection-3.5.140.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
|
17
|
+
scriptcollection-3.5.140.dist-info/RECORD,,
|
@@ -35,6 +35,9 @@ sclistfoldercontent = ScriptCollection.Executables:ListFolderContent
|
|
35
35
|
scmergepdfs = ScriptCollection.Executables:MergePDFs
|
36
36
|
scnpmi = ScriptCollection.Executables:NpmI
|
37
37
|
scobfuscatefilesfolder = ScriptCollection.Executables:ObfuscateFilesFolder
|
38
|
+
scocranalysisoffile = ScriptCollection.Executables:OCRAnalysisOfFile
|
39
|
+
scocranalysisoffolder = ScriptCollection.Executables:OCRAnalysisOfFolder
|
40
|
+
scocranalysisofrepository = ScriptCollection.Executables:OCRAnalysisOfRepository
|
38
41
|
scorganizelinesinfile = ScriptCollection.Executables:OrganizeLinesInFile
|
39
42
|
scpdftoimage = ScriptCollection.Executables:PDFToImage
|
40
43
|
scprintcurrentworkingdirectory = ScriptCollection.Executables:PrintCurrecntWorkingDirectory
|
@@ -51,5 +54,6 @@ scsetcontentoffile = ScriptCollection.Executables:SetContentOfFile
|
|
51
54
|
scshow2faasqrcode = ScriptCollection.Executables:Show2FAAsQRCode
|
52
55
|
scshowmissingfiles = ScriptCollection.Executables:ShowMissingFiles
|
53
56
|
scsigncertificate = ScriptCollection.Executables:SignCertificate
|
57
|
+
scupdateimagesindockercomposefile = ScriptCollection.Executables:UpdateImagesInDockerComposeFile
|
54
58
|
scupdatenugetpackagesincsharpproject = ScriptCollection.Executables:UpdateNugetpackagesInCsharpProject
|
55
59
|
scuploadfile = ScriptCollection.Executables:UploadFile
|
File without changes
|
File without changes
|