Added format and color to the logs. Also enhanced the yaml/pcbnew log error.
This commit is contained in:
parent
a043e4f7da
commit
c0acfe3865
|
|
@ -7,6 +7,7 @@ import sys
|
|||
|
||||
from . import kiplot
|
||||
from . import config_reader
|
||||
from . import log
|
||||
|
||||
|
||||
def main():
|
||||
|
|
@ -30,18 +31,14 @@ def main():
|
|||
|
||||
args = parser.parse_args()
|
||||
|
||||
log_level = logging.INFO
|
||||
if args.verbose:
|
||||
log_level = logging.DEBUG
|
||||
if args.quiet:
|
||||
log_level = logging.WARNING
|
||||
logging.basicConfig(level=log_level)
|
||||
# Create a logger with the specified verbosity
|
||||
logger = log.init(args.verbose, args.quiet)
|
||||
|
||||
if not os.path.isfile(args.board_file):
|
||||
logging.error("Board file not found: {}".format(args.board_file))
|
||||
logger.error("Board file not found: {}".format(args.board_file))
|
||||
|
||||
if not os.path.isfile(args.plot_config):
|
||||
logging.error("Plot config file not found: {}"
|
||||
logger.error("Plot config file not found: {}"
|
||||
.format(args.plot_config))
|
||||
sys.exit(EXIT_BAD_ARGS)
|
||||
|
||||
|
|
@ -58,7 +55,7 @@ def main():
|
|||
errs = cfg.validate()
|
||||
|
||||
if errs:
|
||||
logging.error('Invalid config:\n\n' + "\n".join(errs))
|
||||
logger.error('Invalid config:\n\n' + "\n".join(errs))
|
||||
sys.exit(EXIT_BAD_CONFIG)
|
||||
|
||||
# Set up the plotter and do it
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
Class to read KiPlot config files
|
||||
"""
|
||||
|
||||
import logging
|
||||
import yaml
|
||||
import os
|
||||
import re
|
||||
|
||||
|
|
@ -11,10 +9,21 @@ import pcbnew
|
|||
|
||||
from . import plot_config as PC
|
||||
from . import error
|
||||
from . import log
|
||||
from . import misc
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
try:
|
||||
import yaml
|
||||
except:
|
||||
log.init(False,False)
|
||||
logger.error('No yaml module for Python, install python3-yaml')
|
||||
import sys
|
||||
sys.exit(misc.NO_YAML_MODULE)
|
||||
|
||||
|
||||
class CfgReader(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
|
@ -443,7 +452,7 @@ class CfgYamlReader(CfgReader):
|
|||
except KeyError:
|
||||
raise YamlError("Output need to have options specified")
|
||||
|
||||
logging.debug("Parsing output options for {} ({})".format(name, otype))
|
||||
logger.debug("Parsing output options for {} ({})".format(name, otype))
|
||||
|
||||
outdir = self._get_required(o_obj, 'dir')
|
||||
|
||||
|
|
@ -464,7 +473,7 @@ class CfgYamlReader(CfgReader):
|
|||
|
||||
def _parse_preflight(self, pf, cfg):
|
||||
|
||||
logging.debug("Parsing preflight options: {}".format(pf))
|
||||
logger.debug("Parsing preflight options: {}".format(pf))
|
||||
|
||||
if 'check_zone_fills' in pf:
|
||||
cfg.check_zone_fills = pf['check_zone_fills']
|
||||
|
|
|
|||
|
|
@ -3,20 +3,26 @@ Main Kiplot code
|
|||
"""
|
||||
|
||||
from datetime import datetime
|
||||
import logging
|
||||
import os
|
||||
import operator
|
||||
|
||||
from . import plot_config as PCfg
|
||||
from . import error
|
||||
from . import log
|
||||
from . import misc
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
try:
|
||||
import pcbnew
|
||||
from pcbnew import GERBER_JOBFILE_WRITER
|
||||
except ImportError:
|
||||
logging.error("Failed to import pcbnew Python module."
|
||||
log.init(False,False)
|
||||
logger.error("Failed to import pcbnew Python module."
|
||||
" Is KiCad installed?"
|
||||
" Do you need to add it to PYTHONPATH?")
|
||||
raise
|
||||
import sys
|
||||
sys.exit(misc.NO_PCBNEW_MODULE)
|
||||
|
||||
|
||||
class PlotError(error.KiPlotError):
|
||||
|
|
@ -33,18 +39,18 @@ class Plotter(object):
|
|||
|
||||
def plot(self, brd_file):
|
||||
|
||||
logging.debug("Starting plot of board {}".format(brd_file))
|
||||
logger.debug("Starting plot of board {}".format(brd_file))
|
||||
|
||||
board = pcbnew.LoadBoard(brd_file)
|
||||
|
||||
logging.debug("Board loaded")
|
||||
logger.debug("Board loaded")
|
||||
|
||||
self._preflight_checks(board)
|
||||
|
||||
for op in self.cfg.outputs:
|
||||
|
||||
logging.debug("Processing output: {}".format(op.name))
|
||||
logging.info('- %s (%s)' % (op.description,op.name))
|
||||
logger.debug("Processing output: {}".format(op.name))
|
||||
logger.info('- %s (%s)' % (op.description,op.name))
|
||||
|
||||
# fresh plot controller
|
||||
pc = pcbnew.PLOT_CONTROLLER(board)
|
||||
|
|
@ -64,7 +70,7 @@ class Plotter(object):
|
|||
|
||||
def _preflight_checks(self, board):
|
||||
|
||||
logging.debug("Preflight checks")
|
||||
logger.debug("Preflight checks")
|
||||
|
||||
if self.cfg.check_zone_fills:
|
||||
raise PlotError("Not sure if Python scripts can do zone check!")
|
||||
|
|
@ -157,11 +163,11 @@ class Plotter(object):
|
|||
plot_format = self._get_layer_plot_format(output)
|
||||
|
||||
# Plot single layer to file
|
||||
logging.debug("Opening plot file for layer {} ({})"
|
||||
logger.debug("Opening plot file for layer {} ({})"
|
||||
.format(layer.layer, suffix))
|
||||
plot_ctrl.OpenPlotfile(suffix, plot_format, desc)
|
||||
|
||||
logging.debug("Plotting layer {} to {}".format(
|
||||
logger.debug("Plotting layer {} to {}".format(
|
||||
layer.layer, plot_ctrl.GetPlotFileName()))
|
||||
plot_ctrl.PlotLayer()
|
||||
plot_ctrl.ClosePlot()
|
||||
|
|
@ -230,12 +236,12 @@ class Plotter(object):
|
|||
gen_report = to.generate_report
|
||||
|
||||
if gen_drill:
|
||||
logging.debug("Generating drill files in {}"
|
||||
logger.debug("Generating drill files in {}"
|
||||
.format(outdir))
|
||||
|
||||
if gen_map:
|
||||
drill_writer.SetMapFileFormat(to.map_options.type)
|
||||
logging.debug("Generating drill map type {} in {}"
|
||||
logger.debug("Generating drill map type {} in {}"
|
||||
.format(to.map_options.type, outdir))
|
||||
|
||||
drill_writer.CreateDrillandMapFilesSet(outdir, gen_drill, gen_map)
|
||||
|
|
@ -243,7 +249,7 @@ class Plotter(object):
|
|||
if gen_report:
|
||||
drill_report_file = os.path.join(outdir,
|
||||
to.report_options.filename)
|
||||
logging.debug("Generating drill report: {}"
|
||||
logger.debug("Generating drill report: {}"
|
||||
.format(drill_report_file))
|
||||
|
||||
drill_writer.GenDrillReportFile(drill_report_file)
|
||||
|
|
@ -464,13 +470,13 @@ class Plotter(object):
|
|||
# outdir is a combination of the config and output
|
||||
outdir = os.path.join(self.cfg.outdir, output.outdir)
|
||||
|
||||
logging.debug("Output destination: {}".format(outdir))
|
||||
logger.debug("Output destination: {}".format(outdir))
|
||||
|
||||
po.SetOutputDirectory(outdir)
|
||||
|
||||
def _configure_plot_ctrl(self, plot_ctrl, output):
|
||||
|
||||
logging.debug("Configuring plot controller for output")
|
||||
logger.debug("Configuring plot controller for output")
|
||||
|
||||
po = plot_ctrl.GetPlotOptions()
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
"""Log module
|
||||
|
||||
Handles logging initialization and formating.
|
||||
"""
|
||||
import sys
|
||||
import logging
|
||||
|
||||
# Default domain, base name for the tool
|
||||
domain = 'kilog'
|
||||
|
||||
def get_logger(name=None):
|
||||
"""Get a module for a submodule or the root logger if no name is provided"""
|
||||
return logging.getLogger(domain+'.'+name) if name else logging.getLogger(domain)
|
||||
|
||||
def set_domain(name):
|
||||
"""Set the base name for the tool"""
|
||||
global domain
|
||||
domain = name
|
||||
|
||||
|
||||
def init(verbose, quiet):
|
||||
"""Initialize the logging feature using a custom format and the specified verbosity level"""
|
||||
|
||||
log_level = logging.INFO
|
||||
if verbose:
|
||||
log_level = logging.DEBUG
|
||||
if quiet:
|
||||
log_level = logging.WARNING
|
||||
|
||||
logger=get_logger()
|
||||
logger.setLevel(log_level)
|
||||
ch = logging.StreamHandler()
|
||||
ch.setFormatter(CustomFormatter())
|
||||
logger.addHandler(ch)
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
class CustomFormatter(logging.Formatter):
|
||||
"""Logging Formatter to add colors"""
|
||||
|
||||
if sys.stderr.isatty():
|
||||
grey = "\x1b[38;21m"
|
||||
yellow = "\x1b[93;1m"
|
||||
red = "\x1b[91;1m"
|
||||
bold_red = "\x1b[91;21m"
|
||||
cyan = "\x1b[36;1m"
|
||||
reset = "\x1b[0m"
|
||||
else:
|
||||
grey = ""
|
||||
yellow = ""
|
||||
red = ""
|
||||
bold_red = ""
|
||||
cyan = ""
|
||||
reset = ""
|
||||
#format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
|
||||
format = "%(levelname)s:%(message)s (%(name)s - %(filename)s:%(lineno)d)"
|
||||
format_simple = "%(message)s"
|
||||
|
||||
FORMATS = {
|
||||
logging.DEBUG: cyan + format + reset,
|
||||
logging.INFO: grey + format_simple + reset,
|
||||
logging.WARNING: yellow + format + reset,
|
||||
logging.ERROR: red + format + reset,
|
||||
logging.CRITICAL: bold_red + format + reset
|
||||
}
|
||||
|
||||
def format(self, record):
|
||||
log_fmt = self.FORMATS.get(record.levelno)
|
||||
formatter = logging.Formatter(log_fmt)
|
||||
return formatter.format(record)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
"""Miscellaneous definitions
|
||||
"""
|
||||
|
||||
# Error levels
|
||||
NO_YAML_MODULE = 1
|
||||
NO_PCBNEW_MODULE = 2
|
||||
Loading…
Reference in New Issue