Skip to content

Commit 6dea83f

Browse files
committed
TextFSM 在线解析前端页面及后端 API
1 parent 38e379f commit 6dea83f

25 files changed

Lines changed: 26288 additions & 34 deletions

demo/fastapi_demo/templates/data.json

Lines changed: 0 additions & 9 deletions
This file was deleted.

demo/fastapi_demo/textfsm_demo.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1+
from fastapi import FastAPI
2+
from fastapi.middleware.cors import CORSMiddleware
3+
from pydantic import BaseModel
14
import textfsm
25
import tempfile
3-
6+
7+
48
def str_to_file_obj(text):
59
f_obj = tempfile.NamedTemporaryFile()
610
f_obj.write(text)
7-
# 确保string立即写入文件
11+
# 确保 string 立即写入文件
812
f_obj.flush()
913
# 将文件读取指针返回到文件开头位置
1014
f_obj.seek(0)
1115
return f_obj
1216

1317

14-
def textfsm_parser(raw_text, template_text):
18+
def textfsm_parser(raw_text: str, template_text: str) -> str:
1519
textfsm_data = []
1620
fsm_handler = None
17-
21+
# 字符串转为 bytes
22+
template_text = template_text.encode("utf-8")
1823
try:
1924
fsm_handler = textfsm.TextFSM(str_to_file_obj(template_text))
2025
for obj in fsm_handler.ParseText(raw_text):
@@ -27,19 +32,31 @@ def textfsm_parser(raw_text, template_text):
2732
except textfsm.parser.Error as tfte:
2833
return str(tfte)
2934

30-
raw_text = r'''IP
31-
192.168.1.1
32-
IP
33-
192.168.1.12
34-
IP
35-
192.168.1.13
36-
IP
37-
192.168.1.14'''
38-
template_text = b'''Value IPADD (\d+(\.\d+){3})
39-
40-
Start
41-
^IP
42-
^${IPADD} -> Record'''
43-
44-
ret = textfsm_parser(raw_text, template_text)
45-
print(ret)
35+
36+
app = FastAPI()
37+
38+
origins = [
39+
"http://localhost:8080",
40+
]
41+
42+
app.add_middleware(
43+
CORSMiddleware,
44+
allow_origins=origins,
45+
allow_methods=["*"],
46+
allow_headers=["*"],
47+
)
48+
49+
class TextFSMBody(BaseModel):
50+
raw_text: str
51+
template_text: str
52+
53+
54+
@app.post("/parser")
55+
async def parse_textfsm(textfsm_body: TextFSMBody):
56+
return textfsm_parser(**dict(textfsm_body))
57+
58+
59+
if __name__ == "__main__":
60+
import uvicorn
61+
62+
uvicorn.run(app, host="127.0.0.1", port=8000)

demo/textfsm_demo.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import textfsm
2+
import tempfile
3+
from pprint import pprint
4+
5+
def str_to_file_obj(text):
6+
f_obj = tempfile.NamedTemporaryFile()
7+
f_obj.write(text)
8+
# 确保string立即写入文件
9+
f_obj.flush()
10+
# 将文件读取指针返回到文件开头位置
11+
f_obj.seek(0)
12+
return f_obj
13+
14+
15+
def textfsm_parser(raw_text: str, template_text: str) -> str:
16+
textfsm_data = []
17+
fsm_handler = None
18+
template_text = template_text.encode('utf-8')
19+
try:
20+
fsm_handler = textfsm.TextFSM(str_to_file_obj(template_text))
21+
for obj in fsm_handler.ParseText(raw_text):
22+
entry = {}
23+
for index, entry_value in enumerate(obj):
24+
entry[fsm_handler.header[index]] = entry_value
25+
textfsm_data.append(entry)
26+
return textfsm_data
27+
28+
except textfsm.parser.Error as tfte:
29+
return str(tfte)
30+
31+
raw_text = r'''IP
32+
192.168.1.1
33+
IP
34+
192.168.1.12
35+
IP
36+
192.168.1.13
37+
IP
38+
192.168.1.14'''
39+
template_text = '''Value IPADD (\d+(\.\d+){3})
40+
41+
Start
42+
^IP
43+
^${IPADD} -> Record'''
44+
45+
pprint(raw_text)
46+
pprint(template_text)
47+
ret = textfsm_parser(raw_text, template_text)
48+
print(ret)

demo/vue_demo/myvue/package-lock.json

Lines changed: 61 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/vue_demo/myvue/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
},
1313
"dependencies": {
1414
"ant-design-vue": "^1.7.8",
15+
"axios": "^0.26.1",
1516
"vue": "^2.5.2",
17+
"vue-codemirror": "^4.0.6",
1618
"vue-router": "^3.0.1"
1719
},
1820
"devDependencies": {

demo/vue_demo/myvue/src/App.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
import HelloWorld from './components/HelloWorld.vue'
99
import myHello from './components/hello.vue'
1010
import Index from './components/Index.vue'
11-
import TodoList from './components/TodoList'
11+
import TodoList from './components/TodoList.vue'
12+
import TextFSMOnlile from './components/TextFSMOnline.vue'
1213
1314
/*
1415
添加组件的流程:
@@ -24,7 +25,7 @@ main.js 和 index.html 一般情况下是不用做改动的。
2425
*/
2526
2627
export default {
27-
components: { HelloWorld, myHello, Index, TodoList },
28+
components: { HelloWorld, myHello, Index, TodoList, TextFSMOnlile },
2829
name: 'App'
2930
}
3031
</script>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<template>
2+
<div>
3+
<h1>TextFSM 在线解析</h1>
4+
<codemirror v-model="code" :options="cmOptions"/>
5+
</div>
6+
7+
</template>
8+
9+
<script>
10+
// import language js
11+
import 'codemirror/mode/javascript/javascript.js'
12+
13+
// import theme style
14+
import 'codemirror/theme/lesser-dark.css'
15+
16+
// import more 'codemirror/some-resource...'
17+
18+
export default {
19+
data () {
20+
return {
21+
code: 'asdasdasd',
22+
cmOptions: {
23+
tabSize: 2,
24+
mode: 'text/javascript',
25+
theme: 'lesser-dark',
26+
lineNumbers: true,
27+
line: true
28+
// more CodeMirror options...
29+
}
30+
}
31+
},
32+
methods: {
33+
onCmReady (cm) {
34+
console.log('the editor is readied!', cm)
35+
},
36+
onCmFocus (cm) {
37+
console.log('the editor is focused!', cm)
38+
},
39+
onCmCodeChange (newCode) {
40+
console.log('this is new code', newCode)
41+
this.code = newCode
42+
}
43+
},
44+
computed: {
45+
codemirror () {
46+
return this.$refs.cmEditor.codemirror
47+
}
48+
}
49+
}
50+
</script>
51+
52+
<style>
53+
.el-row {
54+
margin-bottom: 20px;
55+
}
56+
.el-col {
57+
border-radius: 4px;
58+
}
59+
.grid-content {
60+
border-radius: 4px;
61+
margin: 1px;
62+
}
63+
.CodeMirror {
64+
border: 1px solid #eee;
65+
border-radius: 10px;
66+
padding: 5px;
67+
height: auto;
68+
}
69+
.CodeMirror-scroll {
70+
height: auto;
71+
overflow-y: hidden;
72+
overflow-x: auto;
73+
}
74+
</style>

0 commit comments

Comments
 (0)