ScriptCollection 3.5.12__py3-none-any.whl → 3.5.13__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.
@@ -574,12 +574,14 @@ class GeneralUtilities:
574
574
  @check_arguments
575
575
  def get_direct_files_of_folder(folder: str) -> list[str]:
576
576
  result = [os.path.join(folder, f) for f in listdir(folder) if isfile(join(folder, f))]
577
+ result = sorted(result, key=str.casefold)
577
578
  return result
578
579
 
579
580
  @staticmethod
580
581
  @check_arguments
581
582
  def get_direct_folders_of_folder(folder: str) -> list[str]:
582
583
  result = [os.path.join(folder, f) for f in listdir(folder) if isdir(join(folder, f))]
584
+ result = sorted(result, key=str.casefold)
583
585
  return result
584
586
 
585
587
  @staticmethod
@@ -589,6 +591,7 @@ class GeneralUtilities:
589
591
  result.extend(GeneralUtilities.get_direct_files_of_folder(folder))
590
592
  for subfolder in GeneralUtilities.get_direct_folders_of_folder(folder):
591
593
  result.extend(GeneralUtilities.get_all_files_of_folder(subfolder))
594
+ result = sorted(result, key=str.casefold)
592
595
  return result
593
596
 
594
597
  @staticmethod
@@ -599,12 +602,13 @@ class GeneralUtilities:
599
602
  result.extend(subfolders)
600
603
  for subfolder in subfolders:
601
604
  result.extend(GeneralUtilities.get_all_folders_of_folder(subfolder))
605
+ result = sorted(result, key=str.casefold)
602
606
  return result
603
607
 
604
608
  @staticmethod
605
609
  @check_arguments
606
610
  def get_all_objects_of_folder(folder: str) -> list[str]:
607
- return GeneralUtilities.get_all_files_of_folder(folder) + GeneralUtilities.get_all_folders_of_folder(folder)
611
+ return sorted(GeneralUtilities.get_all_files_of_folder(folder) + GeneralUtilities.get_all_folders_of_folder(folder), key=str.casefold)
608
612
 
609
613
  @staticmethod
610
614
  @check_arguments
@@ -29,7 +29,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
29
29
  from .ProgramRunnerPopen import ProgramRunnerPopen
30
30
  from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
31
31
 
32
- version = "3.5.12"
32
+ version = "3.5.13"
33
33
  __version__ = version
34
34
 
35
35
 
@@ -562,9 +562,11 @@ class ScriptCollectionCore:
562
562
  with open(target_file, "w", encoding=encoding) as file_object:
563
563
  file_object.write("\n".join(lines))
564
564
 
565
+ @GeneralUtilities.check_arguments
565
566
  def escape_git_repositories_in_folder(self, folder: str) -> dict[str, str]:
566
567
  return self.__escape_git_repositories_in_folder_internal(folder, dict[str, str]())
567
568
 
569
+ @GeneralUtilities.check_arguments
568
570
  def __escape_git_repositories_in_folder_internal(self, folder: str, renamed_items: dict[str, str]) -> dict[str, str]:
569
571
  for file in GeneralUtilities.get_direct_files_of_folder(folder):
570
572
  filename = os.path.basename(file)
@@ -586,10 +588,12 @@ class ScriptCollectionCore:
586
588
  self.__escape_git_repositories_in_folder_internal(subfolder2, renamed_items)
587
589
  return renamed_items
588
590
 
591
+ @GeneralUtilities.check_arguments
589
592
  def deescape_git_repositories_in_folder(self, renamed_items: dict[str, str]):
590
593
  for renamed_item, original_name in renamed_items.items():
591
594
  os.rename(renamed_item, original_name)
592
595
 
596
+ @GeneralUtilities.check_arguments
593
597
  def __sort_fmd(self, line: str):
594
598
  splitted: list = line.split(";")
595
599
  filetype: str = splitted[1]
@@ -626,29 +630,36 @@ class ScriptCollectionCore:
626
630
 
627
631
  @GeneralUtilities.check_arguments
628
632
  def __calculate_lengh_in_seconds(self, filename: str, folder: str) -> float:
629
- argument = ['-v', 'error', '-show_entries', 'format=duration',
630
- '-of', 'default=noprint_wrappers=1:nokey=1', filename]
633
+ argument = ['-v', 'error', '-show_entries', 'format=duration', '-of', 'default=noprint_wrappers=1:nokey=1', filename]
631
634
  result = self.run_program_argsasarray("ffprobe", argument, folder, throw_exception_if_exitcode_is_not_zero=True)
632
635
  return float(result[1].replace('\n', ''))
633
636
 
634
637
  @GeneralUtilities.check_arguments
635
- def __create_thumbnails(self, filename: str, fps: str, folder: str, tempname_for_thumbnails: str) -> None:
636
- argument = ['-i', filename, '-r', str(fps), '-vf', 'scale=-1:120',
637
- '-vcodec', 'png', f'{tempname_for_thumbnails}-%002d.png']
638
+ def __create_thumbnails(self, filename: str, fps: str, folder: str, tempname_for_thumbnails: str) -> list[str]:
639
+ argument = ['-i', filename, '-r', str(fps), '-vf', 'scale=-1:120', '-vcodec', 'png', f'{tempname_for_thumbnails}-%002d.png']
638
640
  self.run_program_argsasarray("ffmpeg", argument, folder, throw_exception_if_exitcode_is_not_zero=True)
641
+ files = GeneralUtilities.get_direct_files_of_folder(folder)
642
+ result: list[str] = []
643
+ regex = "^"+re.escape(tempname_for_thumbnails)+"\\-\\d+\\.png$"
644
+ regex_for_files = re.compile(regex)
645
+ for file in files:
646
+ filename = os.path.basename(file)
647
+ if regex_for_files.match(filename):
648
+ result.append(file)
649
+ GeneralUtilities.assert_condition(0 < len(result), "No thumbnail-files found.")
650
+ return result
639
651
 
640
652
  @GeneralUtilities.check_arguments
641
653
  def __create_thumbnail(self, outputfilename: str, folder: str, length_in_seconds: float, tempname_for_thumbnails: str, amount_of_images: int) -> None:
642
654
  duration = timedelta(seconds=length_in_seconds)
643
655
  info = GeneralUtilities.timedelta_to_simple_string(duration)
644
- next_square_number = str(int(math.sqrt(GeneralUtilities.get_next_square_number(amount_of_images))))
645
- argument = ['-title', f'"{outputfilename} ({info})"', '-tile', f'{next_square_number}x{next_square_number}',
646
- f'{tempname_for_thumbnails}*.png', f'{outputfilename}.png']
647
- self.run_program_argsasarray(
648
- "montage", argument, folder, throw_exception_if_exitcode_is_not_zero=True)
656
+ rows: int = 5
657
+ columns: int = math.ceil(amount_of_images/rows)
658
+ argument = ['-title', f'"{outputfilename} ({info})"', '-tile', f'{rows}x{columns}', f'{tempname_for_thumbnails}*.png', f'{outputfilename}.png']
659
+ self.run_program_argsasarray("montage", argument, folder, throw_exception_if_exitcode_is_not_zero=True)
649
660
 
650
661
  @GeneralUtilities.check_arguments
651
- def roundup(self, x: float, places: int) -> int:
662
+ def __roundup(self, x: float, places: int) -> int:
652
663
  d = 10 ** places
653
664
  if x < 0:
654
665
  return math.floor(x * d) / d
@@ -656,33 +667,35 @@ class ScriptCollectionCore:
656
667
  return math.ceil(x * d) / d
657
668
 
658
669
  @GeneralUtilities.check_arguments
659
- def generate_thumbnail(self, file: str, frames_per_second: str, tempname_for_thumbnails: str = None) -> None:
670
+ def generate_thumbnail(self, file: str, frames_per_second: str, tempname_for_thumbnails: str = None, hook=None) -> None:
660
671
  if tempname_for_thumbnails is None:
661
- tempname_for_thumbnails = "t"+str(uuid.uuid4())
672
+ tempname_for_thumbnails = "t_"+str(uuid.uuid4())
662
673
 
663
674
  file = GeneralUtilities.resolve_relative_path_from_current_working_directory(file)
664
675
  filename = os.path.basename(file)
665
676
  folder = os.path.dirname(file)
666
677
  filename_without_extension = Path(file).stem
667
-
678
+ preview_files: list[str] = []
668
679
  try:
669
680
  length_in_seconds = self.__calculate_lengh_in_seconds(filename, folder)
670
681
  if (frames_per_second.endswith("fps")):
671
682
  # frames per second, example: frames_per_second="20fps" => 20 frames per second
672
- x = self.roundup(float(frames_per_second[:-3]), 2)
673
- frames_per_secondx = str(x)
674
- amounf_of_previewframes = int(math.floor(length_in_seconds*x))
683
+ frames_per_second = self.__roundup(float(frames_per_second[:-3]), 2)
684
+ frames_per_second_as_string = str(frames_per_second)
685
+ amounf_of_previewframes = int(math.floor(length_in_seconds*frames_per_second))
675
686
  else:
676
687
  # concrete amount of frame, examples: frames_per_second="16" => 16 frames for entire video
677
688
  amounf_of_previewframes = int(float(frames_per_second))
678
689
  # self.roundup((amounf_of_previewframes-2)/length_in_seconds, 2)
679
- frames_per_secondx = f"{amounf_of_previewframes-2}/{length_in_seconds}"
680
- self.__create_thumbnails(filename, frames_per_secondx, folder, tempname_for_thumbnails)
681
- self.__create_thumbnail(filename_without_extension, folder, length_in_seconds, tempname_for_thumbnails, amounf_of_previewframes)
690
+ frames_per_second_as_string = f"{amounf_of_previewframes-2}/{length_in_seconds}"
691
+ preview_files = self.__create_thumbnails(filename, frames_per_second_as_string, folder, tempname_for_thumbnails)
692
+ if hook is not None:
693
+ hook(file, preview_files)
694
+ actual_amounf_of_previewframes = len(preview_files)
695
+ self.__create_thumbnail(filename_without_extension, folder, length_in_seconds, tempname_for_thumbnails, actual_amounf_of_previewframes)
682
696
  finally:
683
- for thumbnail_to_delete in Path(folder).rglob(tempname_for_thumbnails+"-*"):
684
- file = str(thumbnail_to_delete)
685
- os.remove(file)
697
+ for thumbnail_to_delete in preview_files:
698
+ os.remove(thumbnail_to_delete)
686
699
 
687
700
  @GeneralUtilities.check_arguments
688
701
  def extract_pdf_pages(self, file: str, from_page: int, to_page: int, outputfile: str) -> None:
@@ -1783,11 +1796,11 @@ DNS = {domain}
1783
1796
 
1784
1797
  @GeneralUtilities.check_arguments
1785
1798
  def change_file_extensions(self, folder: str, from_extension: str, to_extension: str, recursive: bool, ignore_case: bool) -> None:
1786
- extension_to_compare:str=None
1799
+ extension_to_compare: str = None
1787
1800
  if ignore_case:
1788
- extension_to_compare=from_extension.lower()
1801
+ extension_to_compare = from_extension.lower()
1789
1802
  else:
1790
- extension_to_compare=from_extension
1803
+ extension_to_compare = from_extension
1791
1804
  for file in GeneralUtilities.get_direct_files_of_folder(folder):
1792
1805
  if (ignore_case and file.lower().endswith(f".{extension_to_compare}")
1793
1806
  or not ignore_case and file.endswith(f".{extension_to_compare}")):
@@ -1795,4 +1808,4 @@ DNS = {domain}
1795
1808
  p.rename(p.with_suffix('.'+to_extension))
1796
1809
  if recursive:
1797
1810
  for subfolder in GeneralUtilities.get_direct_folders_of_folder(folder):
1798
- self.change_file_extensions(subfolder, from_extension, to_extension, recursive,ignore_case)
1811
+ self.change_file_extensions(subfolder, from_extension, to_extension, recursive, ignore_case)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ScriptCollection
3
- Version: 3.5.12
3
+ Version: 3.5.13
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
@@ -1,16 +1,16 @@
1
1
  ScriptCollection/Executables.py,sha256=msAlVLjgrxCxW-5Uu7Gk8NI1CNQLK2i6TjNR1fppaCY,19535
2
- ScriptCollection/GeneralUtilities.py,sha256=kfvlZaqbbC9ZPgEiNIHFdleUpu-686rRjcNKDreiqaE,34941
2
+ ScriptCollection/GeneralUtilities.py,sha256=1Q5ML9RwwS5e1mZPuJps3Z3ceVCGF5taFhh0GEG6MlY,35167
3
3
  ScriptCollection/ProcessesRunner.py,sha256=3mu4ZxzZleQo0Op6o9EYTCFiJfb6kx5ov2YfZfT89mU,1395
4
4
  ScriptCollection/ProgramRunnerBase.py,sha256=7QAjoqOz6XPmJH19F2k-Z1fFQB_uZnPFvn-T54IJcHQ,2324
5
5
  ScriptCollection/ProgramRunnerEpew.py,sha256=C2Rs3YWOWWWJct7XmKphp5CF1tf0j4Fp-ljV2drLTfs,6349
6
6
  ScriptCollection/ProgramRunnerPopen.py,sha256=ECx35Yz-MKPeoRa_42Bsq8qmbHd13I40vXUJSpZPrI4,3475
7
7
  ScriptCollection/RPStream.py,sha256=NRRHL3YSP3D9MuAV2jB_--0KUKCsvJGxeKnxgrRZ9kY,1545
8
- ScriptCollection/ScriptCollectionCore.py,sha256=Xi9Htfv8F8AXQ04cbPpm2cf2KgqRpNyAWv2eFP2mMlM,96680
8
+ ScriptCollection/ScriptCollectionCore.py,sha256=cWn10QGcBDP4C6u5TtzGYn6OiYV5OpY8BRkeNGQo00w,97421
9
9
  ScriptCollection/TasksForCommonProjectStructure.py,sha256=-QxOB01yFHrcPpTNnDA0GY0rv9McvQ95DZ3PNHRCrFE,184090
10
10
  ScriptCollection/UpdateCertificates.py,sha256=Eynbgu7k9jLxApP2D_8Il77B6BFjJap6K7oTeEAZYbk,7790
11
11
  ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- ScriptCollection-3.5.12.dist-info/METADATA,sha256=KluMvH8NET-JxQTy_phEnaAkKFOrWzEzP5dFBSZR36o,7680
13
- ScriptCollection-3.5.12.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
14
- ScriptCollection-3.5.12.dist-info/entry_points.txt,sha256=Jz1pyS3Q6lqpuOWVHogt00jGwrpcHYtPrHGY0_Ltjbo,2227
15
- ScriptCollection-3.5.12.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
- ScriptCollection-3.5.12.dist-info/RECORD,,
12
+ ScriptCollection-3.5.13.dist-info/METADATA,sha256=LxH_9vYMJRCIrEukh8lc02T6npy78tCjQTrpaOtYB1A,7680
13
+ ScriptCollection-3.5.13.dist-info/WHEEL,sha256=ixB2d4u7mugx_bCBycvM9OzZ5yD7NmPXFRtKlORZS2Y,91
14
+ ScriptCollection-3.5.13.dist-info/entry_points.txt,sha256=Jz1pyS3Q6lqpuOWVHogt00jGwrpcHYtPrHGY0_Ltjbo,2227
15
+ ScriptCollection-3.5.13.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
16
+ ScriptCollection-3.5.13.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.0.0)
2
+ Generator: setuptools (74.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5