atomicshop 2.5.13__py3-none-any.whl → 2.5.15__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 +1 -1
- atomicshop/addons/mains/search_for_hyperlinks_in_docx.py +16 -0
- atomicshop/file_io/docxs.py +23 -20
- atomicshop/file_io/file_io.py +55 -8
- atomicshop/permissions.py +35 -0
- {atomicshop-2.5.13.dist-info → atomicshop-2.5.15.dist-info}/METADATA +1 -1
- {atomicshop-2.5.13.dist-info → atomicshop-2.5.15.dist-info}/RECORD +10 -9
- {atomicshop-2.5.13.dist-info → atomicshop-2.5.15.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.5.13.dist-info → atomicshop-2.5.15.dist-info}/WHEEL +0 -0
- {atomicshop-2.5.13.dist-info → atomicshop-2.5.15.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from atomicshop import filesystem
|
|
3
|
+
from atomicshop.file_io import docxs, file_io
|
|
4
|
+
|
|
5
|
+
# Usage
|
|
6
|
+
directory_path = r"D:/directory_with_docx_files"
|
|
7
|
+
script_directory: str = filesystem.get_file_directory(__file__)
|
|
8
|
+
string_file_path: str = script_directory + os.sep + r"hyperlink.txt"
|
|
9
|
+
hyperlink: str = file_io.read_file(string_file_path)
|
|
10
|
+
|
|
11
|
+
found_in_files = docxs.search_for_hyperlink_in_files(directory_path, hyperlink, relative_paths=True)
|
|
12
|
+
|
|
13
|
+
for found_file in found_in_files:
|
|
14
|
+
print(found_file)
|
|
15
|
+
|
|
16
|
+
input('press Enter')
|
atomicshop/file_io/docxs.py
CHANGED
|
@@ -33,32 +33,35 @@ def get_hyperlinks(docx_path):
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
def search_for_hyperlink_in_files(directory_path: str, hyperlink: str, relative_paths: bool = False):
|
|
36
|
+
# noinspection GrazieInspection
|
|
36
37
|
"""
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
Search for a hyperlink in all the docx files in the specified directory.
|
|
39
|
+
:param directory_path: string, path to the directory with docx files.
|
|
40
|
+
:param hyperlink: string, hyperlink to search for.
|
|
41
|
+
:param relative_paths: boolean, if True, the function will return relative paths to the files and not the full
|
|
42
|
+
file paths. Example: 'content\file.docx' instead of 'D:/content/file.docx' if you specified 'D:/' as
|
|
43
|
+
'directory_path'.
|
|
44
|
+
:return:
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
Main function example:
|
|
47
|
+
import os
|
|
48
|
+
from atomicshop import filesystem
|
|
49
|
+
from atomicshop.file_io import docxs, file_io
|
|
49
50
|
|
|
50
|
-
directory_path = r"D:/directory_with_docx_files"
|
|
51
|
-
script_directory: str = filesystem.get_file_directory(__file__)
|
|
52
|
-
string_file_path: str = script_directory + r"/hyperlink.txt"
|
|
53
|
-
hyperlink: str = file_io.read_file(string_file_path)
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
# Usage
|
|
53
|
+
directory_path = r"D:/directory_with_docx_files"
|
|
54
|
+
script_directory: str = filesystem.get_file_directory(__file__)
|
|
55
|
+
string_file_path: str = script_directory + os.sep + r"hyperlink.txt"
|
|
56
|
+
hyperlink: str = file_io.read_file(string_file_path)
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
print(found_file)
|
|
58
|
+
found_in_files = docxs.search_for_hyperlink_in_files(directory_path, hyperlink, relative_paths=True)
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
for found_file in found_in_files:
|
|
61
|
+
print(found_file)
|
|
62
|
+
|
|
63
|
+
input('press Enter')
|
|
64
|
+
"""
|
|
62
65
|
|
|
63
66
|
if not filesystem.check_directory_existence(directory_path):
|
|
64
67
|
raise NotADirectoryError(f"Directory doesn't exist: {directory_path}")
|
atomicshop/file_io/file_io.py
CHANGED
|
@@ -22,7 +22,7 @@ def write_file_decorator(function_name):
|
|
|
22
22
|
print_api(message=f"Writing file: {kwargs['file_path']}", **kwargs)
|
|
23
23
|
|
|
24
24
|
try:
|
|
25
|
-
with open(kwargs['file_path'], kwargs['file_mode']) as output_file:
|
|
25
|
+
with open(kwargs['file_path'], kwargs['file_mode'], encoding=kwargs['encoding']) as output_file:
|
|
26
26
|
# Pass the 'output_file' object to kwargs that will pass the object to the executing function.
|
|
27
27
|
kwargs['file_object'] = output_file
|
|
28
28
|
# Since our 'kwargs' has already all the needed arguments, we don't need 'args'.
|
|
@@ -73,24 +73,33 @@ def read_file_decorator(function_name):
|
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
@write_file_decorator
|
|
76
|
-
def write_file(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
def write_file(
|
|
77
|
+
content: Union[str, list[str]],
|
|
78
|
+
file_path: str,
|
|
79
|
+
file_mode: str = 'w',
|
|
80
|
+
encoding: str = None,
|
|
81
|
+
file_object=None,
|
|
82
|
+
**kwargs) -> None:
|
|
81
83
|
"""
|
|
82
84
|
Export string to text file.
|
|
83
85
|
|
|
84
|
-
:param content: string, that includes formatted text content.
|
|
86
|
+
:param content: string or list of strings, that includes formatted text content.
|
|
85
87
|
:param file_path: Full file path string to the file to output. Used in the decorator, then passed to this function.
|
|
86
88
|
:param file_mode: string, file writing mode. Examples: 'x', 'w', 'wb'.
|
|
87
89
|
Default is 'w'.
|
|
90
|
+
:param encoding: string, write the file with encoding. Example: 'utf-8'. 'None' is default, since it is default
|
|
91
|
+
in 'open()' function.
|
|
88
92
|
:param file_object: file object of the 'open()' function in the decorator. Decorator executes the 'with open()'
|
|
89
93
|
statement and passes to this function. That's why the default is 'None', since we get it from the decorator.
|
|
90
94
|
:return:
|
|
91
95
|
"""
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
if isinstance(content, list):
|
|
98
|
+
file_object.writelines(content)
|
|
99
|
+
elif isinstance(content, str):
|
|
100
|
+
file_object.write(content)
|
|
101
|
+
else:
|
|
102
|
+
raise TypeError(f"Content type is not supported: {type(content)}")
|
|
94
103
|
|
|
95
104
|
|
|
96
105
|
@read_file_decorator
|
|
@@ -122,3 +131,41 @@ def read_file(file_path: str,
|
|
|
122
131
|
result = file_object.read()
|
|
123
132
|
|
|
124
133
|
return result
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def find_and_replace_in_file(
|
|
137
|
+
file_path: str,
|
|
138
|
+
find_what: str,
|
|
139
|
+
replace_to: str,
|
|
140
|
+
encoding: str = None,
|
|
141
|
+
raise_if_more_than_one_found: bool = False,
|
|
142
|
+
**kwargs
|
|
143
|
+
) -> None:
|
|
144
|
+
"""
|
|
145
|
+
Find and replace string in file.
|
|
146
|
+
|
|
147
|
+
:param file_path: String with full file path to read.
|
|
148
|
+
:param find_what: String to find in the file.
|
|
149
|
+
:param replace_to: String to replace the found string.
|
|
150
|
+
:param encoding: string, read the file with encoding. Example: 'utf-8'. 'None' is default, since it is default
|
|
151
|
+
in 'open()' function.
|
|
152
|
+
:param raise_if_more_than_one_found: Boolean, if True, the function will raise an error if more than one string
|
|
153
|
+
instance was found in the file.
|
|
154
|
+
:return: None
|
|
155
|
+
"""
|
|
156
|
+
|
|
157
|
+
# Read the file to variable.
|
|
158
|
+
file_data = read_file(file_path=file_path, read_to_list=True, encoding=encoding)
|
|
159
|
+
|
|
160
|
+
# Find and replace the string.
|
|
161
|
+
found_string_counter = 0
|
|
162
|
+
for index, line in enumerate(file_data):
|
|
163
|
+
if find_what in line:
|
|
164
|
+
file_data[index] = line.replace(find_what, replace_to)
|
|
165
|
+
found_string_counter += 1
|
|
166
|
+
|
|
167
|
+
if raise_if_more_than_one_found and found_string_counter > 1:
|
|
168
|
+
raise LookupError(f"More than one string instance was found in the file: {file_path}\n"
|
|
169
|
+
f"Nothing was changed.")
|
|
170
|
+
|
|
171
|
+
write_file(content=file_data, file_path=file_path, encoding=encoding)
|
atomicshop/permissions.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import ctypes
|
|
3
|
+
import contextlib
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
def is_admin() -> bool:
|
|
@@ -20,3 +21,37 @@ def is_admin() -> bool:
|
|
|
20
21
|
result = False
|
|
21
22
|
|
|
22
23
|
return result
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@contextlib.contextmanager
|
|
27
|
+
def temporary_regular_permissions():
|
|
28
|
+
"""
|
|
29
|
+
This function is used to temporarily change the effective user and group ID to the original user's.
|
|
30
|
+
This is used to run commands with the original user's permissions.
|
|
31
|
+
If you executed a script with 'sudo' and wanted certain action to execute as regular user and not root.
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
with temporary_regular_permissions():
|
|
35
|
+
# Do something with regular permissions.
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
:return:
|
|
39
|
+
"""
|
|
40
|
+
# Save the current effective user and group ID
|
|
41
|
+
original_euid, original_egid = os.geteuid(), os.getegid()
|
|
42
|
+
|
|
43
|
+
try:
|
|
44
|
+
# Get the original user's UID and GID
|
|
45
|
+
orig_uid = int(os.environ.get('SUDO_UID', os.getuid()))
|
|
46
|
+
orig_gid = int(os.environ.get('SUDO_GID', os.getgid()))
|
|
47
|
+
|
|
48
|
+
# Set the effective user and group ID to the original user's
|
|
49
|
+
os.setegid(orig_gid)
|
|
50
|
+
os.seteuid(orig_uid)
|
|
51
|
+
|
|
52
|
+
# Provide the context to do something with these permissions
|
|
53
|
+
yield
|
|
54
|
+
finally:
|
|
55
|
+
# Revert to the original effective user and group ID
|
|
56
|
+
os.seteuid(original_euid)
|
|
57
|
+
os.setegid(original_egid)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=VHWnXlEZ9dAZpc3c2DWsrkxZnCkZZZQ7x9bDbQCK-1A,123
|
|
2
2
|
atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
|
|
3
3
|
atomicshop/appointment_management.py,sha256=N3wVGJgrqJfsj_lqiRfaL3FxMEe57by5Stzanh189mk,7263
|
|
4
4
|
atomicshop/archiver.py,sha256=QuDKx6bJEM29u-7r2tsizXEEGJmPuv0Xm91JQOpg__8,7152
|
|
@@ -20,7 +20,7 @@ atomicshop/inspect_wrapper.py,sha256=sGRVQhrJovNygHTydqJj0hxES-aB2Eg9KbIk3G31apw
|
|
|
20
20
|
atomicshop/ip_addresses.py,sha256=GBG9YXEqHItmGEgKwqatx28CbWislFI2ZI2xVHGIqO4,759
|
|
21
21
|
atomicshop/keyboard_press.py,sha256=1W5kRtOB75fulVx-uF2yarBhW0_IzdI1k73AnvXstk0,452
|
|
22
22
|
atomicshop/pbtkmultifile_argparse.py,sha256=aEk8nhvoQVu-xyfZosK3ma17CwIgOjzO1erXXdjwtS4,4574
|
|
23
|
-
atomicshop/permissions.py,sha256=
|
|
23
|
+
atomicshop/permissions.py,sha256=tfODaD-81zv0PrpAW-9MMULHaGe2r9TRnkP7MPhN-mQ,1735
|
|
24
24
|
atomicshop/print_api.py,sha256=3n1CoiXvDcDGg00n5gEmQYInHryIhWbcpNjVobO1Gao,11468
|
|
25
25
|
atomicshop/process.py,sha256=i_25PrSqSBbTcstCi_8rWVXAEYco81l6b9x1l_egTOY,14193
|
|
26
26
|
atomicshop/process_name_cmd.py,sha256=TNAK6kQZm5JKWzEW6QLqVHEG98ZLNDQiSS4YwDk8V8c,3830
|
|
@@ -45,6 +45,7 @@ atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh,sha256=lM7LkXQ2AxfF
|
|
|
45
45
|
atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd,sha256=lEP_o6rWcBFUyup6_c-LTL3Q2LRMqryLuG3mJw080Zc,115
|
|
46
46
|
atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py,sha256=3VDGDO41Vubzf64DaBapLlFYX52dEdyPBNfolSsbGcM,161
|
|
47
47
|
atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py,sha256=PrvZ4hMuadzj2GYKRZSwyNayJUuaSnCF9nV6ORqoPdo,123
|
|
48
|
+
atomicshop/addons/mains/search_for_hyperlinks_in_docx.py,sha256=HkIdo_Sz9nPbbbJf1mwfwFkyI7vkvpH8qiIkuYopN4w,529
|
|
48
49
|
atomicshop/addons/mains/FACT/factw_fact_extractor_docker_image_main_sudo.py,sha256=DDKX3Wp2SmzMCEtCIEOUbEKMob2ZQ7VEQGLEf9uYXrs,320
|
|
49
50
|
atomicshop/addons/mains/FACT/update_extract.py,sha256=rvpgoBqDKlVsI9WxJfkpjbVPAWTsxC7M3MdmXJhrqo8,171
|
|
50
51
|
atomicshop/addons/package_setup/CreateWheel.cmd,sha256=hq9aWBSH6iffYlZyaCNrFlA0vxMh3j1k8DQE8IARQuA,189
|
|
@@ -83,8 +84,8 @@ atomicshop/etw/dns_trace.py,sha256=ZbEf1gptnUnJwaRURUW9ENDwC9Q41Zl6NtxgMNELJcg,5
|
|
|
83
84
|
atomicshop/etw/etw.py,sha256=xVJNbfCq4KgRfsDnul6CrIdAMl9xRBixZ-hUyqiB2g4,2403
|
|
84
85
|
atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
86
|
atomicshop/file_io/csvs.py,sha256=4R4Kij8FmxNwXFjDtlF_A0flAk0Hj5nZKlEnqC5VxgQ,3125
|
|
86
|
-
atomicshop/file_io/docxs.py,sha256=
|
|
87
|
-
atomicshop/file_io/file_io.py,sha256=
|
|
87
|
+
atomicshop/file_io/docxs.py,sha256=2lue7_eAz0fI8X3vCn34lHarU5xGSm4-Yqr0PeUPt84,4359
|
|
88
|
+
atomicshop/file_io/file_io.py,sha256=5bLEXOhvem-k8UwbmvFugyvzt-zgIdz2RVSR4ZZNV3Y,7557
|
|
88
89
|
atomicshop/file_io/jsons.py,sha256=4xCnC6MfajLouXUFl2aVXUPvftQVf2eS5DgydPZHF_c,4170
|
|
89
90
|
atomicshop/file_io/tomls.py,sha256=oa0Wm8yMkPRXKN9jgBuTnKbioSOee4mABW5IMUFCYyU,3041
|
|
90
91
|
atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
|
|
@@ -191,8 +192,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=VfNthyBvgI5tL9v3Qprh4
|
|
|
191
192
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
|
|
192
193
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
|
|
193
194
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
|
|
194
|
-
atomicshop-2.5.
|
|
195
|
-
atomicshop-2.5.
|
|
196
|
-
atomicshop-2.5.
|
|
197
|
-
atomicshop-2.5.
|
|
198
|
-
atomicshop-2.5.
|
|
195
|
+
atomicshop-2.5.15.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
196
|
+
atomicshop-2.5.15.dist-info/METADATA,sha256=AyVvRv1KbiiTq3Nt404Vt_r12RbbmEYuCOs5oOZ_HaM,10268
|
|
197
|
+
atomicshop-2.5.15.dist-info/WHEEL,sha256=Xo9-1PvkuimrydujYJAjF7pCkriuXBpUPEjma1nZyJ0,92
|
|
198
|
+
atomicshop-2.5.15.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
199
|
+
atomicshop-2.5.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|