diff --git a/BOTFATHER_COMMANDS.txt b/BOTFATHER_COMMANDS.txt index fce9120..f34070e 100644 --- a/BOTFATHER_COMMANDS.txt +++ b/BOTFATHER_COMMANDS.txt @@ -28,7 +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 +logs - Show last 50 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/application_handler.py b/application_handler.py index f94c2c6..0ed2f76 100644 --- a/application_handler.py +++ b/application_handler.py @@ -292,8 +292,18 @@ class ApplicationHandler: def has_applied(self, listing_id: str) -> bool: - """Check if we've already applied to this listing.""" - return listing_id in self.load_applications() + """ + Check if we've already applied to this listing. + Excludes baseline entries from first run (not auto-applied). + """ + applications = self.load_applications() + if listing_id not in applications: + return False + app = applications[listing_id] + # If message contains "First run, not auto-applied", treat as not applied + if "First run, not auto-applied" in app.get("message", ""): + return False + return True def load_previous_listings(self) -> dict: diff --git a/main.py b/main.py index 21d2e28..2503f84 100644 --- a/main.py +++ b/main.py @@ -10,20 +10,36 @@ from dotenv import load_dotenv from state_manager import StateManager from pathlib import Path from autoclean_debug import autoclean_debug_material +from datetime import datetime, timezone +import time # --- Environment & Logging Setup --- # Load environment variables from .env file load_dotenv() +# Custom formatter with Berlin timezone (UTC+1) +class BerlinFormatter(logging.Formatter): + def formatTime(self, record, datefmt=None): + dt = datetime.fromtimestamp(record.created, tz=timezone.utc) + # Berlin is UTC+1 (CET) or UTC+2 (CEST), using UTC+1 for simplicity + berlin_dt = dt.astimezone(timezone(timedelta(hours=1))) + if datefmt: + return berlin_dt.strftime(datefmt) + return berlin_dt.strftime("%Y-%m-%d %H:%M:%S,%f")[:-3] + +from datetime import timedelta + # Configure logging: file (rotating) + console for Docker visibility, enforce for all modules +file_handler = RotatingFileHandler("data/monitor.log", maxBytes=1 * 1024 * 1024, backupCount=3) +file_handler.setFormatter(BerlinFormatter("%(asctime)s [%(levelname)-5s] %(name)-20s | %(message)s")) + +console_handler = logging.StreamHandler() +console_handler.setFormatter(BerlinFormatter("%(asctime)s [%(levelname)-5s] %(name)-20s | %(message)s")) + logging.basicConfig( level=logging.INFO, - format="%(asctime)s [%(levelname)-5s] %(name)-20s | %(message)s", - handlers=[ - RotatingFileHandler("data/monitor.log", maxBytes=1 * 1024 * 1024, backupCount=3), - logging.StreamHandler() - ], + handlers=[file_handler, console_handler], force=True # Enforce for all modules, Python 3.8+ ) logger = logging.getLogger(__name__) # Use named logger