atomicshop 2.18.28__py3-none-any.whl → 2.18.30__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.

Potentially problematic release.


This version of atomicshop might be problematic. Click here for more details.

atomicshop/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.18.28'
4
+ __version__ = '2.18.30'
@@ -125,8 +125,8 @@ class MultiProcessorRecursive:
125
125
  result = async_result.get()
126
126
  # Assuming process_function returns a list, extend new_input_list
127
127
  new_input_list.extend(result)
128
- except Exception as e:
129
- print(f"An error occurred: {e}")
128
+ except Exception:
129
+ raise
130
130
 
131
131
  # Update the input_list for the next iteration
132
132
  self.input_list = new_input_list
atomicshop/filesystem.py CHANGED
@@ -329,6 +329,30 @@ def remove_directory(directory_path: str, force_readonly: bool = False, print_kw
329
329
  return False
330
330
 
331
331
 
332
+ def clear_directory(directory: str) -> tuple[list[str], list[str]]:
333
+ """
334
+ The function will clear the directory of all files and subdirectories.
335
+ :param directory:
336
+ :return: tuple of lists of removed file paths and removed directory paths.
337
+ """
338
+
339
+ file_paths: list = []
340
+ directory_paths: list = []
341
+ # Iterate through all files and subdirectories in the directory
342
+ for item in os.listdir(directory):
343
+ item_path = os.path.join(directory, item)
344
+ # If it's a file, remove it
345
+ if os.path.isfile(item_path) or os.path.islink(item_path): # Handle symbolic links too
346
+ os.remove(item_path)
347
+ file_paths.append(item_path)
348
+ # If it's a directory, remove it and its contents
349
+ elif os.path.isdir(item_path):
350
+ shutil.rmtree(item_path)
351
+ directory_paths.append(item_path)
352
+
353
+ return file_paths, directory_paths
354
+
355
+
332
356
  def remove_empty_directories(directory_path: str) -> list[str]:
333
357
  """
334
358
  Recursively removes empty directories in the given path, including the given path if it is empty.
@@ -675,12 +699,12 @@ def move_folder_contents_to_folder(
675
699
 
676
700
  if os.path.isdir(s):
677
701
  if os.path.exists(d) and not overwrite:
678
- print(f"Directory {d} already exists. Skipping due to overwrite=False.")
702
+ raise FileExistsError(f"Directory already exists: {d}. Skipping due to overwrite=False.")
679
703
  else:
680
704
  shutil.move(s, d)
681
705
  else:
682
706
  if os.path.exists(d) and not overwrite:
683
- print(f"File {d} already exists. Skipping due to overwrite=False.")
707
+ raise FileExistsError(f"File {d} already exists. Skipping due to overwrite=False.")
684
708
  else:
685
709
  shutil.move(s, d)
686
710
 
@@ -1675,3 +1699,95 @@ def find_file(file_name: str, directory_path: str):
1675
1699
  if filename == file_name:
1676
1700
  return os.path.join(dir_path, filename)
1677
1701
  return None
1702
+
1703
+
1704
+ def create_ubuntu_desktop_shortcut(
1705
+ file_path: str = None,
1706
+ shortcut_name: str = None,
1707
+ command: str = None,
1708
+ working_directory: str = None,
1709
+ icon_path: str = None,
1710
+ terminal: bool = False,
1711
+ comment: str = "Shortcut to execute the Python script",
1712
+ categories: str = "Utility",
1713
+ set_executable: bool = False,
1714
+ set_trusted: bool = False,
1715
+ set_xfce_exe_checksum: bool = False
1716
+ ):
1717
+ """
1718
+ Create a desktop shortcut on Ubuntu.
1719
+
1720
+ Either file_path or command must be specified.
1721
+ If command is specified, working_directory must be specified.
1722
+
1723
+ :param file_path: string, The file_path to execute when the shortcut is clicked.
1724
+ Example2: '/path/to/script.sh'
1725
+ :param shortcut_name: string, The name of the shortcut.
1726
+ Example: 'My Python Script'
1727
+ Result: 'My Python Script.desktop'
1728
+ :param command: string, The command to execute when the shortcut is clicked.
1729
+ Example: 'python3 /path/to/script.py'
1730
+ :param working_directory: string, The working directory for the command.
1731
+ If None, the command will be executed in the same script's directory.
1732
+ :param icon_path: string, The path to the icon file.
1733
+ :param terminal: boolean, If True, the command will be executed in a terminal.
1734
+ :param comment: string, A comment to describe the shortcut.
1735
+ :param categories: string, The categories of the shortcut.
1736
+ :param set_executable: boolean, If True, the shortcut will be made executable.
1737
+ :param set_trusted: boolean, If True, the shortcut will be marked as trusted.
1738
+ This is needed for GNOME.
1739
+ :param set_xfce_exe_checksum: boolean, If True, the shortcut will be made safe executable for XFCE.
1740
+
1741
+ :return: None
1742
+ """
1743
+
1744
+ if not file_path and not command:
1745
+ raise ValueError("Either 'file_path' or 'command' must be specified.")
1746
+ if command and file_path:
1747
+ raise ValueError("Only one of 'file_path' or 'command' can be specified.")
1748
+ if command and not working_directory:
1749
+ raise ValueError("Working directory must be specified if 'command' is specified.")
1750
+
1751
+ from .permissions import ubuntu_permissions
1752
+
1753
+ # Get the user's directory.
1754
+ desktop_dir = os.path.expanduser("~/Desktop")
1755
+
1756
+ if not working_directory:
1757
+ working_directory = os.path.dirname(file_path)
1758
+
1759
+ if not shortcut_name:
1760
+ shortcut_name: str = Path(file_path).stem
1761
+
1762
+ # Full path to the .desktop file
1763
+ shortcut_path = os.path.join(desktop_dir, f"{shortcut_name}.desktop")
1764
+
1765
+ # Generate the content for the .desktop file
1766
+ desktop_entry = [
1767
+ "[Desktop Entry]",
1768
+ "Version=1.0",
1769
+ "Type=Application",
1770
+ f"Name={shortcut_name}",
1771
+ f"Exec={file_path}",
1772
+ f"Path={working_directory}",
1773
+ f"Icon={icon_path}" if icon_path else "",
1774
+ f"Terminal={'true' if terminal else 'false'}",
1775
+ f"Comment={comment}",
1776
+ f"Categories={categories};",
1777
+ ]
1778
+
1779
+ # Write the .desktop file
1780
+ with open(shortcut_path, "w") as shortcut_file:
1781
+ shortcut_file.write("\n".join(line for line in desktop_entry if line)) # Skip empty lines
1782
+
1783
+ # Make the .desktop file executable
1784
+ if set_executable:
1785
+ ubuntu_permissions.set_executable(shortcut_path)
1786
+
1787
+ # Mark the .desktop file as trusted
1788
+ if set_trusted:
1789
+ ubuntu_permissions.set_trusted_executable(shortcut_path)
1790
+
1791
+ # Make the .desktop file safe executable for XFCE
1792
+ if set_xfce_exe_checksum:
1793
+ ubuntu_permissions.set_xfce_exe_checksum(shortcut_path)
@@ -33,6 +33,48 @@ def set_executable(file_path: str):
33
33
  os.chmod(file_path, os.stat(file_path).st_mode | stat.S_IXUSR)
34
34
 
35
35
 
36
+ def set_trusted_executable(file_path: str):
37
+ """
38
+ Function sets the executable permission on a file and marks it as trusted.
39
+ :param file_path: str, path to the file.
40
+ :return:
41
+ """
42
+
43
+ # Check if the file exists
44
+ if not os.path.exists(file_path):
45
+ raise FileNotFoundError(f"The file does not exist: {file_path} ")
46
+
47
+ # Execute the `gio set` command
48
+ subprocess.run(
49
+ ["gio", "set", file_path, "metadata::trusted", "true"],
50
+ check=True
51
+ )
52
+
53
+
54
+ def set_xfce_exe_checksum(desktop_file_path):
55
+ # Expand `~` to the full home directory path
56
+ desktop_file_path = os.path.expanduser(desktop_file_path)
57
+
58
+ # Ensure the file exists
59
+ if not os.path.exists(desktop_file_path):
60
+ raise FileNotFoundError(f"The file does not exist: {desktop_file_path} ")
61
+
62
+ # Calculate the SHA256 checksum of the file
63
+ result = subprocess.run(
64
+ ["sha256sum", desktop_file_path],
65
+ stdout=subprocess.PIPE,
66
+ check=True,
67
+ text=True
68
+ )
69
+ checksum = result.stdout.split()[0]
70
+
71
+ # Set the metadata::xfce-exe-checksum attribute using `gio`
72
+ subprocess.run(
73
+ ["gio", "set", "-t", "string", desktop_file_path, "metadata::xfce-exe-checksum", checksum],
74
+ check=True
75
+ )
76
+
77
+
36
78
  def change_file_owner(file_path: str, username: str):
37
79
  """
38
80
  Function changes the owner of the file to the specified user.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.18.28
3
+ Version: 2.18.30
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=NPXYaerttT8nwfrwAuSuQRk-VuX8kIyXrNdJ0gpi-e4,124
1
+ atomicshop/__init__.py,sha256=6a8s52oEErBoMqHlOVc95TxLFuoK8ZGvWHPZKkVUgAA,124
2
2
  atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
3
3
  atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
4
4
  atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
@@ -14,7 +14,7 @@ atomicshop/dns.py,sha256=5Gimq_WY2arqg7BeGmR7P--fGfnH0Dsh8lrOt_H0jRY,6817
14
14
  atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
15
15
  atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
16
16
  atomicshop/file_types.py,sha256=-0jzQMRlmU1AP9DARjk-HJm1tVE22E6ngP2mRblyEjY,763
17
- atomicshop/filesystem.py,sha256=StVeiGCjlpvMOmB-4SW-s7eR_qxYofW9jsfh1ewpaG4,63263
17
+ atomicshop/filesystem.py,sha256=vXyc73_8ltcsuvPrmFor8QtehZs0Dg3_FvflAoZKT00,67857
18
18
  atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
19
19
  atomicshop/get_process_list.py,sha256=8cxb7gKe9sl4R6H2yMi8J6oe-RkonTvCdKjRFqi-Fs4,6075
20
20
  atomicshop/get_process_name_cmd_dll.py,sha256=CtaSp3mgxxJKCCVW8BLx6BJNx4giCklU_T7USiCEwfc,5162
@@ -100,7 +100,7 @@ atomicshop/basics/isinstancing.py,sha256=fQ35xfqbguQz2BUn-3a4KVGskhTcIn8JjRtxV2r
100
100
  atomicshop/basics/list_of_classes.py,sha256=PJoE1VJdhhQ4gSFr88zW7IApXd4Ez7xLz-7vAM-7gug,978
101
101
  atomicshop/basics/list_of_dicts.py,sha256=tj0LNPf1ljNI_qpoO-PiOT4Ulmk1M-UpTGyn9twVcw8,8039
102
102
  atomicshop/basics/lists.py,sha256=I0C62vrDrNwCTNl0EjUZNa1Jsd8l0rTkp28GEx9QoEI,4258
103
- atomicshop/basics/multiprocesses.py,sha256=nSskxJSlEdalPM_Uf8cc9kAYYlVwYM1GonBLAhCL2mM,18831
103
+ atomicshop/basics/multiprocesses.py,sha256=oU6LjcLLGBtPIGJzZBpDWoLU3HRmMoanITEOE2luAYw,18799
104
104
  atomicshop/basics/numbers.py,sha256=ESX0z_7o_ok3sOmCKAUBoZinATklgMy2v-4RndqXlVM,1837
105
105
  atomicshop/basics/package_module.py,sha256=fBd0uVgFce25ZCVtLq83iyowRlbwdWYFj_t4Ml7LU14,391
106
106
  atomicshop/basics/randoms.py,sha256=DmYLtnIhDK29tAQrGP1Nt-A-v8WC7WIEB8Edi-nk3N4,282
@@ -159,7 +159,7 @@ atomicshop/monitor/checks/process_running.py,sha256=x66wd6-l466r8sbRQaIli0yswyGt
159
159
  atomicshop/monitor/checks/url.py,sha256=1PvKt_d7wFg7rDMFpUejAQhj0mqWsmlmrNfjNAV2G4g,4123
160
160
  atomicshop/permissions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
161
161
  atomicshop/permissions/permissions.py,sha256=CYTDVOI0jh9ks0ZLnnOuPzppgCszFEc9-92DTkVTYi4,522
162
- atomicshop/permissions/ubuntu_permissions.py,sha256=xmLfrBh-uhJqmZzx754Yt2ECBsZI5uwWECg6hCsTtek,4649
162
+ atomicshop/permissions/ubuntu_permissions.py,sha256=n8z1vcIXDts4zLVue33dtJiTopjgEAYPg4dqFn0qwwc,5943
163
163
  atomicshop/permissions/win_permissions.py,sha256=eDQm1jfK9x_hkbLqIJjFTwfqinAWQ0iSr0kW3XrF1BE,1272
164
164
  atomicshop/process_poller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
165
  atomicshop/process_poller/process_pool.py,sha256=4Qs427qd7OcBxu5PMFU5PTmyuxRy0vgj2GLsRt0IoEw,9565
@@ -321,8 +321,8 @@ atomicshop/wrappers/socketw/statistics_csv.py,sha256=fgMzDXI0cybwUEqAxprRmY3lqbh
321
321
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
322
322
  atomicshop/wrappers/winregw/winreg_installed_software.py,sha256=Qzmyktvob1qp6Tjk2DjLfAqr_yXV0sgWzdMW_9kwNjY,2345
323
323
  atomicshop/wrappers/winregw/winreg_network.py,sha256=AENV88H1qDidrcpyM9OwEZxX5svfi-Jb4N6FkS1xtqA,8851
324
- atomicshop-2.18.28.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
325
- atomicshop-2.18.28.dist-info/METADATA,sha256=SsZ4Ze8vESp5LjMbbM8_MghpZ9WhVYHs36BxPg63-CE,10631
326
- atomicshop-2.18.28.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
327
- atomicshop-2.18.28.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
328
- atomicshop-2.18.28.dist-info/RECORD,,
324
+ atomicshop-2.18.30.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
325
+ atomicshop-2.18.30.dist-info/METADATA,sha256=c7ZY3AG2mw1LVujTZo1Svw7dQLemtJdNBBLUE_7obZc,10631
326
+ atomicshop-2.18.30.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
327
+ atomicshop-2.18.30.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
328
+ atomicshop-2.18.30.dist-info/RECORD,,