From 5ce3da2bcc5b879385d7edff82106239f894da8a Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Thu, 25 Jun 2020 11:32:13 -0300 Subject: [PATCH] Added a macro decorator to register output classes. --- kiplot/macros.py | 20 +++++++++++++++++++- kiplot/out_dxf.py | 8 ++------ kiplot/out_excellon.py | 8 ++------ kiplot/out_gerb_drill.py | 11 ++++------- kiplot/out_gerber.py | 8 ++------ kiplot/out_hpgl.py | 8 ++------ kiplot/out_ibom.py | 10 +++------- kiplot/out_kibom.py | 10 +++------- kiplot/out_pdf.py | 8 ++------ kiplot/out_pdf_pcb_print.py | 12 ++++-------- kiplot/out_pdf_sch_print.py | 12 ++++-------- kiplot/out_position.py | 10 +++------- kiplot/out_ps.py | 8 ++------ kiplot/out_step.py | 10 +++------- kiplot/out_svg.py | 8 ++------ 15 files changed, 57 insertions(+), 94 deletions(-) diff --git a/kiplot/macros.py b/kiplot/macros.py index a0b0acb2..75d7d618 100644 --- a/kiplot/macros.py +++ b/kiplot/macros.py @@ -1,4 +1,5 @@ -from ast import (Assign, Name, Attribute, Expr, Num, Str, NameConstant, Load, Store, UnaryOp, USub) +from ast import (Assign, Name, Attribute, Expr, Num, Str, NameConstant, Load, Store, UnaryOp, USub, + ClassDef, Call, ImportFrom, alias) def document(sentences, to_source, **kw): @@ -55,3 +56,20 @@ def document(sentences, to_source, **kw): prev = s # Return the modified AST return sentences + + +def output_class(tree, **kw): + if isinstance(tree, ClassDef): + # Create the register call + name = tree.name + reg_name = name.lower() + # BaseOutput.register member: + attr = Attribute(value=Name(id='BaseOutput', ctx=Load()), attr='register', ctx=Load()) + # Function call to it passing reg_name and name + do_register = Expr(value=Call(func=attr, args=[Str(s=reg_name), Name(id=name, ctx=Load())], keywords=[])) + + # Create the import + do_import = ImportFrom(module='out_base', names=[alias(name='BaseOutput', asname=None)], level=1) + + return [do_import, tree, do_register] + return tree diff --git a/kiplot/out_dxf.py b/kiplot/out_dxf.py index 9ace46a2..16a577c9 100644 --- a/kiplot/out_dxf.py +++ b/kiplot/out_dxf.py @@ -1,10 +1,10 @@ from pcbnew import PLOT_FORMAT_DXF from .error import KiPlotConfigurationError -from .out_base import (BaseOutput) from .out_any_layer import (AnyLayer) -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 +@output_class class DXF(AnyLayer): """ DXF (Drawing Exchange Format) @@ -41,7 +41,3 @@ class DXF(AnyLayer): def _configure_plot_ctrl(self, po, output_dir): super()._configure_plot_ctrl(po, output_dir) po.SetDXFPlotPolygonMode(self.polygon_mode) - - -# Register it -BaseOutput.register('dxf', DXF) diff --git a/kiplot/out_excellon.py b/kiplot/out_excellon.py index d3af23a6..7d49fc8d 100644 --- a/kiplot/out_excellon.py +++ b/kiplot/out_excellon.py @@ -1,9 +1,9 @@ from pcbnew import (EXCELLON_WRITER) -from .out_base import (BaseOutput) from .out_any_drill import (AnyDrill) -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 +@output_class class Excellon(AnyDrill): """ Excellon drill format This is the main format for the drilling machine. @@ -26,7 +26,3 @@ class Excellon(AnyDrill): drill_writer.SetOptions(self.mirror_y_axis, self.minimal_header, offset, self.pth_and_npth_single_file) drill_writer.SetFormat(self.metric_units, EXCELLON_WRITER.DECIMAL_FORMAT) return drill_writer - - -# Register it -BaseOutput.register('excellon', Excellon) diff --git a/kiplot/out_gerb_drill.py b/kiplot/out_gerb_drill.py index 088f167d..17c6c9b9 100644 --- a/kiplot/out_gerb_drill.py +++ b/kiplot/out_gerb_drill.py @@ -1,15 +1,16 @@ from pcbnew import (GERBER_WRITER) -from .out_base import (BaseOutput) from .out_any_drill import (AnyDrill) +from kiplot.macros import macros, output_class # noqa: F401 -class GerbDrill(AnyDrill): +@output_class +class Gerb_Drill(AnyDrill): """ Gerber drill format This is the information for the drilling machine in gerber format. You can create a map file for documentation purposes. This output is what you get from the 'File/Fabrication output/Drill Files' menu in pcbnew. """ def __init__(self, name, type, description): - super(GerbDrill, self).__init__(name, type, description) + super(Gerb_Drill, self).__init__(name, type, description) def _configure_writer(self, board, offset): drill_writer = GERBER_WRITER(board) @@ -17,7 +18,3 @@ class GerbDrill(AnyDrill): drill_writer.SetFormat(5) drill_writer.SetOptions(offset) return drill_writer - - -# Register it -BaseOutput.register('gerb_drill', GerbDrill) diff --git a/kiplot/out_gerber.py b/kiplot/out_gerber.py index 667c00cd..3c81db00 100644 --- a/kiplot/out_gerber.py +++ b/kiplot/out_gerber.py @@ -1,10 +1,10 @@ from pcbnew import (PLOT_FORMAT_GERBER) -from .out_base import (BaseOutput) from .out_any_layer import (AnyLayer) from .error import KiPlotConfigurationError -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 +@output_class class Gerber(AnyLayer): """ Gerber format This is the main fabrication format for the PCB. @@ -52,7 +52,3 @@ class Gerber(AnyLayer): po.SetCreateGerberJobFile(self.create_gerber_job_file) po.SetUseGerberAttributes(self.use_gerber_x2_attributes) po.SetIncludeGerberNetlistInfo(self.use_gerber_net_attributes) - - -# Register it -BaseOutput.register('gerber', Gerber) diff --git a/kiplot/out_hpgl.py b/kiplot/out_hpgl.py index 79298080..82ba3458 100644 --- a/kiplot/out_hpgl.py +++ b/kiplot/out_hpgl.py @@ -1,10 +1,10 @@ from pcbnew import (PLOT_FORMAT_HPGL) -from .out_base import (BaseOutput) from .out_any_layer import (AnyLayer) from .error import KiPlotConfigurationError -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 +@output_class class HPGL(AnyLayer): """ HPGL (Hewlett & Packard Graphics Language) Exports the PCB for plotters and laser printers. @@ -41,7 +41,3 @@ class HPGL(AnyLayer): def _configure_plot_ctrl(self, po, output_dir): super()._configure_plot_ctrl(po, output_dir) po.SetHPGLPenDiameter(self.pen_width) - - -# Register it -BaseOutput.register('hpgl', HPGL) diff --git a/kiplot/out_ibom.py b/kiplot/out_ibom.py index 4c857fd0..c8427ba7 100644 --- a/kiplot/out_ibom.py +++ b/kiplot/out_ibom.py @@ -1,15 +1,15 @@ import os from subprocess import (check_output, STDOUT, CalledProcessError) -from .out_base import (BaseOutput) from .misc import (CMD_IBOM, URL_IBOM, BOM_ERROR) from .kiplot import (GS, check_script) -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger(__name__) -class IBoM(BaseOutput): +@output_class +class IBoM(BaseOutput): # noqa: F821 """ IBoM (Interactive HTML BoM) Generates an interactive web page useful to identify the position of the components in the PCB. For more information: https://github.com/INTI-CMNB/InteractiveHtmlBom @@ -45,7 +45,3 @@ class IBoM(BaseOutput): logger.debug('Output from command: '+e.output.decode()) exit(BOM_ERROR) logger.debug('Output from command:\n'+cmd_output.decode()+'\n') - - -# Register it -BaseOutput.register('ibom', IBoM) diff --git a/kiplot/out_kibom.py b/kiplot/out_kibom.py index d9e055cc..9acd24e2 100644 --- a/kiplot/out_kibom.py +++ b/kiplot/out_kibom.py @@ -1,17 +1,17 @@ import os from glob import (glob) from subprocess import (check_output, STDOUT, CalledProcessError) -from .out_base import (BaseOutput) from .error import KiPlotConfigurationError from .misc import (CMD_KIBOM, URL_KIBOM, BOM_ERROR) from .kiplot import (GS, check_script) -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger(__name__) -class KiBoM(BaseOutput): +@output_class +class KiBoM(BaseOutput): # noqa: F821 """ KiBoM (KiCad Bill of Materials) Used to generate the BoM in HTML or CSV format using the KiBoM plug-in. For more information: https://github.com/INTI-CMNB/KiBoM @@ -52,7 +52,3 @@ class KiBoM(BaseOutput): for f in glob(os.path.join(output_dir, prj)+'*.tmp'): os.remove(f) logger.debug('Output from command:\n'+cmd_output.decode()) - - -# Register it -BaseOutput.register('kibom', KiBoM) diff --git a/kiplot/out_pdf.py b/kiplot/out_pdf.py index 3e632f93..a0bc7da4 100644 --- a/kiplot/out_pdf.py +++ b/kiplot/out_pdf.py @@ -1,10 +1,10 @@ from pcbnew import PLOT_FORMAT_PDF -from .out_base import BaseOutput from .out_any_layer import AnyLayer from .error import KiPlotConfigurationError -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 +@output_class class PDF(AnyLayer): """ PDF (Portable Document Format) Exports the PCB to the most common exhange format. Suitable for printing. @@ -37,7 +37,3 @@ class PDF(AnyLayer): def config(self, outdir, options, layers): super().config(outdir, options, layers) self._drill_marks = self._drill_marks_map[self._drill_marks] - - -# Register it -BaseOutput.register('pdf', PDF) diff --git a/kiplot/out_pdf_pcb_print.py b/kiplot/out_pdf_pcb_print.py index 239b85ab..1cb56ef6 100644 --- a/kiplot/out_pdf_pcb_print.py +++ b/kiplot/out_pdf_pcb_print.py @@ -1,23 +1,23 @@ import os from subprocess import (call) -from .out_base import BaseOutput from .pre_base import BasePreFlight from .error import (KiPlotConfigurationError, PlotError) from .kiplot import (check_script, GS) from .misc import (CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, PDF_PCB_PRINT) -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger(__name__) -class PDFPcbPrint(BaseOutput): +@output_class +class PDF_Pcb_Print(BaseOutput): # noqa: F821 """ PDF PCB Print (Portable Document Format) Exports the PCB to the most common exhange format. Suitable for printing. This is the main format to document your PCB. This output is what you get from the 'File/Print' menu in pcbnew. """ def __init__(self, name, type, description): - super(PDFPcbPrint, self).__init__(name, type, description) + super(PDF_Pcb_Print, self).__init__(name, type, description) # Options with document: self.output_name = '' @@ -58,7 +58,3 @@ class PDFPcbPrint(BaseOutput): if ret: logger.error(CMD_PCBNEW_PRINT_LAYERS+' returned %d', ret) exit(PDF_PCB_PRINT) - - -# Register it -BaseOutput.register('pdf_pcb_print', PDFPcbPrint) diff --git a/kiplot/out_pdf_sch_print.py b/kiplot/out_pdf_sch_print.py index 64e4d82d..fc511dc2 100644 --- a/kiplot/out_pdf_sch_print.py +++ b/kiplot/out_pdf_sch_print.py @@ -1,21 +1,21 @@ import os from subprocess import (call) -from .out_base import BaseOutput from .kiplot import (check_eeschema_do, GS) from .misc import (CMD_EESCHEMA_DO, PDF_SCH_PRINT) -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger(__name__) -class PDFSchPrint(BaseOutput): +@output_class +class PDF_Sch_Print(BaseOutput): # noqa: F821 """ PDF Schematic Print (Portable Document Format) Exports the PCB to the most common exhange format. Suitable for printing. This is the main format to document your schematic. This output is what you get from the 'File/Print' menu in eeschema. """ def __init__(self, name, type, description): - super(PDFSchPrint, self).__init__(name, type, description) + super(PDF_Sch_Print, self).__init__(name, type, description) self._sch_related = True # Options with document: @@ -38,7 +38,3 @@ class PDFSchPrint(BaseOutput): new = os.path.abspath(os.path.join(output_dir, self.output)) logger.debug('Moving '+cur+' -> '+new) os.rename(cur, new) - - -# Register it -BaseOutput.register('pdf_sch_print', PDFSchPrint) diff --git a/kiplot/out_position.py b/kiplot/out_position.py index ef92de58..362b212b 100644 --- a/kiplot/out_position.py +++ b/kiplot/out_position.py @@ -2,12 +2,12 @@ import os import operator from datetime import datetime from pcbnew import (IU_PER_MM, IU_PER_MILS) -from .out_base import BaseOutput from .error import KiPlotConfigurationError -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 -class Position(BaseOutput): +@output_class +class Position(BaseOutput): # noqa: F821 """ Pick & place Generates the file with position information for the PCB components, used by the pick and place machine. This output is what you get from the 'File/Fabrication output/Footprint poistion (.pos) file' menu in pcbnew. """ @@ -174,7 +174,3 @@ class Position(BaseOutput): self._do_position_plot_ascii(board, output_dir, columns, modules, maxlengths) else: # if self.format == 'CSV': self._do_position_plot_csv(board, output_dir, columns, modules) - - -# Register it -BaseOutput.register('position', Position) diff --git a/kiplot/out_ps.py b/kiplot/out_ps.py index ef96938f..ccee1119 100644 --- a/kiplot/out_ps.py +++ b/kiplot/out_ps.py @@ -1,10 +1,10 @@ from pcbnew import PLOT_FORMAT_POST -from .out_base import BaseOutput from .out_any_layer import AnyLayer from .error import KiPlotConfigurationError -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 +@output_class class PS(AnyLayer): """ PS (Postscript) Exports the PCB to a format suitable for printing. @@ -56,7 +56,3 @@ class PS(AnyLayer): po.SetFineScaleAdjustX(self.scale_adjust_x) po.SetFineScaleAdjustX(self.scale_adjust_y) po.SetA4Output(self.a4_output) - - -# Register it -BaseOutput.register('ps', PS) diff --git a/kiplot/out_step.py b/kiplot/out_step.py index d422f9b1..daa49a92 100644 --- a/kiplot/out_step.py +++ b/kiplot/out_step.py @@ -1,17 +1,17 @@ import os import re from subprocess import (check_output, STDOUT, CalledProcessError) -from .out_base import BaseOutput from .error import KiPlotConfigurationError from .misc import (KICAD2STEP, KICAD2STEP_ERR) from .kiplot import (GS) -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger(__name__) -class STEP(BaseOutput): +@output_class +class STEP(BaseOutput): # noqa: F821 """ STEP (ISO 10303-21 Clear Text Encoding of the Exchange Structure) Exports the PCB as a 3D model. This is the most common 3D format for exchange purposes. @@ -81,7 +81,3 @@ class STEP(BaseOutput): logger.debug('Output from command: '+e.output.decode()) exit(KICAD2STEP_ERR) logger.debug('Output from command:\n'+cmd_output.decode()) - - -# Register it -BaseOutput.register('step', STEP) diff --git a/kiplot/out_svg.py b/kiplot/out_svg.py index a94f06ff..4da8898f 100644 --- a/kiplot/out_svg.py +++ b/kiplot/out_svg.py @@ -1,10 +1,10 @@ from pcbnew import PLOT_FORMAT_SVG -from .out_base import BaseOutput from .out_any_layer import AnyLayer from .error import KiPlotConfigurationError -from kiplot.macros import macros, document # noqa: F401 +from kiplot.macros import macros, document, output_class # noqa: F401 +@output_class class SVG(AnyLayer): """ SVG (Scalable Vector Graphics) Exports the PCB to a format suitable for 2D graphics software. @@ -37,7 +37,3 @@ class SVG(AnyLayer): def config(self, outdir, options, layers): super().config(outdir, options, layers) self._drill_marks = self._drill_marks_map[self._drill_marks] - - -# Register it -BaseOutput.register('svg', SVG)