Skip to content

Commit 4d93829

Browse files
committed
refactor(sudo): simplify reboot and update commands, enhance restart logic
1 parent c9c255f commit 4d93829

File tree

5 files changed

+67
-34
lines changed

5 files changed

+67
-34
lines changed

src/korone/client.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from hydrogram.errors import MessageIdInvalid, MessageNotModified
1717
from hydrogram.raw.all import layer
1818

19+
from korone import constants
1920
from korone.config import ConfigManager
2021
from korone.utils.backup import do_backup
2122

@@ -96,7 +97,7 @@ async def start(self) -> None:
9697
if backups_chat:
9798
aiocron.crontab("0 * * * *", do_backup, loop=self.loop, args=(self, backups_chat))
9899

99-
reboot_data: dict[str, Any] | None = await cache.get("korone-reboot")
100+
reboot_data: dict[str, Any] | None = await cache.get(constants.REBOOT_CACHE_KEY)
100101
if reboot_data:
101102
with suppress(MessageNotModified, MessageIdInvalid, KeyError):
102103
chat_id = reboot_data["chat_id"]

src/korone/constants.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,6 @@
9898
PRIVACY_POLICY_URL: str = f"{DOCS_URL}/en/latest/privacy.html"
9999

100100
MESSAGE_LENGTH_LIMIT: int = 4096
101+
102+
REBOOT_CACHE_KEY: str = "korone-reboot"
103+
REBOOT_CACHE_TTL: int = 300
Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,15 @@
11
# SPDX-License-Identifier: BSD-3-Clause
22
# Copyright (c) 2025 Hitalo M. <https://github.com/HitaloM>
33

4-
import os
5-
import sys
6-
import time
7-
from typing import TypedDict
8-
94
from hydrogram import Client
105
from hydrogram.types import Message
116

127
from korone.decorators import router
138
from korone.filters import Command, IsSudo
14-
from korone.utils.caching import cache
15-
16-
17-
class RebootCache(TypedDict):
18-
chat_id: int
19-
message_id: int
20-
time: float
9+
from korone.modules.sudo.utils import restart_bot
2110

2211

2312
@router.message(Command("reboot", disableable=False) & IsSudo)
2413
async def reboot_command(client: Client, message: Message) -> None:
25-
cache_key = "korone-reboot"
26-
27-
if await cache.get(cache_key):
28-
await cache.delete(cache_key)
29-
30-
sent = await message.reply("Rebooting...")
31-
32-
value: RebootCache = {"chat_id": message.chat.id, "message_id": sent.id, "time": time.time()}
33-
await cache.set(cache_key, value=value, expire=300)
34-
35-
os.execv(sys.executable, [sys.executable, "-m", "korone"])
14+
sent = await message.reply("Starting reboot...")
15+
await restart_bot(sent, "Rebooting...")

src/korone/modules/sudo/handlers/updater.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
generate_document,
1717
parse_commits,
1818
perform_update,
19+
restart_bot,
1920
)
20-
from korone.utils.caching import cache
2121

2222

2323
@router.message(Command(commands=["update", "upgrade"], disableable=False) & IsSudo)
@@ -27,7 +27,7 @@ async def update_command(client: Client, message: Message) -> None:
2727
try:
2828
stdout = await fetch_updates()
2929
except Exception as e:
30-
await sent.edit(f"An error occurred:\n<code>{e}</code>")
30+
await sent.edit(f"An error occurred:\n<code>{html.escape(str(e))}</code>")
3131
return
3232

3333
if not stdout.strip():
@@ -45,23 +45,29 @@ async def update_command(client: Client, message: Message) -> None:
4545

4646
@router.callback_query(UpdateCallbackData.filter() & IsSudo)
4747
async def update_callback(client: Client, callback: CallbackQuery) -> None:
48-
cache_key = "korone-reboot"
49-
if await cache.get(cache_key):
50-
await cache.delete(cache_key)
51-
5248
message = callback.message
49+
50+
await callback.answer("Starting upgrade...")
5351
await message.edit_reply_markup()
5452
sent = await message.reply("Upgrading...")
5553

5654
try:
5755
stdout = await perform_update()
5856
except Exception as e:
59-
await sent.edit(f"An error occurred:\n<code>{e}</code>")
57+
await sent.edit(f"An error occurred:\n<code>{html.escape(str(e))}</code>")
58+
await callback.answer("Upgrade failed.", show_alert=True)
6059
return
6160

6261
if len(stdout) > MESSAGE_LENGTH_LIMIT:
63-
await sent.edit("Upgrade completed successfully. Reboot is required...")
6462
await generate_document(stdout, message)
63+
final_text = "Upgrade completed successfully. Output sent as document. Rebooting..."
64+
await restart_bot(sent, final_text)
6565
return
6666

67-
await sent.edit(f"<pre language='bash'>{html.escape(stdout)}</pre>")
67+
formatted_stdout = html.escape(stdout) if stdout else "No output returned."
68+
final_text = (
69+
"Upgrade completed successfully.\n"
70+
f"<pre language='bash'>{formatted_stdout}</pre>\n"
71+
"Rebooting..."
72+
)
73+
await restart_bot(sent, final_text)

src/korone/modules/sudo/utils.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,29 @@
33

44
import html
55
import io
6+
import os
7+
import sys
8+
import time
69
from subprocess import PIPE
7-
from typing import Any, TypedDict
10+
from typing import Any, Never, TypedDict
811

912
from anyio import run_process
1013
from hydrogram.types import Message
1114

15+
from korone import constants
16+
from korone.utils.caching import cache
17+
1218

1319
class CommitInfo(TypedDict):
1420
title: str
1521

1622

23+
class RebootCache(TypedDict):
24+
chat_id: int
25+
message_id: int
26+
time: float
27+
28+
1729
async def generate_document(output: Any, message: Message) -> None:
1830
with io.BytesIO(str.encode(str(output))) as file:
1931
file.name = "output.txt"
@@ -56,3 +68,34 @@ def generate_changelog(commits: dict[str, CommitInfo]) -> str:
5668
async def perform_update() -> str:
5769
commands = ["git reset --hard origin/main", "pybabel compile -d locales -D bot", "uv sync"]
5870
return "".join([await run_command(command) for command in commands])
71+
72+
73+
async def restart_bot(message: Message, text: str) -> Never:
74+
await cache.delete(constants.REBOOT_CACHE_KEY)
75+
await message.edit_text(text)
76+
77+
value: RebootCache = {
78+
"chat_id": message.chat.id,
79+
"message_id": message.id,
80+
"time": time.time(),
81+
}
82+
await cache.set(constants.REBOOT_CACHE_KEY, value=value, expire=constants.REBOOT_CACHE_TTL)
83+
84+
main_module = sys.modules.get("__main__")
85+
module_name = None
86+
87+
if main_module is not None:
88+
if package_name := getattr(main_module, "__package__", None):
89+
module_name = package_name
90+
elif (spec := getattr(main_module, "__spec__", None)) and (
91+
spec_name := getattr(spec, "name", None)
92+
):
93+
module_name = spec_name.removesuffix(".__main__")
94+
95+
if module_name:
96+
args = [sys.executable, "-m", module_name, *sys.argv[1:]]
97+
else:
98+
script_candidate = sys.argv[0] or getattr(main_module, "__file__", "")
99+
args = [sys.executable, script_candidate, *sys.argv[1:]]
100+
101+
os.execv(sys.executable, args)

0 commit comments

Comments
 (0)