diff --git a/.gitignore b/.gitignore index 31a0f73..2ad7aac 100644 --- a/.gitignore +++ b/.gitignore @@ -140,4 +140,6 @@ cython_debug/ # Project Specific Excludes .vscode secrets.txt -messages.txt \ No newline at end of file +messages.txt +Vagrantfile +.vagrant \ No newline at end of file diff --git a/template_vagrantfile b/template_vagrantfile new file mode 100644 index 0000000..08ae8d4 --- /dev/null +++ b/template_vagrantfile @@ -0,0 +1,32 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| + config.vm.box = "generic/ubuntu2010" + + # Publically forwarded ports. + # The below ports are accessible to all machines on the same network. + # To limit access to the local network, add "host_ip". + # Eg: config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" + config.vm.network "forwarded_port", guest: 8000, host: 8000 # Web App + config.vm.network "forwarded_port", guest: 9000, host: 9000 # Remote server + + # Explicitly create a shared folder of the Vagrantfile directory at /vagrant in the VM + config.vm.synced_folder ".", "/vagrant" + + # Install NXBT + config.vm.provision "shell", inline: <<-SHELL + apt-get update + apt-get install -y python3-pip bluez bluetooth pkg-config build-essential libdbus-glib-1-dev libgirepository1.0-dev + {{SHELL_CONFIG}} + SHELL + + # Enable USB Controller on VirtualBox + config.vm.provider "virtualbox" do |vb| + vb.memory = "2048" + vb.cpus = 2 + vb.customize ["modifyvm", :id, "--usb", "on"] + vb.customize ["modifyvm", :id, "--usbehci", "on"] + {{USB_FILTER}} + end +end diff --git a/vagrant_setup.py b/vagrant_setup.py new file mode 100644 index 0000000..0cf65ed --- /dev/null +++ b/vagrant_setup.py @@ -0,0 +1,131 @@ +import re +from shutil import which +import subprocess +import os + + +def find_line_items(identifier, input_string): + pattern = re.compile(fr"(?<={re.escape(identifier)}: ).*.") + matches = pattern.findall(input_string) + matches = list(map(str.strip, matches)) + return matches + +def get_usb_devices(): + usb_string = subprocess.check_output(['VBoxManage', 'list', 'usbhost']) + usb_string = usb_string.decode("utf-8") + + usb_devices = usb_string.split("\n\n") + devices = [] + for device in usb_devices: + productid = find_line_items("ProductId", device) + vendorid = find_line_items("VendorId", device) + manufacturer = find_line_items("Manufacturer", device) + product = find_line_items("Product", device) + + if (len(productid) < 1 or len(vendorid) < 1 or + len(manufacturer) < 1 or len(product) < 1): + continue + + productid = productid[0] + vendorid = vendorid[0] + manufacturer = manufacturer[0] + product = product[0] + + if len(productid) != 13 or len(vendorid) != 13: + continue + + devices.append({ + 'product': product, + 'manufacturer': manufacturer, + 'productid': productid[8:12], + 'vendorid': vendorid[8:12] + }) + + return devices + +def is_cli(cli_string): + return which(cli_string) is not None + +def check_cli(name, cli_string): + print(name, end="") + if is_cli(cli_string): + print(" [OK]") + else: + print(" [ERROR]") + print(f" -> {name} wasn't found on your system") + exit(1) + +GH_SHELL_CONFIG = """cd /vagrant + pip3 install -e .""" +PYPI_SHELL_CONFIG = """pip3 install nxbt""" + +if __name__ == "__main__": + print("Checking for the required utilities...") + check_cli("Vagrant", "vagrant") + check_cli("VirtualBox", "VBoxManage") + check_cli("Git", "git") + print("") + + print("---") + print("Welcome to the nxbt-vagrant setup.") + print("As part of the first step in this process, you will " + "select the USB Bluetooth adapter that will be used with NXBT.") + print("Please ensure that your adapter is plugged into this computer.") + print("---") + input("Press the enter key to continue.") + print("") + + print("USB Devices:") + print("---") + devices = get_usb_devices() + for i, device in enumerate(devices): + print(f"{i:3}. {device['product']} ({device['manufacturer']})") + print() + + # Choose a USB Bluetooth adapter + invalid_choice = True + while invalid_choice: + usb_choice = input( + f"Please choose your Bluetooth USB Adapter from the above list [0-{len(devices)-1}]: ") + if usb_choice.isdigit() and int(usb_choice) < len(devices): + invalid_choice = False + else: + print(f"Invalid choice. Please choose a number from 0 to {len(devices)-1}.") + adapter_info = devices[int(usb_choice)] + print("") + + # Choose how to install NXBT (PyPi or Github) + invalid_choice = True + while invalid_choice: + install_choice = input( + "Would you like to install NXBT from (1) PyPi or (2) install from local files? (1/2) ") + if install_choice in ['1', '2']: + invalid_choice = False + else: + print("Invalid choice. Please choose PyPi (1) or Github clone/install (2)") + print("") + + print("Configuring...") + with open("template_vagrantfile", "r") as f: + vagrantfile = f.read() + + vb_usb_filter = f"""vb.customize ["usbfilter", "add", "0", + "--target", :id, + "--name", "{adapter_info['product']} ({adapter_info['manufacturer']})", + "--product", "{adapter_info['product']}", + "--manufacturer", "{adapter_info['manufacturer']}", + "--productid", "{adapter_info['productid']}", + "--vendorid", "{adapter_info['vendorid']}",]""" + vagrantfile = vagrantfile.replace("{{USB_FILTER}}", vb_usb_filter) + if install_choice == '1': + vagrantfile = vagrantfile.replace("{{SHELL_CONFIG}}", PYPI_SHELL_CONFIG) + else: + vagrantfile = vagrantfile.replace("{{SHELL_CONFIG}}", GH_SHELL_CONFIG) + + with open("Vagrantfile", "w") as f: + f.write(vagrantfile) + print("Done!") + print("") + + print("You can now start the NXBT Vagrant Box with 'vagrant up'.") + print("After booting up, the Vagrant Box can be access with 'vagrant ssh'.")