Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions InteractiveHtmlBom/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,28 @@ def callback(_):
top_tb.Realize()


def _supports_ipc_api():
# KiCad 9+ ships the IPC API plugin system; the iBOM action is then
# provided through the plugin manifest (ipc_entrypoint.py) instead of
# the legacy SWIG ActionPlugin, so registering the SWIG one would just
# duplicate the toolbar button.
try:
import pcbnew
except ImportError:
return False
if not hasattr(pcbnew, 'Version'):
return False
try:
major = int(pcbnew.Version().split('.')[0].split('-')[0])
except (ValueError, IndexError):
return False
return major >= 9


if (not os.environ.get('INTERACTIVE_HTML_BOM_CLI_MODE', False) and
not os.path.basename(sys.argv[0]).startswith('generate_interactive_bom')):
from .ecad.kicad import InteractiveHtmlBomPlugin
not os.path.basename(sys.argv[0]).startswith('generate_interactive_bom')
and not _supports_ipc_api()):
from .ecad.kicad_swig import InteractiveHtmlBomPlugin

plugin = InteractiveHtmlBomPlugin()
plugin.register()
Expand Down
27 changes: 24 additions & 3 deletions InteractiveHtmlBom/ecad/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,19 @@
def get_parser_by_extension(file_name, config, logger):
ext = os.path.splitext(file_name)[1]
if ext == '.kicad_pcb':
return get_kicad_parser(file_name, config, logger)
# Prefer the IPC API parser, but only when an API server context is
# actually present (KICAD_API_SOCKET is set by a running KiCad or by
# kicad-cli's server mode, and kipy picks it up automatically).
# Without it we must not connect to some unrelated running KiCad and
# parse its open board; we fall back to the legacy SWIG parser, which
# is the only one that loads the board file straight from disk.
if os.environ.get('KICAD_API_SOCKET'):
try:
return get_kicad_parser(file_name, config, logger)
except Exception as e:
logger.info("IPC API unavailable (%s), "
"falling back to SWIG parser." % e)
return get_kicad_swig_parser(file_name, config, logger)
elif ext == '.json':
""".json file may be from EasyEDA or a generic json format"""
import io
Expand All @@ -21,8 +33,17 @@ def get_parser_by_extension(file_name, config, logger):
return None


def get_kicad_parser(file_name, config, logger, board=None):
from .kicad import PcbnewParser
def get_kicad_parser(file_name, config, logger, kicad=None, board=None):
from .kicad import IpcApiParser
return IpcApiParser(file_name, config, logger, kicad, board)


# Backwards compatible alias for the IPC parser.
get_kicad_ipc_parser = get_kicad_parser


def get_kicad_swig_parser(file_name, config, logger, board=None):
from .kicad_swig import PcbnewParser
return PcbnewParser(file_name, config, logger, board)


Expand Down
Loading