Files

53 lines
1.6 KiB
Python

import re
from .constants import BACKEND_TELEGRAM, PREFIXES
from .models import Command
NAME_RE = re.compile(r"^[a-z][a-z0-9_]{0,31}$")
QUOTES = {'"': '"', "“": "”", "„": "“"}
def tokenize(text: str) -> list[str]:
tokens: list[str] = []
current: list[str] = []
in_token = False
closing: str | None = None
for char in text:
if closing:
if char == closing:
closing = None
else:
current.append(char)
elif char in QUOTES and not in_token:
closing, in_token = QUOTES[char], True
elif char.isspace():
if in_token:
tokens.append("".join(current))
current, in_token = [], False
else:
current.append(char)
in_token = True
if in_token:
tokens.append("".join(current))
return tokens
def parse(backend: str, text: str, bot_name: str | None = None) -> Command | None:
prefix = PREFIXES.get(backend)
text = text.strip()
if not prefix or not text.startswith(prefix):
return None
body = text[len(prefix):]
if not body or body[0].isspace():
return None
parts = body.split(None, 1)
head, rest = parts[0], parts[1] if len(parts) > 1 else ""
head, _, addressed = head.partition("@")
if addressed and (backend != BACKEND_TELEGRAM or (bot_name and addressed.lower() != bot_name.lower().lstrip("@"))):
return None
name = head.lower()
if not NAME_RE.match(name):
return None
rest = rest.strip()
return Command(name, tuple(tokenize(rest)), rest)