Markus Hofbauer 3 лет назад
Родитель
Сommit
e14c4ab961
11 измененных файлов с 357 добавлено и 85 удалено
  1. 2 0
      .flake8
  2. 19 26
      .github/workflows/ci.yml
  3. 18 18
      .github/workflows/codeql-analysis.yml
  4. 161 0
      .gitignore
  5. 95 0
      .pre-commit-config.yaml
  6. 27 0
      .pylintrc
  7. 0 9
      Makefile
  8. 1 1
      docker-compose.yml
  9. 33 30
      main.py
  10. 1 1
      requirements.txt
  11. 0 0
      static/pure-min.css

+ 2 - 0
.flake8

@@ -0,0 +1,2 @@
+[flake8]
+max-line-length = 120

+ 19 - 26
.github/workflows/ci.yml

@@ -1,37 +1,30 @@
 name: CI
 name: CI
 
 
-on: [push, pull_request]
+on:
+  push:
+    branches: [master]
+  pull_request:
+    branches: [master]
 
 
 jobs:
 jobs:
   check:
   check:
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
     steps:
     steps:
-    - uses: actions/checkout@v2
-    - name: Set up Python 3.8
-      uses: actions/setup-python@v1
-      with:
-        python-version: 3.8
-    - name: Install dependencies
-      run: |
-        python -m pip install --upgrade pip
-        pip install -r requirements.txt
-    - name: Check code format
-      run: |
-        make check_format
-
-  super-lint:
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v2
-    - name: Lint Code Base
-      uses: docker://github/super-linter:v2.1.0
-      env:
-        VALIDATE_PYTHON: false
-        VALIDATE_CSS: false
+      - uses: actions/checkout@v3
+      - name: Set up Python 3.8
+        uses: actions/setup-python@v4
+        with:
+          python-version: 3.8
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install -r requirements.txt
+      - name: Check
+        run: pre-commit run --all-files
 
 
   docker:
   docker:
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
     steps:
     steps:
-    - uses: actions/checkout@v2
-    - name: Docker Build
-      run: docker build . --tag tcgui:$(date +%s)
+      - uses: actions/checkout@v3
+      - name: Docker Build
+        run: docker build . --tag tcgui:$(date +%s)

+ 18 - 18
.github/workflows/codeql-analysis.yml

@@ -3,7 +3,7 @@
 #
 #
 # You may wish to alter this file to override the set of languages analyzed,
 # You may wish to alter this file to override the set of languages analyzed,
 # or to provide custom queries or build logic.
 # or to provide custom queries or build logic.
-name: "CodeQL"
+name: CodeQL
 
 
 on:
 on:
   push:
   push:
@@ -12,7 +12,7 @@ on:
     # The branches below must be a subset of the branches above
     # The branches below must be a subset of the branches above
     branches: [master]
     branches: [master]
   schedule:
   schedule:
-    - cron: '0 7 * * 0'
+    - cron: 0 7 * * 0
 
 
 jobs:
 jobs:
   analyze:
   analyze:
@@ -24,37 +24,37 @@ jobs:
       matrix:
       matrix:
         # Override automatic language detection by changing the below list
         # Override automatic language detection by changing the below list
         # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
         # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
-        language: ['python']
+        language: [python]
         # Learn more...
         # Learn more...
         # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
         # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
 
 
     steps:
     steps:
-    - name: Checkout repository
-      uses: actions/checkout@v2
-      with:
+      - name: Checkout repository
+        uses: actions/checkout@v3
+        with:
         # We must fetch at least the immediate parents so that if this is
         # We must fetch at least the immediate parents so that if this is
         # a pull request then we can checkout the head.
         # a pull request then we can checkout the head.
-        fetch-depth: 2
+          fetch-depth: 2
 
 
     # If this run was triggered by a pull request event, then checkout
     # If this run was triggered by a pull request event, then checkout
     # the head of the pull request instead of the merge commit.
     # the head of the pull request instead of the merge commit.
-    - run: git checkout HEAD^2
-      if: ${{ github.event_name == 'pull_request' }}
+      - run: git checkout HEAD^2
+        if: ${{ github.event_name == 'pull_request' }}
 
 
     # Initializes the CodeQL tools for scanning.
     # Initializes the CodeQL tools for scanning.
-    - name: Initialize CodeQL
-      uses: github/codeql-action/init@v1
-      with:
-        languages: ${{ matrix.language }}
+      - name: Initialize CodeQL
+        uses: github/codeql-action/init@v2
+        with:
+          languages: ${{ matrix.language }}
         # If you wish to specify custom queries, you can do so here or in a config file.
         # If you wish to specify custom queries, you can do so here or in a config file.
-        # By default, queries listed here will override any specified in a config file. 
+        # By default, queries listed here will override any specified in a config file.
         # Prefix the list here with "+" to use these queries and those in the config file.
         # Prefix the list here with "+" to use these queries and those in the config file.
         # queries: ./path/to/local/query, your-org/your-repo/queries@main
         # queries: ./path/to/local/query, your-org/your-repo/queries@main
 
 
     # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
     # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
     # If this step fails, then you should remove it and run the build manually (see below)
     # If this step fails, then you should remove it and run the build manually (see below)
-    - name: Autobuild
-      uses: github/codeql-action/autobuild@v1
+      - name: Autobuild
+        uses: github/codeql-action/autobuild@v2
 
 
     # ℹ️ Command-line programs to run using the OS shell.
     # ℹ️ Command-line programs to run using the OS shell.
     # 📚 https://git.io/JvXDl
     # 📚 https://git.io/JvXDl
@@ -67,5 +67,5 @@ jobs:
     #   make bootstrap
     #   make bootstrap
     #   make release
     #   make release
 
 
-    - name: Perform CodeQL Analysis
-      uses: github/codeql-action/analyze@v1
+      - name: Perform CodeQL Analysis
+        uses: github/codeql-action/analyze@v2

+ 161 - 0
.gitignore

@@ -1 +1,162 @@
 .vagrant/
 .vagrant/
+
+# 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/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# 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/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# 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/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/

+ 95 - 0
.pre-commit-config.yaml

@@ -0,0 +1,95 @@
+default_stages:
+  - commit
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.3.0
+    hooks:
+      - id: check-added-large-files
+      - id: check-case-conflict
+      - id: check-docstring-first
+      - id: check-executables-have-shebangs
+      - id: check-shebang-scripts-are-executable
+      - id: check-symlinks
+      - id: check-yaml
+      - id: debug-statements
+      - id: destroyed-symlinks
+      - id: detect-private-key
+      - id: end-of-file-fixer
+      - id: requirements-txt-fixer
+      - id: trailing-whitespace
+  - repo: https://github.com/executablebooks/mdformat
+    rev: 0.7.16
+    hooks:
+      - id: mdformat
+        additional_dependencies:
+          - mdformat-gfm
+          - mdformat-black
+  - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt
+    rev: 0.2.2
+    hooks:
+      - id: yamlfmt
+        args:
+          - --mapping
+          - '2'
+          - --sequence
+          - '4'
+          - --offset
+          - '2'
+          - --implicit_start
+  - repo: https://github.com/psf/black
+    rev: 22.8.0
+    hooks:
+      - id: black
+        language_version: python3
+      - id: black-jupyter
+        language_version: python3
+  - repo: https://github.com/asottile/blacken-docs
+    rev: v1.12.1
+    hooks:
+      - id: blacken-docs
+  - repo: https://github.com/PyCQA/isort
+    rev: 5.10.1
+    hooks:
+      - id: isort
+        args: [--profile, black]
+  - repo: https://github.com/PyCQA/docformatter
+    rev: v1.5.0
+    hooks:
+      - id: docformatter
+        args:
+          - --in-place
+          - --wrap-summaries
+          - '88'
+          - --wrap-descriptions
+          - '81'
+  - repo: https://github.com/PyCQA/flake8
+    rev: 5.0.4
+    hooks:
+      - id: flake8
+        additional_dependencies:
+          - flake8-use-pathlib
+          - flake8-bugbear
+          - flake8-pytest-style
+          - flake8-comprehensions
+  - repo: https://github.com/PyCQA/pylint
+    rev: v2.15.0
+    hooks:
+      - id: pylint
+  - repo: https://github.com/asottile/pyupgrade
+    rev: v2.37.3
+    hooks:
+      - id: pyupgrade
+        args:
+          - --py38-plus
+  - repo: https://github.com/asottile/yesqa
+    rev: v1.4.0
+    hooks:
+      - id: yesqa
+  - repo: https://github.com/PyCQA/autoflake
+    rev: v1.5.3
+    hooks:
+      - id: autoflake
+  # - repo: https://github.com/crate-ci/typos
+  #   rev: v1.12.4
+  #   hooks:
+  #     - id: typos

+ 27 - 0
.pylintrc

@@ -0,0 +1,27 @@
+[MASTER]
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=venv
+
+[BASIC]
+
+# Stick to snake case, but accept setUp and tearDown from unittest
+method-rgx=(([a-z_][a-z0-9_]*)|(setUp)|(tearDown))$
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
+confidence=
+
+disable=
+    missing-function-docstring,
+    import-error, # disabled since pre-commit runs pylint in a separate venv
+    fixme,
+    consider-using-with
+
+[FORMAT]
+
+# Maximum number of characters on a single line.
+max-line-length=120

+ 0 - 9
Makefile

@@ -1,9 +0,0 @@
-file_finder = find . -type f $(1) -not -path './venv/*'
-
-PY_FILES = $(call file_finder,-name "*.py")
-
-format:
-	$(PY_FILES) | xargs black
-
-check_format:
-	$(PY_FILES) | xargs black --diff --check

+ 1 - 1
docker-compose.yml

@@ -6,6 +6,6 @@ services:
       TCGUI_IP: 0.0.0.0
       TCGUI_IP: 0.0.0.0
       TCGUI_PORT: 5000
       TCGUI_PORT: 5000
     ports:
     ports:
-      - '5000:5000'
+      - 5000:5000
     cap_add:
     cap_add:
       - NET_ADMIN
       - NET_ADMIN

+ 33 - 30
main.py

@@ -1,10 +1,12 @@
-import subprocess
+"""TC web GUI."""
+
+import argparse
 import os
 import os
 import re
 import re
-import argparse
-
-from flask import Flask, render_template, redirect, request, url_for
+import subprocess
+import sys
 
 
+from flask import Flask, redirect, render_template, request, url_for
 
 
 BANDWIDTH_UNITS = [
 BANDWIDTH_UNITS = [
     "bit",  # Bits per second
     "bit",  # Bits per second
@@ -23,15 +25,15 @@ STANDARD_UNIT = "mbit"
 
 
 
 
 app = Flask(__name__)
 app = Flask(__name__)
-pattern = None
-dev_list = None
+PATTERN = None
+DEV_LIST = None
 
 
 app.static_folder = "static"
 app.static_folder = "static"
 
 
 
 
 def parse_arguments():
 def parse_arguments():
     parser = argparse.ArgumentParser(
     parser = argparse.ArgumentParser(
-        description="TC web GUI",
+        description=__doc__,
         formatter_class=argparse.ArgumentDefaultsHelpFormatter,
         formatter_class=argparse.ArgumentDefaultsHelpFormatter,
     )
     )
     parser.add_argument(
     parser.add_argument(
@@ -88,33 +90,33 @@ def new_rule(interface):
     interface = filter_interface_name(interface)
     interface = filter_interface_name(interface)
 
 
     # remove old setup
     # remove old setup
-    command = "tc qdisc del dev %s root netem" % interface
+    command = f"tc qdisc del dev {interface} root netem"
     command = command.split(" ")
     command = command.split(" ")
     proc = subprocess.Popen(command)
     proc = subprocess.Popen(command)
     proc.wait()
     proc.wait()
 
 
     # apply new setup
     # apply new setup
-    command = "tc qdisc add dev %s root netem" % interface
+    command = f"tc qdisc add dev {interface} root netem"
     if rate != "":
     if rate != "":
-        command += " rate %s%s" % (rate, rate_unit)
+        command += f" rate {rate}{rate_unit}"
     if delay != "":
     if delay != "":
-        command += " delay %sms" % delay
+        command += f" delay {delay}ms"
         if delay_variance != "":
         if delay_variance != "":
-            command += " %sms" % delay_variance
+            command += f" {delay_variance}ms"
     if loss != "":
     if loss != "":
-        command += " loss %s%%" % loss
+        command += f" loss {loss}%%"
         if loss_correlation != "":
         if loss_correlation != "":
-            command += " %s%%" % loss_correlation
+            command += f" {loss_correlation}%%"
     if duplicate != "":
     if duplicate != "":
-        command += " duplicate %s%%" % duplicate
+        command += f" duplicate {duplicate}%%"
     if reorder != "":
     if reorder != "":
-        command += " reorder %s%%" % reorder
+        command += f" reorder {reorder}%%"
         if reorder_correlation != "":
         if reorder_correlation != "":
-            command += " %s%%" % reorder_correlation
+            command += f" {reorder_correlation}%%"
     if corrupt != "":
     if corrupt != "":
-        command += " corrupt %s%%" % corrupt
+        command += f" corrupt {corrupt}%%"
     if limit != "":
     if limit != "":
-        command += " limit %s" % limit
+        command += f" limit {limit}"
     print(command)
     print(command)
     command = command.split(" ")
     command = command.split(" ")
     proc = subprocess.Popen(command)
     proc = subprocess.Popen(command)
@@ -127,7 +129,7 @@ def remove_rule(interface):
     interface = filter_interface_name(interface)
     interface = filter_interface_name(interface)
 
 
     # remove old setup
     # remove old setup
-    command = "tc qdisc del dev %s root netem" % interface
+    command = f"tc qdisc del dev {interface} root netem"
     command = command.split(" ")
     command = command.split(" ")
     proc = subprocess.Popen(command)
     proc = subprocess.Popen(command)
     proc.wait()
     proc.wait()
@@ -154,6 +156,7 @@ def get_active_rules():
 
 
 
 
 def parse_rule(split_rule):
 def parse_rule(split_rule):
+    # pylint: disable=too-many-branches
     rule = {
     rule = {
         "name": None,
         "name": None,
         "rate": None,
         "rate": None,
@@ -170,16 +173,16 @@ def parse_rule(split_rule):
     i = 0
     i = 0
     for argument in split_rule:
     for argument in split_rule:
         if argument == "dev":
         if argument == "dev":
-            # Both regex pattern and dev name can be given
-            # An interface could match the pattern and/or
+            # Both regex PATTERN and dev name can be given
+            # An interface could match the PATTERN and/or
             # be in the interface list
             # be in the interface list
-            if pattern is None and dev_list is None:
+            if PATTERN is None and DEV_LIST is None:
                 rule["name"] = split_rule[i + 1]
                 rule["name"] = split_rule[i + 1]
-            if pattern:
-                if pattern.match(split_rule[i + 1]):
+            if PATTERN:
+                if PATTERN.match(split_rule[i + 1]):
                     rule["name"] = split_rule[i + 1]
                     rule["name"] = split_rule[i + 1]
-            if dev_list:
-                if split_rule[i + 1] in dev_list:
+            if DEV_LIST:
+                if split_rule[i + 1] in DEV_LIST:
                     rule["name"] = split_rule[i + 1]
                     rule["name"] = split_rule[i + 1]
         elif argument == "rate":
         elif argument == "rate":
             rule["rate"] = split_rule[i + 1].split("Mbit")[0]
             rule["rate"] = split_rule[i + 1].split("Mbit")[0]
@@ -211,13 +214,13 @@ if __name__ == "__main__":
             "You need to have root privileges to run this script.\n"
             "You need to have root privileges to run this script.\n"
             "Please try again, this time using 'sudo'. Exiting."
             "Please try again, this time using 'sudo'. Exiting."
         )
         )
-        exit(1)
+        sys.exit(1)
 
 
     # TC Variables
     # TC Variables
     args = parse_arguments()
     args = parse_arguments()
 
 
-    pattern = re.compile(args.regex) if args.regex else args.regex
-    dev_list = args.dev
+    PATTERN = re.compile(args.regex) if args.regex else args.regex
+    DEV_LIST = args.dev
 
 
     # Flask Variable
     # Flask Variable
     app_args = {"host": args.ip, "port": args.port}
     app_args = {"host": args.ip, "port": args.port}

+ 1 - 1
requirements.txt

@@ -1,2 +1,2 @@
-black
 flask
 flask
+pre-commit

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
static/pure-min.css


Некоторые файлы не были показаны из-за большого количества измененных файлов