app
Adom Desktop - KiCad Bridge
Public Made by Adomby adom
Reference implementation of the KiCad bridge — multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
"""Handler for install_footprint command.
Atomic command that decodes a base64-encoded .kicad_mod file, places it
into the global Adom.pretty footprint library, registers the library in
fp-lib-table if needed, and optionally opens the Footprint Editor.
Steps:
1. Decode base64 file content
2. Write .kicad_mod into Adom.pretty/ (creates directory if needed)
3. Register Adom in fp-lib-table if not already registered
4. Optionally open Footprint Editor with the footprint loaded
"""
import base64
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
from lib_table import LibTable, LibEntry
from handlers.open_footprint_editor import handle_open_footprint_editor
ADOM_FP_LIB_NAME = "Adom"
ADOM_FP_DIR_NAME = "Adom.pretty"
ADOM_FP_LIB_DESCRIPTION = "Adom Desktop - custom footprints"
def handle_install_footprint(kicad_info: dict, args: dict) -> dict:
"""Install a KiCad footprint from base64-encoded file content.
Args:
kicad_info: KiCad detection info dict.
args: Dict with:
- fileName (required): Original filename (e.g. "BMI423.kicad_mod")
- fileContent (required): Base64-encoded .kicad_mod file content
- footprintName (optional): Specific footprint to open in the editor
- openEditor (optional): Whether to open Footprint Editor (default: true)
Returns:
Dict with:
- success: bool
- installedPath: path to the .kicad_mod file
- footprintName: name of the footprint
- libraryName: always "Adom"
- editorOpened: bool
- output: human-readable summary
- error: error message (only if success is false)
"""
if not kicad_info.get("installed"):
return {
"success": False,
"error": "KiCad not installed",
"_hint": "Report to the user and ask them to install KiCad from https://www.kicad.org/download/, then retry.",
}
file_name = args.get("fileName", "")
file_content = args.get("fileContent", "")
footprint_name = args.get("footprintName", "")
quiet_install = args.get("quietInstall", False)
open_editor = False if quiet_install else args.get("openEditor", True)
if not file_name:
return {"success": False, "error": "No fileName specified"}
if not file_content:
return {"success": False, "error": "No fileContent specified"}
# --- Step 1: Decode the file ---
try:
decoded = base64.b64decode(file_content)
footprint_text = decoded.decode("utf-8")
except Exception as e:
return {"success": False, "error": f"Failed to decode fileContent: {e}"}
# Extract footprint name from file content if not provided
if not footprint_name:
import re
name_match = re.search(r'\(footprint "([^"]+)"', footprint_text)
if name_match:
footprint_name = name_match.group(1)
else:
footprint_name = Path(file_name).stem
# --- Step 2: Write into Adom.pretty ---
user_dir = kicad_info.get("user_dir")
config_dir = kicad_info.get("config_dir")
if not user_dir or not config_dir:
return {"success": False, "error": "KiCad user/config directory not found"}
fp_dir = Path(user_dir) / "footprints"
fp_dir.mkdir(parents=True, exist_ok=True)
pretty_dir = fp_dir / ADOM_FP_DIR_NAME
pretty_dir.mkdir(parents=True, exist_ok=True)
# The .kicad_mod file must be named to match the footprint name inside it
dest_file = pretty_dir / f"{footprint_name}.kicad_mod"
dest_file.write_text(footprint_text, encoding="utf-8")
# --- Step 3: Register in fp-lib-table ---
table_path = Path(config_dir) / "fp-lib-table"
table = LibTable.parse_file(str(table_path))
registered = False
if not table.has_library(ADOM_FP_LIB_NAME):
uri = str(pretty_dir).replace("\\", "/")
entry = LibEntry(
name=ADOM_FP_LIB_NAME,
lib_type="KiCad",
uri=uri,
options="",
descr=ADOM_FP_LIB_DESCRIPTION,
)
table.add_library(entry)
table.write_file(str(table_path))
registered = True
# --- Step 4: Optionally open Footprint Editor ---
editor_opened = False
editor_output = ""
if open_editor:
editor_result = handle_open_footprint_editor(kicad_info, {
"footprintName": footprint_name,
"libraryName": ADOM_FP_LIB_NAME,
})
editor_opened = editor_result.get("success", False)
editor_output = editor_result.get("output", editor_result.get("error", ""))
# --- Build result ---
output_parts = [
f"Footprint '{footprint_name}' installed to '{ADOM_FP_LIB_NAME}' library"
]
if registered:
output_parts.append("registered in fp-lib-table")
if editor_opened:
output_parts.append(f"Footprint Editor: {editor_output}")
elif open_editor:
output_parts.append(f"Footprint Editor: {editor_output}")
return {
"success": True,
"output": " | ".join(output_parts),
"installedPath": str(dest_file),
"footprintName": footprint_name,
"libraryName": ADOM_FP_LIB_NAME,
"editorOpened": editor_opened,
}