Markus Hofbauer 3 lat temu
rodzic
commit
e14c4ab961
11 zmienionych plików z 357 dodań i 85 usunięć
  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
 
-on: [push, pull_request]
+on:
+  push:
+    branches: [master]
+  pull_request:
+    branches: [master]
 
 jobs:
   check:
     runs-on: ubuntu-latest
     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:
     runs-on: ubuntu-latest
     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,
 # or to provide custom queries or build logic.
-name: "CodeQL"
+name: CodeQL
 
 on:
   push:
@@ -12,7 +12,7 @@ on:
     # The branches below must be a subset of the branches above
     branches: [master]
   schedule:
-    - cron: '0 7 * * 0'
+    - cron: 0 7 * * 0
 
 jobs:
   analyze:
@@ -24,37 +24,37 @@ jobs:
       matrix:
         # Override automatic language detection by changing the below list
         # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
-        language: ['python']
+        language: [python]
         # Learn more...
         # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
 
     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
         # 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
     # 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.
-    - 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.
-        # 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.
         # queries: ./path/to/local/query, your-org/your-repo/queries@main
 
     # 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)
-    - 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.
     # 📚 https://git.io/JvXDl
@@ -67,5 +67,5 @@ jobs:
     #   make bootstrap
     #   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/
+
+# 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_PORT: 5000
     ports:
-      - '5000:5000'
+      - 5000:5000
     cap_add:
       - NET_ADMIN

+ 33 - 30
main.py

@@ -1,10 +1,12 @@
-import subprocess
+"""TC web GUI."""
+
+import argparse
 import os
 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 = [
     "bit",  # Bits per second
@@ -23,15 +25,15 @@ STANDARD_UNIT = "mbit"
 
 
 app = Flask(__name__)
-pattern = None
-dev_list = None
+PATTERN = None
+DEV_LIST = None
 
 app.static_folder = "static"
 
 
 def parse_arguments():
     parser = argparse.ArgumentParser(
-        description="TC web GUI",
+        description=__doc__,
         formatter_class=argparse.ArgumentDefaultsHelpFormatter,
     )
     parser.add_argument(
@@ -88,33 +90,33 @@ def new_rule(interface):
     interface = filter_interface_name(interface)
 
     # remove old setup
-    command = "tc qdisc del dev %s root netem" % interface
+    command = f"tc qdisc del dev {interface} root netem"
     command = command.split(" ")
     proc = subprocess.Popen(command)
     proc.wait()
 
     # apply new setup
-    command = "tc qdisc add dev %s root netem" % interface
+    command = f"tc qdisc add dev {interface} root netem"
     if rate != "":
-        command += " rate %s%s" % (rate, rate_unit)
+        command += f" rate {rate}{rate_unit}"
     if delay != "":
-        command += " delay %sms" % delay
+        command += f" delay {delay}ms"
         if delay_variance != "":
-            command += " %sms" % delay_variance
+            command += f" {delay_variance}ms"
     if loss != "":
-        command += " loss %s%%" % loss
+        command += f" loss {loss}%%"
         if loss_correlation != "":
-            command += " %s%%" % loss_correlation
+            command += f" {loss_correlation}%%"
     if duplicate != "":
-        command += " duplicate %s%%" % duplicate
+        command += f" duplicate {duplicate}%%"
     if reorder != "":
-        command += " reorder %s%%" % reorder
+        command += f" reorder {reorder}%%"
         if reorder_correlation != "":
-            command += " %s%%" % reorder_correlation
+            command += f" {reorder_correlation}%%"
     if corrupt != "":
-        command += " corrupt %s%%" % corrupt
+        command += f" corrupt {corrupt}%%"
     if limit != "":
-        command += " limit %s" % limit
+        command += f" limit {limit}"
     print(command)
     command = command.split(" ")
     proc = subprocess.Popen(command)
@@ -127,7 +129,7 @@ def remove_rule(interface):
     interface = filter_interface_name(interface)
 
     # remove old setup
-    command = "tc qdisc del dev %s root netem" % interface
+    command = f"tc qdisc del dev {interface} root netem"
     command = command.split(" ")
     proc = subprocess.Popen(command)
     proc.wait()
@@ -154,6 +156,7 @@ def get_active_rules():
 
 
 def parse_rule(split_rule):
+    # pylint: disable=too-many-branches
     rule = {
         "name": None,
         "rate": None,
@@ -170,16 +173,16 @@ def parse_rule(split_rule):
     i = 0
     for argument in split_rule:
         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
-            if pattern is None and dev_list is None:
+            if PATTERN is None and DEV_LIST is None:
                 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]
-            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]
         elif argument == "rate":
             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"
             "Please try again, this time using 'sudo'. Exiting."
         )
-        exit(1)
+        sys.exit(1)
 
     # TC Variables
     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
     app_args = {"host": args.ip, "port": args.port}

+ 1 - 1
requirements.txt

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

Plik diff jest za duży
+ 0 - 0
static/pure-min.css


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików