automatic

This commit is contained in:
2026-05-29 13:35:15 +00:00
parent c401204fa2
commit 735b282179
9 changed files with 92 additions and 41 deletions

View File

@@ -109,7 +109,7 @@
"949388626146517022"
],
"user_name": "Marius",
"default_voice": "M2",
"default_voice": "F1",
"auto_leave_minutes": 5
},
"paths": {

View File

@@ -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"
}
]

View File

@@ -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": "<!-- Echo: completează cu rezumat -->"
},
{
"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": "<!-- Echo: completează cu rezumat -->"
},
{
"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,

View File

@@ -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.")

View File

@@ -1,5 +1,5 @@
{
"D100": "126ebae8fc65d7ae19c9fe14e755c6421152aac16b19abf7fafeaa34aa87cafe",
"D100": "27cf97a4d10c8529669d95b2d96ca3c9b41f7e4e50091dce19cf8af117f0ac4a",
"D101": "f72fc1c29657ea11e0238806a28f6abccf5b00e45904e1e0c9385cc64491fcaf",
"D300": "cb7b55b568ab893024884971eac0367fb6fe487c297e355d64258dae437f6ddd",
"D394": "c4c4e62bda30032f12c17edf9a5087b6173a350ccb1fd750158978b3bd0acb7d",

View File

@@ -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

View File

@@ -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"
},

View File

@@ -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()

View File

@@ -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()