Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docs/PROJECT_INVENTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
| Метрика | Значение |
|---|---:|
| Package version | `19.9.0` |
| Стабильных tracked-файлов | 6,370 |
| Строк | 612,637 |
| Стабильных tracked-файлов | 6,371 |
| Строк | 612,727 |
| Размер | 24.99 MiB |
| Python-файлов | 3,524 |
| Строк Python | 362,343 |
| Классов / функций / async | 2,988 / 20,004 / 1,636 |
| Python-файлов | 3,525 |
| Строк Python | 362,433 |
| Классов / функций / async | 2,988 / 20,008 / 1,636 |
| Python syntax errors | 0 |
| Test Python files / test functions | 972 / 6,728 |
| Markdown-файлов | 2,046 |
Expand All @@ -29,7 +29,7 @@
| `docs` | 477 | 76,067 | 3.27 MiB |
| `tests` | 554 | 71,349 | 2.48 MiB |
| `[root]` | 217 | 35,241 | 1.39 MiB |
| `scripts` | 280 | 33,755 | 1.28 MiB |
| `scripts` | 281 | 33,845 | 1.28 MiB |
| `attic` | 33 | 30,669 | 1.61 MiB |
| `octopus_services` | 110 | 27,850 | 0.90 MiB |
| `tg_bot` | 34 | 12,812 | 0.65 MiB |
Expand All @@ -49,7 +49,7 @@

| Расширение | Файлов |
|---|---:|
| `.py` | 3,524 |
| `.py` | 3,525 |
| `.md` | 2,046 |
| `.json` | 147 |
| `.service` | 135 |
Expand Down
90 changes: 90 additions & 0 deletions scripts/send_trading_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env python3
"""Send the detailed trading report (Трейдинг button content) to the owner's
Telegram chat: data chunks immediately, LLM section after generation."""

import json
import sys
import urllib.request
from pathlib import Path

ROOT = Path("/root/AIOS")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: ROOT = Path("/root/AIOS") — This script is so committed to its /root/AIOS address that it won't even consider running anywhere else. It's the "I only date people from my hometown" of Python scripts.

🩹 The Fix:

Suggested change
ROOT = Path("/root/AIOS")
ROOT = Path(__file__).resolve().parent.parent

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

sys.path.insert(0, str(ROOT))


def _env(key: str) -> str:
if key in ("AIOS_TELEGRAM_TOKEN", "TELEGRAM_BOT_TOKEN"):
from tg_bot.credentials import secret_from_env_or_credential
value = secret_from_env_or_credential(
"AIOS_TELEGRAM_TOKEN", "TELEGRAM_BOT_TOKEN", credential="telegram_token"
)
if value:
return value
if key in ("TELEGRAM_CHAT_ID", "AIOS_OWNER_CHAT_ID"):
from tg_bot.credentials import read_systemd_credential
value = read_systemd_credential("telegram_owner_chat_id")
if value:
return value
import os
v = os.environ.get(key, "")
if v:
return v
p = ROOT / ".env"
if p.exists():
for line in p.read_text(encoding="utf-8").splitlines():
line = line.strip()
if line.startswith(key + "="):
return line.split("=", 1)[1].strip().strip('"').strip("'")
return ""


def _post(payload: dict, token: str) -> tuple[bool, str]:
req = urllib.request.Request(
f"https://api.telegram.org/bot{token}/sendMessage",
data=json.dumps(payload).encode(),
headers={"Content-Type": "application/json"})
try:
with urllib.request.urlopen(req, timeout=60) as resp:
data = json.loads(resp.read())
return bool(data.get("ok")), data.get("description", "")
except urllib.error.HTTPError as exc:
return False, exc.read().decode(errors="replace")[:300]
except Exception as exc:
return False, str(exc)


def tg_send(text: str) -> tuple[bool, str]:
token = _env("TELEGRAM_BOT_TOKEN") or _env("AIOS_TELEGRAM_TOKEN")
chat = _env("TELEGRAM_CHAT_ID") or _env("AIOS_OWNER_CHAT_ID")
if not token or not chat:
return False, "no credentials"
base = {
"chat_id": int(chat),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: "chat_id": int(chat) — Converting to int() with the optimism of a golden retriever. If chat contains a single non-numeric character, this script crashes harder than a cron job at 3 AM.

🩹 The Fix:

Suggested change
"chat_id": int(chat),
"chat_id": int(chat) if str(chat).lstrip("-").isdigit() else chat,

📏 Severity: warning


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"text": text[:3900],
"disable_web_page_preview": True,
}
ok, err = _post({**base, "parse_mode": "HTML"}, token)
if ok:
return True, ""
# HTML-режим мог сломаться о символы в LLM-тексте — ретрай без разметки
ok2, err2 = _post(base, token)
return ok2, f"html:{err[:80]}; plain:{err2[:120]}"


def main() -> int:
from tg_bot.trading_report import full_report

messages = full_report()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥 The Roast: messages = full_report() — Calling an external function with all the safety precautions of a base jumper without a parachute. If full_report() raises, the script exits with a stack trace instead of a graceful error.

🩹 The Fix:

Suggested change
messages = full_report()
try:
messages = full_report()
except Exception as exc:
print(f"failed to generate report: {exc}")
return 1

📏 Severity: suggestion


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

sent = 0
for i, msg in enumerate(messages, 1):
ok, err = tg_send(msg)
if ok:
sent += 1
print(f"chunk {i}/{len(messages)}: sent ({len(msg)} chars)")
else:
print(f"chunk {i}/{len(messages)}: FAIL {err[:200]}")
print(f"total sent: {sent}/{len(messages)}")
return 0 if sent == len(messages) else 1


if __name__ == "__main__":
raise SystemExit(main())
Loading