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.
- {datacomshell-0.26.1 → datacomshell-0.26.6}/PKG-INFO +2 -1
- {datacomshell-0.26.1 → datacomshell-0.26.6}/pyproject.toml +2 -1
- {datacomshell-0.26.1 → datacomshell-0.26.6}/src/datacomshell/AsyncTelnetClientUtil.py +77 -3
- {datacomshell-0.26.1 → datacomshell-0.26.6}/README.md +0 -0
- {datacomshell-0.26.1 → datacomshell-0.26.6}/src/datacomshell/Auth.py +0 -0
- {datacomshell-0.26.1 → datacomshell-0.26.6}/src/datacomshell/__init__.py +0 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: datacomshell
|
|
3
|
-
Version: 0.26.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
File without changes
|
|
File without changes
|