datacomshell 0.26.1__tar.gz → 0.26.6__tar.gz

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.
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: datacomshell
3
- Version: 0.26.1
3
+ Version: 0.26.6
4
4
  Summary: Add your description here
5
5
  Author: Saven
6
6
  Author-email: Saven <2416844857@qq.com>
7
+ Requires-Dist: aiofiles>=25.1.0
7
8
  Requires-Dist: telnetlib3>=4.0.2
8
9
  Requires-Python: >=3.14
9
10
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datacomshell"
3
- version = "0.26.1"
3
+ version = "0.26.6"
4
4
  description = "Add your description here"
5
5
  authors = [
6
6
  { name = "Saven", email = "2416844857@qq.com" },
@@ -8,6 +8,7 @@ authors = [
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.14"
10
10
  dependencies = [
11
+ "aiofiles>=25.1.0",
11
12
  "telnetlib3>=4.0.2",
12
13
  ]
13
14
 
@@ -1,7 +1,12 @@
1
1
  from typing import Optional, Union, Tuple, cast
2
2
  from datacomshell.Auth import Auth, AuthState, UsernamePasswordAuth
3
3
  from telnetlib3 import TelnetReader, TelnetReaderUnicode, TelnetWriter, TelnetWriterUnicode, open_connection
4
+ from datetime import datetime
4
5
  import asyncio
6
+ import aiofiles
7
+ from aiofiles.threadpool.text import AsyncTextIOWrapper
8
+ import pathlib
9
+
5
10
  import re
6
11
 
7
12
  _DEFAULT_ENDING = '[saven-process-end]'
@@ -51,6 +56,8 @@ class AsyncTelnetClientUtil(object):
51
56
  connect_timeout: float = 10.0,
52
57
  login_timeout: float = 10.0,
53
58
  exc_command_timeout: float = 10.0,
59
+ log_folder_path: Optional[str] = None,
60
+ log_new_second: float = 1800,
54
61
  wait_input_tag_partten_list: list[re.Pattern] = _DEFAULT_WAIT_INPUT_TAG_PARTTEN_LIST,
55
62
  ) -> None:
56
63
  self.__host: str = host
@@ -65,6 +72,17 @@ class AsyncTelnetClientUtil(object):
65
72
  self.__reader: _READER_TYPE | None = None
66
73
  self.__writer: _WRITER_TYPE | None = None
67
74
 
75
+ self.__log_folder_path: str | None = log_folder_path
76
+ self.__log_new_second: float = log_new_second
77
+ self.__timestemp: float = datetime.now().timestamp()
78
+ self.__log_file: AsyncTextIOWrapper | None = None
79
+
80
+ self.__is_log = True if log_folder_path != None else False
81
+
82
+ if self.__is_log and self.__log_folder_path != None:
83
+ pathlib.Path(self.__log_folder_path).mkdir(
84
+ parents=True, exist_ok=True)
85
+
68
86
  async def __initConnect(self) -> None:
69
87
  if self.__auth_type == AuthState.NONE_AUTH:
70
88
  res = await self.__none_auth()
@@ -85,6 +103,8 @@ class AsyncTelnetClientUtil(object):
85
103
  connect_timeout: float = 10.0,
86
104
  login_timeout: float = 10.0,
87
105
  exc_command_timeout: float = 10.0,
106
+ log_folder_path: Optional[str] = None,
107
+ log_new_second: float = 1800,
88
108
  wait_input_tag_partten_list: list[re.Pattern] = _DEFAULT_WAIT_INPUT_TAG_PARTTEN_LIST,) -> 'AsyncTelnetClientUtil':
89
109
 
90
110
  instance: AsyncTelnetClientUtil = cls(
@@ -94,10 +114,16 @@ class AsyncTelnetClientUtil(object):
94
114
  connect_timeout=connect_timeout,
95
115
  login_timeout=login_timeout,
96
116
  exc_command_timeout=exc_command_timeout,
117
+ log_folder_path=log_folder_path,
118
+ log_new_second=log_new_second,
97
119
  wait_input_tag_partten_list=wait_input_tag_partten_list,
98
120
  )
99
121
 
100
122
  await instance.__initConnect()
123
+
124
+ if instance.__is_log:
125
+ await instance.__create_log_file()
126
+
101
127
  print(f"""
102
128
  [I] connect success: {instance.__host}:{instance.__port}
103
129
  [I] login type: {instance.__auth.get_auth_type().name}
@@ -130,16 +156,26 @@ class AsyncTelnetClientUtil(object):
130
156
  _writer = cast(TelnetWriterUnicode, writer)
131
157
  _auth = cast(UsernamePasswordAuth, self.__auth)
132
158
 
159
+ buffer = ''
133
160
  try:
134
- await self.__read_login_wait_wrapper(_reader.readuntil(b'Username:'))
161
+ res: bytes = b''
162
+ res: bytes = await self.__read_login_wait_wrapper(_reader.readuntil(b'Username:'))
163
+ buffer = buffer + res.decode()
135
164
  _writer.write(self.__command_wrapper(_auth.get_username()))
136
165
  await _writer.drain()
137
166
 
138
- await self.__read_login_wait_wrapper(_reader.readuntil(b'Password:'))
167
+ res: bytes = b''
168
+ res: bytes = await self.__read_login_wait_wrapper(_reader.readuntil(b'Password:'))
169
+ buffer = buffer + res.decode()
139
170
  _writer.write(self.__command_wrapper(_auth.get_password()))
140
171
  await _writer.drain()
141
172
 
142
- await self.__read_login_wait_wrapper(_reader.readuntil(b'>'))
173
+ res: bytes = b''
174
+ res: bytes = await self.__read_login_wait_wrapper(_reader.readuntil(b'>'))
175
+ buffer = buffer + res.decode()
176
+
177
+ # Log
178
+ await self.__log(buffer)
143
179
  except asyncio.TimeoutError:
144
180
  raise LoginTimoutError('Login timeout')
145
181
 
@@ -150,6 +186,40 @@ class AsyncTelnetClientUtil(object):
150
186
  await self.__login_of_username_password(reader, writer)
151
187
  return reader, writer
152
188
 
189
+ async def __close_log_file(self):
190
+ if self.__log_file != None:
191
+ await self.__log_file.close()
192
+
193
+ async def __create_log_file(self):
194
+ await self.__close_log_file()
195
+ filename = datetime.now().strftime('%Y-%m-%d_%H-%M-%S-%f') + '.log'
196
+
197
+ if self.__log_folder_path == None:
198
+ raise RuntimeError('[IE] log_folder_path error')
199
+
200
+ self.__timestemp = datetime.now().timestamp()
201
+ en_path = self.__log_folder_path + '/' + filename
202
+ self.__log_file = await aiofiles.open(en_path, 'a', encoding='utf-8')
203
+
204
+ await self.__log_file.write(f'================ {filename} ================')
205
+
206
+ async def __log(self, message: str):
207
+ if self.__is_log != True:
208
+ return
209
+
210
+ curren_timestemp: float = datetime.now().timestamp()
211
+ diff = curren_timestemp - self.__timestemp
212
+
213
+ # 新建
214
+ if diff > self.__log_new_second:
215
+ await self.__create_log_file()
216
+
217
+ # 记录
218
+ if self.__log_file == None:
219
+ raise RuntimeError('[IE] log_file is None')
220
+ else:
221
+ await self.__log_file.write(message)
222
+
153
223
  async def execute(self, command: str) -> bytes:
154
224
  if self.__reader == None and self.__writer == None:
155
225
  raise OperationObjNullError("[IE]: __reader and __writer is None")
@@ -166,6 +236,7 @@ class AsyncTelnetClientUtil(object):
166
236
  res = b'null'
167
237
  try:
168
238
  res = await self.__read_wait_wrapper(_reader.readuntil(_DEFAULT_ENDING.encode('utf-8')))
239
+ await self.__log(res.decode())
169
240
  except asyncio.TimeoutError as e:
170
241
  print("[I] reader buffer empty")
171
242
 
@@ -182,6 +253,9 @@ class AsyncTelnetClientUtil(object):
182
253
  _reader = cast(_READER_TYPE, self.__reader)
183
254
  _writer = cast(TelnetWriterUnicode, self.__writer)
184
255
 
256
+ if self.__log_file != None:
257
+ await self.__log_file.close()
258
+
185
259
  _reader.close()
186
260
  _writer.close()
187
261
 
File without changes