from sopel import plugin
import time
from threading import Timer
from datetime import datetime, timedelta
import json
import os
# Emlékeztetők tárolásának fájl elérési útja
REMINDER_FILE = '/home/ai/.sopel/plugins/notify/reminders.json'
# Szótár a timer objektumok tárolására
timer_objects = {}
# Biztosítjuk, hogy a könyvtár létezzen
os.makedirs(os.path.dirname(REMINDER_FILE), exist_ok=True)
def load_reminders():
"""Emlékeztetők betöltése fájlból és időbélyegek átalakítása datetime objektumokká."""
try:
with open(REMINDER_FILE, 'r', encoding='utf-8') as f:
content = f.read()
if not content:
return {}
loaded_data = json.loads(content)
# Átalakítjuk a string típusú időpontokat datetime objektumokká
for username, reminders_list in loaded_data.items():
for reminder in reminders_list:
if isinstance(reminder['time'], str):
reminder['time'] = datetime.strptime(reminder['time'], '%Y-%m-%d %H:%M:%S')
return loaded_data
except (FileNotFoundError, json.JSONDecodeError):
return {}
def save_reminders(reminders):
"""Emlékeztetők mentése fájlba, datetime objektumok stringgé alakítása."""
serializable_reminders = {}
for username, reminders_list in reminders.items():
serializable_reminders[username] = []
for reminder in reminders_list:
reminder_copy = reminder.copy()
if isinstance(reminder_copy['time'], datetime):
reminder_copy['time'] = reminder_copy['time'].strftime('%Y-%m-%d %H:%M:%S')
serializable_reminders[username].append(reminder_copy)
with open(REMINDER_FILE, 'w', encoding='utf-8') as f:
json.dump(serializable_reminders, f, ensure_ascii=False)
def send_reminder(bot, username, reminder_id, reminder_message):
"""Emlékeztető küldése a felhasználónak és az emlékeztető adatainak törlése."""
try:
bot.say(f"@{username} - {reminder_message}")
# Emlékeztetők betöltése fájlból
reminders = load_reminders()
if username in reminders:
# Az elküldött emlékeztető kiszűrése az id alapján
reminders[username] = [r for r in reminders[username] if r['id'] != reminder_id]
# Ha nincs több emlékeztető a felhasználónak, töröljük a felhasználó kulcsát
if not reminders[username]:
del reminders[username]
# Frissített emlékeztetők mentése fájlba
save_reminders(reminders)
# Timer objektum törlése, ha létezik
timer_key = f"{username}_{reminder_id}"
if timer_key in timer_objects:
del timer_objects[timer_key]
except Exception as e:
bot.say(f"Hiba történt {username} emlékeztetőjének küldésekor: {e}")
def check_existing_reminders(bot):
"""Ellenőrzi az elmaradt emlékeztetőket és újraütemezi a jövőbeli emlékeztetőket."""
now = datetime.now()
reminders = load_reminders()
for username, reminders_to_process in reminders.items():
for reminder_data in reminders_to_process:
reminder_time = reminder_data['time']
# Biztosítjuk, hogy reminder_time egy datetime objektum
if isinstance(reminder_time, str):
reminder_time = datetime.strptime(reminder_time, '%Y-%m-%d %H:%M:%S')
if reminder_time <= now:
# Az elmaradt emlékeztető azonnali küldése
send_reminder(bot, username, reminder_data['id'],
f"{reminder_data['message']} (Elmaradt emlékeztető {reminder_time.strftime('%Y-%m-%d %H:%M:%S')}-ról)")
# Emlékeztetők újra betöltése és elmaradtak eltávolítása
reminders = load_reminders()
reminders[username] = [r for r in reminders[username] if r['id'] != reminder_data['id']]
if not reminders[username]:
del reminders[username]
save_reminders(reminders)
# Timer objektum törlése
timer_key = f"{username}_{reminder_data['id']}"
if timer_key in timer_objects:
del timer_objects[timer_key]
else:
# Jövőbeli emlékeztetők ütemezése
delay = (reminder_time - now).total_seconds()
if delay > 0:
timer = Timer(delay, send_reminder,
[bot, username, reminder_data['id'], reminder_data['message']])
timer.start()
timer_objects[f"{username}_{reminder_data['id']}"] = timer
@plugin.event('READY')
def on_ready(bot, trigger):
"""Emlékeztetők inicializálása, amikor a bot elindul."""
try:
reminders = load_reminders()
check_existing_reminders(bot)
# Rendszeres időzítő beállítása, hogy 5 percenként ellenőrizze az elmaradt emlékeztetőket
check_timer = Timer(300, check_existing_reminders, [bot]) # 300 másodperc = 5 perc
check_timer.start()
timer_objects['check_existing_reminders'] = check_timer
except Exception as e:
bot.say(f"Hiba történt az emlékeztetők ellenőrzésekor: {e}")
@plugin.event('SHUTDOWN')
def on_shutdown(bot, trigger):
"""Időzítők törlése, amikor a bot leáll."""
for timer in timer_objects.values():
if timer.is_alive():
timer.cancel()
timer_objects.clear()
@plugin.rule(r'\[(\S+)\]!ora ?(\d+)(m|h|d) ?(.*)')
def set_reminder(bot, trigger):
"""Új emlékeztető beállítása, amikor a szabály illeszkedik."""
try:
username = trigger.group(1)
time_value = int(trigger.group(2))
time_unit = trigger.group(3)
reminder_message = trigger.group(4).strip()
if not reminder_message:
bot.say("Kérlek, adj meg egy emlékeztető üzenetet!")
return
# Idő átváltása másodpercekké
time_units = {'m': 60, 'h': 3600, 'd': 86400}
if time_unit not in time_units:
bot.say("Sajnálom, csak perceket (m), órákat (h) és napokat (d) támogatok.")
return
delay = time_value * time_units[time_unit]
# Emlékeztető időpontjának kiszámítása
reminder_time = datetime.now() + timedelta(seconds=delay)
# Egyedi ID létrehozása
reminder_id = str(int(time.time() * 1000))
# Emlékeztető ütemezése
timer = Timer(delay, send_reminder, [bot, username, reminder_id, reminder_message])
timer.start()
timer_objects[f"{username}_{reminder_id}"] = timer
# Aktuális emlékeztetők betöltése fájlból
reminders = load_reminders()
# Emlékeztető mentése
if username not in reminders:
reminders[username] = []
reminders[username].append({
'id': reminder_id,
'message': reminder_message,
'time': reminder_time
})
save_reminders(reminders)
# Emlékeztető megerősítése
bot.say(f"Emlékeztető beállítva {time_value}{time_unit}-ra/ért. Emlékeztetlek: {reminder_message} - időpont: {reminder_time.strftime('%Y-%m-%d %H:%M:%S')}")
except Exception as e:
bot.say(f"Hiba történt az emlékeztető feldolgozásakor: {e}")
@plugin.rule(r'\[(\S+)\]!orak')
def list_reminders(bot, trigger):
"""Összes aktív emlékeztető felsorolása egy felhasználó számára."""
username = trigger.group(1)
# Emlékeztetők betöltése fájlból, hogy biztosan az aktuális adatokat tartalmazza
reminders = load_reminders()
if username not in reminders or not reminders[username]:
bot.say(f"@{username} nincsenek aktív emlékeztetőid.")
return
bot.say(f"@{username} aktív emlékeztetők:")
for idx, reminder in enumerate(reminders[username], 1):
reminder_time = reminder['time']
if isinstance(reminder_time, str):
reminder_time = datetime.strptime(reminder_time, '%Y-%m-%d %H:%M:%S')
time_left = reminder_time - datetime.now()
days, seconds = time_left.days, time_left.seconds
hours = seconds // 3600
minutes = (seconds % 3600) // 60
time_str = []
if days > 0:
time_str.append(f"{days} nap")
if hours > 0:
time_str.append(f"{hours} óra")
if minutes > 0:
time_str.append(f"{minutes} perc")
time_display = ", ".join(time_str) if time_str else "kevesebb mint 1 perc"
bot.say(f"{idx}. '{reminder['message']}' - {time_display} múlva")
@plugin.rule(r'\[(\S+)\]!delora (\d+)')
def delete_reminder(bot, trigger):
"""Egy adott emlékeztető törlése."""
username = trigger.group(1)
try:
reminder_index = int(trigger.group(2)) - 1
reminders = load_reminders()
if username not in reminders or not reminders[username]:
bot.say(f"@{username} nincsenek aktív emlékeztetőid.")
return
if reminder_index < 0 or reminder_index >= len(reminders[username]):
bot.say(f"@{username} érvénytelen emlékeztető szám. Használhatod a !orak parancsot a listázáshoz.")
return
# Az emlékeztető törlése
reminder_to_delete = reminders[username][reminder_index]
# Timer törlése, ha létezik
timer_key = f"{username}_{reminder_to_delete['id']}"
if timer_key in timer_objects:
if timer_objects[timer_key].is_alive():
timer_objects[timer_key].cancel()
del timer_objects[timer_key]
# Emlékeztető eltávolítása a listából
del reminders[username][reminder_index]
if not reminders[username]:
del reminders[username]
save_reminders(reminders)
bot.say(f"@{username} emlékeztető törölve: '{reminder_to_delete['message']}'")
except (ValueError, IndexError) as e:
bot.say(f"@{username} hiba történt az emlékeztető törlésekor: {e}")