-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.pyw
126 lines (105 loc) · 3.8 KB
/
main.pyw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import configparser
import logging
import os
import sched
import sys
import threading
import time
from shutil import copyfile
import discord
import serial
import serial.tools.list_ports
from pyautogui import hotkey
import SysTrayIcon
REFRESH_RATE = 0.1 # seconds
DISCONNECTED = 0
CONNECTED = 1
MUTED = 2
DEAFENED = 3
logger = logging.getLogger()
logger.setLevel(logging.INFO)
class DiscordListener:
def __init__(self):
self.client = discord.Client()
self.config = configparser.ConfigParser()
if not os.path.isfile("config.ini"):
copyfile("default.ini", "config.ini")
self.config.read("config.ini")
self.token = self.config['LoginInfo']['Token']
self.port = self.get_arduino_port()
self.ser = serial.Serial(self.port, timeout=0)
self.threads = dict()
self.sched = sched.scheduler(time.time, time.sleep)
self.sched.enter(REFRESH_RATE, 1, self.update_status)
sched_thread = threading.Thread(target=self.sched.run, daemon=True)
sched_thread.start()
self.threads["sched_thread"] = sched_thread
def run_tray_icon(): SysTrayIcon.SysTrayIcon('tray_icon.ico', 'DesktopBuddy', (),
on_quit=lambda *_: self.exit())
tray_thread = threading.Thread(target=run_tray_icon, daemon=False)
tray_thread.start()
self.threads["tray_thread"] = tray_thread
self.voice_state = -1
self.attempt_login()
@staticmethod
def get_arduino_port():
logging.info("Finding Arduino port...")
ports = list(serial.tools.list_ports.comports())
for p in ports:
if 'arduino' in p.description.lower():
logging.info("Done")
return p.device
raise Exception("No Arduino found on any COM ports")
def get_client_state(self):
state = DISCONNECTED
if self.client.is_ready():
for server in self.client.guilds:
mem = server.get_member(self.client.user.id)
vs = mem.voice
if vs and vs.channel is not None:
if vs.deaf or vs.self_deaf:
state = DEAFENED
break
elif vs.mute or vs.self_mute:
state = MUTED
break
else:
state = CONNECTED
break
return state
def update_status(self):
state = self.get_client_state()
if self.voice_state != state:
self.voice_state = state
self.ser.write(str(state).encode())
logging.info("Serial TX: {}".format(str(state).encode()))
if self.ser.in_waiting:
byte_in = self.ser.read()
logging.info("Serial RX: {}".format(str(byte_in)))
if byte_in == b'\x00':
hotkey(*self.config["Keybinds"]["Mute"].split('+'))
self.sched.enter(REFRESH_RATE, 1, self.update_status)
def attempt_login(self):
logging.info("Attempting to log in with token {}".format(self.token))
if self.threads.get("client_thread"):
self.client.logout()
client_thread = threading.Thread(target=self.client.run, args=(self.token,), kwargs={"bot": False}, daemon=True)
client_thread.start()
self.threads["client_thread"] = client_thread
logging.info("Login successful!")
def exit(self):
logging.info("Exiting...")
self.ser.write(0xFF)
self.ser.close()
sys.exit()
def main():
DiscordListener()
if __name__ == "__main__":
# If we have any exception, the program restarts
while True:
try:
main()
except Exception as e:
logging.exception(e)
else:
break