diff --git a/BOTFATHER_COMMANDS.txt b/BOTFATHER_COMMANDS.txt index 3fabcc7..fce9120 100644 --- a/BOTFATHER_COMMANDS.txt +++ b/BOTFATHER_COMMANDS.txt @@ -28,6 +28,7 @@ plot - Show weekly listing patterns (image) errorrate - Show autopilot success vs failure plot (image) retryfailed - Retry all failed applications up to 3 times (excludes deactivated listings) resetlistings - Delete all seen listings (forces re-check of all flats, does not affect stats or WGcompany) +logs - Show last 50 log lines from monitor.log help - Show help and command usage Example: send `/setcommands` to @BotFather, then paste the above lines and confirm. diff --git a/handlers/wgcompany_notifier.py b/handlers/wgcompany_notifier.py index 6022f09..1f11134 100644 --- a/handlers/wgcompany_notifier.py +++ b/handlers/wgcompany_notifier.py @@ -132,8 +132,8 @@ class WGCompanyNotifier: return [] def load_previous_listings(self): - if self.listings_file.exists(): - with open(self.listings_file, 'r') as f: + if WGCOMPANY_LISTINGS_FILE.exists(): + with open(WGCOMPANY_LISTINGS_FILE, 'r') as f: data = json.load(f) logger.debug(f"[WG] Loaded {len(data)} previous listings") return data @@ -142,7 +142,7 @@ class WGCompanyNotifier: def save_listings(self, listings: list[dict]) -> None: listings_dict = {l['id']: l for l in listings} logger.debug(f"[WG] Saving {len(listings_dict)} listings") - with open(self.listings_file, 'w') as f: + with open(WGCOMPANY_LISTINGS_FILE, 'w') as f: json.dump(listings_dict, f, indent=2, ensure_ascii=False) def find_new_listings(self, current: list[dict], previous: dict) -> list[dict]: diff --git a/telegram_bot.py b/telegram_bot.py index 8843a3a..c1e08f8 100644 --- a/telegram_bot.py +++ b/telegram_bot.py @@ -28,6 +28,7 @@ class TelegramBot: "/errorrate - Show autopilot error rate plot\n" "/retryfailed - Retry failed applications\n" "/resetlistings - Reset listings file\n" + "/logs - Show last 50 log lines\n" "/help - Show this help message" ) await self._send_message(help_text) @@ -59,6 +60,32 @@ class TelegramBot: ) logger.info("Monitoring paused via /stop command") + async def _handle_logs_command(self) -> None: + """Send the last 50 lines of the log file.""" + log_file = "data/monitor.log" + try: + if not os.path.exists(log_file): + await self._send_message("📋 No log file found.") + return + + with open(log_file, "r", encoding="utf-8") as f: + lines = f.readlines() + + last_lines = lines[-50:] if len(lines) > 50 else lines + log_text = "".join(last_lines) + + # Truncate if too long for Telegram (4096 char limit) + if len(log_text) > 4000: + log_text = log_text[-4000:] + log_text = "..." + log_text[log_text.find("\n") + 1:] # Start from next newline + + message = f"📋 Last {len(last_lines)} log lines:\n\n
{log_text}"
+ await self._send_message(message)
+ logger.info("Sent last 50 log lines via /logs command")
+ except Exception as e:
+ logger.error(f"Failed to read log file: {e}")
+ await self._send_message(f"❌ Error reading logs: {e}")
+
async def _handle_reset_listings_command(self) -> None:
"""Move listings.json to data/old/ with a timestamp, preserving statistics and application history."""
import shutil
@@ -179,6 +206,8 @@ class TelegramBot:
logger.error(f"/retryfailed command failed: {e}")
elif text == "/resetlistings":
asyncio.run_coroutine_threadsafe(self._handle_reset_listings_command(), loop)
+ elif text == "/logs":
+ asyncio.run_coroutine_threadsafe(self._handle_logs_command(), loop)
elif text.startswith("/"):
asyncio.run_coroutine_threadsafe(self._handle_unknown_command(text), loop)