tplinkrouterc6u 5.2.1__py3-none-any.whl → 5.4.0__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.
test/test_client_c1200.py CHANGED
@@ -3,41 +3,45 @@ from json import loads
3
3
  from tplinkrouterc6u import (
4
4
  TplinkC1200Router,
5
5
  Connection,
6
- ClientException
6
+ ClientException,
7
7
  )
8
+ from tplinkrouterc6u.common.package_enum import VPN
8
9
 
9
10
 
10
11
  class TestTPLinkC1200Client(TestCase):
11
-
12
12
  def test_set_led_on(self) -> None:
13
-
14
- response_led_general_read = '''
13
+ response_led_general_read = """
15
14
  {
16
15
  "enable": "off",
17
16
  "time_set": "yes",
18
17
  "ledpm_support": "yes"
19
18
  }
20
- '''
19
+ """
21
20
 
22
- response_led_general_write = '''
21
+ response_led_general_write = """
23
22
  {
24
23
  "enable": "on",
25
24
  "time_set": "yes",
26
25
  "ledpm_support": "yes"
27
26
  }
28
- '''
27
+ """
29
28
 
30
29
  class TPLinkRouterTest(TplinkC1200Router):
31
- def request(self, path: str, data: str,
32
- ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
33
- if path == 'admin/ledgeneral?form=setting&operation=read':
30
+ def request(
31
+ self,
32
+ path: str,
33
+ data: str,
34
+ ignore_response: bool = False,
35
+ ignore_errors: bool = False,
36
+ ) -> dict | None:
37
+ if path == "admin/ledgeneral?form=setting&operation=read":
34
38
  return loads(response_led_general_read)
35
- if path == 'admin/ledgeneral?form=setting&operation=write':
39
+ if path == "admin/ledgeneral?form=setting&operation=write":
36
40
  self.captured_path = path
37
41
  return loads(response_led_general_write)
38
42
  raise ClientException()
39
43
 
40
- client = TPLinkRouterTest('', '')
44
+ client = TPLinkRouterTest("", "")
41
45
 
42
46
  client.set_led(True)
43
47
 
@@ -46,34 +50,38 @@ class TestTPLinkC1200Client(TestCase):
46
50
  self.assertEqual(client.captured_path, expected_path)
47
51
 
48
52
  def test_set_led_off(self) -> None:
49
-
50
- response_led_general_read = '''
53
+ response_led_general_read = """
51
54
  {
52
55
  "enable": "on",
53
56
  "time_set": "yes",
54
57
  "ledpm_support": "yes"
55
58
  }
56
- '''
59
+ """
57
60
 
58
- response_led_general_write = '''
61
+ response_led_general_write = """
59
62
  {
60
63
  "enable": "off",
61
64
  "time_set": "yes",
62
65
  "ledpm_support": "yes"
63
66
  }
64
- '''
67
+ """
65
68
 
66
69
  class TPLinkRouterTest(TplinkC1200Router):
67
- def request(self, path: str, data: str,
68
- ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
69
- if path == 'admin/ledgeneral?form=setting&operation=read':
70
+ def request(
71
+ self,
72
+ path: str,
73
+ data: str,
74
+ ignore_response: bool = False,
75
+ ignore_errors: bool = False,
76
+ ) -> dict | None:
77
+ if path == "admin/ledgeneral?form=setting&operation=read":
70
78
  return loads(response_led_general_read)
71
- elif path == 'admin/ledgeneral?form=setting&operation=write':
79
+ if path == "admin/ledgeneral?form=setting&operation=write":
72
80
  self.captured_path = path
73
81
  return loads(response_led_general_write)
74
82
  raise ClientException()
75
83
 
76
- client = TPLinkRouterTest('', '')
84
+ client = TPLinkRouterTest("", "")
77
85
 
78
86
  client.set_led(False)
79
87
 
@@ -82,37 +90,44 @@ class TestTPLinkC1200Client(TestCase):
82
90
  self.assertEqual(client.captured_path, expected_path)
83
91
 
84
92
  def test_led_status(self) -> None:
85
-
86
- response_led_general_read = '''
93
+ response_led_general_read = """
87
94
  {
88
95
  "enable": "on",
89
96
  "time_set": "yes",
90
97
  "ledpm_support": "yes"
91
98
  }
92
- '''
99
+ """
93
100
 
94
101
  class TPLinkRouterTest(TplinkC1200Router):
95
- def request(self, path: str, data: str,
96
- ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
97
- if path == 'admin/ledgeneral?form=setting&operation=read':
102
+ def request(
103
+ self,
104
+ path: str,
105
+ data: str,
106
+ ignore_response: bool = False,
107
+ ignore_errors: bool = False,
108
+ ) -> dict | None:
109
+ if path == "admin/ledgeneral?form=setting&operation=read":
98
110
  return loads(response_led_general_read)
99
111
  raise ClientException()
100
112
 
101
- client = TPLinkRouterTest('', '')
113
+ client = TPLinkRouterTest("", "")
102
114
 
103
115
  led_status = client.get_led()
104
116
  self.assertTrue(led_status)
105
117
 
106
118
  def test_set_wifi(self) -> None:
107
-
108
119
  class TPLinkRouterTest(TplinkC1200Router):
109
- def request(self, path: str, data: str,
110
- ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
111
-
120
+ def request(
121
+ self,
122
+ path: str,
123
+ data: str,
124
+ ignore_response: bool = False,
125
+ ignore_errors: bool = False,
126
+ ) -> dict | None:
112
127
  self.captured_path = path
113
128
  self.captured_data = data
114
129
 
115
- client = TPLinkRouterTest('', '')
130
+ client = TPLinkRouterTest("", "")
116
131
  client.set_wifi(
117
132
  Connection.HOST_5G,
118
133
  enable=True,
@@ -126,17 +141,119 @@ class TestTPLinkC1200Client(TestCase):
126
141
  htmode="VHT20",
127
142
  channel=36,
128
143
  txpower="20",
129
- disabled_all="no"
144
+ disabled_all="no",
130
145
  )
131
146
 
132
- expected_data = ("operation=write&enable=on&ssid=TestSSID&hidden=no&encryption=WPA3-PSK&"
133
- "psk_version=2&psk_cipher=AES&psk_key=testkey123&hwmode=11ac&"
134
- "htmode=VHT20&channel=36&txpower=20&disabled_all=no")
147
+ expected_data = (
148
+ "operation=write&enable=on&ssid=TestSSID&hidden=no&encryption=WPA3-PSK&"
149
+ "psk_version=2&psk_cipher=AES&psk_key=testkey123&hwmode=11ac&"
150
+ "htmode=VHT20&channel=36&txpower=20&disabled_all=no"
151
+ )
135
152
  expected_path = f"admin/wireless?form=wireless_5g&{expected_data}"
136
153
 
137
154
  self.assertEqual(client.captured_path, expected_path)
138
155
  self.assertEqual(client.captured_data, expected_data)
139
156
 
157
+ def test_vpn_status(self) -> None:
158
+ response_openvpn_read = """
159
+ {
160
+ "enabled": "on",
161
+ "proto": "udp",
162
+ "access": "home",
163
+ "cert_exist": true,
164
+ "mask": "255.255.255.0",
165
+ "port": "1194",
166
+ "serverip": "10.8.0.0"
167
+ }
168
+ """
169
+
170
+ response_pptp_read = """
171
+ {
172
+ "enabled": "off",
173
+ "unencrypted_access": "on",
174
+ "samba_access": "on",
175
+ "netbios_pass": "on",
176
+ "remoteip": "10.0.0.11-20"
177
+ }
178
+ """
179
+
180
+ respone_vpnconn_openvpn = """[
181
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
182
+ "extra": "7450", "vpntype": "openvpn", "key": "7450"},
183
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
184
+ "extra": "7450", "vpntype": "openvpn", "key": "7450"}
185
+ ]"""
186
+
187
+ respone_vpnconn_pptpvpn = """[
188
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
189
+ "extra": "7450", "vpntype": "pptp", "key": "7450"},
190
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
191
+ "extra": "7450", "vpntype": "pptp", "key": "7450"},
192
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
193
+ "extra": "7450", "vpntype": "pptp", "key": "7450"}
194
+ ]"""
195
+
196
+ class TPLinkRouterTest(TplinkC1200Router):
197
+ def request(
198
+ self,
199
+ path: str,
200
+ data: str,
201
+ ignore_response: bool = False,
202
+ ignore_errors: bool = False,
203
+ ) -> dict | None:
204
+ if path == "/admin/openvpn?form=config&operation=read":
205
+ return loads(response_openvpn_read)
206
+ if path == "/admin/pptpd?form=config&operation=read":
207
+ return loads(response_pptp_read)
208
+ if path == "/admin/vpnconn?form=config&operation=list&vpntype=openvpn":
209
+ return loads(respone_vpnconn_openvpn)
210
+ if path == "/admin/vpnconn?form=config&operation=list&vpntype=pptp":
211
+ return loads(respone_vpnconn_pptpvpn)
212
+ raise ClientException()
213
+
214
+ client = TPLinkRouterTest("", "")
215
+
216
+ vpn_status = client.get_vpn_status()
217
+ self.assertTrue(vpn_status.openvpn_enable)
218
+ self.assertFalse(vpn_status.pptpvpn_enable)
219
+ self.assertEqual(vpn_status.openvpn_clients_total, 2)
220
+ self.assertEqual(vpn_status.pptpvpn_clients_total, 3)
221
+
222
+ def test_set_vpn(self) -> None:
223
+ response_openvpn_read = """
224
+ {
225
+ "enabled": "on",
226
+ "proto": "udp",
227
+ "access": "home",
228
+ "cert_exist": true,
229
+ "mask": "255.255.255.0",
230
+ "port": "1194",
231
+ "serverip": "10.8.0.0"
232
+ }
233
+ """
234
+
235
+ class TPLinkRouterTest(TplinkC1200Router):
236
+ def request(
237
+ self,
238
+ path: str,
239
+ data: str,
240
+ ignore_response: bool = False,
241
+ ignore_errors: bool = False,
242
+ ) -> dict | None:
243
+ if path == "/admin/openvpn?form=config&operation=read":
244
+ return loads(response_openvpn_read)
245
+ self.captured_path = path
246
+
247
+ client = TPLinkRouterTest("", "")
248
+ client.set_vpn(VPN.OPEN_VPN, True)
249
+
250
+ expected_path = (
251
+ "/admin/openvpn?form=config&operation=write&enabled=on"
252
+ "&proto=udp&access=home&cert_exist=True"
253
+ "&mask=255.255.255.0&port=1194&serverip=10.8.0.0"
254
+ )
255
+ self.assertEqual(client.captured_path, expected_path)
256
+
140
257
 
141
- if __name__ == '__main__':
258
+ if __name__ == "__main__":
142
259
  main()
test/test_client_ex.py CHANGED
@@ -11,6 +11,8 @@ from tplinkrouterc6u import (
11
11
  IPv4DHCPLease,
12
12
  IPv4Status,
13
13
  ClientException,
14
+ VPNStatus,
15
+ VPN,
14
16
  )
15
17
 
16
18
 
@@ -334,6 +336,65 @@ class TestTPLinkEXClient(TestCase):
334
336
  self.assertEqual(check_data, '{"data":{"stack":"1,0,0,0,0,0","pstack":"0,0,0,0,0,0",'
335
337
  '"primaryEnable":"1"},"operation":"so","oid":"DEV2_ADT_WIFI_COMMON"}')
336
338
 
339
+ def test_get_vpn_status(self) -> None:
340
+ DEV2_OPENVPN = ('{"data":{"enable":"1","stack":"0,0,0,0,0,0"},'
341
+ '"operation":"go","oid":"DEV2_OPENVPN","success":true}')
342
+ DEV2_PPTPVPN = ('{"data":{"enable":"0","stack":"0,0,0,0,0,0"},'
343
+ '"operation":"go","oid":"DEV2_PPTPVPN","success":true}')
344
+ DEV2_OVPN_CLIENT = ('{"data":[{"connAct":"1","stack":"1,0,0,0,0,0"}, {"connAct":"1","stack":"2,0,0,0,0,0"},'
345
+ '{"connAct":"0","stack":"3,0,0,0,0,0"}, {"connAct":"0","stack":"4,0,0,0,0,0"},'
346
+ '{"connAct":"0","stack":"5,0,0,0,0,0"}, {"connAct":"0","stack":"6,0,0,0,0,0"},'
347
+ '{"connAct":"0","stack":"7,0,0,0,0,0"}, {"connAct":"0","stack":"8,0,0,0,0,0"},'
348
+ '{"connAct":"0","stack":"9,0,0,0,0,0"}, {"connAct":"0","stack":"10,0,0,0,0,0"}],'
349
+ '"operation":"gl","oid":"DEV2_OVPN_CLIENT","success":true}')
350
+ DEV2_PVPN_CLIENT = ('{"data":[{"connAct":"0","stack":"1,0,0,0,0,0"}, {"connAct":"0","stack":"2,0,0,0,0,0"},'
351
+ '{"connAct":"1","stack":"3,0,0,0,0,0"}, {"connAct":"0","stack":"4,0,0,0,0,0"},'
352
+ '{"connAct":"0","stack":"5,0,0,0,0,0"}, {"connAct":"0","stack":"6,0,0,0,0,0"},'
353
+ '{"connAct":"0","stack":"7,0,0,0,0,0"}, {"connAct":"0","stack":"8,0,0,0,0,0"},'
354
+ '{"connAct":"0","stack":"9,0,0,0,0,0"}, {"connAct":"0","stack":"10,0,0,0,0,0"}],'
355
+ '"operation":"gl","oid":"DEV2_PVPN_CLIENT","success":true}')
356
+
357
+ class TPLinkEXClientTest(TPLinkEXClient):
358
+ def _request(self, url, method='POST', data_str=None, encrypt=False):
359
+ if 'DEV2_OPENVPN' in data_str:
360
+ return 200, DEV2_OPENVPN
361
+ elif 'DEV2_PPTPVPN' in data_str:
362
+ return 200, DEV2_PPTPVPN
363
+ elif 'DEV2_OVPN_CLIENT' in data_str:
364
+ return 200, DEV2_OVPN_CLIENT
365
+ elif 'DEV2_PVPN_CLIENT' in data_str:
366
+ return 200, DEV2_PVPN_CLIENT
367
+ raise ClientException()
368
+
369
+ client = TPLinkEXClientTest('', '')
370
+ status = client.get_vpn_status()
371
+
372
+ self.assertIsInstance(status, VPNStatus)
373
+ self.assertEqual(status.openvpn_enable, True)
374
+ self.assertEqual(status.pptpvpn_enable, False)
375
+ self.assertEqual(status.openvpn_clients_total, 2)
376
+ self.assertEqual(status.pptpvpn_clients_total, 1)
377
+
378
+ def test_set_vpn(self) -> None:
379
+ response = '{"success":true, "errorcode":0}'
380
+
381
+ check_url = ''
382
+ check_data = ''
383
+
384
+ class TPLinkEXClientTest(TPLinkEXClient):
385
+ def _request(self, url, method='POST', data_str=None, encrypt=False):
386
+ nonlocal check_url, check_data
387
+ check_url = url
388
+ check_data = data_str
389
+ return 200, response
390
+
391
+ client = TPLinkEXClientTest('', '')
392
+ client.set_vpn(VPN.OPEN_VPN, True)
393
+
394
+ self.assertIn('http:///cgi_gdpr?9?_=', check_url)
395
+ self.assertEqual(check_data, '{"data":{"stack":"0,0,0,0,0,0","pstack":"0,0,0,0,0,0",'
396
+ '"enable":"1"},"operation":"so","oid":"DEV2_OPENVPN"}')
397
+
337
398
 
338
399
  if __name__ == '__main__':
339
400
  main()
@@ -1,8 +1,11 @@
1
1
  from re import search
2
2
  from requests import post, Response
3
+ from urllib.parse import urlencode
3
4
  from tplinkrouterc6u.common.encryption import EncryptionWrapper
4
5
  from tplinkrouterc6u.common.exception import ClientException, AuthorizeError
5
6
  from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
7
+ from tplinkrouterc6u.common.dataclass import VPNStatus
8
+ from tplinkrouterc6u.common.package_enum import VPN
6
9
 
7
10
 
8
11
  class TplinkC1200Router(TplinkC5400XRouter):
@@ -100,3 +103,36 @@ class TplinkC1200Router(TplinkC5400XRouter):
100
103
  @staticmethod
101
104
  def _get_login_data(crypted_pwd: str) -> str:
102
105
  return 'operation=login&password={}'.format(crypted_pwd)
106
+
107
+ def get_vpn_status(self) -> VPNStatus:
108
+ status = VPNStatus()
109
+
110
+ values = [
111
+ self.request("/admin/openvpn?form=config&operation=read", "operation=read"),
112
+ self.request("/admin/pptpd?form=config&operation=read", "operation=read"),
113
+ self.request("/admin/vpnconn?form=config&operation=list&vpntype=openvpn",
114
+ "operation=list&operation=list&vpntype=openvpn"),
115
+ self.request("/admin/vpnconn?form=config&operation=list&vpntype=pptp",
116
+ "operation=list&operation=list&vpntype=pptp"),
117
+ ]
118
+
119
+ status.openvpn_enable = values[0]['enabled'] == 'on'
120
+ status.pptpvpn_enable = values[1]['enabled'] == 'on'
121
+
122
+ if isinstance(values[2], list):
123
+ status.openvpn_clients_total = len(values[2])
124
+ status.pptpvpn_clients_total = len(values[3])
125
+ else:
126
+ status.openvpn_clients_total = 0
127
+ status.pptpvpn_clients_total = 0
128
+
129
+ return status
130
+
131
+ def set_vpn(self, vpn: VPN, enable: bool) -> None:
132
+ path = "/admin/{}?form=config&operation=read".format(vpn.lowercase)
133
+ current_config = self.request(path, "operation=read")
134
+ current_config['enabled'] = "on" if enable else "off"
135
+ data = urlencode(current_config)
136
+ data = "&operation=write&{}".format(data)
137
+ path = "/admin/{}?form=config{}".format(vpn.lowercase, data)
138
+ self.request(path, data)
@@ -42,7 +42,7 @@ class TplinkC5400XRouter(TplinkBaseRouter):
42
42
  if current_state != enable:
43
43
  self.request('admin/ledgeneral?form=setting&operation=write', 'operation=write')
44
44
 
45
- def get_led(self) -> bool:
45
+ def get_led(self) -> bool | None:
46
46
 
47
47
  data = self.request('admin/ledgeneral?form=setting&operation=read', 'operation=read')
48
48
  led_status = data.get('enable') if 'enable' in data else None
@@ -4,8 +4,15 @@ from datetime import timedelta
4
4
  from macaddress import EUI48
5
5
  from ipaddress import IPv4Address
6
6
  from logging import Logger
7
- from tplinkrouterc6u.common.package_enum import Connection
8
- from tplinkrouterc6u.common.dataclass import Firmware, Status, Device, IPv4Reservation, IPv4DHCPLease, IPv4Status
7
+ from tplinkrouterc6u.common.package_enum import Connection, VPN
8
+ from tplinkrouterc6u.common.dataclass import (
9
+ Firmware,
10
+ Status,
11
+ Device,
12
+ IPv4Reservation,
13
+ IPv4DHCPLease,
14
+ IPv4Status,
15
+ VPNStatus)
9
16
  from tplinkrouterc6u.common.exception import ClientException, ClientError
10
17
  from tplinkrouterc6u.client.mr import TPLinkMRClientBase
11
18
 
@@ -293,3 +300,33 @@ class TPLinkEXClient(TPLinkMRClientBase):
293
300
  if self._logger:
294
301
  self._logger.debug(error)
295
302
  raise ClientException(error)
303
+
304
+ def get_vpn_status(self) -> VPNStatus:
305
+ status = VPNStatus()
306
+ acts = [
307
+ self.ActItem(self.ActItem.GET, 'DEV2_OPENVPN', attrs=['enable']),
308
+ self.ActItem(self.ActItem.GET, 'DEV2_PPTPVPN', attrs=['enable']),
309
+ self.ActItem(self.ActItem.GL, 'DEV2_OVPN_CLIENT', attrs=['connAct']),
310
+ self.ActItem(self.ActItem.GL, 'DEV2_PVPN_CLIENT', attrs=['connAct']),
311
+ ]
312
+ _, values = self.req_act(acts)
313
+
314
+ status.openvpn_enable = values[0]['enable'] == '1'
315
+ status.pptpvpn_enable = values[1]['enable'] == '1'
316
+
317
+ for item in values[2]:
318
+ if item['connAct'] == '1':
319
+ status.openvpn_clients_total += 1
320
+
321
+ for item in values[3]:
322
+ if item['connAct'] == '1':
323
+ status.pptpvpn_clients_total += 1
324
+
325
+ return status
326
+
327
+ def set_vpn(self, vpn: VPN, enable: bool) -> None:
328
+ acts = [
329
+ self.ActItem(self.ActItem.SET, "DEV2_" + vpn.value, attrs=[f'"enable":"{int(enable)}"'])
330
+ ]
331
+
332
+ self.req_act(acts)
@@ -599,7 +599,7 @@ class TPLinkMRClient(TPLinkMRClientBase):
599
599
  messages.append(
600
600
  SMS(
601
601
  i, item['from'], item['content'], datetime.fromisoformat(item['receivedTime']),
602
- True if item['unread'] == '1' else False
602
+ item['unread'] == '1'
603
603
  )
604
604
  )
605
605
  i += 1
@@ -691,8 +691,8 @@ class TPLinkMRClient(TPLinkMRClientBase):
691
691
  ]
692
692
  _, values = self.req_act(acts)
693
693
 
694
- status.openvpn_enable = True if values['0']['enable'] == '1' else False
695
- status.pptpvpn_enable = True if values['1']['enable'] == '1' else False
694
+ status.openvpn_enable = values['0']['enable'] == '1'
695
+ status.pptpvpn_enable = values['1']['enable'] == '1'
696
696
 
697
697
  for item in values['2']:
698
698
  if item['connAct'] == '1':
@@ -49,3 +49,8 @@ class Connection(Enum):
49
49
  class VPN(Enum):
50
50
  OPEN_VPN = 'OPENVPN'
51
51
  PPTP_VPN = 'PPTPVPN'
52
+
53
+ @property
54
+ def lowercase(self) -> str:
55
+ """Returns the lowercase version of the enum value. Needed for the c1200 router."""
56
+ return self.value.lower()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tplinkrouterc6u
3
- Version: 5.2.1
3
+ Version: 5.4.0
4
4
  Summary: TP-Link Router API
5
5
  Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
6
6
  Author: Alex Erohin
@@ -303,7 +303,8 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
303
303
  - Archer C7 (v4.0, v5.0)
304
304
  - Archer C5400X V1
305
305
  - Archer GX90 v1.0
306
- - Archer MR200 (v5, v5.3)
306
+ - Archer MR200 (v5, v5.3, v6.0)
307
+ - Archer MR550 v1
307
308
  - Archer MR600 (v1, v2, v3)
308
309
  - Archer VR600 v3
309
310
  - Archer VR900v
@@ -327,6 +328,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
327
328
  - TL-MR6500v
328
329
  - TL-XDR3010 V2
329
330
  - TL-WA3001 v1.0
331
+ - NX510v v1.0
330
332
 
331
333
  ### Not fully tested Hardware Versions
332
334
  - AD7200 V2
@@ -1,30 +1,30 @@
1
1
  test/__init__.py,sha256=McQmUjeN3AwmwdS6QNfwGXXE77OKoPK852I2BM9XsrU,210
2
- test/test_client_c1200.py,sha256=O6NK9uXIEb_vks6lI3g7j6q8TYJ9MSDFYzGA_wOBhOA,4620
2
+ test/test_client_c1200.py,sha256=4RdwMEwTGWLOxOVTuPikifXDcUJFQ13DuyWGm2Aevrk,8811
3
3
  test/test_client_c6u.py,sha256=qC0PNE-Hz3d8PYIGej4j_M4cLDqffnPiXu_ff7Ft29M,30709
4
4
  test/test_client_deco.py,sha256=ur4u-pWB-6WaYW6PSpK9OvCg3rfo2x06V5Cf_eE2UYU,30447
5
- test/test_client_ex.py,sha256=cSIMh6yjiAknt0mk7u1dCpXVzZTR_Y95XvXRBRusbpg,17092
5
+ test/test_client_ex.py,sha256=YGY3auCiZTM91640LHmsL6r2-xcK5n5cB_CpvD83GeI,20429
6
6
  test/test_client_mr.py,sha256=Uomg3T_SA5Y1tb4wlniMKQDi_uJ2Vqm30I-GKgOXBRc,32703
7
7
  test/test_client_xdr.py,sha256=Tm3fXAmSxa8F_YNv66eN3zSvy2GKi_q6tuuw8GWqL-c,20698
8
8
  tplinkrouterc6u/__init__.py,sha256=bLlCkiL9ycyRVG7VqPOJWPcoPmUfMkdTcUKFYKNP8QI,900
9
9
  tplinkrouterc6u/client_abstract.py,sha256=OgftTH6bELzhFWom0MOX4EJe3RNS003ezpHyyRnh2tQ,1328
10
10
  tplinkrouterc6u/provider.py,sha256=SsyGu_2SZ-a46ADl9aw_0wx0lgbsJhS6wnwUzb_1qGg,1900
11
11
  tplinkrouterc6u/client/__init__.py,sha256=KBy3fmtA9wgyFrb0Urh2x4CkKtWVnESdp-vxmuOvq0k,27
12
- tplinkrouterc6u/client/c1200.py,sha256=4XEYidEGmVIJk0YQLvmTnd0Gqa7glH2gUWvjreHpWrk,3178
13
- tplinkrouterc6u/client/c5400x.py,sha256=EhcNcaj2U8OBSv1Bftrg3rH9ylP_73P2VO1JHA9CYO4,4322
12
+ tplinkrouterc6u/client/c1200.py,sha256=_nY_pJ-wPWODAaes9kHPdVcM6YM54f1E54CfdoFHqbE,4771
13
+ tplinkrouterc6u/client/c5400x.py,sha256=9E0omBSbWY_ljrs5MTCMu5brmrLtzsDB5O62Db8lP8Q,4329
14
14
  tplinkrouterc6u/client/c6u.py,sha256=8n3nMW20k3SEXamCYzq7-mzBM6wyn5Txl6XxzjHEa6c,17411
15
15
  tplinkrouterc6u/client/c6v4.py,sha256=-IF7SqTZx56lRAVmiyxK9VKkrmD7srQSJWFvn2Z0DII,1489
16
16
  tplinkrouterc6u/client/deco.py,sha256=0Hwy_kVQshYd-5Oa3mIASaZI_4NUD09NFEdRyPtzjdI,8265
17
- tplinkrouterc6u/client/ex.py,sha256=jkxCgqbjp-SfjlzgKeNj4WhV3v9gEOzKgrgfVgy9SB4,11604
18
- tplinkrouterc6u/client/mr.py,sha256=1-aP8xo5JUiFzKmeyOjolzyKR_yIUwTBrRG562tmfAg,25638
17
+ tplinkrouterc6u/client/ex.py,sha256=PxMKq7Yj-2iJBtSKzgxaJ1D0SrblFwhPWJYyrac0c9Q,12706
18
+ tplinkrouterc6u/client/mr.py,sha256=eQuHi37pIVaKXWb_S34HJ416xxpGvZNWxxaJTv8Bz4I,25581
19
19
  tplinkrouterc6u/client/xdr.py,sha256=lqsBGxi9wZsz1IqQ9KZjAY6gd9-IgK0Cm2oRaswYFSs,9773
20
20
  tplinkrouterc6u/common/__init__.py,sha256=pCTvVZ9CAwgb7MxRnLx0y1rI0sTKSwT24FfxWfQXeTM,33
21
21
  tplinkrouterc6u/common/dataclass.py,sha256=__u8I8URLk_AdIEN4Jd8Pswh4ujURlJxw8YunuVStwk,7630
22
22
  tplinkrouterc6u/common/encryption.py,sha256=4HelTxzN6esMfDZRBt3m8bwB9Nj_biKijnCnrGWPWKg,6228
23
23
  tplinkrouterc6u/common/exception.py,sha256=_0G8ZvW5__CsGifHrsZeULdl8c6EUD071sDCQsQgrHY,140
24
24
  tplinkrouterc6u/common/helper.py,sha256=phcPUdpY7lJVWF8Ih4KHNdsdem2ed6qFSDXuEAtAgug,334
25
- tplinkrouterc6u/common/package_enum.py,sha256=py31wF7SntZ0D_o0PS7az29wtsWdp0r0uE7QMmiWigY,1451
26
- tplinkrouterc6u-5.2.1.dist-info/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
27
- tplinkrouterc6u-5.2.1.dist-info/METADATA,sha256=KqphtW9gVYMljs9l84CGB6uwutisAIQesbE0ixlSTuA,14917
28
- tplinkrouterc6u-5.2.1.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
29
- tplinkrouterc6u-5.2.1.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
30
- tplinkrouterc6u-5.2.1.dist-info/RECORD,,
25
+ tplinkrouterc6u/common/package_enum.py,sha256=4ykL_2Pw0nDEIH_qR9UJlFF6stTgSfhPz32r8KT-sh8,1624
26
+ tplinkrouterc6u-5.4.0.dist-info/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
27
+ tplinkrouterc6u-5.4.0.dist-info/METADATA,sha256=xIApxXPRLkY6oFNFMxg6vv6Tt-qLn23EbQyIfVQ-Nyc,14955
28
+ tplinkrouterc6u-5.4.0.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
29
+ tplinkrouterc6u-5.4.0.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
30
+ tplinkrouterc6u-5.4.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.5.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5