DiscordBotLinuxMonitor 1.6.0__tar.gz → 1.6.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/DiscordBotLinuxMonitor.egg-info/PKG-INFO +7 -2
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/DiscordBotLinuxMonitor.egg-info/requires.txt +1 -1
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/PKG-INFO +7 -2
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/README.md +5 -0
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/discordbotlinuxmonitor/__main__.py +4 -0
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/discordbotlinuxmonitor/discordbotlinuxmonitor.py +181 -2
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/setup.py +2 -2
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/DiscordBotLinuxMonitor.egg-info/SOURCES.txt +0 -0
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/DiscordBotLinuxMonitor.egg-info/dependency_links.txt +0 -0
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/DiscordBotLinuxMonitor.egg-info/top_level.txt +0 -0
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/LICENSE.md +0 -0
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/discordbotlinuxmonitor/__init__.py +0 -0
- {discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DiscordBotLinuxMonitor
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.2
|
|
4
4
|
Summary: From discord channels: Get information and warning status of Linux server like service, port, ping, ssl certificate, disk/folder/cpu/ram/swap usage, ip connection, ... (Python and shell library, Linux ONLY)
|
|
5
5
|
Home-page: https://github.com/QuentinCG/Discord-Bot-Linux-Monitor-Python-Library
|
|
6
6
|
Author: Quentin Comte-Gaz
|
|
@@ -22,7 +22,7 @@ Classifier: Environment :: Console
|
|
|
22
22
|
Requires-Python: >=3.3
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE.md
|
|
25
|
-
Requires-Dist: linuxmonitor~=1.5.
|
|
25
|
+
Requires-Dist: linuxmonitor~=1.5.8
|
|
26
26
|
Requires-Dist: discord.py
|
|
27
27
|
Requires-Dist: typing
|
|
28
28
|
Requires-Dist: asyncio
|
|
@@ -121,6 +121,8 @@ Displayed infos are not the same if you do the command in private or public chan
|
|
|
121
121
|
- `/kill_process`: 🚫 Stop a process by PID 🚫
|
|
122
122
|
<img src="https://raw.githubusercontent.com/QuentinCG/Discord-Bot-Linux-Monitor-Python-Library/master/example/kill_process.jpg" height="200">
|
|
123
123
|
|
|
124
|
+
- `/clear_channel_messages {channel}`: 🧹 Remove all messages from a target channel (can clean any channel, command itself is private-only) 🧹
|
|
125
|
+
|
|
124
126
|
## How to install (for first launch)
|
|
125
127
|
|
|
126
128
|
- Install package calling `python -m pip install discordbotlinuxmonitor` (or `python setup.py install` from the root of this repository)
|
|
@@ -158,6 +160,9 @@ DISCORD_BOT_FOLDER="/opt/DiscordBot/"
|
|
|
158
160
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /sbin/reboot" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
159
161
|
# Only if this library should be able to kill a process on demand:
|
|
160
162
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /bin/kill" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
163
|
+
# To check last user connection
|
|
164
|
+
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /usr/bin/last" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
165
|
+
|
|
161
166
|
# Add also all processes added in your config JSON file you want the library to be able to execute
|
|
162
167
|
# Example for the existing config-example.json file:
|
|
163
168
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: DiscordBotLinuxMonitor
|
|
3
|
-
Version: 1.6.
|
|
3
|
+
Version: 1.6.2
|
|
4
4
|
Summary: From discord channels: Get information and warning status of Linux server like service, port, ping, ssl certificate, disk/folder/cpu/ram/swap usage, ip connection, ... (Python and shell library, Linux ONLY)
|
|
5
5
|
Home-page: https://github.com/QuentinCG/Discord-Bot-Linux-Monitor-Python-Library
|
|
6
6
|
Author: Quentin Comte-Gaz
|
|
@@ -22,7 +22,7 @@ Classifier: Environment :: Console
|
|
|
22
22
|
Requires-Python: >=3.3
|
|
23
23
|
Description-Content-Type: text/markdown
|
|
24
24
|
License-File: LICENSE.md
|
|
25
|
-
Requires-Dist: linuxmonitor~=1.5.
|
|
25
|
+
Requires-Dist: linuxmonitor~=1.5.8
|
|
26
26
|
Requires-Dist: discord.py
|
|
27
27
|
Requires-Dist: typing
|
|
28
28
|
Requires-Dist: asyncio
|
|
@@ -121,6 +121,8 @@ Displayed infos are not the same if you do the command in private or public chan
|
|
|
121
121
|
- `/kill_process`: 🚫 Stop a process by PID 🚫
|
|
122
122
|
<img src="https://raw.githubusercontent.com/QuentinCG/Discord-Bot-Linux-Monitor-Python-Library/master/example/kill_process.jpg" height="200">
|
|
123
123
|
|
|
124
|
+
- `/clear_channel_messages {channel}`: 🧹 Remove all messages from a target channel (can clean any channel, command itself is private-only) 🧹
|
|
125
|
+
|
|
124
126
|
## How to install (for first launch)
|
|
125
127
|
|
|
126
128
|
- Install package calling `python -m pip install discordbotlinuxmonitor` (or `python setup.py install` from the root of this repository)
|
|
@@ -158,6 +160,9 @@ DISCORD_BOT_FOLDER="/opt/DiscordBot/"
|
|
|
158
160
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /sbin/reboot" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
159
161
|
# Only if this library should be able to kill a process on demand:
|
|
160
162
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /bin/kill" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
163
|
+
# To check last user connection
|
|
164
|
+
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /usr/bin/last" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
165
|
+
|
|
161
166
|
# Add also all processes added in your config JSON file you want the library to be able to execute
|
|
162
167
|
# Example for the existing config-example.json file:
|
|
163
168
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
@@ -79,6 +79,8 @@ Displayed infos are not the same if you do the command in private or public chan
|
|
|
79
79
|
- `/kill_process`: 🚫 Stop a process by PID 🚫
|
|
80
80
|
<img src="https://raw.githubusercontent.com/QuentinCG/Discord-Bot-Linux-Monitor-Python-Library/master/example/kill_process.jpg" height="200">
|
|
81
81
|
|
|
82
|
+
- `/clear_channel_messages {channel}`: 🧹 Remove all messages from a target channel (can clean any channel, command itself is private-only) 🧹
|
|
83
|
+
|
|
82
84
|
## How to install (for first launch)
|
|
83
85
|
|
|
84
86
|
- Install package calling `python -m pip install discordbotlinuxmonitor` (or `python setup.py install` from the root of this repository)
|
|
@@ -116,6 +118,9 @@ DISCORD_BOT_FOLDER="/opt/DiscordBot/"
|
|
|
116
118
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /sbin/reboot" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
117
119
|
# Only if this library should be able to kill a process on demand:
|
|
118
120
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /bin/kill" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
121
|
+
# To check last user connection
|
|
122
|
+
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /usr/bin/last" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
|
123
|
+
|
|
119
124
|
# Add also all processes added in your config JSON file you want the library to be able to execute
|
|
120
125
|
# Example for the existing config-example.json file:
|
|
121
126
|
echo "$DISCORD_BOT_SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl" >> /etc/sudoers.d/$DISCORD_BOT_SERVICE_USER
|
{discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/discordbotlinuxmonitor/__main__.py
RENAMED
|
@@ -122,6 +122,10 @@ def main() -> None:
|
|
|
122
122
|
async def kill_process(interaction: discord.Interaction, pid: int) -> None: # type: ignore
|
|
123
123
|
await discord_bot_linux_monitor.kill_process(interaction, pid)
|
|
124
124
|
|
|
125
|
+
@discord_bot.tree.command(name="clear_channel_messages", description="[Private] 🧹 Remove all messages from a channel 🧹")
|
|
126
|
+
async def clear_channel_messages(interaction: discord.Interaction, channel: discord.TextChannel) -> None: # type: ignore
|
|
127
|
+
await discord_bot_linux_monitor.clear_channel_messages(interaction, channel)
|
|
128
|
+
|
|
125
129
|
@discord_bot.tree.command(name="list_commands", description="📋 List all available commands 📋")
|
|
126
130
|
async def list_commands(interaction: discord.Interaction) -> None: # type: ignore
|
|
127
131
|
await discord_bot_linux_monitor.list_commands(interaction)
|
|
@@ -33,7 +33,7 @@ __email__ = "quentin@comte-gaz.com"
|
|
|
33
33
|
__license__ = "MIT License"
|
|
34
34
|
__copyright__ = "Copyright Quentin Comte-Gaz (2026)"
|
|
35
35
|
__python_version__ = "3.+"
|
|
36
|
-
__version__ = "1.6.
|
|
36
|
+
__version__ = "1.6.2 (2026/08/24)"
|
|
37
37
|
__status__ = "Usable for any Linux project"
|
|
38
38
|
|
|
39
39
|
# pyright: reportMissingTypeStubs=false
|
|
@@ -43,7 +43,8 @@ import discord
|
|
|
43
43
|
from discord.app_commands.models import AppCommand
|
|
44
44
|
from discord.ext import commands
|
|
45
45
|
import json
|
|
46
|
-
from typing import List, Union, Awaitable, Callable
|
|
46
|
+
from typing import List, Union, Awaitable, Callable, Any, Dict, Optional
|
|
47
|
+
from datetime import datetime, timedelta, timezone
|
|
47
48
|
|
|
48
49
|
import asyncio
|
|
49
50
|
|
|
@@ -285,6 +286,66 @@ class DiscordBotLinuxMonitor:
|
|
|
285
286
|
logging.exception(msg=out_msg)
|
|
286
287
|
return out_msg
|
|
287
288
|
|
|
289
|
+
def _get_rate_limit_wait_seconds(self, error: discord.HTTPException, fallback_seconds: float = 1.5) -> float:
|
|
290
|
+
retry_after = getattr(error, "retry_after", None)
|
|
291
|
+
if isinstance(retry_after, (int, float)) and retry_after > 0:
|
|
292
|
+
return float(retry_after)
|
|
293
|
+
|
|
294
|
+
response = getattr(error, "response", None)
|
|
295
|
+
if response is not None:
|
|
296
|
+
headers = getattr(response, "headers", None)
|
|
297
|
+
if headers is not None:
|
|
298
|
+
header_retry_after = headers.get("Retry-After")
|
|
299
|
+
if header_retry_after is not None:
|
|
300
|
+
try:
|
|
301
|
+
parsed_retry_after = float(header_retry_after)
|
|
302
|
+
if parsed_retry_after > 0:
|
|
303
|
+
return parsed_retry_after
|
|
304
|
+
except (ValueError, TypeError):
|
|
305
|
+
pass
|
|
306
|
+
|
|
307
|
+
return fallback_seconds
|
|
308
|
+
|
|
309
|
+
async def _delete_message_with_rate_limit_retry(self, message: discord.Message, reason: str, max_retries: int = 10, on_rate_limit: Optional[Callable[[], None]] = None) -> None:
|
|
310
|
+
for attempt in range(max_retries + 1):
|
|
311
|
+
try:
|
|
312
|
+
await message.delete(reason=reason)
|
|
313
|
+
return
|
|
314
|
+
except discord.NotFound:
|
|
315
|
+
return
|
|
316
|
+
except discord.HTTPException as e:
|
|
317
|
+
if e.status == 429 and attempt < max_retries:
|
|
318
|
+
if on_rate_limit is not None:
|
|
319
|
+
on_rate_limit()
|
|
320
|
+
wait_seconds = self._get_rate_limit_wait_seconds(error=e)
|
|
321
|
+
logging.warning(msg=f"Rate limited while deleting message {message.id}, waiting {wait_seconds:.2f}s before retry...")
|
|
322
|
+
await asyncio.sleep(wait_seconds)
|
|
323
|
+
continue
|
|
324
|
+
raise
|
|
325
|
+
|
|
326
|
+
async def _bulk_delete_messages_with_rate_limit_retry(self, channel: discord.TextChannel, messages: List[discord.Message], reason: str, max_retries: int = 10, on_rate_limit: Optional[Callable[[], None]] = None) -> None:
|
|
327
|
+
if len(messages) == 0:
|
|
328
|
+
return
|
|
329
|
+
|
|
330
|
+
for attempt in range(max_retries + 1):
|
|
331
|
+
try:
|
|
332
|
+
if len(messages) == 1:
|
|
333
|
+
await messages[0].delete(reason=reason)
|
|
334
|
+
else:
|
|
335
|
+
await channel.delete_messages(messages, reason=reason)
|
|
336
|
+
return
|
|
337
|
+
except discord.NotFound:
|
|
338
|
+
return
|
|
339
|
+
except discord.HTTPException as e:
|
|
340
|
+
if e.status == 429 and attempt < max_retries:
|
|
341
|
+
if on_rate_limit is not None:
|
|
342
|
+
on_rate_limit()
|
|
343
|
+
wait_seconds = self._get_rate_limit_wait_seconds(error=e)
|
|
344
|
+
logging.warning(msg=f"Rate limited while bulk deleting {len(messages)} messages in '{channel.name}', waiting {wait_seconds:.2f}s before retry...")
|
|
345
|
+
await asyncio.sleep(wait_seconds)
|
|
346
|
+
continue
|
|
347
|
+
raise
|
|
348
|
+
|
|
288
349
|
#endregion
|
|
289
350
|
|
|
290
351
|
#region BOT COMMANDS AND EVENTS DEFINITIONS
|
|
@@ -783,6 +844,124 @@ class DiscordBotLinuxMonitor:
|
|
|
783
844
|
logging.exception(msg=out_msg)
|
|
784
845
|
await self._interaction_followup_send_no_limit(interaction=interaction, msg=out_msg)
|
|
785
846
|
|
|
847
|
+
async def clear_channel_messages(self, interaction: discord.Interaction, channel: discord.TextChannel) -> None:
|
|
848
|
+
if not self._check_if_valid_guild(guild=interaction.guild):
|
|
849
|
+
return
|
|
850
|
+
if not (await self._is_bot_channel_interaction(interaction=interaction, send_message_if_not_bot=True)):
|
|
851
|
+
return
|
|
852
|
+
if not self._is_private_channel(channel=interaction.channel): # type: ignore
|
|
853
|
+
await interaction.response.send_message(content="❌ Public channels do not allow this command.", ephemeral=True)
|
|
854
|
+
return
|
|
855
|
+
|
|
856
|
+
# Make sure only authorized users can trigger a destructive command.
|
|
857
|
+
permissions = channel.permissions_for(interaction.user) # type: ignore
|
|
858
|
+
if not permissions.manage_messages:
|
|
859
|
+
await interaction.response.send_message(content=f"❌ You need 'Manage Messages' permission on channel '{channel.name}' to clear it.", ephemeral=True)
|
|
860
|
+
return
|
|
861
|
+
|
|
862
|
+
bot_member = interaction.guild.me if interaction.guild is not None else None # type: ignore
|
|
863
|
+
if bot_member is None:
|
|
864
|
+
await interaction.response.send_message(content="❌ Unable to resolve bot permissions.", ephemeral=True)
|
|
865
|
+
return
|
|
866
|
+
|
|
867
|
+
bot_permissions = channel.permissions_for(bot_member)
|
|
868
|
+
if not bot_permissions.manage_messages or not bot_permissions.read_message_history:
|
|
869
|
+
await interaction.response.send_message(content=f"❌ Bot is missing required permissions on channel '{channel.name}' (Manage Messages and Read Message History).", ephemeral=True)
|
|
870
|
+
return
|
|
871
|
+
|
|
872
|
+
await interaction.response.defer(ephemeral=True)
|
|
873
|
+
|
|
874
|
+
deleted_count: int = 0
|
|
875
|
+
rate_limit_retries: int = 0
|
|
876
|
+
delete_reason: str = f"Requested by {interaction.user} from private channel"
|
|
877
|
+
two_weeks_ago = datetime.now(timezone.utc) - timedelta(days=14)
|
|
878
|
+
progress_every_seconds: float = 2.5
|
|
879
|
+
progress_every_deleted_messages: int = 200
|
|
880
|
+
started_monotonic: float = asyncio.get_running_loop().time()
|
|
881
|
+
last_progress_monotonic: float = started_monotonic
|
|
882
|
+
last_reported_deleted_count: int = 0
|
|
883
|
+
|
|
884
|
+
def _on_rate_limit_hit() -> None:
|
|
885
|
+
nonlocal rate_limit_retries
|
|
886
|
+
rate_limit_retries += 1
|
|
887
|
+
|
|
888
|
+
async def _update_progress(force: bool = False) -> None:
|
|
889
|
+
nonlocal last_progress_monotonic
|
|
890
|
+
nonlocal last_reported_deleted_count
|
|
891
|
+
|
|
892
|
+
now = asyncio.get_running_loop().time()
|
|
893
|
+
should_update = force
|
|
894
|
+
if not should_update:
|
|
895
|
+
enough_time_elapsed = (now - last_progress_monotonic) >= progress_every_seconds
|
|
896
|
+
enough_messages_deleted = (deleted_count - last_reported_deleted_count) >= progress_every_deleted_messages
|
|
897
|
+
should_update = enough_time_elapsed or enough_messages_deleted
|
|
898
|
+
|
|
899
|
+
if not should_update:
|
|
900
|
+
return
|
|
901
|
+
|
|
902
|
+
elapsed_seconds = int(now - started_monotonic)
|
|
903
|
+
progress_msg = (
|
|
904
|
+
f"🧹 Cleaning channel '{channel.name}'...\n"
|
|
905
|
+
f"Deleted messages: {deleted_count}\n"
|
|
906
|
+
f"Rate-limit waits: {rate_limit_retries}\n"
|
|
907
|
+
f"Elapsed: {elapsed_seconds}s"
|
|
908
|
+
)
|
|
909
|
+
|
|
910
|
+
try:
|
|
911
|
+
await interaction.edit_original_response(content=progress_msg)
|
|
912
|
+
last_progress_monotonic = now
|
|
913
|
+
last_reported_deleted_count = deleted_count
|
|
914
|
+
except discord.HTTPException as e:
|
|
915
|
+
if e.status == 429:
|
|
916
|
+
_on_rate_limit_hit()
|
|
917
|
+
wait_seconds = self._get_rate_limit_wait_seconds(error=e)
|
|
918
|
+
await asyncio.sleep(wait_seconds)
|
|
919
|
+
else:
|
|
920
|
+
logging.warning(msg=f"Failed to update cleanup progress message: {e}")
|
|
921
|
+
|
|
922
|
+
try:
|
|
923
|
+
await _update_progress(force=True)
|
|
924
|
+
recent_batch: List[discord.Message] = []
|
|
925
|
+
|
|
926
|
+
async for message in channel.history(limit=None, oldest_first=False):
|
|
927
|
+
if message.created_at >= two_weeks_ago:
|
|
928
|
+
recent_batch.append(message)
|
|
929
|
+
|
|
930
|
+
# Bulk delete by chunks of 100 to reduce API calls and rate-limit pressure.
|
|
931
|
+
if len(recent_batch) == 100:
|
|
932
|
+
await self._bulk_delete_messages_with_rate_limit_retry(channel=channel, messages=recent_batch, reason=delete_reason, on_rate_limit=_on_rate_limit_hit)
|
|
933
|
+
deleted_count += len(recent_batch)
|
|
934
|
+
recent_batch = []
|
|
935
|
+
await _update_progress()
|
|
936
|
+
else:
|
|
937
|
+
await self._delete_message_with_rate_limit_retry(message=message, reason=delete_reason, on_rate_limit=_on_rate_limit_hit)
|
|
938
|
+
deleted_count += 1
|
|
939
|
+
await _update_progress()
|
|
940
|
+
|
|
941
|
+
if len(recent_batch) > 0:
|
|
942
|
+
await self._bulk_delete_messages_with_rate_limit_retry(channel=channel, messages=recent_batch, reason=delete_reason, on_rate_limit=_on_rate_limit_hit)
|
|
943
|
+
deleted_count += len(recent_batch)
|
|
944
|
+
await _update_progress()
|
|
945
|
+
|
|
946
|
+
elapsed_seconds = int(asyncio.get_running_loop().time() - started_monotonic)
|
|
947
|
+
out_msg = (
|
|
948
|
+
f"✅ Cleared channel '{channel.name}'.\n"
|
|
949
|
+
f"Deleted messages: {deleted_count}\n"
|
|
950
|
+
f"Rate-limit waits: {rate_limit_retries}\n"
|
|
951
|
+
f"Elapsed: {elapsed_seconds}s"
|
|
952
|
+
)
|
|
953
|
+
await interaction.edit_original_response(content=out_msg)
|
|
954
|
+
except discord.HTTPException as e:
|
|
955
|
+
if e.status == 429:
|
|
956
|
+
_on_rate_limit_hit()
|
|
957
|
+
out_msg = f"**Discord API error while clearing messages in channel '{channel.name}'** (status {e.status}, retries: {rate_limit_retries}):\n```sh\n{e}\n```"
|
|
958
|
+
logging.exception(msg=out_msg)
|
|
959
|
+
await interaction.edit_original_response(content=out_msg)
|
|
960
|
+
except Exception as e:
|
|
961
|
+
out_msg = f"**Internal error while clearing messages in channel '{channel.name}'**:\n```sh\n{e}\n```"
|
|
962
|
+
logging.exception(msg=out_msg)
|
|
963
|
+
await interaction.edit_original_response(content=out_msg)
|
|
964
|
+
|
|
786
965
|
async def list_commands(self, interaction: discord.Interaction) -> None:
|
|
787
966
|
if not self._check_if_valid_guild(guild=interaction.guild):
|
|
788
967
|
return
|
|
@@ -6,7 +6,7 @@ with io.open(file='README.md', mode='r', encoding='utf-8') as readme_file:
|
|
|
6
6
|
|
|
7
7
|
setup(
|
|
8
8
|
name="DiscordBotLinuxMonitor",
|
|
9
|
-
version="1.6.
|
|
9
|
+
version="1.6.2",
|
|
10
10
|
description="From discord channels: Get information and warning status of Linux server like service, port, ping, ssl certificate, disk/folder/cpu/ram/swap usage, ip connection, ... (Python and shell library, Linux ONLY)",
|
|
11
11
|
long_description=readme,
|
|
12
12
|
long_description_content_type="text/markdown",
|
|
@@ -36,7 +36,7 @@ setup(
|
|
|
36
36
|
keywords='discord bot warning info linux monitor monitoring server service port ping ssl certificate disk folder cpu ram swap usage ip connection',
|
|
37
37
|
platforms='Linux',
|
|
38
38
|
install_requires=[
|
|
39
|
-
"linuxmonitor~=1.5.
|
|
39
|
+
"linuxmonitor~=1.5.8", # follows the {MAJOR}.{MINOR}.x version range (because LinuxMonitor and DiscordBotLinuxMonitor are tightly coupled and should have same major and minor version)
|
|
40
40
|
"discord.py",
|
|
41
41
|
"typing",
|
|
42
42
|
"asyncio",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{discordbotlinuxmonitor-1.6.0 → discordbotlinuxmonitor-1.6.2}/discordbotlinuxmonitor/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|