Skip to content

Commit 5182762

Browse files
Merge pull request #3 from surajstaabi/main
File path + Exception handling
2 parents 58dd3fa + 88ba3af commit 5182762

File tree

10 files changed

+211
-67
lines changed

10 files changed

+211
-67
lines changed

.gitignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.env
22
.gitattributes
33
.gitignore
4-
.venv
4+
.venv/*
55

66
# config file
77
key.txt
@@ -13,4 +13,7 @@ data/mouse-ss.png
1313
data/combined_image.png
1414
data/webcam-capture.jpg
1515
test.py
16-
commands-to-be-added/*
16+
commands-to-be-added/*
17+
18+
commands/__pycache__/*
19+
/venv

README.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Discord Windows Controller Bot
22

3-
The Discord Windows Controller Bot is a Python bot designed to control Windows operations through Discord commands. It can perform tasks like locking your workstation and monitoring mouse movement in a specified channel. Follow these steps to set up and run the bot.
3+
The Discord Windows Controller Bot is a Python bot designed to control Windows operations through Discord commands. It can perform tasks like locking your workstation and monitoring mouse movement in a specified channel as well as saving files you send to the local workstation. Follow these steps to set up and run the bot.
44

55
## Step 1: Clone the Repository
66

@@ -45,6 +45,38 @@ Install the necessary libraries for your bot using the following command:
4545
pip install -r requirements.txt
4646
```
4747

48+
### Troubleshooting Installation Errors
49+
50+
If you encounter an error message similar to the following:
51+
52+
```
53+
error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
54+
```
55+
56+
This error occurs because some packages require compilation, and your system is missing the necessary tools. To resolve this:
57+
58+
1. Install Microsoft Visual C++ Build Tools:
59+
- Go to https://visualstudio.microsoft.com/visual-cpp-build-tools/
60+
- Download and run the installer
61+
- In the installer, select "C++ build tools" and install it
62+
63+
2. After installation, restart your computer.
64+
65+
3. Try running the pip install command again:
66+
67+
```bash
68+
pip install -r requirements.txt
69+
```
70+
71+
If you still face issues, try the following:
72+
73+
- Update pip and setuptools:
74+
```bash
75+
pip install --upgrade pip setuptools wheel
76+
```
77+
78+
- If problems persist, please open an issue on the GitHub repository for further assistance.
79+
4880
## Step 5: Create a Discord Bot
4981

5082
1. Go to the Discord Developer Portal: [Discord Developer Portal](https://discord.com/developers/applications)
@@ -65,6 +97,7 @@ pip install -r requirements.txt
6597
1. In the project folder, create a text file named "key.txt."
6698
2. Paste the copied bot token into the "key.txt" file and save it.
6799
3. Get your Channel ID and your own ID from Discord, and paste them into the "config.json" file.
100+
4. Create a folder where you would want the files to be saved to locally, and copy the path to the `file_save_path` variable
68101

69102
Example:
70103

@@ -73,7 +106,8 @@ Example:
73106
"command_channel_id": 1137276176451079374,
74107
"author_id": 637917562920429309,
75108
"log_channel_id": 1137693326543122128,
76-
"mouse_log_channel_id": 1137693326543123128
109+
"mouse_log_channel_id": 1137693326543123128,
110+
"file_save_path": "insert/file/path"
77111
}
78112
```
79113

@@ -100,4 +134,4 @@ Example:
100134
## Step 9: Test the Functionality
101135

102136
1. In the server where your bot is added, send a message with the content "lock" in the designated channel.
103-
2. The bot should respond by locking the workstation and sending a confirmation message.
137+
2. The bot should respond by locking the workstation and sending a confirmation message.

bot.py

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
import asyncio
66
import pyautogui
77
from commands.mouse_movement import monitor_mouse_movement
8+
from aiohttp.client_exceptions import ClientConnectorError
89

9-
KEY_PATH = "D:\Coding\Discord bots\python-windows-bot\key.txt"
10-
CONFIG_PATH = "D:\Coding\Discord bots\python-windows-bot\config.json"
10+
KEY_PATH = "key.txt"
11+
CONFIG_PATH = "config.json"
1112

1213
def is_connected():
1314
try:
14-
# Try to resolve a common domain to check if the network is available
1515
socket.create_connection(("www.google.com", 80))
1616
return True
1717
except OSError:
@@ -29,14 +29,14 @@ async def network_monitor():
2929
if not is_connected():
3030
print("Network connection lost. Waiting for network...")
3131
while not is_connected():
32-
await asyncio.sleep(5) # Wait for 5 seconds before checking again
32+
await asyncio.sleep(5)
3333
print("Network has been restored.")
34-
await asyncio.sleep(60) # Check network status every 60 seconds
34+
await asyncio.sleep(60)
3535

3636
async def main():
3737
if os.path.exists(KEY_PATH):
3838
with open(KEY_PATH, "r") as f:
39-
TOKEN = f.read()
39+
TOKEN = f.read().strip()
4040
else:
4141
TOKEN = ""
4242

@@ -46,16 +46,13 @@ async def main():
4646

4747
client = discord.Client(intents=intents)
4848

49-
# Start the network monitoring task in the background
50-
asyncio.create_task(network_monitor())
51-
5249
@client.event
5350
async def on_ready():
5451
print(f"We have logged in as {client.user}")
5552
starting_mouse_position = pyautogui.position()
5653
asyncio.create_task(
5754
monitor_mouse_movement(client, config, starting_mouse_position)
58-
) # Call the function
55+
)
5956

6057
@client.event
6158
async def on_message(message):
@@ -73,23 +70,61 @@ async def on_message(message):
7370

7471
if str(message.attachments) != "[]":
7572
from commands.file_save import execute_file_save
76-
7773
await execute_file_save(client, message, config)
7874

7975
if msg == "lock":
8076
from commands.lock_command import execute_lock_command
81-
8277
await execute_lock_command(client, message, config)
8378

8479
if msg == "ping":
8580
from commands.ping_command import execute_ping_command
86-
8781
await execute_ping_command(client, message, config)
8882

8983
if msg == "ss" or msg == "screenshot":
9084
from commands.screenshot_command import execute_screenshot_command
9185
await execute_screenshot_command(message, args)
86+
87+
if msg == "help" or msg == "?":
88+
from commands.help_command import execute_help_command
89+
await execute_help_command(client, message, config)
90+
91+
async def start_bot():
92+
while True:
93+
try:
94+
# Start the network monitoring task
95+
network_task = asyncio.create_task(network_monitor())
96+
97+
# Start the client
98+
await client.start(TOKEN)
99+
except ClientConnectorError:
100+
print("Failed to connect to Discord. Retrying in 30 seconds...")
101+
await asyncio.sleep(30)
102+
except KeyboardInterrupt:
103+
print("Interrupt received. Shutting down gracefully...")
104+
break
105+
except Exception as e:
106+
print(f"An unexpected error occurred: {e}")
107+
print("Restarting the bot in 30 seconds...")
108+
await asyncio.sleep(30)
92109

93-
await client.start(TOKEN)
110+
try:
111+
await start_bot()
112+
finally:
113+
# Cancel all running tasks
114+
tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
115+
for task in tasks:
116+
task.cancel()
117+
118+
# Wait for all tasks to complete
119+
await asyncio.gather(*tasks, return_exceptions=True)
120+
121+
# Close the client connection
122+
await client.close()
123+
124+
print("Bot has been shut down.")
94125

95-
asyncio.run(main())
126+
if __name__ == "__main__":
127+
try:
128+
asyncio.run(main())
129+
except KeyboardInterrupt:
130+
print("Bot stopped.")

commands/file_save.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,35 @@
1+
import json
2+
import os
3+
14
async def execute_file_save(client, message, config):
25
LOG_CHANNEL_ID = config["log_channel_id"]
6+
7+
# Load the configuration file
8+
with open('config.json', 'r') as config_file:
9+
full_config = json.load(config_file)
10+
11+
# Get the file save path from the config
12+
file_save_path = full_config.get("file_save_path", "")
13+
14+
if not file_save_path:
15+
await message.guild.get_channel(LOG_CHANNEL_ID).send("Error: file_save_path not configured in config.json")
16+
print("[file_save_LOG] - Error: file_save_path not configured in config.json")
17+
return
318

419
split_v1 = str(message.attachments).split("filename='")[1]
520
filename = str(split_v1).split("' ")[0]
621
await message.guild.get_channel(LOG_CHANNEL_ID).send(f"File Detected: {filename}")
22+
723
try:
8-
await message.attachments[0].save(
9-
fp="D:/Coding\Discord bots/python-windows-bot/files/{}".format(filename)
10-
) # saves the file
11-
await message.guild.get_channel(LOG_CHANNEL_ID).send("File Sucessfully saved")
12-
print(f"[file_save_LOG] - File Sucessfully saved.")
24+
# Ensure the directory exists
25+
os.makedirs(file_save_path, exist_ok=True)
26+
27+
# Construct the full file path
28+
full_file_path = os.path.join(file_save_path, filename)
29+
30+
await message.attachments[0].save(fp=full_file_path) # saves the file
31+
await message.guild.get_channel(LOG_CHANNEL_ID).send("File Successfully saved")
32+
print(f"[file_save_LOG] - File Successfully saved to {full_file_path}")
1333
except Exception as e:
1434
await message.guild.get_channel(LOG_CHANNEL_ID).send(f"Error while saving: {e}")
15-
print(f"[file_save_LOG] - Error while saving: {e}")
35+
print(f"[file_save_LOG] - Error while saving: {e}")

commands/help_command.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import os
2+
import discord
3+
from discord.ext import commands
4+
5+
async def execute_help_command(client, message, config):
6+
"""
7+
Displays a list of all available commands and their descriptions.
8+
9+
Usage: !help or !?
10+
"""
11+
LOG_CHANNEL_ID = config["log_channel_id"]
12+
13+
commands_dir = r"D:\Coding\python-discord-windows-controller\commands"
14+
command_files = [f for f in os.listdir(commands_dir) if f.endswith('.py') and f != '__init__.py']
15+
16+
embed = discord.Embed(title="Bot Commands", description="Here are all available commands:", color=discord.Color.blue())
17+
18+
for file in command_files:
19+
command_name = file[:-3] # Remove .py extension
20+
module = __import__(f"commands.{command_name}", fromlist=[''])
21+
22+
# Try to get the docstring of the execute function
23+
try:
24+
func = getattr(module, f"execute_{command_name}_command")
25+
description = func.__doc__ or "No description available."
26+
except AttributeError:
27+
description = "No description available."
28+
29+
embed.add_field(name=f"!{command_name}", value=description, inline=False)
30+
31+
await message.channel.send(embed=embed)
32+
print(f"[help_command_LOG] - Help command executed.")
33+
await message.delete()

commands/lock_command.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33

44
async def execute_lock_command(client, message, config):
5+
"""
6+
Locks the computer screen.
7+
8+
Usage: !lock
9+
"""
510
LOG_CHANNEL_ID = config["log_channel_id"]
611

712
command = "rundll32.exe user32.dll,LockWorkStation"

0 commit comments

Comments
 (0)