• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

INTI-CMNB / KiAuto / 6981974383

24 Nov 2023 02:31PM UTC coverage: 88.592%. First build
6981974383

push

github

set-soft
Forced test

3021 of 3410 relevant lines covered (88.59%)

3.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.67
/src/kicad2step_do
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
# Copyright (c) 2021 Salvador E. Tropea
4
# Copyright (c) 2021 Instituto Nacional de Tecnologïa Industrial
5
# License: Apache 2.0
6
# Project: KiAuto (formerly kicad-automation-scripts)
7
"""
6✔
8
Wrapper for kicad2step
9
On KiCad 6.0.0 this became a graphical tool
10
"""
11

12
import os
6✔
13
from subprocess import run, PIPE
6✔
14
import sys
6✔
15
import re
6✔
16
import argparse
6✔
17
import atexit
6✔
18
import json
6✔
19
import time
6✔
20
from time import sleep
6✔
21

22
# Look for the 'kiauto' module from where the script is running
23
script_dir = os.path.dirname(os.path.abspath(__file__))
6✔
24
sys.path.insert(0, os.path.dirname(script_dir))
6✔
25
# kiauto import
26
# Log functionality first
27
from kiauto import log
6✔
28
log.set_domain(os.path.splitext(os.path.basename(__file__))[0])
6✔
29
logger = log.init()
6✔
30

31
from kiauto.file_util import (get_log_files)
6✔
32
from kiauto.ui_automation import (PopenContext, xdotool, wait_not_focused, wait_for_window, recorded_xvfb,
6✔
33
                                  wait_point, text_replace, set_time_out_scale, clipboard_retrieve, ShowInfoAction)
34
from kiauto.misc import (REC_W, REC_H, __version__, WAIT_START, Config, __copyright__, __license__, TIME_OUT_MULT)
6✔
35

36

37
def run_gui_version(cmd, cfg, flog_out, flog_err):
6✔
38
    retry = 1
2✔
39
    with recorded_xvfb(cfg, retry):
2✔
40
        with PopenContext(cmd, stderr=flog_err, close_fds=True, stdout=flog_out, start_new_session=True) as proc:
2✔
41
            wait_for_window('KiCad to STEP', 'Kicad2step', popen_obj=proc)
2✔
42
            # Wait until the export finishes and get the messages
43
            timeout = 60*cfg.time_out_scale
2✔
44
            DELAY = 0.3
2✔
45
            for i in range(int(timeout/DELAY)):
2✔
46
                xdotool(['click', '1'])
2✔
47
                xdotool(['key', 'ctrl+a', 'ctrl+c'])
2✔
48
                text = clipboard_retrieve()
2✔
49
                res = proc.poll()
2✔
50
                if ('STRING not available' in text) or ('There is no owner' in text):
2✔
51
                    if res is not None:
×
52
                        logger.error('KiCad to STEP died')
×
53
                        break
×
54
                    sleep(DELAY)
×
55
                else:
56
                    logger.info(text)
2✔
57
                    for _ in range(int(timeout/DELAY)):
2✔
58
                        xdotool(['key', 'Tab', 'Return'])
2✔
59
                        sleep(DELAY)
2✔
60
                        res = proc.poll()
2✔
61
                        if res is not None:
2✔
62
                           break
2✔
63
                    if res is None:
2✔
64
                        logger.error('Still running')
×
65
                        res = -1
×
66
                    break
2✔
67
    return res
2✔
68

69

70
def run_cli_version(cmd, cfg):
6✔
71
    res = run(cmd, stderr=PIPE, stdout=PIPE)
4✔
72
    logger.info(res.stdout.decode())
4✔
73
    if res.stderr:
4✔
74
        logger.error(res.stderr.decode())
×
75
    return res.returncode
4✔
76

77

78
if __name__ == '__main__':
6✔
79
    parser = argparse.ArgumentParser(description='KiCad step converter wrapper')
6✔
80

81
    parser.add_argument('pcb_filename', help='KiCad PCB file')
6✔
82

83
    parser.add_argument('--output-filename', '-o', nargs=1, help='output filename')
6✔
84
    parser.add_argument('--force', '-f', help='overwrite output file', action='store_true')
6✔
85
    parser.add_argument('--drill-origin', help='Use Drill Origin for output origin', action='store_true')
6✔
86
    parser.add_argument('--grid-origin', help='Use Grid Origin for output origin', action='store_true')
6✔
87
    parser.add_argument('--user-origin', nargs=1, help='User-specified output origin ex. 1x1in, 1x1inch, 25.4x25.4mm (default mm)')
6✔
88
    parser.add_argument('--no-virtual', help="exclude 3D models for components with 'virtual'/'unspecified' attribute", action='store_true')
6✔
89
    parser.add_argument('--subst-models', help='Substitute STEP or IGS models with the same name in place of VRML models (KiCad 6)', action='store_true')
6✔
90
    parser.add_argument('--min-distance', nargs=1, help='Minimum distance between points to treat them as separate ones (default 0.01 mm)')
6✔
91
    # Our options
92
    parser.add_argument('--info', '-n', help='Show information about the installation', action=ShowInfoAction, nargs=0)
6✔
93
    parser.add_argument('--record', '-r', help='Record the UI automation', action='store_true')
6✔
94
    parser.add_argument('--rec_width', help='Record width ['+str(REC_W)+']', type=int, default=REC_W)
6✔
95
    parser.add_argument('--rec_height', help='Record height ['+str(REC_H)+']', type=int, default=REC_H)
6✔
96
    parser.add_argument('--start_x11vnc', '-s', help='Start x11vnc (debug)', action='store_true')
6✔
97
    parser.add_argument('--use_wm', '-m', help='Use a window manager (fluxbox)', action='store_true')
6✔
98
    parser.add_argument('--verbose', '-v', action='count', default=0)
6✔
99
    parser.add_argument('--version', '-V', action='version', version='%(prog)s '+__version__+' - ' +
6✔
100
                        __copyright__+' - License: '+__license__)
101
    parser.add_argument('--wait_key', '-w', help='Wait for key to advance (debug)', action='store_true')
6✔
102
    parser.add_argument('--wait_start', help='Timeout to pcbnew start ['+str(WAIT_START)+']', type=int, default=WAIT_START)
6✔
103
    parser.add_argument('--time_out_scale', help='Timeout multiplier, affects most timeouts',
6✔
104
                        type=float, default=TIME_OUT_MULT)
105
    parser.add_argument('--output-dir', '-d', nargs=1, help="output directory, only used when the name doesn't contain a path")
6✔
106
    args = parser.parse_args()
6✔
107
    log.set_level(logger, args.verbose)
6✔
108
    if args.output_dir is None:
6✔
109
        args.output_dir = '.'
×
110
    else:
111
        args.output_dir = args.output_dir[0]
6✔
112
    cfg = Config(logger, args.pcb_filename, args)
6✔
113

114
    # Create output dir, compute full name for output file and remove it
115
    output_dir = os.path.abspath(args.output_dir)
6✔
116
    cfg.video_dir = cfg.output_dir = output_dir
6✔
117
    logger.debug('Output dir: '+output_dir)
6✔
118
    cfg.video_name = 'kicad2step_screencast.ogv'
6✔
119
    os.makedirs(output_dir, exist_ok=True)
6✔
120

121
    logger.info('KiCad to STEP wrapper')
6✔
122

123
    cmd = [cfg.kicad2step]
6✔
124
    if cfg.ki7:
6✔
125
        cmd.extend(['pcb', 'export', 'step'])
2✔
126
    if args.output_filename:
6✔
127
        fname = args.output_filename[0]
6✔
128
        if os.path.basename(fname) == fname:
6✔
129
            fname = os.path.abspath(os.path.join(output_dir, fname))
6✔
130
        cmd.extend(['-o', fname])
6✔
131
    if args.force:
6✔
132
        cmd.append('-f')
×
133
    if args.drill_origin:
6✔
134
        cmd.append('--drill-origin')
×
135
    if args.grid_origin:
6✔
136
        cmd.append('--grid-origin')
×
137
    if args.user_origin:
6✔
138
        cmd.append('--user-origin='+args.user_origin[0])
×
139
    if args.no_virtual:
6✔
140
        if cfg.ki8:
×
141
            cmd.append('--no-unspecified')
×
142
        else:
143
            cmd.append('--no-virtual')
×
144
    if args.min_distance:
6✔
145
        cmd.append('--min-distance='+args.min_distance[0])
×
146
    if args.subst_models and cfg.kicad_version_major > 5:
6✔
147
        cmd.append('--subst-models')
4✔
148
    cmd.append(args.pcb_filename)
6✔
149
    logger.debug("Command: "+str(cmd))
6✔
150

151
    flog_out, flog_err, _ = get_log_files(output_dir, 'kicad2step')
6✔
152

153
    if cfg.kicad_version_major == 5 or cfg.ki7:
6✔
154
        res = run_cli_version(cmd, cfg)
4✔
155
    else:
156
        res = run_gui_version(cmd, cfg, flog_out, flog_err)
2✔
157
    logger.debug('Error level '+str(res))
6✔
158
    exit(res)
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc