aboutsummaryrefslogtreecommitdiffstats
path: root/cogs/cron.py
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-04-29 14:47:32 +0200
committersalmonik <raisersoft@proton.me>2026-04-29 14:47:32 +0200
commit8a4352ebb5e15ff4be82a9b4e111c1535aab349e (patch)
tree2c4d5b4b65bdc8308b35c411cffa7f17b1bfeb4d /cogs/cron.py
parentfix: fallback to plaintext if no json is provided for assistant.py (diff)
parentproper context for settings (diff)
downloadsenator-sperma-8a4352ebb5e15ff4be82a9b4e111c1535aab349e.tar.gz
senator-sperma-8a4352ebb5e15ff4be82a9b4e111c1535aab349e.zip
Merge branch 'dev'
Signed-off-by: salmonik <raisersoft@proton.me>
Diffstat (limited to '')
-rw-r--r--cogs/cron.py98
1 files changed, 65 insertions, 33 deletions
diff --git a/cogs/cron.py b/cogs/cron.py
index da8127b..aad43d2 100644
--- a/cogs/cron.py
+++ b/cogs/cron.py
@@ -4,9 +4,7 @@
4# https://codeberg.org/salmonik/senator-sperma 4# https://codeberg.org/salmonik/senator-sperma
5 5
6import asyncio 6import asyncio
7import json
8import logging 7import logging
9import os
10from datetime import datetime 8from datetime import datetime
11from venv import logger 9from venv import logger
12 10
@@ -16,37 +14,67 @@ from discord.ext import commands
16 14
17from cogs.utils import file_search as search_utils 15from cogs.utils import file_search as search_utils
18from cogs.voice import get_voice_manager 16from cogs.voice import get_voice_manager
17from cogs.utils.database import get_connection, init_database
19 18
20logger = logging.getLogger(__name__) 19logger = logging.getLogger(__name__)
21 20
21init_database()
22
22 23
23class Cron(commands.Cog): 24class Cron(commands.Cog):
24 def __init__(self, bot): 25 def __init__(self, bot):
25 self.bot = bot 26 self.bot = bot
26 self.scheduled_tasks = [] 27 self.scheduled_tasks = []
27 self.cron_file = "data/cron_jobs.json"
28 self.load_tasks() 28 self.load_tasks()
29 self.task = bot.loop.create_task(self.schedule_checker()) 29 self.task = bot.loop.create_task(self.schedule_checker())
30 30
31 def load_tasks(self): 31 def load_tasks(self):
32 """Load scheduled tasks from file"""
33 try: 32 try:
34 if os.path.exists(self.cron_file): 33 with get_connection() as conn:
35 with open(self.cron_file, "r") as f: 34 c = conn.cursor()
36 self.scheduled_tasks = json.load(f) 35 c.execute("SELECT id, cron_expression, type, channel_id, active, audio_filename, message FROM cron_jobs")
37 logger.info(f"Loaded {len(self.scheduled_tasks)} cron jobs") 36 rows = c.fetchall()
38 else: 37
39 self.scheduled_tasks = [] 38 self.scheduled_tasks = [
39 {
40 "id": row[0],
41 "cron_expression": row[1],
42 "type": row[2],
43 "channel_id": row[3],
44 "active": bool(row[4]),
45 "audio_filename": row[5],
46 "message": row[6],
47 }
48 for row in rows
49 ]
50 logger.info(f"Loaded {len(self.scheduled_tasks)} cron jobs from database")
40 except Exception as e: 51 except Exception as e:
41 logger.error(f"Error loading cron jobs: {e}") 52 logger.error(f"Error loading cron jobs: {e}")
42 self.scheduled_tasks = [] 53 self.scheduled_tasks = []
43 54
44 def save_tasks(self): 55 def save_tasks(self):
45 """Save scheduled tasks to file"""
46 try: 56 try:
47 os.makedirs(os.path.dirname(self.cron_file), exist_ok=True) 57 with get_connection() as conn:
48 with open(self.cron_file, "w") as f: 58 c = conn.cursor()
49 json.dump(self.scheduled_tasks, f, indent=2) 59 c.execute("PRAGMA foreign_keys = ON")
60
61 c.execute("DELETE FROM cron_jobs")
62
63 for task in self.scheduled_tasks:
64 c.execute(
65 """INSERT INTO cron_jobs (id, cron_expression, type, channel_id, active, audio_filename, message)
66 VALUES (?, ?, ?, ?, ?, ?, ?)""",
67 (
68 task.get("id"),
69 task["cron_expression"],
70 task["type"],
71 task["channel_id"],
72 int(task.get("active", True)),
73 task.get("audio_filename"),
74 task.get("message"),
75 ),
76 )
77 conn.commit()
50 except Exception as e: 78 except Exception as e:
51 logger.error(f"Error saving cron jobs: {e}") 79 logger.error(f"Error saving cron jobs: {e}")
52 80
@@ -104,7 +132,7 @@ class Cron(commands.Cog):
104 132
105 if task_type in ("zagraj_audio", "audio"): 133 if task_type in ("zagraj_audio", "audio"):
106 await self.play_audio_task(task, channel) 134 await self.play_audio_task(task, channel)
107 elif task_type in ("wyślij_wiadomość", "send_message"): 135 elif task_type in ("wyślij_wiadomość", "send_message", "wiadomość"):
108 await self.send_message_task(task, channel) 136 await self.send_message_task(task, channel)
109 137
110 logger.info(f"Executed task {task['id']} of type {task_type}") 138 logger.info(f"Executed task {task['id']} of type {task_type}")
@@ -132,11 +160,13 @@ class Cron(commands.Cog):
132 while voice_client.is_playing(): 160 while voice_client.is_playing():
133 await asyncio.sleep(1) 161 await asyncio.sleep(1)
134 162
163 logger.info("Audio playback finished normally - disconnecting")
135 await voice_client.disconnect() 164 await voice_client.disconnect()
136 logger.info(f"Finished playing audio: {audio_url}") 165 logger.info(f"Finished playing audio: {audio_url}")
137 except Exception as e: 166 except Exception as e:
138 logger.error(f"Error playing audio: {e}") 167 logger.error(f"Error playing audio: {e}")
139 if voice_client.is_connected(): 168 if voice_client.is_connected():
169 logger.info("Audio playback failed - disconnecting")
140 await voice_client.disconnect() 170 await voice_client.disconnect()
141 if channel.guild.system_channel: 171 if channel.guild.system_channel:
142 await channel.guild.system_channel.send( 172 await channel.guild.system_channel.send(
@@ -176,8 +206,19 @@ class Cron(commands.Cog):
176 else [discord.OptionChoice(name="Brak wyników", value="")] 206 else [discord.OptionChoice(name="Brak wyników", value="")]
177 ) 207 )
178 208
179 @commands.slash_command( 209 def _get_baseurl(self):
180 name="cron_dodaj_audio", description="Dodaj nowe zadanie cron audio" 210 """Get base URL from settings"""
211 try:
212 from cogs.utils.settings import get_baseurl
213
214 return get_baseurl()
215 except Exception:
216 return ""
217
218 trigger_group = discord.SlashCommandGroup("cron", "komendy cron")
219
220 @trigger_group.command(
221 name="dodaj_audio", description="Dodaj nowe zadanie cron audio"
181 ) 222 )
182 async def cron_add_audio( 223 async def cron_add_audio(
183 self, 224 self,
@@ -227,8 +268,8 @@ class Cron(commands.Cog):
227 f"Zadanie cron dodane. ID: {task_id}\nSkładnia: `{cron_expression}`\nAkcja: audio\nKanał: <#{channel.id}>" 268 f"Zadanie cron dodane. ID: {task_id}\nSkładnia: `{cron_expression}`\nAkcja: audio\nKanał: <#{channel.id}>"
228 ) 269 )
229 270
230 @commands.slash_command( 271 @trigger_group.command(
231 name="cron_dodaj_wiadomość", description="Dodaj nowe zadanie cron wiadomość" 272 name="dodaj_wiadomość", description="Dodaj nowe zadanie cron wiadomość"
232 ) 273 )
233 async def cron_add_message( 274 async def cron_add_message(
234 self, 275 self,
@@ -272,17 +313,8 @@ class Cron(commands.Cog):
272 f"Zadanie cron dodane. ID: {task_id}\nSkładnia: `{cron_expression}`\nAkcja: wiadomość\nKanał: <#{channel.id}>" 313 f"Zadanie cron dodane. ID: {task_id}\nSkładnia: `{cron_expression}`\nAkcja: wiadomość\nKanał: <#{channel.id}>"
273 ) 314 )
274 315
275 def _get_baseurl(self): 316 @trigger_group.command(
276 """Get base URL from settings""" 317 name="pokaż", description="Pokaż wszystkie zadania cron"
277 try:
278 from cogs.utils.settings import get_baseurl
279
280 return get_baseurl()
281 except Exception:
282 return ""
283
284 @commands.slash_command(
285 name="cron_pokaż", description="Pokaż wszystkie zadania cron"
286 ) 318 )
287 async def cron_list(self, ctx): 319 async def cron_list(self, ctx):
288 """List all cron jobs""" 320 """List all cron jobs"""
@@ -313,7 +345,7 @@ class Cron(commands.Cog):
313 345
314 await ctx.respond(embed=embed) 346 await ctx.respond(embed=embed)
315 347
316 @commands.slash_command(name="cron_usuń", description="Usuń zadanie cron z ID") 348 @trigger_group.command(name="usuń", description="Usuń zadanie cron z ID")
317 async def cron_remove( 349 async def cron_remove(
318 self, 350 self,
319 ctx, 351 ctx,
@@ -331,7 +363,7 @@ class Cron(commands.Cog):
331 363
332 await ctx.respond(f"Nie znaleziono zadania cron z ID {job_id}") 364 await ctx.respond(f"Nie znaleziono zadania cron z ID {job_id}")
333 365
334 @commands.slash_command(name="cron_pauza", description="Zapauzuj zadanie cron z ID") 366 @trigger_group.command(name="pauza", description="Zapauzuj zadanie cron z ID")
335 async def cron_pause( 367 async def cron_pause(
336 self, 368 self,
337 ctx, 369 ctx,
@@ -349,7 +381,7 @@ class Cron(commands.Cog):
349 381
350 await ctx.respond(f"Nie znaleziono zadania cron z ID {job_id}") 382 await ctx.respond(f"Nie znaleziono zadania cron z ID {job_id}")
351 383
352 @commands.slash_command(name="cron_wznów", description="Wznów zadanie cron z ID") 384 @trigger_group.command(name="wznów", description="Wznów zadanie cron z ID")
353 async def cron_resume( 385 async def cron_resume(
354 self, 386 self,
355 ctx, 387 ctx,