Skip to content

Commit 20b7e09

Browse files
authored
Merge pull request #5 from psmode/TL-SG1024DE-support
Adding TL-SG1024DE support to address #4
2 parents f0b4edf + 9271887 commit 20b7e09

2 files changed

Lines changed: 113 additions & 59 deletions

File tree

CHANGELOG.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
# Change Log
22
All notable changes to this project will be documented in this file.
3-
3+
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
6-
6+
7+
8+
## [0.5.0] - 2021-04-25
9+
10+
### Addeded
11+
- [essstat.py] Added propper support for TL-SG1024DE model as per Issue #4.
12+
Many thanks to @FreedThx for his report and for providing the output from
13+
that model that enabled the devlopment of this code change.
14+
15+
716
## [0.4.1] - 2021-04-03
817

918
### Fixed
1019

1120
- [essstat.xlsm] Dynamic rescaling of X-axis labels and tickmarks
12-
- [essstat.py] Fix for Issue #3 reported by jan-lukes, AttributeError: 'NoneType'
21+
- [essstat.py] Fix for Issue #3 reported by jan-lukes, AttributeError: 'NoneType'
1322
object has no attribute 'group'. The problem was a code compatibility issue
14-
with newer versions of BeautifulSoup sometime after version 4.8.2. Changing
23+
with newer versions of BeautifulSoup sometime after version 4.8.2. Changing
1524
references to soup.script.text to soup.script.string fixes the problem and
1625
is backwards compatible, at least to beautifulsoup4-4.8.2.
1726

@@ -23,10 +32,10 @@ is backwards compatible, at least to beautifulsoup4-4.8.2.
2332
- [essstat.xlsm] Macro-enabled Excel workbook will automatically construct
2433
a query and execute a web GET operation against the monitoring server using
2534
the `essstat2.cgi` script. It uses the returned data to plot charts of the
26-
port statistics using dynaic chart ranges.
35+
port statistics using dynaic chart ranges.
2736
- [essstat2.cgi] This CGI script is designed to support operation of the essstat.xlsm
28-
Excel workbook. This script will return the average packets per second rate since
29-
the previous record.
37+
Excel workbook. This script will return the average packets per second rate since
38+
the previous record.
3039

3140

3241
## [0.3.2] - 2020-03-30
@@ -40,7 +49,7 @@ the previous record.
4049
statistics.
4150

4251
### Changed
43-
- [essstat.py] Modified --1line output to use only numeric codes for
52+
- [essstat.py] Modified --1line output to use only numeric codes for
4453
port state and link status. This is a preferred approach since it will use
4554
much less disk space when accumulating in a CSV file.
4655

essstat.py

Lines changed: 96 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
#!/usr/bin/env python3
22
# coding: utf-8
33

4-
# In[ ]:
4+
# In[1]:
55

66

77
__author__ = "Peter Smode"
88
__copyright__ = "Copyright 2021, Peter Smode"
99
__credits__ = "Peter Smode"
1010
__license__ = "GPL 3.0"
11-
__version__ = "0.4.1"
11+
__version__ = "0.5.0"
1212
__maintainer__ = "Peter Smode"
1313
__email__ = "psmode@kitsnet.us"
1414
__status__ = "Beta"
1515

1616

17-
# In[3]:
17+
# In[2]:
1818

1919

2020
import argparse, pprint, re, requests, sys
2121
from datetime import datetime
2222
from bs4 import BeautifulSoup
2323

2424

25-
# In[4]:
25+
# In[3]:
2626

2727

2828
TPlinkStatus = {'0': "Link Down", '1': "LS 1", '2': "10M Half", '3': "10M Full", '4': "LS 4", '5': "100M Full", '6': "1000M Full"}
2929
TPstate = {'0': 'Disabled', '1': 'Enabled'}
3030

3131

32-
# In[5]:
32+
# In[4]:
3333

3434

3535
def isnotebook():
@@ -45,7 +45,7 @@ def isnotebook():
4545
return False # Probably standard Python interpreter
4646

4747

48-
# In[6]:
48+
# In[5]:
4949

5050

5151
if not isnotebook():
@@ -66,7 +66,7 @@ def isnotebook():
6666
TPLdebug = args['debug']
6767

6868

69-
# In[7]:
69+
# In[6]:
7070

7171

7272
if isnotebook():
@@ -78,7 +78,7 @@ def isnotebook():
7878
TPLdebug = True
7979

8080

81-
# In[8]:
81+
# In[7]:
8282

8383

8484
if TPLdebug:
@@ -87,13 +87,13 @@ def isnotebook():
8787
print(BASE_URL)
8888

8989

90-
# In[87]:
90+
# In[8]:
9191

9292

9393
s = requests.Session()
9494

9595

96-
# In[88]:
96+
# In[9]:
9797

9898

9999
data = {"logon": "Login", "username": TPLuser, "password": TPLpswd}
@@ -106,7 +106,7 @@ def isnotebook():
106106
sys.exit("ERROR: General error at login: "+str(err))
107107

108108

109-
# In[90]:
109+
# In[10]:
110110

111111

112112
headers = {'Referer': f'{BASE_URL}/',
@@ -115,79 +115,112 @@ def isnotebook():
115115
r = s.get(f'{BASE_URL}/PortStatisticsRpm.htm', headers=headers, timeout=6)
116116

117117

118-
# In[91]:
118+
# In[11]:
119119

120120

121121
soup = BeautifulSoup(r.text, 'html.parser')
122122
if TPLdebug:
123+
from bs4 import __version__ as bs4__version__
124+
print("BeautifulSoup4 version: " + bs4__version__)
123125
print(r)
124126

125127

126-
# In[92]:
128+
# In[12]:
127129

128130

131+
convoluted = (soup.script == soup.head.script) #TL-SG1016DE and TL-SG108E models have a script before the HEAD block
129132
if TPLdebug:
130-
pprint.pprint(soup.script)
133+
pprint.pprint(convoluted)
131134

132135

133-
# In[93]:
136+
# In[13]:
137+
138+
139+
if TPLdebug:
140+
if convoluted:
141+
# This is the 24 port TL-SG1024DE model with the stats in a different place (and convoluted coding)
142+
pprint.pprint(soup.head.find_all("script"))
143+
pprint.pprint(soup.body.script)
144+
else:
145+
# This should be a TL-SG1016DE or a TL-SG108E
146+
pprint.pprint(soup.script)
147+
148+
149+
# In[14]:
134150

135151

136152
if str(r) != "<Response [200]>":
137153
sys.exit("ERROR: Login failure - bad credential?")
138154

139155

140-
# In[94]:
156+
# In[15]:
157+
141158

142159
pattern = re.compile(r"var (max_port_num) = (.*?);$", re.MULTILINE)
143160

144161

145-
# In[95]:
162+
# In[16]:
146163

147164

148165
if TPLdebug:
149-
print(pattern.search(soup.script.string).group(0))
150-
print(pattern.search(soup.script.string).group(1))
151-
print(pattern.search(soup.script.string).group(2))
166+
if convoluted:
167+
print(pattern.search(str(soup.head.find_all("script"))).group(0))
168+
print(pattern.search(str(soup.head.find_all("script"))).group(1))
169+
print(pattern.search(str(soup.head.find_all("script"))).group(2))
170+
else:
171+
print(pattern.search(str(soup.script)).group(0))
172+
print(pattern.search(str(soup.script)).group(1))
173+
print(pattern.search(str(soup.script)).group(2))
152174

153175

154-
# In[117]:
176+
# In[17]:
155177

156178

157179
current_dt = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
158-
max_port_num = int(pattern.search(soup.script.string).group(2))
180+
if convoluted:
181+
max_port_num = int(pattern.search(str(soup.head.find_all("script"))).group(2))
182+
else:
183+
max_port_num = int(pattern.search(str(soup.script)).group(2))
159184
if not (TPLstatsonly or TPL1line):
160185
print(current_dt)
161186
print("max_port_num={0:d}".format(max_port_num))
162187

163188

164-
# In[97]:
189+
# In[18]:
165190

166191

167-
pattern2 = re.compile(r"var all_info = {\n?(.*?)\n?};$", re.MULTILINE | re.DOTALL)
192+
if convoluted:
193+
i1 = re.compile(r'tmp_info = "(.*?)";$', re.MULTILINE | re.DOTALL).search(str(soup.body.script)).group(1)
194+
i2 = re.compile(r'tmp_info2 = "(.*?)";$', re.MULTILINE | re.DOTALL).search(str(soup.body.script)).group(1)
195+
# We simulate bug for bug the way the variables are loaded on the "normal" switch models. In those, each
196+
# data array has two extra 0 cells at the end. To remain compatible with the balance of the code here,
197+
# we need to add in these redundant entries so they can be removed later. (smh)
198+
script_vars = ('tmp_info:[' + i1.rstrip() + ' ' + i2.rstrip() + ',0,0]').replace(" ", ",")
199+
else:
200+
script_vars = re.compile(r"var all_info = {\n?(.*?)\n?};$", re.MULTILINE | re.DOTALL).search(str(soup.script)).group(1)
168201

169202

170-
# In[98]:
203+
# In[19]:
171204

172205

173206
if TPLdebug:
174-
print(pattern2.search(soup.script.string).group(1))
207+
print(script_vars)
175208

176209

177-
# In[99]:
210+
# In[20]:
178211

179212

180-
entries = re.split(",?\n+", pattern2.search(soup.script.string).group(1))
213+
entries = re.split(",?\n+", script_vars)
181214

182215

183-
# In[100]:
216+
# In[21]:
184217

185218

186219
if TPLdebug:
187220
pprint.pprint(entries)
188221

189222

190-
# In[101]:
223+
# In[22]:
191224

192225

193226
edict = {}
@@ -197,61 +230,73 @@ def isnotebook():
197230
edict[str(e2[0])] = drop2.search(e2[1]).group(1)
198231

199232

200-
# In[102]:
233+
# In[23]:
201234

202235

203236
if TPLdebug:
204237
pprint.pprint(edict)
205238

206239

207-
# In[103]:
240+
# In[24]:
208241

209242

210-
e3 = re.split(",", edict['state'])
211-
e4 = re.split(",", edict['link_status'])
212-
e5 = re.split(",", edict['pkts'])
243+
if convoluted:
244+
e3 = {}
245+
e4 = {}
246+
e5 = {}
247+
ee = re.split(",", edict['tmp_info'])
248+
for x in range (0, max_port_num):
249+
e3[x] = ee[(x*6)]
250+
e4[x] = ee[(x*6)+1]
251+
e5[(x*4)] = ee[(x*6)+2]
252+
e5[(x*4)+1] = ee[(x*6)+3]
253+
e5[(x*4)+2] = ee[(x*6)+4]
254+
e5[(x*4)+3] = ee[(x*6)+5]
255+
else:
256+
e3 = re.split(",", edict['state'])
257+
e4 = re.split(",", edict['link_status'])
258+
e5 = re.split(",", edict['pkts'])
213259

214260

215-
# In[122]:
261+
# In[25]:
216262

217263

218264
if TPL1line:
219-
print(current_dt+"," + str(max_port_num)+",", end="")
220-
output_format = "{0:d},{1:s},{2:s},{3:s},{4:s},{5:s},{6:s}"
221-
myend = ","
265+
print(current_dt+"," + str(max_port_num)+",", end="")
266+
output_format = "{0:d},{1:s},{2:s},{3:s},{4:s},{5:s},{6:s}"
267+
myend = ","
222268
else:
223-
output_format = "{0:d};{1:s};{2:s};{3:s},{4:s},{5:s},{6:s}"
224-
myend = "\n"
269+
output_format = "{0:d};{1:s};{2:s};{3:s},{4:s},{5:s},{6:s}"
270+
myend = "\n"
225271

226272
pdict = {}
227273
for x in range(1, max_port_num+1):
228274
#print(x, ((x-1)*4), ((x-1)*4)+1, ((x-1)*4)+2, ((x-1)*4)+3 )
229275
pdict[x] = {}
230276
if TPL1line:
231-
pdict[x]['state'] = e3[x-1]
232-
pdict[x]['link_status'] = e4[x-1]
277+
pdict[x]['state'] = e3[x-1]
278+
pdict[x]['link_status'] = e4[x-1]
233279
else:
234-
pdict[x]['state'] = TPstate[e3[x-1]]
235-
pdict[x]['link_status'] = TPlinkStatus[e4[x-1]]
280+
pdict[x]['state'] = TPstate[e3[x-1]]
281+
pdict[x]['link_status'] = TPlinkStatus[e4[x-1]]
236282
pdict[x]['TxGoodPkt'] = e5[((x-1)*4)]
237283
pdict[x]['TxBadPkt'] = e5[((x-1)*4)+1]
238284
pdict[x]['RxGoodPkt'] = e5[((x-1)*4)+2]
239285
pdict[x]['RxBadPkt'] = e5[((x-1)*4)+3]
240-
286+
241287
if (x == max_port_num):
242-
myend = "\n"
243-
print(output_format.format( x,
244-
pdict[x]['state'],
288+
myend = "\n"
289+
print(output_format.format(x,
290+
pdict[x]['state'],
245291
pdict[x]['link_status'],
246292
pdict[x]['TxGoodPkt'],
247293
pdict[x]['TxBadPkt'],
248294
pdict[x]['RxGoodPkt'],
249295
pdict[x]['RxBadPkt']), end=myend)
250296

251297

252-
# In[120]:
298+
# In[26]:
253299

254300

255301
if TPLdebug:
256302
pprint.pprint(pdict)
257-

0 commit comments

Comments
 (0)