From f92ade0359a4fce131d4292f41140f41b9c4785c Mon Sep 17 00:00:00 2001 From: ANGELUSD11 Date: Tue, 28 Apr 2026 15:57:13 -0500 Subject: [PATCH] add linux support, update and fix dependences --- README.md | 120 +++++++++++++++++++++------------------------ config.example.ini | 2 +- main.py | 62 ++++++++++++++++++----- main.pyw | 62 ++++++++++++++++++----- requirements.txt | 2 +- 5 files changed, 160 insertions(+), 88 deletions(-) diff --git a/README.md b/README.md index 3f90d13..ffde02e 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,71 @@ -# VirtualBox Rich Presence +# VirtualBox Rich Presence (DiscordBox) [![pypresence](https://img.shields.io/badge/using-pypresence-00bb88.svg?style=for-the-badge&logo=discord&logoWidth=20)](https://github.com/qwertyquerty/pypresence) -## Screenshot -![discord ststus](.github/archived/images/v2023.10.01/discord-status.png) +Display your VirtualBox virtual machines as a Discord Rich Presence status. Works on Windows and Linux! -## Installation -*(for now only available on windows)* +## Screenshot +![discord status](.github/archived/images/v2023.10.01/discord-status.png) -Download [last release](https://github.com/bukanspot/DiscordBox/releases), instruction for installation include in zip file. +## Features & Improvements (Latest PR) +- **Zero-Manual SDK Setup:** Removed the requirement to manually install the VirtualBox SDK via `vboxapisetup.py`. The script now uses the `virtualbox` python wrapper which handles the connection automatically. +- **Cross-Platform Support:** Added full support for Linux and improved Windows compatibility. +- **Auto-Fixing Paths:** The script automatically detects if you are on Linux and corrects Windows-style paths in your configuration. +- **Dependency Automation:** Automatically installs `pywin32` on Windows systems if it's missing. +## Installation -## Develovment -- [Setup](#setup) -- [Config](#config) -- [Available Values](#available-values) -- [Usage](#usage) -- [Compile](#compile) +### Prerequisites +- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) installed on your system. +- Python 3.8+ ### Setup -First, clone or download the repository. - -```cmd -git clone git@github.com:bukanspot/DiscordBox.git -``` - -Then go to the [VirtualBox downloads page](https://www.virtualbox.org/wiki/Downloads) and download the VirtualBox SDK. - -After downloading it, extract the `VirtualBoxSDK-x.x.x-xxxxxx.zip` file and run the installer. - -```cmd -cd installer -``` - -```cmd -python vboxapisetup.py install -``` - -Then, install the required modules. - -```cmd -cd DiscordBox -``` - -```cmd -pip install -r requirements.txt -``` - -### Config - -The [config](config.example.ini) allows you to change what is displayed on your rich presence. +1. Clone or download the repository. + ```bash + git clone https://github.com/bukanspot/DiscordBox.git + cd DiscordBox + ``` + +2. Install the required modules. + ```bash + pip install -r requirements.txt + ``` + +3. Configure the application. + Make a copy of `config.example.ini` and rename it to `config.ini`. + ```bash + cp config.example.ini config.ini + ``` + +## Config +The `config.ini` allows you to customize what is displayed on your Discord status. ### Available Values +- `{machine name}`: Name of the machine in VirtualBox (e.g., "Development Server") +- `{os name}`: Category of the OS (e.g., "Linux", "Microsoft Windows") +- `{os version name}`: Specific OS name (e.g., "Ubuntu", "Windows 10") +- `{os version image}`: Asset key for the OS icon. +- `{architecture}`: OS architecture (e.g., "64", "32") +- `{architecture image}`: Asset key for the architecture icon. +- `{icon}`: The VirtualBox logo icon. + +## Usage +Run the script using Python: +```bash +python main.py +``` -- `{machine name}`: Name of the machine in VirtualBox (e.g. "My Windows Machine") -- `{os name}`: Name of OS. (e.g. "Microsoft Windows") -- `{os version name}`: Name of OS version. (e.g. "Windows 8") -- `{os version image}`: Image key of OS version. (e.g. "windows_8") -- `{architecture}`: OS architecture (e.g. "64") -- `{architecture image}`: Image key of OS architecture (e.g. "64") -- `{icon}`: Image key of VirtualBox Icon. - -### Usage - -Make a copy of [`config.example.ini`](config.example.ini) and remove the `.example`, then [edit it](#config) if you want. - -Run `main.py`. +*Note: On Windows, you can use `main.pyw` to run the script in the background without a console window.* -### Compile -For compile to `.exe` use this code -```cmd -pyinstaller.exe --onefile .\main.pyw +## Compilation (Optional) +To compile the script into a standalone executable (Windows): +```bash +pip install pyinstaller +pyinstaller --onefile --noconsole main.pyw ``` -The `.exe` file found in `dist` directory. +The resulting file will be in the `dist` directory. -## Note -- The original source has been archived, it's available at [vidhanio/virtualbox-rich-presence](https://github.com/vidhanio/virtualbox-rich-presence) -- File `main.py` is same as `main.pyw`, file `.pyw` just run terminal or cmd in background. +--- +## Credits +- Original source by [vidhanio/virtualbox-rich-presence](https://github.com/vidhanio/virtualbox-rich-presence) (Archived). +- Maintained and improved by [AcezukyRockon](https://github.com/bukanspot). diff --git a/config.example.ini b/config.example.ini index 6cfd4ae..b195eff 100644 --- a/config.example.ini +++ b/config.example.ini @@ -1,7 +1,7 @@ [Rich Presence] client_id=577508122629767179 -virtualbox_directory="C:\Program Files\Oracle\VirtualBox\VirtualBox.exe" +virtualbox_directory="/usr/bin/virtualbox" [In Machine] diff --git a/main.py b/main.py index b12493c..2f166b6 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,42 @@ from __future__ import annotations import virtualbox, json, pprint, configparser, time, psutil, sys, subprocess, os from pypresence import Presence +import platform +import sys + +# Install pywin32 on Windows if not present +if platform.system() == "Windows": + try: + import win32api + except ImportError: + print("pywin32 not found, installing...") + subprocess.check_call([sys.executable, "-m", "pip", "install", "pywin32"]) + import win32api # Initialize the config parser. config = configparser.ConfigParser() config.read("config.ini") # Initialize virtualbox dictionary. -directory = config["Rich Presence"]["virtualbox_directory"] -p = subprocess.Popen(directory) -pid = p.pid +if "Rich Presence" in config and "virtualbox_directory" in config["Rich Presence"]: + directory = config["Rich Presence"]["virtualbox_directory"].strip('"').strip("'") + # Si estamos en Linux pero la ruta guardada parece de Windows (tiene C:\ o \), usamos la de Linux. + if sys.platform.startswith("linux") and (":\\" in directory or "\\" in directory): + directory = "/usr/bin/virtualbox" +else: + # Valores por defecto si no hay config.ini + if sys.platform.startswith("win"): + directory = r"C:\Program Files\Oracle\VirtualBox\VirtualBox.exe" + else: + directory = "/usr/bin/virtualbox" + +try: + p = subprocess.Popen(directory) + pid = p.pid +except FileNotFoundError: + print(f"Error: No se pudo encontrar VirtualBox en {directory}") + sys.exit(1) + class RichPresence: def __init__(self): @@ -29,14 +56,27 @@ def __init__(self): self.format_dict = {"start": time.time()} while True: - - # Check if VirtualBox is running, and that the current OS is Windows. - # [TODO] Add support for other operating systems. - if ( - "VirtualBox.exe" in (p.name() for p in psutil.process_iter()) - or "VirtualBoxVM.exe" in (p.name() for p in psutil.process_iter()) - ): - + # Check if VirtualBox is running + vbox_running = False + if sys.platform.startswith("win"): + print("currently running in Windows") + vbox_processes = ["VirtualBox.exe", "VirtualBoxVM.exe"] + elif sys.platform.startswith("linux"): + print("currently running in Linux distro") + vbox_processes = ["VBoxSVC", "VirtualBoxVM", "VirtualBox"] + else: + vbox_processes = [] + + # Check if any VirtualBox process is running + for proc in psutil.process_iter(): + try: + if proc.name() in vbox_processes: + vbox_running = True + break + except (psutil.NoSuchProcess, psutil.AccessDenied): + pass + + if vbox_running: # Generate the list of machines. self.machine_list = self.generate_machine_list() diff --git a/main.pyw b/main.pyw index b12493c..2f166b6 100644 --- a/main.pyw +++ b/main.pyw @@ -1,15 +1,42 @@ from __future__ import annotations import virtualbox, json, pprint, configparser, time, psutil, sys, subprocess, os from pypresence import Presence +import platform +import sys + +# Install pywin32 on Windows if not present +if platform.system() == "Windows": + try: + import win32api + except ImportError: + print("pywin32 not found, installing...") + subprocess.check_call([sys.executable, "-m", "pip", "install", "pywin32"]) + import win32api # Initialize the config parser. config = configparser.ConfigParser() config.read("config.ini") # Initialize virtualbox dictionary. -directory = config["Rich Presence"]["virtualbox_directory"] -p = subprocess.Popen(directory) -pid = p.pid +if "Rich Presence" in config and "virtualbox_directory" in config["Rich Presence"]: + directory = config["Rich Presence"]["virtualbox_directory"].strip('"').strip("'") + # Si estamos en Linux pero la ruta guardada parece de Windows (tiene C:\ o \), usamos la de Linux. + if sys.platform.startswith("linux") and (":\\" in directory or "\\" in directory): + directory = "/usr/bin/virtualbox" +else: + # Valores por defecto si no hay config.ini + if sys.platform.startswith("win"): + directory = r"C:\Program Files\Oracle\VirtualBox\VirtualBox.exe" + else: + directory = "/usr/bin/virtualbox" + +try: + p = subprocess.Popen(directory) + pid = p.pid +except FileNotFoundError: + print(f"Error: No se pudo encontrar VirtualBox en {directory}") + sys.exit(1) + class RichPresence: def __init__(self): @@ -29,14 +56,27 @@ class RichPresence: self.format_dict = {"start": time.time()} while True: - - # Check if VirtualBox is running, and that the current OS is Windows. - # [TODO] Add support for other operating systems. - if ( - "VirtualBox.exe" in (p.name() for p in psutil.process_iter()) - or "VirtualBoxVM.exe" in (p.name() for p in psutil.process_iter()) - ): - + # Check if VirtualBox is running + vbox_running = False + if sys.platform.startswith("win"): + print("currently running in Windows") + vbox_processes = ["VirtualBox.exe", "VirtualBoxVM.exe"] + elif sys.platform.startswith("linux"): + print("currently running in Linux distro") + vbox_processes = ["VBoxSVC", "VirtualBoxVM", "VirtualBox"] + else: + vbox_processes = [] + + # Check if any VirtualBox process is running + for proc in psutil.process_iter(): + try: + if proc.name() in vbox_processes: + vbox_running = True + break + except (psutil.NoSuchProcess, psutil.AccessDenied): + pass + + if vbox_running: # Generate the list of machines. self.machine_list = self.generate_machine_list() diff --git a/requirements.txt b/requirements.txt index 28de2aa..5e0746f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ virtualbox pypresence psutil -pywin32 +#pywin32