From 68960dd75eb387a57a3f5237c87989f6264919da Mon Sep 17 00:00:00 2001 From: kiriharu Date: Sun, 3 Jan 2021 00:56:55 +0300 Subject: [PATCH] initial commit --- .gitignore | 128 ++++++++++++++++++++++++++++++ apps/__init__.py | 0 apps/api/README.rst | 0 apps/api/__init__.py | 0 apps/api/api/__init__.py | 0 apps/api/api/app.py | 34 ++++++++ apps/api/api/checkers/__init__.py | 0 apps/api/api/checkers/base.py | 12 +++ apps/api/api/checkers/http.py | 49 ++++++++++++ apps/api/api/config.py | 13 +++ apps/api/api/helpers.py | 13 +++ apps/api/pyproject.toml | 19 +++++ apps/core/README.rst | 0 apps/core/__init__.py | 0 apps/core/core/coretypes.py | 33 ++++++++ apps/core/pyproject.toml | 14 ++++ apps/tgbot/README.rst | 0 apps/tgbot/__init__.py | 0 apps/tgbot/pyproject.toml | 16 ++++ pyproject.toml | 14 ++++ 20 files changed, 345 insertions(+) create mode 100644 .gitignore create mode 100644 apps/__init__.py create mode 100644 apps/api/README.rst create mode 100644 apps/api/__init__.py create mode 100644 apps/api/api/__init__.py create mode 100644 apps/api/api/app.py create mode 100644 apps/api/api/checkers/__init__.py create mode 100644 apps/api/api/checkers/base.py create mode 100644 apps/api/api/checkers/http.py create mode 100644 apps/api/api/config.py create mode 100644 apps/api/api/helpers.py create mode 100644 apps/api/pyproject.toml create mode 100644 apps/core/README.rst create mode 100644 apps/core/__init__.py create mode 100644 apps/core/core/coretypes.py create mode 100644 apps/core/pyproject.toml create mode 100644 apps/tgbot/README.rst create mode 100644 apps/tgbot/__init__.py create mode 100644 apps/tgbot/pyproject.toml create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21a9b1c --- /dev/null +++ b/.gitignore @@ -0,0 +1,128 @@ +# Editors +.vscode/ +.idea/ + +# Vagrant +.vagrant/ + +# Mac/OSX +.DS_Store + +# Windows +Thumbs.db + +# Source for the following rules: https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore +# 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 +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 +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# 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/ +.dmypy.json +dmypy.json + +# poetry lock +poetry.lock \ No newline at end of file diff --git a/apps/__init__.py b/apps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/api/README.rst b/apps/api/README.rst new file mode 100644 index 0000000..e69de29 diff --git a/apps/api/__init__.py b/apps/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/api/api/__init__.py b/apps/api/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/api/api/app.py b/apps/api/api/app.py new file mode 100644 index 0000000..cb41b4a --- /dev/null +++ b/apps/api/api/app.py @@ -0,0 +1,34 @@ +from flask import Flask, request, abort, jsonify +from gevent.pywsgi import WSGIServer +from gevent import monkey +from helpers import access_token_required +import config + +monkey.patch_all() +# Monkey patch SSL in requests to prevent RecursionError! DO NOT REMOVE OR MOVE! +from checkers.http import HttpChecker + +app = Flask(__name__) + + +@app.route('/http') +@access_token_required +def http_check(): + target = request.args.get("target", None) + port = int(request.args.get("port", 80)) + + if not target: + abort(400) + + checker = HttpChecker(target, port) + + return jsonify(checker.check()) + + +def main(): + http = WSGIServer(('', config.APP_PORT), app.wsgi_app) + http.serve_forever() + + +if __name__ == '__main__': + main() diff --git a/apps/api/api/checkers/__init__.py b/apps/api/api/checkers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/api/api/checkers/base.py b/apps/api/api/checkers/base.py new file mode 100644 index 0000000..488e5eb --- /dev/null +++ b/apps/api/api/checkers/base.py @@ -0,0 +1,12 @@ +from core.coretypes import Response +from abc import ABC + + +class BaseChecker(ABC): + + def __init__(self, target: str, port: int): + self.target = target + self.port = port + + def check(self) -> Response: + raise NotImplementedError diff --git a/apps/api/api/checkers/http.py b/apps/api/api/checkers/http.py new file mode 100644 index 0000000..972919c --- /dev/null +++ b/apps/api/api/checkers/http.py @@ -0,0 +1,49 @@ +from core.coretypes import ( + Response, HttpCheckerResponse, + ResponseStatus, HttpErrorCodes, ErrorPayload +) +from requests import Session +from requests.exceptions import ConnectionError +from .base import BaseChecker +import time +import re + + +class HttpChecker(BaseChecker): + + default_schema = "http://" + default_schema_re = re.compile("^[hH][tT][tT][pP].*") + + def __init__(self, target: str, port: int): + super(HttpChecker, self).__init__(target, port) + self.session = Session() + + def check(self) -> Response: + + url = f"{self.target}:{self.port}" + if not self.default_schema_re.match(url): + url = f"{self.default_schema}{url}" + + start_time = time.time() + try: + request = self.session.get( + url + ) + except ConnectionError: + return Response( + status=ResponseStatus.ERROR, + payload=ErrorPayload( + message="Failed to establish a new connection", + code=HttpErrorCodes.ConnectError + ) + ) + + end_time = time.time() + + return Response( + status=ResponseStatus.OK, + payload=HttpCheckerResponse( + time=end_time - start_time, + status_code=request.status_code + ) + ) diff --git a/apps/api/api/config.py b/apps/api/api/config.py new file mode 100644 index 0000000..596099d --- /dev/null +++ b/apps/api/api/config.py @@ -0,0 +1,13 @@ +import os + +# APP PORT +APP_PORT = os.environ.get("PORT", 8080) + +# Node name. Will be shown in tgbot +NODE_NAME = os.environ.get("NODE_NAME", "Default node") + +# Node location. Will be shown in tgbot +NODE_LOCATION = os.environ.get("NODE_LOCATION", "Undefined Location") + +# Access token. Will be used for requests +ACCESS_TOKEN = os.environ.get("ACCESS_TOKEN", "CHANGE_TOKEN_BY_ENV") diff --git a/apps/api/api/helpers.py b/apps/api/api/helpers.py new file mode 100644 index 0000000..792d8fe --- /dev/null +++ b/apps/api/api/helpers.py @@ -0,0 +1,13 @@ +from functools import wraps +from flask import request, abort +from config import ACCESS_TOKEN + + +def access_token_required(f): + @wraps(f) + def decorated(*args, **kwargs): + if token := request.args.get('token', None): + if token == ACCESS_TOKEN: + return f(*args, **kwargs) + abort(403) + return decorated diff --git a/apps/api/pyproject.toml b/apps/api/pyproject.toml new file mode 100644 index 0000000..2a5f310 --- /dev/null +++ b/apps/api/pyproject.toml @@ -0,0 +1,19 @@ +[tool.poetry] +name = "api" +version = "0.1.0" +description = "Host report API" +authors = ["kiriharu "] + +[tool.poetry.dependencies] +python = "^3.8.2" +Flask = "^1.1.2" +gevent = "^20.12.1" +requests = "^2.25.1" +core = {path = "../core"} + +[tool.poetry.dev-dependencies] + + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/apps/core/README.rst b/apps/core/README.rst new file mode 100644 index 0000000..e69de29 diff --git a/apps/core/__init__.py b/apps/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/core/core/coretypes.py b/apps/core/core/coretypes.py new file mode 100644 index 0000000..d462bd2 --- /dev/null +++ b/apps/core/core/coretypes.py @@ -0,0 +1,33 @@ +from dataclasses import dataclass +from enum import Enum, IntEnum + + +class Payload: + pass + + +class ResponseStatus(str, Enum): + OK = "ok" + ERROR = "error" + + +class HttpErrorCodes(IntEnum): + ConnectError = 1 + + +@dataclass +class ErrorPayload(Payload): + message: str + code: HttpErrorCodes + + +@dataclass +class HttpCheckerResponse(Payload): + status_code: int + time: float + + +@dataclass +class Response: + status: ResponseStatus + payload: Payload diff --git a/apps/core/pyproject.toml b/apps/core/pyproject.toml new file mode 100644 index 0000000..5788630 --- /dev/null +++ b/apps/core/pyproject.toml @@ -0,0 +1,14 @@ +[tool.poetry] +name = "core" +version = "0.1.0" +description = "Types and other core functionality" +authors = ["kiriharu "] + +[tool.poetry.dependencies] +python = "^3.8" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/apps/tgbot/README.rst b/apps/tgbot/README.rst new file mode 100644 index 0000000..e69de29 diff --git a/apps/tgbot/__init__.py b/apps/tgbot/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/apps/tgbot/pyproject.toml b/apps/tgbot/pyproject.toml new file mode 100644 index 0000000..d2e43a5 --- /dev/null +++ b/apps/tgbot/pyproject.toml @@ -0,0 +1,16 @@ +[tool.poetry] +name = "tgbot" +version = "0.1.0" +description = "Telegram bot" +authors = ["kiriharu "] + +[tool.poetry.dependencies] +python = "^3.8" +aiogram = "^2.11.2" +core = {path = "../core"} + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..19c244a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[tool.poetry] +name = "host_report" +version = "0.1.0" +description = "" +authors = ["kiriharu "] + +[tool.poetry.dependencies] +python = "^3.8.2" + +[tool.poetry.dev-dependencies] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api"