Adauga comenzi Telegram pentru solduri si repara get_telegram_chat_id

- Adauga /scrape_solduri - scraping rapid doar solduri (fara CSV tranzactii)
- Adauga /solduri - afisare instant solduri din cache (fara 2FA)
- Redenumeste comenzi pentru consistenta
- Adauga suport BALANCES_ONLY in scraper (skip download tranzactii)
- Repara get_telegram_chat_id.py - elimina input() interactiv
- Imbunatateste output get_telegram_chat_id.py cu info bot si formatare

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-11 01:03:02 +02:00
parent 7e8dadcbdc
commit e2ec15939c
3 changed files with 163 additions and 62 deletions

View File

@@ -9,6 +9,7 @@ import io
import subprocess
import logging
import json
import csv
import zipfile
from pathlib import Path
from datetime import datetime
@@ -65,6 +66,8 @@ class TelegramTriggerBot:
commands = [
{"command": "scrape", "description": "Rulează scraper-ul BTGO"},
{"command": "scrape_zip", "description": "Rulează scraper + trimite ZIP"},
{"command": "scrape_solduri", "description": "Extrage doar soldurile (fără CSV)"},
{"command": "solduri", "description": "Afișează ultimul fișier solduri"},
{"command": "zip", "description": "Trimite ultimele fișiere ca ZIP"},
{"command": "status", "description": "Status sistem"},
{"command": "help", "description": "Ajutor comenzi"}
@@ -108,11 +111,12 @@ class TelegramTriggerBot:
return True
return user_id in self.allowed_users
def run_scraper(self, chat_id, reply_to_message_id=None, send_as_zip=False):
def run_scraper(self, chat_id, reply_to_message_id=None, send_as_zip=False, balances_only=False):
"""Execută scraper-ul"""
# Trimite mesaj inițial și salvează message_id pentru editare ulterioară
zip_msg = " (arhiva ZIP)" if send_as_zip else ""
response = self.send_message(chat_id, f"*BTGO Scraper pornit{zip_msg}*\n\nAsteapta 2FA pe telefon.", reply_to_message_id)
balances_msg = " - DOAR SOLDURI" if balances_only else ""
response = self.send_message(chat_id, f"*BTGO Scraper pornit{zip_msg}{balances_msg}*\n\nAsteapta 2FA pe telefon.", reply_to_message_id)
message_id = None
try:
message_id = response.json()['result']['message_id']
@@ -122,7 +126,7 @@ class TelegramTriggerBot:
try:
# Rulează scraper-ul
logging.info(f"Pornire scraper (send_as_zip={send_as_zip})...")
logging.info(f"Pornire scraper (send_as_zip={send_as_zip}, balances_only={balances_only})...")
# Prepare environment with global playwright path + Telegram progress info
env = os.environ.copy()
@@ -138,6 +142,11 @@ class TelegramTriggerBot:
if send_as_zip:
env['SEND_AS_ZIP'] = 'true'
logging.info("Mod ZIP activat - va trimite arhivă ZIP")
# Dacă balances_only, comunică să nu descarce tranzacții
if balances_only:
env['BALANCES_ONLY'] = 'true'
logging.info("Mod DOAR SOLDURI activat - nu va descărca tranzacții")
else:
logging.warning("No message_id available for progress updates")
@@ -172,6 +181,59 @@ class TelegramTriggerBot:
logging.error(f"Eroare execuție: {e}")
self.send_message(chat_id, f"*EROARE EXECUTIE*\n\n```\n{str(e)}\n```", reply_to_message_id)
def show_cached_balances(self, chat_id, reply_to_message_id=None):
"""Afișează soldurile din cel mai recent fișier solduri.csv"""
try:
data_dir = Path('data')
if not data_dir.exists():
self.send_message(chat_id, "*EROARE*\n\nDirectorul 'data' nu există!", reply_to_message_id)
return
# Găsește ultimul fișier solduri
solduri_files = sorted(data_dir.glob('solduri_*.csv'), key=lambda x: x.stat().st_mtime, reverse=True)
if not solduri_files:
self.send_message(chat_id, "*EROARE*\n\nNu s-au găsit fișiere solduri!", reply_to_message_id)
return
latest_solduri = solduri_files[0]
solduri_time = latest_solduri.stat().st_mtime
file_datetime = datetime.fromtimestamp(solduri_time).strftime('%Y-%m-%d %H:%M:%S')
# Citește fișierul CSV
accounts = []
with open(latest_solduri, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
accounts.append({
'nume_cont': row['nume_cont'],
'sold': float(row['sold']),
'moneda': row['moneda']
})
# Construiește mesaj cu solduri
total_ron = sum(acc['sold'] for acc in accounts if acc.get('moneda') == 'RON')
message = f"*SOLDURI BANCARE*\n\n"
message += f"Data: {file_datetime}\n"
message += f"Conturi: {len(accounts)}\n\n"
for acc in accounts:
nume = acc['nume_cont']
sold = acc['sold']
moneda = acc['moneda']
message += f"{nume}: {sold:,.2f} {moneda}\n"
message += f"\n*TOTAL: {total_ron:,.2f} RON*"
self.send_message(chat_id, message, reply_to_message_id)
logging.info(f"Afișat solduri cached din {latest_solduri.name}")
except Exception as e:
logging.error(f"Eroare show_cached_balances: {e}", exc_info=True)
self.send_message(chat_id, f"*EROARE*\n\n```\n{str(e)}\n```", reply_to_message_id)
def send_zip_files(self, chat_id, reply_to_message_id=None):
"""Trimite ultimele fișiere ca arhivă ZIP"""
try:
@@ -332,8 +394,10 @@ class TelegramTriggerBot:
welcome_msg += f"Bot activ in grupul *{chat_title}*\n\n"
welcome_msg += (
"Comenzi disponibile:\n"
"`/scrape` - Ruleaza scraper-ul\n"
"`/scrape` - Ruleaza scraper-ul complet\n"
"`/scrape_zip` - Ruleaza scraper + trimite ZIP\n"
"`/scrape_solduri` - Extrage doar soldurile (rapid)\n"
"`/solduri` - Afiseaza ultimul fisier solduri\n"
"`/zip` - Trimite ultimele fisiere ca ZIP\n"
"`/status` - Status sistem\n"
"`/help` - Ajutor"
@@ -348,6 +412,14 @@ class TelegramTriggerBot:
logging.info(f"Comandă /scrape_zip primită în {context}")
self.run_scraper(chat_id, message_id, send_as_zip=True)
elif text == '/scrape_solduri':
logging.info(f"Comandă /scrape_solduri primită în {context}")
self.run_scraper(chat_id, message_id, balances_only=True)
elif text == '/solduri':
logging.info(f"Comandă /solduri primită în {context}")
self.show_cached_balances(chat_id, message_id)
elif text == '/zip':
logging.info(f"Comandă /zip primită în {context}")
self.send_zip_files(chat_id, message_id)
@@ -381,20 +453,25 @@ class TelegramTriggerBot:
"*COMENZI:*\n"
"`/scrape` - Ruleaza scraper + trimite fisiere individuale\n"
"`/scrape_zip` - Ruleaza scraper + trimite arhiva ZIP\n"
"`/scrape_solduri` - Extrage doar soldurile (fara CSV tranzactii)\n"
"`/solduri` - Afiseaza ultimul fisier solduri (instant)\n"
"`/zip` - Trimite ultimele fisiere ca arhiva ZIP (fara scraping)\n"
"`/status` - Informatii sistem\n"
"`/help` - Acest mesaj\n\n"
"*GHID SCRAPER:*\n"
"1. Trimite `/scrape` sau `/scrape_zip`\n"
"1. Trimite `/scrape`, `/scrape_zip` sau `/scrape_solduri`\n"
"2. Asteapta notificarea de 2FA pe telefon\n"
"3. Aproba in aplicatia George\n"
"4. Primesti fisierele automat\n\n"
"*DIFERENTE:*\n"
"• `/scrape` - Fisiere individuale (CSV + JSON)\n"
"• `/scrape_zip` - Un singur ZIP cu toate fisierele\n"
"• `/zip` - Rapid, foloseste datele existente\n\n"
"• `/scrape_solduri` - Doar solduri (RAPID - fara CSV tranzactii)\n"
"• `/solduri` - Vizualizare rapida (fara 2FA)\n"
"• `/zip` - Fisiere existente (fara scraping)\n\n"
"*NOTE:*\n"
"- Scraper-ul ruleaza ~2-3 minute\n"
"- Scraper complet: ~2-3 minute\n"
"- Scraper solduri: ~30-40 secunde\n"
"- VM-ul trebuie sa aiba browser vizibil"
)
self.send_message(chat_id, help_msg, message_id)