2023-11-25 13:33:24 +08:00
|
|
|
import logging
|
2023-11-09 04:51:26 +08:00
|
|
|
import os
|
|
|
|
from typing import List
|
|
|
|
import win32gui
|
|
|
|
import time
|
|
|
|
import psutil
|
|
|
|
import win32process
|
|
|
|
import pypresence
|
|
|
|
|
|
|
|
rpc = pypresence.Presence("1171889899679531129")
|
|
|
|
data = None
|
|
|
|
|
|
|
|
rpc.connect()
|
|
|
|
|
2023-11-25 13:33:24 +08:00
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
|
|
|
2023-11-09 04:51:26 +08:00
|
|
|
|
|
|
|
def find_active_processes(name: str) -> List[int]:
|
|
|
|
processes = []
|
|
|
|
for pid in psutil.pids():
|
|
|
|
try:
|
|
|
|
if psutil.Process(pid) and psutil.Process(pid).name() == name:
|
|
|
|
processes.append(pid)
|
|
|
|
except psutil.NoSuchProcess:
|
|
|
|
pass
|
|
|
|
return processes
|
|
|
|
|
|
|
|
|
2023-11-25 13:33:24 +08:00
|
|
|
LTSPICE_NAME_0 = "LTSPICE.exe"
|
|
|
|
LTSPICE_NAME_1 = "XVIIx64.exe"
|
2023-11-09 04:51:26 +08:00
|
|
|
|
|
|
|
last_state = {}
|
|
|
|
last_program = {"pid": None, "path": None}
|
|
|
|
|
|
|
|
|
|
|
|
def handle_ltspice(title: str) -> None:
|
|
|
|
global last_state
|
|
|
|
filename = title.replace("LTspice XVII - ", "")
|
|
|
|
file, ext = os.path.splitext(filename)
|
2023-11-09 15:24:22 +08:00
|
|
|
|
|
|
|
# The window title is of the format "LTspice XVII - [filename.extension]"
|
|
|
|
# if the view is maximized
|
|
|
|
if ext and ext[-1] == "]":
|
|
|
|
ext = ext[:-1]
|
|
|
|
file = file[1:]
|
|
|
|
# filename = filename[1:-1]
|
|
|
|
|
2023-11-09 04:51:26 +08:00
|
|
|
state = {}
|
|
|
|
if ext in (".asc",): # SCHEMATICS
|
|
|
|
state = {
|
|
|
|
"large_image": "schematic",
|
|
|
|
"large_text": "Schematic",
|
|
|
|
"details": "Editing a schematic",
|
|
|
|
"state": filename,
|
|
|
|
}
|
|
|
|
elif ext in (
|
|
|
|
".cir",
|
|
|
|
".net",
|
|
|
|
".sp",
|
|
|
|
): # NETLISTS
|
|
|
|
state = {
|
|
|
|
"large_image": "symbol", # TODO: Add images for these
|
|
|
|
"large_text": "Symbol",
|
|
|
|
"details": "Editing a netlist",
|
|
|
|
"state": filename,
|
|
|
|
}
|
|
|
|
elif ext in (
|
|
|
|
".raw",
|
|
|
|
".fra",
|
|
|
|
): # WAVEFORMS
|
|
|
|
state = {
|
|
|
|
"large_image": "graph",
|
|
|
|
"large_text": "Waveform",
|
|
|
|
"details": "Viewing a graph",
|
|
|
|
"state": filename,
|
|
|
|
}
|
|
|
|
elif ext in (
|
|
|
|
".bjt",
|
|
|
|
".cap",
|
|
|
|
".dio",
|
|
|
|
".ind",
|
|
|
|
".jft",
|
|
|
|
".mos",
|
|
|
|
".res",
|
|
|
|
): # DISCRETES
|
|
|
|
state = {
|
|
|
|
"large_image": "symbol", # TODO: Add images for each one of these
|
|
|
|
"large_text": "Symbol",
|
|
|
|
"details": "Editing a discrete component",
|
|
|
|
"state": filename,
|
|
|
|
}
|
|
|
|
elif ext in (".asy",): # SYMBOLS
|
|
|
|
state = {
|
|
|
|
"large_image": "symbol",
|
|
|
|
"large_text": "Symbol",
|
|
|
|
"details": "Editing a symbol",
|
|
|
|
"state": filename,
|
|
|
|
}
|
|
|
|
else:
|
|
|
|
rpc.clear()
|
|
|
|
state = {
|
|
|
|
"large_image": "logo",
|
|
|
|
"large_text": "LTspice",
|
|
|
|
"details": "Idling",
|
|
|
|
}
|
|
|
|
|
|
|
|
if state != last_state:
|
2023-11-25 13:33:24 +08:00
|
|
|
logging.info(f"update rpc! {state['details']}")
|
|
|
|
logging.info(f"{filename=} {file=} {ext=}")
|
2023-11-09 04:51:26 +08:00
|
|
|
rpc.update(
|
|
|
|
**state,
|
|
|
|
start=int(time.time()),
|
|
|
|
small_image="logo",
|
|
|
|
small_text="LTspice",
|
|
|
|
)
|
|
|
|
last_state = state
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
|
|
|
global last_program
|
|
|
|
WINDOW_HANDLERS = {
|
2023-11-25 13:33:24 +08:00
|
|
|
LTSPICE_NAME_0: handle_ltspice,
|
|
|
|
LTSPICE_NAME_1: handle_ltspice,
|
2023-11-09 04:51:26 +08:00
|
|
|
}
|
|
|
|
while True:
|
|
|
|
foreground_hwnd = win32gui.GetForegroundWindow()
|
|
|
|
pid = win32process.GetWindowThreadProcessId(foreground_hwnd)
|
|
|
|
if pid[-1] >= 0:
|
2023-11-09 15:24:22 +08:00
|
|
|
try:
|
|
|
|
active_process = psutil.Process(pid[-1])
|
|
|
|
if active_process.name() in WINDOW_HANDLERS.keys():
|
2023-11-25 13:33:24 +08:00
|
|
|
logging.info(pid[-1])
|
|
|
|
logging.info(active_process.name())
|
2023-11-09 15:24:22 +08:00
|
|
|
handler = WINDOW_HANDLERS[active_process.name()]
|
|
|
|
if handler(win32gui.GetWindowText(foreground_hwnd)):
|
|
|
|
last_program = {
|
|
|
|
"pid": active_process.pid,
|
|
|
|
"path": active_process.name(),
|
|
|
|
}
|
|
|
|
except psutil.NoSuchProcess:
|
|
|
|
pass
|
2023-11-09 04:51:26 +08:00
|
|
|
if last_program["pid"] is not None and last_program[
|
|
|
|
"pid"
|
|
|
|
] not in find_active_processes(last_program["path"]):
|
|
|
|
last_program = {"pid": None, "path": None}
|
2023-11-25 13:33:24 +08:00
|
|
|
logging.info("Clear RPC - program closed")
|
2023-11-09 04:51:26 +08:00
|
|
|
rpc.clear()
|
2023-11-25 13:33:24 +08:00
|
|
|
time.sleep(3)
|
2023-11-09 04:51:26 +08:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|