atomicshop 2.10.6__py3-none-any.whl → 2.10.8__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.10.6'
4
+ __version__ = '2.10.8'
@@ -1,7 +1,10 @@
1
1
  import fnmatch
2
2
  import re
3
+ from pathlib import Path
4
+ import argparse
3
5
 
4
6
  from . import lists
7
+ from ..print_api import print_api
5
8
 
6
9
 
7
10
  def get_nth_character_from_start(input_string: str, nth: int):
@@ -411,21 +414,76 @@ def convert_string_to_colon_separated(string: str, number_of_characters: int = 2
411
414
  return ':'.join([string[i:i+number_of_characters] for i in range(0, len(string), number_of_characters)])
412
415
 
413
416
 
414
- def replace_string_in_file(file_path: str, old_string: str, new_string: str):
417
+ def replace_string_in_file(
418
+ file_path: str,
419
+ old_string: str,
420
+ new_string: str = None,
421
+ find_only: bool = False,
422
+ print_kwargs: dict = None
423
+ ) -> list[int]:
415
424
  """
416
425
  Function replaces 'old_string' with 'new_string' in the file.
417
426
  :param file_path: string, path to the file.
418
427
  :param old_string: string, to replace.
419
428
  :param new_string: string, to replace with.
429
+ :param find_only: boolean, if 'True' will only find the 'old_string' and return line numbers where it was found.
430
+ :param print_kwargs: dict, the print_api arguments.
431
+ :return: list of integers, line numbers where the 'old_string' was found.
420
432
  """
421
433
 
422
- # Read in the file
423
- with open(file_path, 'r') as file:
424
- filedata = file.read()
434
+ if not find_only and new_string is None:
435
+ raise ValueError("The 'new_string' string must be provided if 'find_only' is False.")
425
436
 
426
- # Replace the target string
427
- filedata = filedata.replace(old_string, new_string)
437
+ changed_lines = []
428
438
 
429
- # Write the file out again
430
- with open(file_path, 'w') as file:
431
- file.write(filedata)
439
+ # Read the file content
440
+ with open(file_path, 'r', encoding='utf-8') as file:
441
+ lines = file.readlines()
442
+
443
+ # Search for the old string and either replace or just track line numbers
444
+ for index, line in enumerate(lines, start=1):
445
+ if old_string in line:
446
+ changed_lines.append(index)
447
+ if not find_only:
448
+ lines[index - 1] = line.replace(old_string, new_string)
449
+
450
+ # If not in find-only mode, overwrite the file with the replaced content
451
+ if not find_only:
452
+ with open(file_path, 'w', encoding='utf-8') as file:
453
+ file.writelines(lines)
454
+
455
+ # Output the relevant line numbers
456
+ print_api(f"Target string found on the following lines: {changed_lines}", **(print_kwargs or {}))
457
+ return changed_lines
458
+
459
+
460
+ def replace_string_in_file_main_argparse():
461
+ """
462
+ Main function for the 'replace_string_in_file' function.
463
+ You can use this function as a command line tool.
464
+ Example:
465
+ Create a file 'replace_string_in_file.py' with the next content:
466
+ ```
467
+ from atomicshop.basics import strings
468
+
469
+ if __name__ == '__main__':
470
+ strings.replace_string_in_file_main_argparse()
471
+ ```
472
+ """
473
+
474
+ parser = argparse.ArgumentParser(description="Replace string in file.")
475
+ parser.add_argument("file_path", type=Path, help="Path to the file.")
476
+ parser.add_argument("old_string", type=str, help="Old string to replace.")
477
+ parser.add_argument("--new_string", '-n', help="New string to replace with.")
478
+ parser.add_argument(
479
+ '--find_only', '-f', action='store_true',
480
+ help='Only output lines where the old string is found, without replacing.')
481
+
482
+ args = parser.parse_args()
483
+
484
+ replace_string_in_file(
485
+ file_path=args.file_path,
486
+ old_string=args.old_string,
487
+ new_string=args.new_string,
488
+ find_only=args.find_only
489
+ )
@@ -19,7 +19,7 @@ def get_hyperlinks(docx_path):
19
19
  # If the file is empty, it will raise an exception.
20
20
  # The same exception will rise if the file is opened in Word.
21
21
  except PackageNotFoundError:
22
- print_api(f"File is empty or opened in Word: {docx_path}", color="red", error_type=True)
22
+ print_api(f"File is not DOCX format or opened in Word: {docx_path}", color="red", error_type=True)
23
23
  return hyperlinks
24
24
 
25
25
  for paragraph in doc.paragraphs:
@@ -67,7 +67,7 @@ def search_for_hyperlink_in_files(directory_path: str, hyperlink: str, relative_
67
67
 
68
68
  # Get all the docx files in the specified directory.
69
69
  files = filesystem.get_file_paths_from_directory(
70
- directory_path, file_name_check_pattern="*.docx",
70
+ directory_path, file_name_check_pattern="*\.docx",
71
71
  add_relative_directory=True, relative_file_name_as_directory=True)
72
72
 
73
73
  found_in_files: list = list()
@@ -98,14 +98,23 @@ def search_for_hyperlink_in_files_interface_main(script_directory: str = None):
98
98
  def main():
99
99
  docxs.search_for_hyperlink_in_files_interface_main()
100
100
 
101
+ # Create the 'config.toml' file if it doesn't exist.
102
+ # Run the script the first time in order to create empty TOML.
103
+ # Note: relative_paths: boolean, if True, the function will return relative paths to the files and not the full
104
+ # file paths. Example: 'content\file.docx' instead of 'D:/content/file.docx' if you specified 'D:/' as
105
+ # 'directory_path'.
106
+ # hyperlink = 'https://www.example.com'
107
+ # directory_path = 'C:/where/to/look/for/docxs'
108
+ # relative_paths = True
109
+
101
110
  if __name__ == '__main__':
102
111
  main()
103
112
  """
104
113
 
105
114
  # Create the 'config.toml' file if it doesn't exist. Manually constructing the TOML content.
106
115
  toml_dict = {
107
- 'directory_path': '',
108
116
  'hyperlink': '',
117
+ 'directory_path': '',
109
118
  'relative_paths': True
110
119
  }
111
120
 
@@ -117,7 +126,10 @@ def search_for_hyperlink_in_files_interface_main(script_directory: str = None):
117
126
  found_in_files = search_for_hyperlink_in_files(
118
127
  config['directory_path'], config['hyperlink'], relative_paths=config['relative_paths'])
119
128
 
120
- for found_file in found_in_files:
121
- print(found_file)
129
+ print_api(f"Found in [{len(found_in_files)}] files:", color="blue")
130
+
131
+ for index, found_file in enumerate(found_in_files):
132
+ print_api(f"[{index+1}]", print_end="", color="green")
133
+ print_api(f" {found_file}")
122
134
 
123
- input('press Enter')
135
+ input('[*] Press [Enter] to exit...')
atomicshop/filesystem.py CHANGED
@@ -569,6 +569,9 @@ def get_file_paths_from_directory(
569
569
  :param file_name_check_pattern: string, if specified, the function will return only files that match the pattern.
570
570
  The string can contain part of file name to check or full file name with extension.
571
571
  Can contain wildcards.
572
+ If you need to specify a "." in the pattern, you need to escape it with a backslash:
573
+ Example: "*\.txt" will return all files with the extension ".txt".
574
+ While "*.txt" will return all files that contain "txt" in the name.
572
575
  :param add_relative_directory: boolean, if
573
576
  'True', then the function will add relative directory to the output list.
574
577
  In this case the output list will contain dictionaries with keys 'path' and 'relative_dir'.
@@ -59,10 +59,14 @@ def add_current_user_to_docker_group(print_kwargs: dict = None):
59
59
  return False
60
60
 
61
61
 
62
- def install_docker_ubuntu(add_current_user_to_docker_group_bool: bool = True):
62
+ def install_docker_ubuntu(rootless: bool = True, add_current_user_to_docker_group_bool: bool = False):
63
63
  """
64
64
  The function will install docker on ubuntu.
65
+ :param rootless: bool, if True, the rootless installation will be performed.
66
+ Meaning, you will be able to run the 'docker' command without sudo and you will not need to add the
67
+ current user to the docker group.
65
68
  :param add_current_user_to_docker_group_bool: bool, if True, the current user will be added to the docker group.
69
+ So the user will be able to run the 'docker' command without sudo.
66
70
 
67
71
  Usage in main.py (run with sudo):
68
72
  from atomicshop.wrappers.dockerw import install_docker
@@ -32,4 +32,4 @@ def install_after_restart(
32
32
  process.execute_with_live_output(cmd=install_command, verbose=True)
33
33
  # Remove the FACT_core installation log.
34
34
  working_directory_path: str = filesystem.get_working_directory()
35
- filesystem.remove_file(str(Path(working_directory_path, config_install.INSTALL_LOG_FILE_NAME)))
35
+ # filesystem.remove_file(str(Path(working_directory_path, config_install.INSTALL_LOG_FILE_NAME)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.10.6
3
+ Version: 2.10.8
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=tFi0pykEUI0rTZZH1Vg6SdcRfzQTZKkiN45riWXH6hE,123
1
+ atomicshop/__init__.py,sha256=jLebawbp1INbR4X9mVO70IY6_95wF8u3eJf77Id2Cis,123
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=bNZOo5jVPzq7OT2qCPukXoK3zb1oOsyaelUwQEyK1SA,2500
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=FFOEUZygGvPrIdedq4DVaXhMX2YFaFovB2xhDVMCgM4,43813
17
+ atomicshop/filesystem.py,sha256=I72yd_-G1y7aWtD7IzgUQn5BBg8Dpri8o7Jrb_-kfW4,44060
18
18
  atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
19
19
  atomicshop/hashing.py,sha256=Le8qGFyt3_wX-zGTeQShz7L2HL_b6nVv9PnawjglyHo,3474
20
20
  atomicshop/http_parse.py,sha256=nrf2rZcprLqtW8HVrV7TCZ1iTBcWRRy-mXIlAOzcaJs,9703
@@ -90,7 +90,7 @@ atomicshop/basics/lists.py,sha256=pLpYPSu0BjJIAe_Ar55XhLsH2YBhftn7b-tTAdkK1sw,39
90
90
  atomicshop/basics/multiprocesses.py,sha256=nSskxJSlEdalPM_Uf8cc9kAYYlVwYM1GonBLAhCL2mM,18831
91
91
  atomicshop/basics/numbers.py,sha256=ESX0z_7o_ok3sOmCKAUBoZinATklgMy2v-4RndqXlVM,1837
92
92
  atomicshop/basics/randoms.py,sha256=DmYLtnIhDK29tAQrGP1Nt-A-v8WC7WIEB8Edi-nk3N4,282
93
- atomicshop/basics/strings.py,sha256=aQ92AJPvb3U0O6n2FMqRUqEsPCiklwGX--jPmB9M0_s,15418
93
+ atomicshop/basics/strings.py,sha256=9DH1190jgSpSRPgcywSysJ0iovqPOWjSokumP6ng2BI,17686
94
94
  atomicshop/basics/threads.py,sha256=xvgdDJdmgN0wmmARoZ-H7Kvl1GOcEbvgaeGL4M3Hcx8,2819
95
95
  atomicshop/basics/timeit_template.py,sha256=fYLrk-X_dhdVtnPU22tarrhhvlggeW6FdKCXM8zkX68,405
96
96
  atomicshop/basics/tracebacks.py,sha256=cNfh_oAwF55kSIdqtv3boHZQIoQI8TajxkTnwJwpweI,535
@@ -99,7 +99,7 @@ atomicshop/etw/dns_trace.py,sha256=RaREpwJETAMZSd1Lhbg0sO3ugBMw3y1fSKdvP5NfTqM,5
99
99
  atomicshop/etw/etw.py,sha256=xVJNbfCq4KgRfsDnul6CrIdAMl9xRBixZ-hUyqiB2g4,2403
100
100
  atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
101
  atomicshop/file_io/csvs.py,sha256=4R4Kij8FmxNwXFjDtlF_A0flAk0Hj5nZKlEnqC5VxgQ,3125
102
- atomicshop/file_io/docxs.py,sha256=3IFtaurVhvntcuCL59bpFlzGyKxvDmVUjUQTHWluOMY,4369
102
+ atomicshop/file_io/docxs.py,sha256=6tcYFGp0vRsHR47VwcRqwhdt2DQOwrAUYhrwN996n9U,5117
103
103
  atomicshop/file_io/file_io.py,sha256=FR84ihjGlr7Eqejo-_js4nBICVst31axD0bwX19S2eM,6385
104
104
  atomicshop/file_io/jsons.py,sha256=q9ZU8slBKnHLrtn3TnbK1qxrRpj5ZvCm6AlsFzoANjo,5303
105
105
  atomicshop/file_io/tomls.py,sha256=oa0Wm8yMkPRXKN9jgBuTnKbioSOee4mABW5IMUFCYyU,3041
@@ -155,7 +155,7 @@ atomicshop/wrappers/certauthw/certauthw.py,sha256=4WvhjANI7Kzqrr_nKmtA8Kf7B6rute
155
155
  atomicshop/wrappers/ctyping/process_winapi.py,sha256=QcXL-ETtlSSkoT8F7pYle97ubGWsjYp8cx8HxkVMgAc,2762
156
156
  atomicshop/wrappers/dockerw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
157
  atomicshop/wrappers/dockerw/dockerw.py,sha256=w8zSJr5C7cbvbuG09ORCpAe0BOcibqqL_Z2EKEBHYK4,6266
158
- atomicshop/wrappers/dockerw/install_docker.py,sha256=eF0raR1EO9Xk1MVH7CvtkFI2Fgu9zL12MIYV_1vPTQk,4799
158
+ atomicshop/wrappers/dockerw/install_docker.py,sha256=glX5UKReRc8rUrBQUKqIQb7HnLiG2QlPXxC-qemNpAc,5133
159
159
  atomicshop/wrappers/elasticsearchw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
160
  atomicshop/wrappers/elasticsearchw/config_basic.py,sha256=fDujtrjEjbWiYh_WQ3OcYp_8mXhXPYeKLy4wSPL5qM0,1177
161
161
  atomicshop/wrappers/elasticsearchw/elasticsearchw.py,sha256=7TqFdEFznO8NlligJhEKk1vm641ALpCYdaRl1uoXdzM,9768
@@ -177,7 +177,7 @@ atomicshop/wrappers/factw/fact_extractor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
177
177
  atomicshop/wrappers/factw/fact_extractor/docker_image.py,sha256=jJAoJNQ4aoATjn3x_va031Obb4oBtcqCY40hydghm0s,2504
178
178
  atomicshop/wrappers/factw/fact_extractor/get_extractor.py,sha256=2mfOAftHIlCcGt1s7MWdq7DsDCuI6wX3MtvcEZ4SK-0,756
179
179
  atomicshop/wrappers/factw/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
180
- atomicshop/wrappers/factw/install/install_after_restart.py,sha256=roM1W2hkDynpEKda55xd7AsZxodsFj8i4wmFGt_HHzA,1558
180
+ atomicshop/wrappers/factw/install/install_after_restart.py,sha256=-VXC3KDX2BzF0oi0ELCmfch55vLk-3t16KxlmYyUGD8,1560
181
181
  atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py,sha256=7Yk1xZXFXoPZVsSvgZzOLMoZza9OFIB5HplLQxY-7Bs,4251
182
182
  atomicshop/wrappers/factw/postgresql/__init__.py,sha256=xMBn2d3Exo23IPP2F_9-SXmOlhFbwWDgS9KwozSTjA0,162
183
183
  atomicshop/wrappers/factw/postgresql/analysis.py,sha256=2Rxzy2jyq3zEKIo53z8VkjuslKE_i5mq2ZpmJAvyd6U,716
@@ -233,8 +233,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
233
233
  atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
234
234
  atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
235
235
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
236
- atomicshop-2.10.6.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
237
- atomicshop-2.10.6.dist-info/METADATA,sha256=mwost6XyCI5vs7r3uag442WjE7EudZ3K8Hp429Wj9fs,10423
238
- atomicshop-2.10.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
239
- atomicshop-2.10.6.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
240
- atomicshop-2.10.6.dist-info/RECORD,,
236
+ atomicshop-2.10.8.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
237
+ atomicshop-2.10.8.dist-info/METADATA,sha256=35z6a8qlF_O0hPLHYCDfdrqRN_5nx52xrhoaQ0BbCqk,10423
238
+ atomicshop-2.10.8.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
239
+ atomicshop-2.10.8.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
240
+ atomicshop-2.10.8.dist-info/RECORD,,