minecraft endpoint, close #6

This commit is contained in:
kiriharu 2021-01-05 02:18:06 +03:00
parent ab49ad92b0
commit 46e46471e9
10 changed files with 91 additions and 26 deletions

View File

@ -3,7 +3,7 @@ from gevent.pywsgi import WSGIServer
from helpers import access_token_required from helpers import access_token_required
import config import config
from checkers import HttpChecker, ICMPChecker, TCPPortChecker from checkers import HttpChecker, ICMPChecker, TCPPortChecker, MinecraftChecker
app = Flask(__name__) app = Flask(__name__)
@ -13,12 +13,9 @@ app = Flask(__name__)
def http_check(): def http_check():
target = request.args.get("target", None) target = request.args.get("target", None)
port = int(request.args.get("port", 80)) port = int(request.args.get("port", 80))
if not target: if not target:
abort(400) abort(400)
checker = HttpChecker(target, port) checker = HttpChecker(target, port)
return jsonify(checker.check()) return jsonify(checker.check())
@ -27,12 +24,20 @@ def http_check():
def tcp_port_check(): def tcp_port_check():
target = request.args.get("target", None) target = request.args.get("target", None)
port = int(request.args.get("port", None)) port = int(request.args.get("port", None))
if not target or not port: if not target or not port:
abort(400) abort(400)
checker = TCPPortChecker(target, port) checker = TCPPortChecker(target, port)
return jsonify(checker.check())
@app.route('/minecraft')
@access_token_required
def minecraft_check():
target = request.args.get("target", None)
port = int(request.args.get("port", 25565))
if not target:
abort(400)
checker = MinecraftChecker(target, port)
return jsonify(checker.check()) return jsonify(checker.check())
@ -40,12 +45,9 @@ def tcp_port_check():
@access_token_required @access_token_required
def icmp_check(): def icmp_check():
target = request.args.get("target", None) target = request.args.get("target", None)
if not target: if not target:
abort(400) abort(400)
checker = ICMPChecker(target) checker = ICMPChecker(target)
return jsonify(checker.check()) return jsonify(checker.check())

View File

@ -1,3 +1,4 @@
from .http import HttpChecker from .http import HttpChecker
from .icmp import ICMPChecker from .icmp import ICMPChecker
from .tcp_port import TCPPortChecker from .tcp_port import TCPPortChecker
from .minecraft import MinecraftChecker

View File

@ -10,6 +10,7 @@ Flask = "^1.1.2"
gevent = "^20.12.1" gevent = "^20.12.1"
requests = "^2.25.1" requests = "^2.25.1"
icmplib = "^2.0.1" icmplib = "^2.0.1"
mcstatus = "^4.1.0"
core = {path = "../core"} core = {path = "../core"}
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]

View File

@ -45,6 +45,12 @@ class APINodeInfo:
location: str location: str
@dataclass
class MinecraftResponse(Payload):
latency: float
max_players: int
online: int
@dataclass @dataclass
class PortResponse(Payload): class PortResponse(Payload):
open: bool open: bool

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "core" name = "core"
version = "0.7.0" version = "0.10.0"
description = "Types and other core functionality" description = "Types and other core functionality"
authors = ["kiriharu <kiriharu@yandex.ru>"] authors = ["kiriharu <kiriharu@yandex.ru>"]

View File

@ -7,9 +7,9 @@ authors = ["kiriharu <kiriharu@yandex.ru>"]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.8" python = "^3.8"
aiogram = "^2.11.2" aiogram = "^2.11.2"
core = {path = "../core"}
httpx = "^0.16.1" httpx = "^0.16.1"
python-whois = "^0.7.3" python-whois = "^0.7.3"
core = {path = "../core"}
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]

View File

@ -6,7 +6,7 @@ from httpx import Response
from aiogram.bot import Bot from aiogram.bot import Bot
from datetime import datetime from datetime import datetime
from core.coretypes import APINodeInfo from core.coretypes import APINodeInfo
from .helpers import send_api_requests from .helpers import send_api_requests, check_int
header = "Отчет о проверке хоста:" \ header = "Отчет о проверке хоста:" \
"\n\n— Хост: {target_fq}"\ "\n\n— Хост: {target_fq}"\
@ -58,3 +58,18 @@ class CheckerBaseHandler:
async def prepare_message(self, res: Response) -> str: async def prepare_message(self, res: Response) -> str:
raise NotImplemented raise NotImplemented
def process_args_for_host_port(text: str, default_port: int) -> list:
port = None
args = text.split(" ")
if len(args) < 2:
raise NotEnoughArgs()
if len(args) == 2:
port = default_port
if len(args) == 3:
port = args[2]
if not check_int(port):
raise InvalidPort()
host = args[1]
return [host, port]

View File

@ -5,6 +5,7 @@ from .web import WebCheckerHandler
from .whois import whois_cmd from .whois import whois_cmd
from .icmp import ICMPCheckerHandler from .icmp import ICMPCheckerHandler
from .tcp import TCPCheckerHandler from .tcp import TCPCheckerHandler
from .minecraft import MinecraftCheckerHandler
def setup(dp: Dispatcher): def setup(dp: Dispatcher):
@ -13,3 +14,4 @@ def setup(dp: Dispatcher):
dp.register_message_handler(whois_cmd, is_forwarded=False, commands=['whois']) dp.register_message_handler(whois_cmd, is_forwarded=False, commands=['whois'])
dp.register_message_handler(ICMPCheckerHandler().handler, is_forwarded=False, commands=['icmp', 'ping']) dp.register_message_handler(ICMPCheckerHandler().handler, is_forwarded=False, commands=['icmp', 'ping'])
dp.register_message_handler(TCPCheckerHandler().handler, is_forwarded=False, commands=['tcp']) dp.register_message_handler(TCPCheckerHandler().handler, is_forwarded=False, commands=['tcp'])
dp.register_message_handler(MinecraftCheckerHandler().handler, is_forwarded=False, commands=['minecraft'])

View File

@ -0,0 +1,50 @@
from aiogram.types import Message
from core.coretypes import ResponseStatus, ErrorPayload, MinecraftResponse
from httpx import Response
from tgbot.handlers.base import CheckerBaseHandler, NotEnoughArgs, InvalidPort, process_args_for_host_port
minecraft_help_message = """
Получает статистику о Minecraft сервере
Использование:
`/minecraft <hostname> <port>`
`/minecraft <hostname>` - автоматически выставит порт 25565
"""
invalid_port = """❗Неправильный порт. Напишите /minecraft чтобы увидеть справку к данному способу проверки."""
class MinecraftCheckerHandler(CheckerBaseHandler):
help_message = minecraft_help_message
api_endpoint = "minecraft"
def __init__(self):
super().__init__()
async def handler(self, message: Message):
try:
args = await self.process_args(message.text)
except NotEnoughArgs:
return await message.answer(self.help_message, parse_mode="Markdown")
except InvalidPort:
return await message.answer(invalid_port, parse_mode="Markdown")
await self.check(
message.chat.id,
message.bot,
dict(target=args[0], port=args[1], target_fq=f"{args[0]}:{args[1]}")
)
async def process_args(self, text: str) -> list:
return process_args_for_host_port(text, 25565)
async def prepare_message(self, res: Response):
message, status = await self.message_std_vals(res)
if status == ResponseStatus.OK:
payload = MinecraftResponse(**res.json().get("payload"))
message += f"✅ 👤{payload.online}/{payload.max_players} 📶{payload.latency}ms"
if status == ResponseStatus.ERROR:
payload = ErrorPayload(**res.json().get("payload"))
message += f"❌️ {payload.message}"
return message

View File

@ -1,8 +1,7 @@
from aiogram.types import Message from aiogram.types import Message
from tgbot.handlers.helpers import check_int
from httpx import Response from httpx import Response
from core.coretypes import ResponseStatus, HTTP_EMOJI, HttpCheckerResponse, ErrorPayload from core.coretypes import ResponseStatus, HTTP_EMOJI, HttpCheckerResponse, ErrorPayload
from ..base import CheckerBaseHandler, NotEnoughArgs, InvalidPort from ..base import CheckerBaseHandler, NotEnoughArgs, InvalidPort, process_args_for_host_port
web_help_message = """ web_help_message = """
Производит проверку хоста по протоколу HTTP. Производит проверку хоста по протоколу HTTP.
@ -36,18 +35,7 @@ class WebCheckerHandler(CheckerBaseHandler):
) )
async def process_args(self, text: str) -> list: async def process_args(self, text: str) -> list:
port = None return process_args_for_host_port(text, 80)
args = text.split(" ")
if len(args) < 2:
raise NotEnoughArgs()
if len(args) == 3:
port = args[2]
if not check_int(port):
raise InvalidPort()
if len(args) == 2:
port = 80
host = args[1]
return [host, port]
async def prepare_message(self, res: Response): async def prepare_message(self, res: Response):
message, status = await self.message_std_vals(res) message, status = await self.message_std_vals(res)