atomicshop 2.2.7__py3-none-any.whl → 2.2.9__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.2.7'
4
+ __version__ = '2.2.9'
@@ -38,7 +38,7 @@ class AppointmentManager:
38
38
  def read_latest_date_csv(self):
39
39
  try:
40
40
  # Read the csv to list of dicts.
41
- csv_list = read_csv_to_list(file_path=self.latest_date_to_check_filepath, raise_exception=True)
41
+ csv_list, _ = read_csv_to_list(file_path=self.latest_date_to_check_filepath, raise_exception=True)
42
42
  # It has only 1 line, so get it to dict.
43
43
  latest_date_dict = csv_list[0]
44
44
 
@@ -100,7 +100,7 @@ class BlacklistEngine:
100
100
  def read_blacklist_csv(self) -> None:
101
101
  try:
102
102
  # Read the csv to list of dicts.
103
- csv_list = read_csv_to_list(file_path=self.blacklist_dates_filepath, raise_exception=True)
103
+ csv_list, _ = read_csv_to_list(file_path=self.blacklist_dates_filepath, raise_exception=True)
104
104
 
105
105
  daterange = None
106
106
  # Iterate through all the rows.
atomicshop/datetimes.py CHANGED
@@ -1,4 +1,3 @@
1
- # v1.0.2 - 21.03.2023 18:00
2
1
  import datetime
3
2
  from datetime import timedelta
4
3
  import time
@@ -1,20 +1,26 @@
1
1
  import csv
2
+ from typing import Tuple, List
2
3
 
3
4
  from .file_io import read_file_decorator
5
+ from . import file_io
4
6
 
5
7
 
6
8
  @read_file_decorator
7
9
  def read_csv_to_list(file_path: str,
8
10
  file_mode: str = 'r',
9
11
  encoding=None,
12
+ header: list = None,
10
13
  file_object=None,
11
- **kwargs) -> list:
14
+ **kwargs) -> Tuple[List, List | None]:
12
15
  """
13
16
  Function to read csv file and output its contents as list of dictionaries for each row.
14
17
 
15
18
  :param file_path: String with full file path to json file.
16
19
  :param file_mode: string, file reading mode. Examples: 'r', 'rb'. Default is 'r'.
17
20
  :param encoding: string, encoding of the file. Default is 'None'.
21
+ :param header: list, list of strings that will be the header of the CSV file. Default is 'None'.
22
+ If you want to use the header from the CSV file, use 'None'. In this case, the first row of the CSV file will
23
+ be the header.
18
24
  :param file_object: file object of the 'open()' function in the decorator. Decorator executes the 'with open()'
19
25
  statement and passes to this function. That's why the default is 'None', since we get it from the decorator.
20
26
  :return: list.
@@ -22,13 +28,15 @@ def read_csv_to_list(file_path: str,
22
28
 
23
29
  # The header fields will be separated to list of "csv_reader.fieldnames".
24
30
 
25
- # Create CSV reader from 'input_file'.
26
- csv_reader = csv.DictReader(file_object)
31
+ # Create CSV reader from 'input_file'. By default, the first row will be the header if 'fieldnames' is None.
32
+ csv_reader = csv.DictReader(file_object, fieldnames=header)
27
33
 
28
34
  # Create list of dictionaries out of 'csv_reader'.
29
35
  csv_list: list = list(csv_reader)
30
36
 
31
- return csv_list
37
+ header = csv_reader.fieldnames
38
+
39
+ return csv_list, header
32
40
 
33
41
 
34
42
  def write_list_to_csv(csv_list: list, csv_filepath: str) -> None:
@@ -50,3 +58,23 @@ def write_list_to_csv(csv_list: list, csv_filepath: str) -> None:
50
58
  writer.writeheader()
51
59
  # Write list of dits as rows.
52
60
  writer.writerows(csv_list)
61
+
62
+
63
+ def get_header(file_path: str, print_kwargs: dict = None) -> list:
64
+ """
65
+ Function to get header from CSV file.
66
+
67
+ :param file_path: Full file path to CSV file.
68
+ :param print_kwargs: Keyword arguments dict for 'print_api' function.
69
+
70
+ :return: list of strings, each string is a header field.
71
+ """
72
+
73
+ if not print_kwargs:
74
+ print_kwargs = dict()
75
+
76
+ # Get the first line of the file as text, which is the header.
77
+ header = file_io.read_file(file_path, read_to_list=True, **print_kwargs)[0]
78
+ # Split the header to list of keys.
79
+ header = header.split(',')
80
+ return header
@@ -1,3 +1,4 @@
1
+ from typing import Union
1
2
  import functools
2
3
 
3
4
  from ..print_api import print_api
@@ -96,8 +97,9 @@ def write_file(content: str,
96
97
  def read_file(file_path: str,
97
98
  file_mode: str = 'r',
98
99
  encoding=None,
100
+ read_to_list: bool = False,
99
101
  file_object=None,
100
- **kwargs) -> str:
102
+ **kwargs) -> Union[str, list]:
101
103
  """
102
104
  Read file and return its content as string.
103
105
 
@@ -105,10 +107,18 @@ def read_file(file_path: str,
105
107
  :param file_mode: string, file reading mode. Examples: 'r', 'rb'. Default is 'r'.
106
108
  :param encoding: string, read the file with encoding. Example: 'utf-8'. 'None' is default, since it is default
107
109
  in 'open()' function.
110
+ :param read_to_list: Boolean, if True, the file will be read to list of strings, each string is a line.
108
111
  :param file_object: file object of the 'open()' function in the decorator. Decorator executes the 'with open()'
109
112
  statement and passes to this function. That's why the default is 'None', since we get it from the decorator.
110
- :return: string.
113
+ :return: string or list of strings.
111
114
  """
112
115
 
113
116
  # Read the file to variable.
114
- return file_object.read()
117
+ if read_to_list:
118
+ # This method avoids creating an intermediary list by directly reading and processing the file within the list
119
+ # comprehension.
120
+ result = [line.rstrip() for line in file_object]
121
+ else:
122
+ result = file_object.read()
123
+
124
+ return result
atomicshop/filesystem.py CHANGED
@@ -44,6 +44,16 @@ def add_object_to_path(path: str, object_string: str) -> str:
44
44
  return os.path.join(path, object_string)
45
45
 
46
46
 
47
+ def get_file_name_with_extension(file_path: str) -> str:
48
+ """
49
+ The function will return file name with extension of the file.
50
+
51
+ :param file_path: string, full file path.
52
+ :return: string.
53
+ """
54
+ return str(Path(file_path).name)
55
+
56
+
47
57
  def get_list_of_directories_in_file_path(
48
58
  file_path: str, get_last_part: bool = True, convert_drive_to_string: bool = False) -> list:
49
59
  """
@@ -79,7 +79,7 @@ def thread_worker_main(
79
79
  # f"{statistics_dict['response_hex']},"
80
80
  f"\"{statistics_dict['file_path']}\","
81
81
  f"\"{statistics_dict['process_cmd']}\","
82
- f"{statistics_dict['error']},"
82
+ f"{statistics_dict['error']}"
83
83
  )
84
84
 
85
85
  try:
@@ -1,6 +1,7 @@
1
+ import os
1
2
  from typing import Literal
2
3
 
3
- from ... import filesystem
4
+ from ... import filesystem, datetimes
4
5
  from ...file_io import csvs
5
6
 
6
7
 
@@ -8,7 +9,9 @@ def get_logs(
8
9
  path: str,
9
10
  pattern: str = '*.*',
10
11
  log_type: Literal['csv'] = 'csv',
12
+ header_type_of_files: Literal['first', 'all'] = 'first',
11
13
  remove_logs: bool = False,
14
+ move_to_path: str = None,
12
15
  print_kwargs: dict = None
13
16
  ):
14
17
  """
@@ -18,10 +21,20 @@ def get_logs(
18
21
  :param pattern: Pattern to match the log files names.
19
22
  Default pattern will match all the files.
20
23
  :param log_type: Type of log to get.
24
+ :param header_type_of_files: Type of header to get from the files.
25
+ 'first' - Only the first file has a header for CSV. This header will be used for the rest of the files.
26
+ 'all' - Each CSV file has a header. Get the header from each file.
21
27
  :param remove_logs: Boolean, if True, the logs will be removed after getting them.
28
+ :param move_to_path: Path to move the logs to.
22
29
  :param print_kwargs: Keyword arguments dict for 'print_api' function.
23
30
  """
24
31
 
32
+ if not print_kwargs:
33
+ print_kwargs = dict()
34
+
35
+ if remove_logs and move_to_path:
36
+ raise ValueError('Both "remove_logs" and "move_to_path" cannot be True/specified at the same time.')
37
+
25
38
  logs_files: list = filesystem.get_files_and_folders(
26
39
  path, string_contains=pattern)
27
40
 
@@ -32,13 +45,41 @@ def get_logs(
32
45
 
33
46
  # Read all the logs.
34
47
  logs_content: list = list()
48
+ header = None
35
49
  for single_file in logs_files:
36
50
  if log_type == 'csv':
37
- logs_content.extend(csvs.read_csv_to_list(single_file, **print_kwargs))
51
+ if header_type_of_files == 'all':
52
+ csv_content, _ = csvs.read_csv_to_list(single_file, **print_kwargs)
53
+ logs_content.extend(csv_content)
54
+ elif header_type_of_files == 'first':
55
+ # The function gets empty header to read it from the CSV file, the returns the header that it read.
56
+ # Then each time the header is fed once again to the function.
57
+ csv_content, header = csvs.read_csv_to_list(single_file, header=header, **print_kwargs)
58
+ # Any way the first file will be read with header.
59
+ logs_content.extend(csv_content)
60
+
61
+ # if not header:
62
+ # # Get the first line of the file as text, which is the header.
63
+ # header = csvs.get_header(single_file, **print_kwargs)
38
64
 
39
65
  if remove_logs:
40
66
  # Remove the statistics files.
41
67
  for single_file in logs_files:
42
68
  filesystem.remove_file(single_file)
43
69
 
70
+ if move_to_path:
71
+ # Get formatted time stamp for file name.
72
+ time_stamp = datetimes.TimeFormats().get_current_formatted_time_filename_stamp()
73
+ # Remove last separator from path if it exists.
74
+ move_to_path_with_timestamp = filesystem.remove_last_separator(move_to_path)
75
+ # Add time stamp to path.
76
+ move_to_path_with_timestamp = f'{move_to_path_with_timestamp}{os.sep}{time_stamp}'
77
+ # Create the path.
78
+ filesystem.create_directory(move_to_path_with_timestamp)
79
+ # Move the statistics files.
80
+ for single_file in logs_files:
81
+ single_file_name = filesystem.get_file_name(single_file)
82
+ move_to_path_with_file = f'{move_to_path_with_timestamp}{os.sep}{single_file_name}'
83
+ filesystem.move_file(single_file, move_to_path_with_file)
84
+
44
85
  return logs_content
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.2.7
3
+ Version: 2.2.9
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,17 +1,17 @@
1
- atomicshop/__init__.py,sha256=HNBmCzxX86cIcPQfx_n4-J0nxm0w-fBMbXUvsSuXhFY,122
1
+ atomicshop/__init__.py,sha256=7FCapWCMZHR5sCrftNZYkTxSJzc7M99vB1QB_20E0ws,122
2
2
  atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
3
- atomicshop/appointment_management.py,sha256=IsaO1O9Lgso_BPm79QNQkIyunYIr7KuAkTYlityM0nw,7257
3
+ atomicshop/appointment_management.py,sha256=N3wVGJgrqJfsj_lqiRfaL3FxMEe57by5Stzanh189mk,7263
4
4
  atomicshop/archiver.py,sha256=KKdNI150yiMO_Y1TZdKjXtw4TP5LI5FJzI8VbvFKVwo,4763
5
5
  atomicshop/certificates.py,sha256=nxuq6HPBT7RfwRTSipOxoRHBS-nZLsaHR9m6UdHmDn4,297
6
6
  atomicshop/command_line_processing.py,sha256=u5yT9Ger_cu7ni5ID0VFlRbVD46ARHeNC9tRM-_YXrQ,1038
7
7
  atomicshop/console_output.py,sha256=G-6jxnWooT1nJSaPxcCqIuw8S22R_0lOJcfrdovRhwE,1372
8
8
  atomicshop/console_user_response.py,sha256=31HIy9QGXa7f-GVR8MzJauQ79E_ZqAeagF3Ks4GGdDU,3234
9
- atomicshop/datetimes.py,sha256=kyB8h5LtC6BDD-rJphps3rtJprsIHhQwaWXfW7WfIqU,13526
9
+ atomicshop/datetimes.py,sha256=B_RYGyC9HxKwYdjxjdl0OrdtHQ-cDyoK1KM4-p9cLJ8,13497
10
10
  atomicshop/diff_check.py,sha256=RON9cSTgy3jAnwUmAUkOyfF6bgrBKOq9Sbgyl3RYodw,12350
11
11
  atomicshop/dns.py,sha256=bNZOo5jVPzq7OT2qCPukXoK3zb1oOsyaelUwQEyK1SA,2500
12
12
  atomicshop/domains.py,sha256=i4PioZSumzaIYfutwph0MQ-iO9--MJYv3-JreTkn86Q,2831
13
13
  atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
14
- atomicshop/filesystem.py,sha256=qirtkFf9ivY0zvcdTatYAZRKEBF6QVq-IAnEvDV2C3g,17401
14
+ atomicshop/filesystem.py,sha256=4JOlQVDavx2W7Xx6TzsQuAjVsGB2SUF01xQCWLz4eNM,17658
15
15
  atomicshop/functions.py,sha256=VqLjxAxhaxUr-Ad8P1cw9bZGdZpbtqfCaXQyHf3CM9g,509
16
16
  atomicshop/github_wrapper.py,sha256=7pZkhliP4vdcdeVtbgTDEzBS3lUw3-mp5PMWUDA19V0,4347
17
17
  atomicshop/hashing.py,sha256=6523xFxuW0Cm1pcJCE63NWeiwt3al3t-FXLv0f0Kzpg,2989
@@ -75,11 +75,11 @@ atomicshop/etw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  atomicshop/etw/dns_trace.py,sha256=ZbEf1gptnUnJwaRURUW9ENDwC9Q41Zl6NtxgMNELJcg,5198
76
76
  atomicshop/etw/etw.py,sha256=xVJNbfCq4KgRfsDnul6CrIdAMl9xRBixZ-hUyqiB2g4,2403
77
77
  atomicshop/file_io/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- atomicshop/file_io/csvs.py,sha256=VSxW7962JmhvvrZvKgrB-Ij89AcliMVmYE6k7W34VtM,2000
79
- atomicshop/file_io/file_io.py,sha256=3w9_CRRDGmIMxQZErmJUyJjH50_6ODUw_6_fyvAZL1c,5176
78
+ atomicshop/file_io/csvs.py,sha256=4R4Kij8FmxNwXFjDtlF_A0flAk0Hj5nZKlEnqC5VxgQ,3125
79
+ atomicshop/file_io/file_io.py,sha256=d7HYaixw12wf0WKKoCpWWjOWtmsFqgGztcSuWL41nlQ,5650
80
80
  atomicshop/file_io/jsons.py,sha256=XgQs--Q6LGqC4ZtcyKvlMY_Fajjjp_l5bi6xYCy2fQQ,3383
81
81
  atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- atomicshop/mitm/connection_thread_worker.py,sha256=u_d_xMuFKFEYg42kZyCoY7CY4qEMapqRWjQhgRAAveQ,20631
82
+ atomicshop/mitm/connection_thread_worker.py,sha256=7f7T3t6ltndzb3125DgyRTzsD-oAbAfewDIhpNEeHRY,20630
83
83
  atomicshop/mitm/import_config.py,sha256=BPZ62ozMUaUKn7Crt6dhzvUgD3dSKd17kMfbJNObvlI,7486
84
84
  atomicshop/mitm/initialize_engines.py,sha256=qCtIjaR-sCbcliKKX_I65O6e4fqc-zDHELGglnL92cw,7687
85
85
  atomicshop/mitm/initialize_mitm_server.py,sha256=ZEYt5GgnhcgMDGtc4a4klYN0ukq8_ZSg91Uta_vzb7A,11345
@@ -126,7 +126,7 @@ atomicshop/wrappers/loggingw/formatters.py,sha256=mUtcJJfmhLNrwUVYShXTmdu40dBaJu
126
126
  atomicshop/wrappers/loggingw/handlers.py,sha256=qm5Fbu8eDmlstMduUe5nKUlJU5IazFkSnQizz8Qt2os,5479
127
127
  atomicshop/wrappers/loggingw/loggers.py,sha256=DHOOTAtqkwn1xgvLHSkOiBm6yFGNuQy1kvbhG-TDog8,2374
128
128
  atomicshop/wrappers/loggingw/loggingw.py,sha256=30uaJOJhPJExYptEmwc5HWScI2RbnDlNgybOsxW7klc,11609
129
- atomicshop/wrappers/loggingw/reading.py,sha256=1WmPl8_Jc1PHXDpvpEJubalFxzmTa0DpTvxehFVvvzw,1510
129
+ atomicshop/wrappers/loggingw/reading.py,sha256=3zT1ahK_xU9YAi3-xk6F2QEzC40lfwTWQr1MrkMpF8o,3786
130
130
  atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
131
  atomicshop/wrappers/playwrightw/_tryouts.py,sha256=l1BLkFsiIMNlgv7nfZd1XGEvXQkIQkIcg48__9OaC00,4920
132
132
  atomicshop/wrappers/playwrightw/base.py,sha256=zwHfbFZV7qqpmReJg5lEpKtOO23DRxEd61ZdoLBU_9Q,9833
@@ -154,8 +154,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=7-G1t2yyDA-cNQF8zCpQS
154
154
  atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
155
155
  atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
156
156
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
157
- atomicshop-2.2.7.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
158
- atomicshop-2.2.7.dist-info/METADATA,sha256=jMjqlMZGxGDvnoszJCov1Y63NuJbBZq3uecEmOpsHuM,9506
159
- atomicshop-2.2.7.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
160
- atomicshop-2.2.7.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
161
- atomicshop-2.2.7.dist-info/RECORD,,
157
+ atomicshop-2.2.9.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
158
+ atomicshop-2.2.9.dist-info/METADATA,sha256=uXxMGqgUIcJdkLOtXGzXJ0RNNDaXtX1ex4gwK0Dz-14,9506
159
+ atomicshop-2.2.9.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
160
+ atomicshop-2.2.9.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
161
+ atomicshop-2.2.9.dist-info/RECORD,,