tplinkrouterc6u 5.7.0__tar.gz → 5.9.0__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.
Files changed (39) hide show
  1. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/PKG-INFO +8 -1
  2. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/README.md +7 -0
  3. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/setup.py +1 -1
  4. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/test_client_c1200.py +4 -40
  5. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/test_client_c6u.py +141 -0
  6. tplinkrouterc6u-5.9.0/test/test_client_wdr.py +292 -0
  7. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/__init__.py +1 -0
  8. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/c1200.py +0 -36
  9. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/c6u.py +50 -3
  10. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/c80.py +5 -2
  11. tplinkrouterc6u-5.9.0/tplinkrouterc6u/client/wdr.py +672 -0
  12. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/provider.py +2 -1
  13. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u.egg-info/PKG-INFO +8 -1
  14. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u.egg-info/SOURCES.txt +2 -0
  15. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/LICENSE +0 -0
  16. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/setup.cfg +0 -0
  17. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/__init__.py +0 -0
  18. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/test_client_c80.py +0 -0
  19. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/test_client_deco.py +0 -0
  20. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/test_client_ex.py +0 -0
  21. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/test_client_mr.py +0 -0
  22. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/test/test_client_xdr.py +0 -0
  23. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/__init__.py +0 -0
  24. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/c5400x.py +0 -0
  25. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/deco.py +0 -0
  26. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/ex.py +0 -0
  27. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/mr.py +0 -0
  28. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/vr.py +0 -0
  29. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client/xdr.py +0 -0
  30. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/client_abstract.py +0 -0
  31. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/common/__init__.py +0 -0
  32. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/common/dataclass.py +0 -0
  33. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/common/encryption.py +0 -0
  34. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/common/exception.py +0 -0
  35. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/common/helper.py +0 -0
  36. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u/common/package_enum.py +0 -0
  37. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u.egg-info/dependency_links.txt +0 -0
  38. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u.egg-info/requires.txt +0 -0
  39. {tplinkrouterc6u-5.7.0 → tplinkrouterc6u-5.9.0}/tplinkrouterc6u.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tplinkrouterc6u
3
- Version: 5.7.0
3
+ Version: 5.9.0
4
4
  Summary: TP-Link Router API (supports also Mercusys Router)
5
5
  Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
6
6
  Author: Alex Erohin
@@ -59,6 +59,7 @@ from tplinkrouterc6u import (
59
59
  TPLinkXDRClient,
60
60
  TPLinkDecoClient,
61
61
  TplinkC80Router,
62
+ TplinkWDRRouter,
62
63
  Connection
63
64
  )
64
65
  from logging import Logger
@@ -289,6 +290,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
289
290
  - [TP-LINK routers](#tplink)
290
291
  - [MERCUSYS routers](#mercusys)
291
292
  ### <a id="tplink">TP-LINK routers</a>
293
+ - Archer A6 V2.0
292
294
  - Archer A7 V5
293
295
  - Archer A8 (1.0, 2.20)
294
296
  - Archer A9 V6
@@ -311,6 +313,8 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
311
313
  - Archer AX3000 V1
312
314
  - Archer AX6000 V1
313
315
  - Archer AX11000 V1
316
+ - Archer BE400 v1.0
317
+ - Archer BE550 v1.0
314
318
  - Archer BE800 v1.0
315
319
  - Archer BE805 v1.0
316
320
  - Archer BE3600 1.6
@@ -332,6 +336,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
332
336
  - Archer VR1200v v1
333
337
  - Archer VR2100v v1
334
338
  - Archer VX1800v v1.0
339
+ - BE11000 2.0
335
340
  - Deco M4 2.0
336
341
  - Deco M4R 2.0
337
342
  - Deco M5 v3
@@ -356,6 +361,8 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
356
361
  - TL-WA1201 3.0
357
362
  - TL-WA3001 v1.0
358
363
  - TL-XDR3010 V2
364
+ - TL-WDR3600 V1
365
+ - VX420-G2h v1.1
359
366
  - XC220-G3v v2.30
360
367
  ### <a id="mercusys">MERCUSYS routers</a>
361
368
  - MR47BE v1.0
@@ -27,6 +27,7 @@ from tplinkrouterc6u import (
27
27
  TPLinkXDRClient,
28
28
  TPLinkDecoClient,
29
29
  TplinkC80Router,
30
+ TplinkWDRRouter,
30
31
  Connection
31
32
  )
32
33
  from logging import Logger
@@ -257,6 +258,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
257
258
  - [TP-LINK routers](#tplink)
258
259
  - [MERCUSYS routers](#mercusys)
259
260
  ### <a id="tplink">TP-LINK routers</a>
261
+ - Archer A6 V2.0
260
262
  - Archer A7 V5
261
263
  - Archer A8 (1.0, 2.20)
262
264
  - Archer A9 V6
@@ -279,6 +281,8 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
279
281
  - Archer AX3000 V1
280
282
  - Archer AX6000 V1
281
283
  - Archer AX11000 V1
284
+ - Archer BE400 v1.0
285
+ - Archer BE550 v1.0
282
286
  - Archer BE800 v1.0
283
287
  - Archer BE805 v1.0
284
288
  - Archer BE3600 1.6
@@ -300,6 +304,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
300
304
  - Archer VR1200v v1
301
305
  - Archer VR2100v v1
302
306
  - Archer VX1800v v1.0
307
+ - BE11000 2.0
303
308
  - Deco M4 2.0
304
309
  - Deco M4R 2.0
305
310
  - Deco M5 v3
@@ -324,6 +329,8 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
324
329
  - TL-WA1201 3.0
325
330
  - TL-WA3001 v1.0
326
331
  - TL-XDR3010 V2
332
+ - TL-WDR3600 V1
333
+ - VX420-G2h v1.1
327
334
  - XC220-G3v v2.30
328
335
  ### <a id="mercusys">MERCUSYS routers</a>
329
336
  - MR47BE v1.0
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="tplinkrouterc6u",
8
- version="5.7.0",
8
+ version="5.9.0",
9
9
  author="Alex Erohin",
10
10
  author_email="alexanderErohin@yandex.ru",
11
11
  description="TP-Link Router API (supports also Mercusys Router)",
@@ -5,7 +5,6 @@ from tplinkrouterc6u import (
5
5
  Connection,
6
6
  ClientException,
7
7
  )
8
- from tplinkrouterc6u.common.package_enum import VPN
9
8
 
10
9
 
11
10
  class TestTPLinkC1200Client(TestCase):
@@ -201,13 +200,13 @@ class TestTPLinkC1200Client(TestCase):
201
200
  ignore_response: bool = False,
202
201
  ignore_errors: bool = False,
203
202
  ) -> dict | None:
204
- if path == "/admin/openvpn?form=config&operation=read":
203
+ if path == "admin/openvpn?form=config&operation=read":
205
204
  return loads(response_openvpn_read)
206
- if path == "/admin/pptpd?form=config&operation=read":
205
+ if path == "admin/pptpd?form=config&operation=read":
207
206
  return loads(response_pptp_read)
208
- if path == "/admin/vpnconn?form=config&operation=list&vpntype=openvpn":
207
+ if path == "admin/vpnconn?form=config&operation=list&vpntype=openvpn":
209
208
  return loads(respone_vpnconn_openvpn)
210
- if path == "/admin/vpnconn?form=config&operation=list&vpntype=pptp":
209
+ if path == "admin/vpnconn?form=config&operation=list&vpntype=pptp":
211
210
  return loads(respone_vpnconn_pptpvpn)
212
211
  raise ClientException()
213
212
 
@@ -219,41 +218,6 @@ class TestTPLinkC1200Client(TestCase):
219
218
  self.assertEqual(vpn_status.openvpn_clients_total, 2)
220
219
  self.assertEqual(vpn_status.pptpvpn_clients_total, 3)
221
220
 
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
-
257
221
 
258
222
  if __name__ == "__main__":
259
223
  main()
@@ -9,6 +9,7 @@ from tplinkrouterc6u import (
9
9
  IPv4Status,
10
10
  Device,
11
11
  ClientException,
12
+ VPN,
12
13
  )
13
14
 
14
15
 
@@ -729,6 +730,146 @@ class TestTPLinkClient(TestCase):
729
730
  self.assertEqual(result.lan_ipv4_dhcp_enable, False)
730
731
  self.assertEqual(result.remote, None)
731
732
 
733
+ def test_get_status_wan_macaddr_empty(self) -> None:
734
+ response_status = '''
735
+ {
736
+ "success": true,
737
+ "data": {
738
+ "lan_macaddr": "06:e6:97:9e:23:f5",
739
+ "wan_macaddr": "",
740
+ "wan_ipv4_ipaddr": "0.0.0.0",
741
+ "wan_ipv4_gateway": "0.0.0.0"
742
+ }
743
+ }
744
+ '''
745
+ response_stats = '''
746
+ {
747
+ "data": [],
748
+ "timeout": false,
749
+ "success": true,
750
+ "operator": "load"
751
+ }
752
+ '''
753
+
754
+ class TPLinkRouterTest(TplinkRouter):
755
+ def request(self, path: str, data: str,
756
+ ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
757
+ if path == 'admin/status?form=all&operation=read':
758
+ return loads(response_status)['data']
759
+ elif path == 'admin/wireless?form=statistics':
760
+ return loads(response_stats)['data']
761
+ raise ClientException()
762
+
763
+ client = TPLinkRouterTest('', '')
764
+ result = client.get_status()
765
+
766
+ self.assertIsInstance(result, Status)
767
+ self.assertEqual(result.wan_macaddr, None)
768
+ self.assertEqual(result.wan_ipv4_addr, '0.0.0.0')
769
+ self.assertEqual(result.wan_ipv4_gateway, '0.0.0.0')
770
+ self.assertEqual(result.lan_macaddr, '06-E6-97-9E-23-F5')
771
+
772
+ def test_vpn_status(self) -> None:
773
+ response_openvpn_read = """
774
+ {
775
+ "enabled": "on",
776
+ "proto": "udp",
777
+ "access": "home",
778
+ "cert_exist": true,
779
+ "mask": "255.255.255.0",
780
+ "port": "1194",
781
+ "serverip": "10.8.0.0"
782
+ }
783
+ """
784
+
785
+ response_pptp_read = """
786
+ {
787
+ "enabled": "off",
788
+ "unencrypted_access": "on",
789
+ "samba_access": "on",
790
+ "netbios_pass": "on",
791
+ "remoteip": "10.0.0.11-20"
792
+ }
793
+ """
794
+
795
+ respone_vpnconn_openvpn = """[
796
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
797
+ "extra": "7450", "vpntype": "openvpn", "key": "7450"},
798
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
799
+ "extra": "7450", "vpntype": "openvpn", "key": "7450"}
800
+ ]"""
801
+
802
+ respone_vpnconn_pptpvpn = """[
803
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
804
+ "extra": "7450", "vpntype": "pptp", "key": "7450"},
805
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
806
+ "extra": "7450", "vpntype": "pptp", "key": "7450"},
807
+ {"username": "admin", "remote_ip": "192.168.0.200", "ipaddr": "10.0.0.11",
808
+ "extra": "7450", "vpntype": "pptp", "key": "7450"}
809
+ ]"""
810
+
811
+ class TPLinkRouterTest(TplinkRouter):
812
+ def request(
813
+ self,
814
+ path: str,
815
+ data: str,
816
+ ignore_response: bool = False,
817
+ ignore_errors: bool = False,
818
+ ) -> dict | None:
819
+ if path == "admin/openvpn?form=config":
820
+ return loads(response_openvpn_read)
821
+ if path == "admin/pptpd?form=config":
822
+ return loads(response_pptp_read)
823
+ if path == "admin/vpnconn?form=config" and data == "operation=list&vpntype=openvpn":
824
+ return loads(respone_vpnconn_openvpn)
825
+ if path == "admin/vpnconn?form=config" and data == "operation=list&vpntype=pptp":
826
+ return loads(respone_vpnconn_pptpvpn)
827
+ raise ClientException()
828
+
829
+ client = TPLinkRouterTest("", "")
830
+
831
+ vpn_status = client.get_vpn_status()
832
+ self.assertTrue(vpn_status.openvpn_enable)
833
+ self.assertFalse(vpn_status.pptpvpn_enable)
834
+ self.assertEqual(vpn_status.openvpn_clients_total, 2)
835
+ self.assertEqual(vpn_status.pptpvpn_clients_total, 3)
836
+
837
+ def test_set_vpn(self) -> None:
838
+ response_openvpn_read = """
839
+ {
840
+ "enabled": "on",
841
+ "proto": "udp",
842
+ "access": "home",
843
+ "cert_exist": true,
844
+ "mask": "255.255.255.0",
845
+ "port": "1194",
846
+ "serverip": "10.8.0.0"
847
+ }
848
+ """
849
+
850
+ class TPLinkRouterTest(TplinkRouter):
851
+ def request(
852
+ self,
853
+ path: str,
854
+ data: str,
855
+ ignore_response: bool = False,
856
+ ignore_errors: bool = False,
857
+ ) -> dict | None:
858
+ if path == "admin/openvpn?form=config" and data == "operation=read":
859
+ return loads(response_openvpn_read)
860
+ self.captured_path = path
861
+ self.captured_data = data
862
+
863
+ client = TPLinkRouterTest("", "")
864
+ client.set_vpn(VPN.OPEN_VPN, True)
865
+
866
+ expected_data = (
867
+ "operation=write&enabled=on"
868
+ "&proto=udp&access=home&cert_exist=True&mask=255.255.255.0&port=1194&serverip=10.8.0.0"
869
+ )
870
+ self.assertEqual(client.captured_path, 'admin/openvpn?form=config')
871
+ self.assertEqual(client.captured_data, expected_data)
872
+
732
873
 
733
874
  if __name__ == '__main__':
734
875
  main()
@@ -0,0 +1,292 @@
1
+ from unittest import main, TestCase
2
+ from ipaddress import IPv4Address
3
+ from macaddress import EUI48
4
+ from tplinkrouterc6u.common.dataclass import Firmware, Status
5
+ from tplinkrouterc6u.common.dataclass import IPv4Status, IPv4Reservation, IPv4DHCPLease
6
+ from tplinkrouterc6u import ClientError
7
+ from tplinkrouterc6u.client.wdr import TplinkWDRRouter
8
+
9
+ _NETWAN = (
10
+ '<SCRIPT language="javascript" type="text/javascript">\nvar wanTypeDetectInfoArray = '
11
+ + "new Array(\n1, 0, 4500, \n0,0 );\n</SCRIPT>\n"
12
+ + '<SCRIPT language="javascript" type="text/javascript">\nvar dhcpInf = new Array(\n1,\n'
13
+ + '0,\n1,\n0,\n0,\n0,\n0,\n0,\n"",\n"",\n0,\n0,\n"",\n"192.168.0.129",\n"255.255.255.0",\n'
14
+ + '"192.168.0.1",\n1,\n0,\n1500,\n0,\n"8.8.8.8",\n1,\n"8.8.4.4",\n0,\n0,\n0,\n"TL-WDR3600",\n0,0 );\n</SCRIPT>\n'
15
+ + '<SCRIPT language="javascript" type="text/javascript">\nvar wantypeinfo = new Array(\n6,\n0,\n'
16
+ + '"WanDynamicIpCfgRpm.htm",\n1,\n"WanStaticIpCfgRpm.htm",\n'
17
+ + '2,\n"PPPoECfgRpm.htm",\n5,\n"BPACfgRpm.htm",\n6,\n"L2TPCfgRpm.htm",\n7,\n"PPTPCfgRpm.htm",\n0,0 );\n</SCRIPT>'
18
+ )
19
+ _NETLAN = (
20
+ '<SCRIPT language="javascript" type="text/javascript">\nvar lanPara = new Array(\n"C4-6E-1F-41-67-C0",\n'
21
+ + '"192.168.1.254",\n2,\n"255.255.255.0",\n1,\n0,0 );\n</SCRIPT>'
22
+ )
23
+
24
+ _W24STA = (
25
+ '<SCRIPT language="javascript" type="text/javascript">\nvar wlanHostPara = new Array(\n1, 1, 8, 5000, 4,\n'
26
+ + '0,0);\n</SCRIPT>\n<SCRIPT language="javascript" type="text/javascript">\nvar hostList = new Array(\n'
27
+ + '"D0-BD-53-57-3E-4A", 1, 170893827, 0,\n"08-16-AC-03-E2-FA", 1, 873409583, 0,\n"F8-F1-E8-CD-0A-CF", 1, '
28
+ + '240958643, 0,\n"ED-49-92-1A-1D-D7", 1, 358743698, 0,\n"0E-50-99-5D-9A-D5", 1, 572346959, 0,\n0,0 );\n</SCRIPT>'
29
+ )
30
+ _W50STA = (
31
+ '<SCRIPT language="javascript" type="text/javascript">\nvar wlanHostPara = new Array(\n1, 1, 8, 5000, 4,\n'
32
+ + '0,0 );\n</SCRIPT>\n<SCRIPT language="javascript" type="text/javascript">\nvar hostList = new Array(\n'
33
+ + '"50-A6-FC-6D-EB-D3", 1, 708938274, 0,\n"6A-D0-5F-2A-FA-2D", 1, 287340958, 0,\n"DA-69-2D-59-B3-FA", 1'
34
+ + ", 540958641, 0,\n0,0 );\n</SCRIPT>"
35
+ )
36
+
37
+ _WLANGUEST = (
38
+ '<SCRIPT language="javascript" type="text/javascript">\nvar guestNetworkBandwidthInf = '
39
+ + "new Array(\n"
40
+ + '0,\n1000000,\n1000000,\n1024,\n1024,\n1,\n0,0);\n</SCRIPT>\n<SCRIPT language="javascript" '
41
+ + 'type="text/javascript">'
42
+ + '\nvar guestNetAccTime2gInf = new Array(\n1,\n1,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n"",\n"",\n'
43
+ + "0,0 );"
44
+ + '\n</SCRIPT>\n<SCRIPT language="javascript" type="text/javascript">\nvar guestNetAccTime5gInf = new Array(\n'
45
+ + '1,\n0,\n0,\n0,\n0,\n1,\n0,\n0,\n0,\n0,\n0,\n0,\n0,\n1,\n"",\n"",\n0,0 );\n</SCRIPT>\n'
46
+ + '<SCRIPT language="javascript" type="text/javascript">\nvar guestNetworkInf = '
47
+ + 'new Array(\n1, 1, 1, 0, "Pegasus", '
48
+ + '"Pegasus", 1, 1, 3, 3, "333", "333", 0, 0, "p4ssw0rd", "p4ssw0rd", '
49
+ + "0, 0, 0, 0, 3, 3, 1, 1, 5, 8, 0, \n0,0 );\n"
50
+ + "</SCRIPT>"
51
+ )
52
+
53
+ _DHCPCFG = (
54
+ '<SCRIPT language="javascript" type="text/javascript">\nvar DHCPPara = new Array(\n1,\n"192.168.1.129",\n'
55
+ + '"192.168.1.192",\n120,\n"192.168.1.254",\n"internal.lan",\n"8.8.8.8",\n"8.8.4.4",\n0,\n0,0 );\n</SCRIPT>'
56
+ )
57
+
58
+ _DHCPLEASES = (
59
+ '<SCRIPT language="javascript" type="text/javascript">var DHCPDynList = new Array(\n"aliquam",'
60
+ + '"A9-A8-2B-F7-9F-5D","192.168.1.123","Permanent",\n"pharetra","B3-A5-1E-C3-92-A9","192.168.1.163","Permanent",\n'
61
+ + '"ligula","71-34-47-FD-DE-84","192.168.1.165","Permanent",\n"vulputate","46-5F-5F-27-23-9F","192.168.1.103",'
62
+ + '"Permanent",\n"amet","86-9F-53-91-04-2B","192.168.1.72","Permanent",\n"volutpat","FA-5C-6F-87-A3-5A",'
63
+ + '"192.168.1.43",'
64
+ + '"Permanent",\n"eget","C4-ED-6C-B6-F6-B9","192.168.1.112","Permanent",\n"ante","FF-C1-A3-93-C8-E6",'
65
+ + '"192.168.1.38",'
66
+ + '"Permanent",\n"pellentesque","E3-5E-59-2E-CF-AD","192.168.1.148","Permanent",\n"metus","AE-15-51-37-0E-9E",'
67
+ + '"192.168.1.178","Permanent",\n0,0 );\n</SCRIPT>\n<SCRIPT language="javascript" type="text/javascript">\n'
68
+ + "var DHCPDynPara = new Array(\n10,\n4,\n0,0 );\n</SCRIPT>"
69
+ )
70
+
71
+ _DHCPRESERVES = (
72
+ '<SCRIPT language="javascript" type="text/javascript">\nvar dhcpList = new Array(\n"9B-FA-04-D8-AB-8D",'
73
+ + '"192.168.1.56",1,\n"EE-7C-6B-B6-05-2F","192.168.1.51",1,\n"09-51-B3-0B-92-01","192.168.1.21",1,\n'
74
+ + '"49-6F-72-CD-68-5D","192.168.1.25",1,\n"DF-24-38-C1-FE-BB","192.168.1.51",1,\n"1A-08-6C-52-31-3D",'
75
+ + '"192.168.1.22",1,\n"DE-E4-DF-9A-AD-0D","192.168.1.17",1,\n"DF-F2-CB-FE-46-15","192.168.1.26",1,\n'
76
+ + '0,0 )\n</SCRIPT>\n<SCRIPT language="javascript" type="text/javascript">var DHCPStaticPara = '
77
+ + "new Array(\n1,\n1,\n8,\n1,\n8,\n0,0 );\n</SCRIPT>"
78
+ )
79
+
80
+ ABSTRACT_STATUS = (
81
+ '<SCRIPT language="javascript" type="text/javascript">\nvar statusPara = new Array(\n1,\n1,\n1,\n'
82
+ + '22,\n20000,\n1468171,\n"3.13.34 Build 130909 Rel.53148n ",\n"WDR3600 v1 00000000",\n6732336,\n0, 0);\n'
83
+ + '</SCRIPT>\n'
84
+ + '<SCRIPT language="javascript" type="text/javascript">\nvar lanPara = new Array(\n"C4-6E-1F-41-67-C0", '
85
+ + '"192.168.1.254", "255.255.255.0",\n0, 0);\n</SCRIPT>\n<SCRIPT language="javascript" type="text/javascript">\n'
86
+ + 'var wlanPara = new Array(\n1,\n"testSSID24",\n15,\n5,\n"C4-6E-1F-41-67-BF",\n"192.168.1.254",\n2,\n8,\n71,\n6,\n'
87
+ + '6,\n0, 0);\n</SCRIPT>\n<SCRIPT language="javascript" type="text/javascript">\nvar wlan5GPara = new Array(\n1,\n'
88
+ + '"testSSID",\n15,\n8,\n"C4-6E-1F-41-67-C0",\n"192.168.1.254",\n2,\n8,\n83,\n36,\n6,\n0, 0);\n</SCRIPT>\n'
89
+ + '<SCRIPT language="javascript" type="text/javascript">\nvar statistList = '
90
+ + "new Array(\n1129349328, 3900411475, 200068023, 165562287,\n0, 0);\n</SCRIPT>\n"
91
+ + '<SCRIPT language="javascript" type="text/javascript">\nvar wanPara = new Array(\n4, '
92
+ + '"C4-6E-1F-41-67-C1", "192.168.0.129", 1, "255.255.255.0", 0, 0, "192.168.0.1", 1, 1, 0, '
93
+ + '"8.8.8.8 , 8.8.4.4", "", 0, 0, "0.0.0.0", "0.0.0.0", "0.0.0.0", "0.0.0.0 , 0.0.0.0", '
94
+ + "0, 0, 0, 0, 0,\n0, 0);\n</SCRIPT>"
95
+ )
96
+
97
+ ABSTRACT_NETWORK = {
98
+ "netWan": _NETWAN,
99
+ "netLan": _NETLAN,
100
+ "w24stations": _W24STA,
101
+ "w50stations": _W50STA,
102
+ "wgsettings": _WLANGUEST,
103
+ "dhcpconfig": _DHCPCFG,
104
+ "dhcplease": _DHCPLEASES,
105
+ "dhcpreserve": _DHCPRESERVES,
106
+ }
107
+
108
+
109
+ class ResponseMock:
110
+ def __init__(self, text: str, status_code=0):
111
+ self.content = text.encode("utf8")
112
+ self.status_code = status_code
113
+ self.headers: dict = {}
114
+
115
+
116
+ class TplinkWDRRouterTest(TplinkWDRRouter):
117
+ response = ""
118
+
119
+ def request(
120
+ self,
121
+ section: str,
122
+ data: str,
123
+ ignore_response: bool = False,
124
+ ignore_errors: bool = False,
125
+ ) -> str | dict | None:
126
+ # only a test, so no extra headers
127
+ # Responses
128
+ sections = "summary,status,"
129
+ sections += "netWan,netLan,dualBand,"
130
+ sections += "w24settings,w24wps,w24sec,w24adv,w24stations,"
131
+ sections += "w50settings,w50wps,w50sec,w50adv,w50stations,"
132
+ sections += "wgsettings,wgshare,dhcpconfig,dhcplease,dhcpreserve,"
133
+ sections += "portFwd,sysroute,upnpFwd"
134
+
135
+ section_list = sections.split(",")
136
+
137
+ if ignore_response:
138
+ return None
139
+ elif section == "check":
140
+ resp = ResponseMock("", 200)
141
+ resp.headers["www-authenticate"] = (
142
+ 'Basic realm="TP-LINK Wireless Dual Band Gigabit Router WDR3600"'
143
+ )
144
+ return resp
145
+ elif section in section_list:
146
+ if section in ["summary", "status"]:
147
+ return ResponseMock(ABSTRACT_STATUS).content
148
+ elif section in ["w24stations", "w50stations", "dhcpreserve"]:
149
+ return ResponseMock(ABSTRACT_NETWORK[section]).content
150
+ elif section in [
151
+ "netLan",
152
+ "netWan",
153
+ # 'w24stations',
154
+ # 'w50stations',
155
+ "wgsettings",
156
+ "dhcpconfig",
157
+ "dhcplease",
158
+ # 'dhcpreserve',
159
+ ]:
160
+ return ResponseMock(ABSTRACT_NETWORK[section]).content
161
+ else:
162
+ return ""
163
+ # raise ClientError (f'Section {section} not allowed')
164
+
165
+ else:
166
+ error = ""
167
+ error = (
168
+ (
169
+ "WDRRouter - {} - Response with error; Request {} - Response {}".format(
170
+ self.__class__.__name__, section, data
171
+ )
172
+ )
173
+ if not error
174
+ else error
175
+ )
176
+ if self._logger:
177
+ self._logger.debug(error)
178
+
179
+ raise ClientError(error)
180
+
181
+
182
+ class TestTPLinkWDRClient(TestCase):
183
+
184
+ def test_supports(self) -> None:
185
+ client = TplinkWDRRouterTest("", "")
186
+ # client.response = ResponseMock(ABSTRACT_STATUS)
187
+ supports = client.supports()
188
+ self.assertTrue(supports)
189
+
190
+ def test_get_firmware(self) -> None:
191
+
192
+ client = TplinkWDRRouterTest("", "")
193
+ client.response = ResponseMock(ABSTRACT_STATUS)
194
+ firmware = client.get_firmware()
195
+
196
+ self.assertIsInstance(firmware, Firmware)
197
+ self.assertEqual(firmware.hardware_version, "WDR3600 v1 00000000")
198
+ self.assertEqual(firmware.model, "WDR3600")
199
+ self.assertEqual(
200
+ firmware.firmware_version.strip(), "3.13.34 Build 130909 Rel.53148n"
201
+ )
202
+
203
+ def test_get_ipv4(self) -> None:
204
+
205
+ client = TplinkWDRRouterTest("", "")
206
+ ipv4status: IPv4Status = IPv4Status()
207
+ ipv4status = client.get_ipv4_status()
208
+
209
+ self.assertIsInstance(ipv4status, IPv4Status)
210
+ self.assertEqual(ipv4status._wan_macaddr, EUI48("C4-6E-1F-41-67-C1"))
211
+ self.assertEqual(
212
+ IPv4Address(ipv4status.wan_ipv4_ipaddr), IPv4Address("192.168.0.129")
213
+ )
214
+ self.assertEqual(
215
+ IPv4Address(ipv4status.wan_ipv4_gateway), IPv4Address("192.168.0.1")
216
+ )
217
+ self.assertEqual(ipv4status.wan_ipv4_conntype, "Dynamic IP")
218
+ self.assertEqual(
219
+ IPv4Address(ipv4status.wan_ipv4_netmask), IPv4Address("255.255.255.0")
220
+ )
221
+ self.assertEqual(
222
+ IPv4Address(ipv4status.wan_ipv4_pridns), IPv4Address("0.0.0.0")
223
+ )
224
+ self.assertEqual(
225
+ IPv4Address(ipv4status.wan_ipv4_snddns), IPv4Address("0.0.0.0")
226
+ )
227
+ self.assertEqual(ipv4status._lan_macaddr, EUI48("C4-6E-1F-41-67-C0"))
228
+ self.assertEqual(
229
+ IPv4Address(ipv4status.lan_ipv4_ipaddr), IPv4Address("192.168.1.254")
230
+ )
231
+ self.assertEqual(ipv4status.lan_ipv4_dhcp_enable, True)
232
+ self.assertEqual(
233
+ IPv4Address(ipv4status.lan_ipv4_netmask), IPv4Address("255.255.255.0")
234
+ )
235
+
236
+ def test_get_ipv4_reservations(self) -> None:
237
+ client = TplinkWDRRouterTest("", "")
238
+ ipv4_reservations: list[IPv4Reservation] = client.get_ipv4_reservations()
239
+ fRes: IPv4Reservation = ipv4_reservations[0]
240
+
241
+ self.assertIsInstance(fRes, IPv4Reservation)
242
+ self.assertEqual(EUI48(fRes.macaddress), EUI48("9B-FA-04-D8-AB-8D"))
243
+ self.assertEqual(IPv4Address(fRes.ipaddress), IPv4Address("192.168.1.56"))
244
+ self.assertEqual(fRes.enabled, True)
245
+
246
+ def test_get_ipv4_dhcp_leases(self) -> None:
247
+ client = TplinkWDRRouterTest("", "")
248
+ dhcp_leases: list[IPv4DHCPLease] = client.get_ipv4_dhcp_leases()
249
+
250
+ self.assertIsInstance(dhcp_leases[0], IPv4DHCPLease)
251
+ self.assertEqual(dhcp_leases[0].macaddress, EUI48("A9-A8-2B-F7-9F-5D"))
252
+ self.assertEqual(dhcp_leases[0].ipaddress, IPv4Address("192.168.1.123"))
253
+ self.assertEqual(dhcp_leases[0].hostname, "aliquam")
254
+ self.assertEqual(dhcp_leases[0].lease_time, "Permanent")
255
+
256
+ self.assertIsInstance(dhcp_leases[1], IPv4DHCPLease)
257
+ self.assertEqual(dhcp_leases[1].macaddress, EUI48("B3-A5-1E-C3-92-A9"))
258
+ self.assertEqual(dhcp_leases[1].ipaddress, IPv4Address("192.168.1.163"))
259
+ self.assertEqual(dhcp_leases[1].hostname, "pharetra")
260
+ self.assertEqual(dhcp_leases[1].lease_time, "Permanent")
261
+
262
+ def test_get_status(self) -> None:
263
+ client = TplinkWDRRouterTest("", "")
264
+ client.response = ResponseMock(ABSTRACT_STATUS)
265
+
266
+ status = client.get_status()
267
+
268
+ self.assertIsInstance(status, Status)
269
+ self.assertEqual(status.wan_macaddr, "C4-6E-1F-41-67-C1")
270
+ self.assertIsInstance(status.wan_macaddress, EUI48)
271
+ self.assertEqual(status.lan_macaddr, "C4-6E-1F-41-67-C0")
272
+ self.assertIsInstance(status.lan_macaddress, EUI48)
273
+ self.assertEqual(status.wan_ipv4_addr, "192.168.0.129")
274
+ self.assertIsInstance(status.lan_ipv4_address, IPv4Address)
275
+ self.assertEqual(status.lan_ipv4_addr, "192.168.1.254")
276
+ self.assertEqual(status.wan_ipv4_gateway, "192.168.0.1")
277
+ self.assertIsInstance(status.wan_ipv4_address, IPv4Address)
278
+
279
+ self.assertEqual(status.wired_total, 10)
280
+ self.assertEqual(status.wifi_clients_total, 8)
281
+ self.assertEqual(status.guest_clients_total, 0)
282
+ self.assertEqual(status.clients_total, 18)
283
+
284
+ self.assertTrue(status.guest_2g_enable)
285
+ self.assertFalse(status.guest_5g_enable)
286
+ self.assertTrue(status.wifi_2g_enable)
287
+ self.assertTrue(status.wifi_5g_enable)
288
+ self.assertEqual(status.wan_ipv4_uptime, 6732336)
289
+
290
+
291
+ if __name__ == "__main__":
292
+ main()
@@ -8,6 +8,7 @@ from tplinkrouterc6u.client.c80 import TplinkC80Router
8
8
  from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
9
9
  from tplinkrouterc6u.client.c1200 import TplinkC1200Router
10
10
  from tplinkrouterc6u.client.xdr import TPLinkXDRClient
11
+ from tplinkrouterc6u.client.wdr import TplinkWDRRouter
11
12
  from tplinkrouterc6u.provider import TplinkRouterProvider
12
13
  from tplinkrouterc6u.common.package_enum import Connection, VPN
13
14
  from tplinkrouterc6u.common.dataclass import (
@@ -1,11 +1,8 @@
1
1
  from re import search
2
2
  from requests import post, Response
3
- from urllib.parse import urlencode
4
3
  from tplinkrouterc6u.common.encryption import EncryptionWrapper
5
4
  from tplinkrouterc6u.common.exception import ClientException, AuthorizeError
6
5
  from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
7
- from tplinkrouterc6u.common.dataclass import VPNStatus
8
- from tplinkrouterc6u.common.package_enum import VPN
9
6
 
10
7
 
11
8
  class TplinkC1200Router(TplinkC5400XRouter):
@@ -103,36 +100,3 @@ class TplinkC1200Router(TplinkC5400XRouter):
103
100
  @staticmethod
104
101
  def _get_login_data(crypted_pwd: str) -> str:
105
102
  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)