init comit
This commit is contained in:
172
.gitignore
vendored
Normal file
172
.gitignore
vendored
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
|
||||||
|
# Created by https://www.gitignore.io/api/python,pycharm+all
|
||||||
|
|
||||||
|
### PyCharm+all ###
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff:
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/dictionaries
|
||||||
|
|
||||||
|
# Sensitive or high-churn files:
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.xml
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
|
||||||
|
# Gradle:
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-debug/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin:
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
## File-based project format:
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
## Plugin-specific files:
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# Ruby plugin and RubyMine
|
||||||
|
/.rakeTasks
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
### PyCharm+all Patch ###
|
||||||
|
# Ignores the whole .idea folder and all .iml files
|
||||||
|
# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023
|
||||||
|
|
||||||
|
*.iml
|
||||||
|
modules.xml
|
||||||
|
.idea/misc.xml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Python ###
|
||||||
|
# Byte-compiled / optimized / DLL files
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# PyInstaller
|
||||||
|
# Usually these files are written by a python script from a template
|
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
.pytest_cache/
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
.hypothesis/
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
|
||||||
|
# Flask stuff:
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
|
||||||
|
# Scrapy stuff:
|
||||||
|
.scrapy
|
||||||
|
|
||||||
|
# Sphinx documentation
|
||||||
|
docs/_build/
|
||||||
|
|
||||||
|
# PyBuilder
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Jupyter Notebook
|
||||||
|
.ipynb_checkpoints
|
||||||
|
|
||||||
|
# pyenv
|
||||||
|
.python-version
|
||||||
|
|
||||||
|
# celery beat schedule file
|
||||||
|
celerybeat-schedule.*
|
||||||
|
|
||||||
|
# SageMath parsed files
|
||||||
|
*.sage.py
|
||||||
|
|
||||||
|
# Environments
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
|
||||||
|
# Spyder project settings
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
|
||||||
|
# Rope project settings
|
||||||
|
.ropeproject
|
||||||
|
|
||||||
|
# mkdocs documentation
|
||||||
|
/site
|
||||||
|
|
||||||
|
# mypy
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
|
||||||
|
# End of https://www.gitignore.io/api/python,pycharm+all
|
||||||
0
mmgs108/__init__.py
Normal file
0
mmgs108/__init__.py
Normal file
0
mmgs108/api/__init__.py
Normal file
0
mmgs108/api/__init__.py
Normal file
0
mmgs108/api/http/__init__.py
Normal file
0
mmgs108/api/http/__init__.py
Normal file
14
mmgs108/api/http/sap.py
Normal file
14
mmgs108/api/http/sap.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
from mmgs108.api.http.session import Session
|
||||||
|
|
||||||
|
|
||||||
|
class Sap:
|
||||||
|
|
||||||
|
def __init__(self, base_address):
|
||||||
|
self.__address = base_address
|
||||||
|
|
||||||
|
def execute_request(self, request, password):
|
||||||
|
with Session(self.__address, password) as apiSession:
|
||||||
|
apiSession.get("foo")
|
||||||
|
|
||||||
|
def generate_url(self, path):
|
||||||
|
return "http://{}/{}".format(self.__address, path)
|
||||||
33
mmgs108/api/http/session.py
Normal file
33
mmgs108/api/http/session.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from requests import session
|
||||||
|
|
||||||
|
|
||||||
|
class Session:
|
||||||
|
__LOGIN_PATH = "login.cgi"
|
||||||
|
__LOGOUT_PATH = "logout.cgi"
|
||||||
|
__PASSWORD_POST_KEY = "password"
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.__http_session.get(self.__logout_url)
|
||||||
|
self.__http_session.close()
|
||||||
|
|
||||||
|
def __init__(self, sap, password):
|
||||||
|
self.__api = sap
|
||||||
|
self.__login_url = sap.generate_url(Session.__LOGIN_PATH)
|
||||||
|
self.__logout_url = sap.generate_url(Session.__LOGOUT_PATH)
|
||||||
|
self.__http_session = session()
|
||||||
|
self.__http_session.post(self.__login_url, data={Session.__PASSWORD_POST_KEY: password})
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def get(self, path):
|
||||||
|
return self.__http_session.get(self.__api.generate_url(path))
|
||||||
|
|
||||||
|
def post(self, path, data):
|
||||||
|
return self.__http_session.post(self.__api.generate_url(path), data=data)
|
||||||
74
mmgs108/api/http/vlan_table.py
Normal file
74
mmgs108/api/http/vlan_table.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class VLanTable:
|
||||||
|
__Q_BASIC = "8021qBasic"
|
||||||
|
__Q_BASIC_HTM = "{}.htm".format(__Q_BASIC)
|
||||||
|
__Q_BASIC_CGI = "{}.cgi".format(__Q_BASIC)
|
||||||
|
|
||||||
|
def __init__(self, session):
|
||||||
|
self.__session = session
|
||||||
|
self.__vlan_table, self.__hash_value = self.__read_table()
|
||||||
|
|
||||||
|
def __read_table(self):
|
||||||
|
response = self.__session.get(VLanTable.__Q_BASIC_HTM)
|
||||||
|
html = response.text
|
||||||
|
table = VLanTable.__html_table_to_dict(html)
|
||||||
|
hash_value = VLanTable.__get_hash_from_html_table(html)
|
||||||
|
return table, hash_value
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.__vlan_table)
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
return self.__vlan_table[item]
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self.__vlan_table[key] = str(value)
|
||||||
|
self.flush_table()
|
||||||
|
|
||||||
|
def flush_table(self):
|
||||||
|
data = VLanTable._create_post_param(self.__vlan_table, self.__hash_value)
|
||||||
|
self.__session.post(VLanTable.__Q_BASIC_CGI, data)
|
||||||
|
self.__vlan_table, self.__hash_value = self.__read_table()
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
return self.__vlan_table.items()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_post_param(table, hash_value):
|
||||||
|
params = {
|
||||||
|
"hash": hash_value,
|
||||||
|
"hiddVlan": "",
|
||||||
|
"status": "Enable",
|
||||||
|
}
|
||||||
|
|
||||||
|
return {**params, **table}
|
||||||
|
|
||||||
|
def to_html_table(self):
|
||||||
|
return VLanTable.__dict_to_html_table(self.__vlan_table)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __html_table_to_dict(html):
|
||||||
|
pattern = re.compile("name='(?P<port_name>port[0-9]+)' value='(?P<port_vlan_id>(all|[0-9]+))'")
|
||||||
|
match_iter = pattern.finditer(html)
|
||||||
|
vlan_table = {}
|
||||||
|
for match in match_iter:
|
||||||
|
vlan_table[match["port_name"]] = match["port_vlan_id"]
|
||||||
|
|
||||||
|
return vlan_table
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __get_hash_from_html_table(html):
|
||||||
|
pattern = re.compile("name='hash' id='hash' value='(?P<hash_value>[0-9]+)'")
|
||||||
|
return pattern.search(html)["hash_value"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __dict_to_html_table(table):
|
||||||
|
header = ""
|
||||||
|
values = ""
|
||||||
|
for key, value in table.items():
|
||||||
|
header = header + "<th>{}</th>\n".format(key)
|
||||||
|
values = values + "<td><input type='text' name='{}' value='{}' size='11' maxlength='4'></td>\n".format(key, value)
|
||||||
|
|
||||||
|
return "<table><tr>{} </tr><tr>{}</tr><table>".format(header, values)
|
||||||
0
mmgs108/ui/__init__.py
Executable file
0
mmgs108/ui/__init__.py
Executable file
0
mmgs108/ui/kivy/__init__.py
Normal file
0
mmgs108/ui/kivy/__init__.py
Normal file
72
mmgs108/ui/kivy/app.py
Normal file
72
mmgs108/ui/kivy/app.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
from kivy.app import App
|
||||||
|
from mmgs108.api.http.session import Session
|
||||||
|
from mmgs108.api.http.vlan_table import VLanTable
|
||||||
|
|
||||||
|
from mmgs108.api.http.sap import Sap
|
||||||
|
from kivy.uix.boxlayout import BoxLayout
|
||||||
|
from kivy.uix.textinput import TextInput
|
||||||
|
from kivy.uix.label import Label
|
||||||
|
from kivy.uix.scrollview import ScrollView
|
||||||
|
from kivy.uix.gridlayout import GridLayout
|
||||||
|
from kivy.core.window import Window
|
||||||
|
|
||||||
|
|
||||||
|
class Gs108App(App):
|
||||||
|
|
||||||
|
def __init__(self, ips, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.__switches = {}
|
||||||
|
self.__ips = ips
|
||||||
|
|
||||||
|
def stop(self, *largs):
|
||||||
|
for key, switch in self.__switches.items():
|
||||||
|
switch["session"].close()
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
|
||||||
|
for ip in self.__ips:
|
||||||
|
sap = Sap(ip)
|
||||||
|
session = Session(sap, "password")
|
||||||
|
table = VLanTable(session)
|
||||||
|
self.__switches[ip] = {
|
||||||
|
"sap": sap,
|
||||||
|
"session": session,
|
||||||
|
"table": table
|
||||||
|
}
|
||||||
|
|
||||||
|
grid = GridLayout(cols=1, spacing=10, size_hint_y=None)
|
||||||
|
grid.bind(minimum_height=grid.setter('height'))
|
||||||
|
for name, switch in self.__switches.items():
|
||||||
|
grid.add_widget(self.build_switch(name, switch["table"]))
|
||||||
|
|
||||||
|
root = ScrollView(size_hint=(1, None), size=(Window.width, Window.height))
|
||||||
|
root.add_widget(grid)
|
||||||
|
return root
|
||||||
|
|
||||||
|
def build_vtable(self, table):
|
||||||
|
layout = BoxLayout()
|
||||||
|
for key, value in table.items():
|
||||||
|
tmp_layout = BoxLayout(orientation='vertical')
|
||||||
|
tmp_layout.add_widget(Label(text='{}:'.format(key), size_hint=(1, None), height=30))
|
||||||
|
vlan_input = VLanIdInput(table, key, text='{}'.format(value), multiline=False, size_hint=(1, None), height=30)
|
||||||
|
tmp_layout.add_widget(vlan_input)
|
||||||
|
layout.add_widget(tmp_layout)
|
||||||
|
|
||||||
|
return layout
|
||||||
|
|
||||||
|
def build_switch(self, switch, table):
|
||||||
|
layout = GridLayout(cols=1, spacing=10, size_hint_y=None)
|
||||||
|
layout.add_widget(Label(text='{}:'.format(switch), size_hint=(1, None), height=30))
|
||||||
|
layout.add_widget(self.build_vtable(table))
|
||||||
|
return layout
|
||||||
|
|
||||||
|
|
||||||
|
class VLanIdInput(TextInput):
|
||||||
|
|
||||||
|
def __init__(self, table, port, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.__table = table
|
||||||
|
self.__port = port
|
||||||
|
|
||||||
|
def on_text_validate(self):
|
||||||
|
self.__table[self.__port] = self.text
|
||||||
0
tests/__init__.py
Normal file
0
tests/__init__.py
Normal file
0
tests/api/__init__.py
Normal file
0
tests/api/__init__.py
Normal file
0
tests/api/http/__init__.py
Normal file
0
tests/api/http/__init__.py
Normal file
16
tests/api/http/test_sap.py
Normal file
16
tests/api/http/test_sap.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import unittest
|
||||||
|
from mmgs108.api.http.sap import Sap
|
||||||
|
from mmgs108.ui.kivy.app import Gs108App
|
||||||
|
|
||||||
|
|
||||||
|
class TestSap(unittest.TestCase):
|
||||||
|
def test_generate_url(self):
|
||||||
|
sap = Sap("foo")
|
||||||
|
self.assertEqual("http://foo/bar", sap.generate_url("bar"))
|
||||||
|
|
||||||
|
def test_runServer(self):
|
||||||
|
Gs108App(["10.0.0.254"]).run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
25
tests/api/http/test_vlan_table.py
Normal file
25
tests/api/http/test_vlan_table.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import unittest
|
||||||
|
import random
|
||||||
|
from mmgs108.api.http.sap import Sap
|
||||||
|
from mmgs108.api.http.session import Session
|
||||||
|
from mmgs108.api.http.vlan_table import VLanTable
|
||||||
|
|
||||||
|
|
||||||
|
class TestVLanTable(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_get_vlan_table(self):
|
||||||
|
sap = Sap("10.0.0.254")
|
||||||
|
vlan_id = random.randrange(1, 4095)
|
||||||
|
port_key = "port{}".format(random.randrange(2, 8))
|
||||||
|
with Session(sap, "password") as session1:
|
||||||
|
table = VLanTable(session1)
|
||||||
|
table[port_key] = vlan_id
|
||||||
|
self.assertEqual(str(vlan_id), table[port_key])
|
||||||
|
|
||||||
|
with Session(sap, "password") as session2:
|
||||||
|
table = VLanTable(session2)
|
||||||
|
self.assertEqual(str(vlan_id), table[port_key])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user