Skip to content

Update and fix select_device.sh - #150

Open
dropafterfree wants to merge 2 commits into
southoz:mainfrom
dropafterfree:add-missing-colors
Open

Update and fix select_device.sh#150
dropafterfree wants to merge 2 commits into
southoz:mainfrom
dropafterfree:add-missing-colors

Conversation

@dropafterfree

Copy link
Copy Markdown

-Add shebang
-Add missing colors definitions
-Rename select_devices.sh to select_device.sh to align with ps1 script

  -Add shebang
  -Add missing colors definitions
  -Rename select_devices.sh to select_device.sh to align with ps1 script
@itsfarseen

Copy link
Copy Markdown

I have a python version that I wrote cuz I couldn't find a version that runs on Linux/Mac in the latest release .7z file.

In case it's useful to anyone, just want to share here:

#!/usr/bin/env python3
"""R36S / Clone / Soysauce DTB Selector — cross-platform port of select_device.ps1"""

import configparser
import math
import shutil
import sys
from pathlib import Path

# ANSI color helpers
CYAN = "\033[36m"
DARK_CYAN = "\033[36;2m"
GREEN = "\033[32m"
YELLOW = "\033[33m"
RED = "\033[31m"
MAGENTA = "\033[35m"
DARK_GRAY = "\033[90m"
WHITE = "\033[97m"
RESET = "\033[0m"


def colored(text, color):
    return f"{color}{text}{RESET}"


def main():
    print(colored("\n==================================================", CYAN))
    print(colored("   R36S DTB Firmware Selector", CYAN))
    print(colored("==================================================\n", CYAN))

    # Determine root folder
    script_dir = Path(__file__).resolve().parent
    if script_dir.name == "dtb":
        root_dir = script_dir.parent
    else:
        root_dir = script_dir

    print(colored(f"Root folder: {root_dir}", DARK_CYAN))

    # Find INI
    ini_candidates = [root_dir / "r36_devices.ini", root_dir / "dtb" / "r36_devices.ini"]
    ini_path = None
    for candidate in ini_candidates:
        if candidate.is_file():
            ini_path = candidate
            print(colored(f"Using INI: {ini_path}", GREEN))
            break

    if not ini_path:
        print(colored("ERROR: r36_devices.ini not found", RED))
        sys.exit(1)

    # Parse INI
    print(colored("\nReading devices...", YELLOW))

    config = configparser.ConfigParser(comment_prefixes=(";",), inline_comment_prefixes=(";",))
    config.optionxform = str  # preserve key case
    config.read(ini_path, encoding="utf-8")

    sections = list(config.sections())
    if not sections:
        print(colored("ERROR: No devices found in INI", RED))
        sys.exit(1)

    # Group by variant
    grouped = {}
    variant_order = []
    for dev in sections:
        v = config.get(dev, "variant", fallback="unknown")
        if v not in grouped:
            grouped[v] = []
            variant_order.append(v)
        grouped[v].append(dev)

    display_order = ["r36s", "clone", "soysauce"]
    sorted_variants = [v for v in display_order if v in grouped]
    sorted_variants += [v for v in variant_order if v not in display_order]

    # Two-column menu
    print(colored("\nAvailable devices:", CYAN))
    print()

    global_index = 1
    device_list = {}

    for variant in sorted_variants:
        devices_in_group = grouped[variant]
        if not devices_in_group:
            continue

        print(colored(f"Variant: {variant}", MAGENTA))
        print(colored("-" * 70, DARK_GRAY))

        half = math.ceil(len(devices_in_group) / 2)
        left = devices_in_group[:half]
        right = devices_in_group[half:]

        for row in range(half):
            left_part = ""
            right_part = ""

            if row < len(left):
                num = global_index
                left_part = f"{num:4d}. {left[row]}"
                device_list[num] = left[row]
                global_index += 1

            if row < len(right):
                num = global_index
                right_part = f"{num:4d}. {right[row]}"
                device_list[num] = right[row]
                global_index += 1

            print(f"{left_part:<40}{right_part}")

        print()

    total = len(sections)
    print(colored("=" * 70, DARK_GRAY))
    print(colored(f"Total: {total} devices", CYAN))

    # Selection
    print(colored(f"\nSelect number (1-{total})", CYAN))
    try:
        raw_input = input().strip()
    except (EOFError, KeyboardInterrupt):
        print()
        sys.exit(1)

    if not raw_input or not raw_input.isdigit():
        print(colored("Please enter a valid number.", RED))
        sys.exit(1)

    sel_num = int(raw_input)
    if sel_num < 1 or sel_num > total:
        print(colored(f"Number must be between 1 and {total}", RED))
        sys.exit(1)

    chosen = device_list[sel_num]
    variant = config.get(chosen, "variant", fallback=None)

    if not variant:
        print(colored(f"ERROR: No 'variant' defined for {chosen}", RED))
        sys.exit(1)

    print(colored(f"\nSelected : {chosen}", GREEN))
    print(colored(f"Variant  : {variant}", GREEN))

    # Build path
    source_folder = root_dir / "dtb" / variant / chosen

    if not source_folder.is_dir():
        print(colored(f"ERROR: Folder not found: {source_folder}", RED))
        sys.exit(1)

    print(colored("\nWill copy files from:", CYAN))
    print(colored(f"  {source_folder}", WHITE))

    # Files to be copied
    print("\nFiles that will be copied from source folder:")
    files_to_copy = list(source_folder.iterdir())
    files_to_copy = [f for f in files_to_copy if f.is_file()]

    if not files_to_copy:
        print(colored("  WARNING: No files found in source folder!", YELLOW))
    else:
        for f in files_to_copy:
            print(f"  {f.name}")

    # Files in root that will be deleted/overwritten
    print("\n.dtb files in root that will be deleted/overwritten:")
    existing_dtbs = list(root_dir.glob("*.dtb"))

    if not existing_dtbs:
        print("  (none currently present)")
    else:
        for f in existing_dtbs:
            print(f"  {f.name}")

    print()
    confirm = input("Proceed with copy? (Y/N) ").strip()
    if confirm.lower() != "y":
        print(colored("Cancelled.", YELLOW))
        sys.exit(0)

    # Delete old .dtb files
    print(colored("\nDeleting old .dtb files in root...", YELLOW))
    deleted = list(root_dir.glob("*.dtb"))

    if deleted:
        print("Deleted:")
        for f in deleted:
            print(f"  {f.name}")
            f.unlink()
    else:
        print("  No .dtb files to delete")

    # Copy new files
    print(colored("\nCopying new files to root...", YELLOW))
    copied = []
    for f in files_to_copy:
        dest = root_dir / f.name
        shutil.copy2(f, dest)
        copied.append(f.name)

    if copied:
        print("Copied:")
        for name in copied:
            print(f"  {name}")
    else:
        print(colored("  No files were copied (source may be empty)", YELLOW))

    print(colored("\n==================================================", GREEN))
    print(colored("   SUCCESS - DTB files updated for:", GREEN))
    print(colored(f"   {chosen}", WHITE))
    print(colored(f"   Variant: {variant}", WHITE))
    print(colored("==================================================\n", GREEN))


if __name__ == "__main__":
    main()

@Exellent1988

Copy link
Copy Markdown

Worked pervectly for me (Macos). Thanks @itsfarseen 👍🏽
i just inserted the contents in a select_device.sh file. chmod +x to the file, run ... done 🏆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants