From 735b282179e6bbd95f1047ed128660d74a3237d2 Mon Sep 17 00:00:00 2001 From: Marius Mutu Date: Fri, 29 May 2026 13:35:15 +0000 Subject: [PATCH] automatic --- config.json | 2 +- cron/jobs.json | 30 ++++++++--------- memory/kb/index.json | 34 ++++++++++++++++--- src/adapters/discord_bot.py | 47 ++++++++++++++++++++------- tools/anaf-monitor/hashes.json | 2 +- tools/anaf-monitor/snapshots/D100.txt | 2 +- tools/anaf-monitor/versions.json | 4 +-- tools/email_digest.py | 6 ++-- tools/email_forward.py | 6 ++-- 9 files changed, 92 insertions(+), 41 deletions(-) diff --git a/config.json b/config.json index e81b8dc..dc3dda9 100644 --- a/config.json +++ b/config.json @@ -109,7 +109,7 @@ "949388626146517022" ], "user_name": "Marius", - "default_voice": "M2", + "default_voice": "F1", "auto_leave_minutes": 5 }, "paths": { diff --git a/cron/jobs.json b/cron/jobs.json index f519fa1..cace59f 100644 --- a/cron/jobs.json +++ b/cron/jobs.json @@ -23,9 +23,9 @@ "report_on": "changes", "timeout": 120, "enabled": true, - "last_run": "2026-05-28T16:00:00.002254+00:00", + "last_run": "2026-05-29T10:00:00.003600+00:00", "last_status": "ok", - "next_run": "2026-05-29T10:00:00+00:00" + "next_run": "2026-05-29T16:00:00+00:00" }, { "name": "security-audit-daily", @@ -39,9 +39,9 @@ "report_on": "changes", "timeout": 180, "enabled": true, - "last_run": "2026-05-28T03:00:00.003748+00:00", - "last_status": "ok", - "next_run": "2026-05-29T03:00:00+00:00" + "last_run": "2026-05-29T03:00:00.002043+00:00", + "last_status": "error", + "next_run": "2026-05-30T03:00:00+00:00" }, { "name": "kb-index-refresh", @@ -55,9 +55,9 @@ "report_on": "never", "timeout": 120, "enabled": true, - "last_run": "2026-05-28T03:30:00.003004+00:00", + "last_run": "2026-05-29T03:30:00.002139+00:00", "last_status": "ok", - "next_run": "2026-05-29T03:30:00+00:00" + "next_run": "2026-05-30T03:30:00+00:00" }, { "name": "archive-tasks-daily", @@ -71,9 +71,9 @@ "report_on": "changes", "timeout": 60, "enabled": true, - "last_run": "2026-05-28T03:00:00.003258+00:00", + "last_run": "2026-05-29T03:00:00.001515+00:00", "last_status": "ok", - "next_run": "2026-05-29T03:00:00+00:00" + "next_run": "2026-05-30T03:00:00+00:00" }, { "name": "backup-config", @@ -87,9 +87,9 @@ "report_on": "never", "timeout": 120, "enabled": true, - "last_run": "2026-05-28T02:00:00.003039+00:00", + "last_run": "2026-05-29T02:00:00.002948+00:00", "last_status": "ok", - "next_run": "2026-05-29T02:00:00+00:00" + "next_run": "2026-05-30T02:00:00+00:00" }, { "name": "insights-extract", @@ -255,9 +255,9 @@ "prompt": "Heartbeat check. Rulează src/heartbeat.py printr-un scurt raport de status.\nDacă nu e nimic de raportat (email=0, calendar nu are evenimente <2h, kb ok), răspunde doar cu HEARTBEAT_OK și oprește-te — nu trimite mesaj.\nDacă e ceva: raport scurt pe Discord #echo-work.", "allowed_tools": [], "enabled": true, - "last_run": "2026-05-28T18:00:00.001555+00:00", + "last_run": "2026-05-29T12:00:00.002840+00:00", "last_status": "ok", - "next_run": "2026-05-29T06:00:00+00:00" + "next_run": "2026-05-29T14:00:00+00:00" }, { "name": "night-execute", @@ -271,8 +271,8 @@ "Read", "Write" ], - "last_run": "2026-05-27T23:00:00.001391+00:00", + "last_run": "2026-05-28T23:00:00.002106+00:00", "last_status": "ok", - "next_run": "2026-05-28T23:00:00+00:00" + "next_run": "2026-05-29T23:00:00+00:00" } ] diff --git a/memory/kb/index.json b/memory/kb/index.json index 02aea6c..7607fcb 100644 --- a/memory/kb/index.json +++ b/memory/kb/index.json @@ -1,5 +1,31 @@ { "notes": [ + { + "file": "notes-data/emails/2026-05-29_fwd-invitatie-festivalul-luminii-brasov-2026.md", + "title": "***SPAM*** Fwd: Invitație – Festivalul Luminii Brașov 2026", + "date": "2026-05-29", + "tags": [], + "domains": [], + "types": [], + "category": "emails", + "project": null, + "subdir": null, + "video": "", + "tldr": "" + }, + { + "file": "notes-data/emails/2026-05-28_fwd-newsletter-20-din-2026.md", + "title": "Newsletter 20 din 2026", + "date": "2026-05-28", + "tags": [], + "domains": [], + "types": [], + "category": "emails", + "project": null, + "subdir": null, + "video": "", + "tldr": "" + }, { "file": "notes-data/facebook/2026-05-26_500k-views-4-8k-reactions.md", "title": "500K views · 4.8K reactions", @@ -9157,8 +9183,8 @@ "title": "Proiect: Vending Master - Integrare Website → ROA", "date": "2026-01-30", "tags": [ - "vending-master", - "integrare" + "integrare", + "vending-master" ], "domains": [ "work" @@ -9638,7 +9664,7 @@ } ], "stats": { - "total": 556, + "total": 558, "by_domain": { "work": 182, "health": 100, @@ -9650,7 +9676,7 @@ "articole": 1, "coaching": 51, "conversations": 0, - "emails": 22, + "emails": 24, "exercitii": 4, "facebook": 8, "health": 6, diff --git a/src/adapters/discord_bot.py b/src/adapters/discord_bot.py index 4d59bfd..6549c8b 100644 --- a/src/adapters/discord_bot.py +++ b/src/adapters/discord_bot.py @@ -889,6 +889,25 @@ def create_bot(config: Config) -> discord.Client: f"Error reading logs: {e}", ephemeral=True ) + def _wav_to_ogg(wav_path: str) -> str: + """Convertește WAV → OGG Opus pentru upload Discord (10x mai mic). Returnează path-ul OGG.""" + import subprocess, tempfile + ogg_path = wav_path.replace(".wav", ".ogg") + if not ogg_path.endswith(".ogg"): + ogg_path = wav_path + ".ogg" + try: + subprocess.run( + [ + "/home/moltbot/.local/bin/ffmpeg", "-y", "-i", wav_path, + "-c:a", "libopus", "-b:a", "24k", "-ar", "24000", ogg_path, + ], + capture_output=True, + timeout=30, + ) + return ogg_path if os.path.exists(ogg_path) else wav_path + except Exception: + return wav_path + @tree.command(name="audio", description="TTS: convertește text sau URL în voice note") @app_commands.describe( voce="Voce (M1-M5 masculin, F1-F5 feminin; default M2)", @@ -930,17 +949,20 @@ def create_bot(config: Config) -> discord.Client: result = await asyncio.to_thread(fast_dispatch, "audio", [voice, chunk]) if result and result.startswith("__AUDIO__:"): wav_path = result[len("__AUDIO__:"):] + ogg_path = await asyncio.to_thread(_wav_to_ogg, wav_path) try: - filename = f"echo-audio-{i}din{total}.wav" if total > 1 else "echo-audio.wav" + ext = "ogg" if ogg_path.endswith(".ogg") else "wav" + filename = f"echo-audio-{i}din{total}.{ext}" if total > 1 else f"echo-audio.{ext}" await interaction.followup.send( content=f"Bucata {i}/{total}" if total > 1 else None, - file=discord.File(wav_path, filename=filename), + file=discord.File(ogg_path, filename=filename), ) finally: - try: - os.unlink(wav_path) - except OSError: - pass + for p in {wav_path, ogg_path}: + try: + os.unlink(p) + except OSError: + pass else: await interaction.followup.send(result or f"Eroare TTS la bucata {i}.") return @@ -957,15 +979,18 @@ def create_bot(config: Config) -> discord.Client: result = await asyncio.to_thread(fast_dispatch, "audio", args) if result and result.startswith("__AUDIO__:"): wav_path = result[len("__AUDIO__:"):] + ogg_path = await asyncio.to_thread(_wav_to_ogg, wav_path) try: + ext = "ogg" if ogg_path.endswith(".ogg") else "wav" await interaction.followup.send( - file=discord.File(wav_path, filename="echo-audio.wav") + file=discord.File(ogg_path, filename=f"echo-audio.{ext}") ) finally: - try: - os.unlink(wav_path) - except OSError: - pass + for p in {wav_path, ogg_path}: + try: + os.unlink(p) + except OSError: + pass else: await interaction.followup.send(result or "Eroare TTS.") diff --git a/tools/anaf-monitor/hashes.json b/tools/anaf-monitor/hashes.json index ba83ec1..b55c22f 100644 --- a/tools/anaf-monitor/hashes.json +++ b/tools/anaf-monitor/hashes.json @@ -1,5 +1,5 @@ { - "D100": "126ebae8fc65d7ae19c9fe14e755c6421152aac16b19abf7fafeaa34aa87cafe", + "D100": "27cf97a4d10c8529669d95b2d96ca3c9b41f7e4e50091dce19cf8af117f0ac4a", "D101": "f72fc1c29657ea11e0238806a28f6abccf5b00e45904e1e0c9385cc64491fcaf", "D300": "cb7b55b568ab893024884971eac0367fb6fe487c297e355d64258dae437f6ddd", "D394": "c4c4e62bda30032f12c17edf9a5087b6173a350ccb1fd750158978b3bd0acb7d", diff --git a/tools/anaf-monitor/snapshots/D100.txt b/tools/anaf-monitor/snapshots/D100.txt index 84cb45d..8e18061 100644 --- a/tools/anaf-monitor/snapshots/D100.txt +++ b/tools/anaf-monitor/snapshots/D100.txt @@ -62,7 +62,7 @@ valabil începand cu 01/2024 - publicat în data de 09.02.2024 soft A actualizat în data de -22.05.2026 +29.05.2026 soft J* actualizat în data de 25.05.2026 diff --git a/tools/anaf-monitor/versions.json b/tools/anaf-monitor/versions.json index 5a1fd49..acbed8d 100644 --- a/tools/anaf-monitor/versions.json +++ b/tools/anaf-monitor/versions.json @@ -1,7 +1,7 @@ { "D100": { - "soft_a_url": "http://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D100_710_XML_0126_220526.pdf", - "soft_a_date": "22.05.2026", + "soft_a_url": "http://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D100_710_XML_0126_290526.pdf", + "soft_a_date": "29.05.2026", "soft_j_url": "http://static.anaf.ro/static/10/Anaf/Declaratii_R/AplicatiiDec/D100_22052026.zip", "soft_j_date": "22.05.2026" }, diff --git a/tools/email_digest.py b/tools/email_digest.py index 83816ad..75106ba 100644 --- a/tools/email_digest.py +++ b/tools/email_digest.py @@ -47,7 +47,7 @@ def get_owner_jid() -> str: return f"{owner}@s.whatsapp.net" -def fetch_unread_emails() -> list[dict]: +def fetch_unread_emails(skip_whitelist: bool = False) -> list[dict]: """Preia emailurile necitite din inbox fără a salva KB notes.""" mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT) mail.login(IMAP_USER, IMAP_PASS) @@ -66,7 +66,7 @@ def fetch_unread_emails() -> list[dict]: from_addr = decode_mime_header(msg['From']) sender_email = extract_sender_email(from_addr) - if sender_email not in WHITELIST: + if not skip_whitelist and sender_email not in WHITELIST: continue attachment_data = {} @@ -197,7 +197,7 @@ def send_whatsapp_document(to: str, filename: str, data: bytes) -> bool: def run_digest(): print("Verific emailuri necitite...") - emails = fetch_unread_emails() + emails = fetch_unread_emails(skip_whitelist=True) owner_jid = get_owner_jid() diff --git a/tools/email_forward.py b/tools/email_forward.py index 569f4c7..3dd8405 100644 --- a/tools/email_forward.py +++ b/tools/email_forward.py @@ -151,7 +151,7 @@ def send_whatsapp_document(to: str, filename: str, data: bytes) -> bool: return False -def fetch_unread_emails(): +def fetch_unread_emails(skip_whitelist: bool = False): """Preia emailurile necitite din inbox fără a le salva sau marca ca citite.""" mail = imaplib.IMAP4_SSL(IMAP_SERVER, IMAP_PORT) mail.login(IMAP_USER, IMAP_PASS) @@ -171,7 +171,7 @@ def fetch_unread_emails(): from_addr = decode_mime_header(msg['From']) sender_email = extract_sender_email(from_addr) - if sender_email not in WHITELIST: + if not skip_whitelist and sender_email not in WHITELIST: continue # Extract attachment data (name → bytes) @@ -216,7 +216,7 @@ def mark_as_seen(email_ids: list[str]) -> None: def run_forward(): print("Verific emailuri necitite...") - emails = fetch_unread_emails() + emails = fetch_unread_emails(skip_whitelist=True) owner_jid = get_owner_jid()