Added filename expansion for SCH related outputs.

pdf_sch_print is the first to support it.
This commit is contained in:
Salvador E. Tropea 2020-07-13 19:20:25 -03:00
parent 3822a39671
commit d5168c37cd
6 changed files with 127 additions and 32 deletions

View File

@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `gerber.gerber_job_file` option to control the gerber job file name.
- `output` option to control the file name to all plot output formats.
- `drill`, `drill.map` and `position` file names can be configured.
- Output file names supports expansion of various interesting values (base
name, sheet title, revision, etc.)
### Changed
- Default file names for:
@ -23,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- dril: uses drill instead of drl, used in gbr and drl.
- position: no -pos in CSVs
- step: adds -3D
- pdf_sch_print: adds -schematic
## [0.5.0] - 2020-07-11
### Changed

View File

@ -1,3 +1,6 @@
import os
import re
from datetime import datetime
from sys import exit
from .misc import (EXIT_BAD_ARGS)
from .log import (get_logger)
@ -11,11 +14,91 @@ class GS(object):
Is a static class, just a placeholder for some global variables.
"""
pcb_file = None
sch_basename = None
sch_file = None
sch_basename = None
out_dir = None
filter_file = None
board = None
debug_enabled = False
n = datetime.now()
today = n.strftime('%Y-%m-%d')
time = n.strftime('%H-%M-%S')
# Data from the SCH because it doesn't have a Python API
sch_title = None
sch_date = None
sch_rev = None
sch_comp = None
# Data from the board title block
pcb_title = None
pcb_date = None
pcb_rev = None
pcb_comp = None
@staticmethod
def load_sch_title_block():
if GS.sch_title is not None:
return
GS.sch_title = ''
GS.sch_date = ''
GS.sch_rev = ''
GS.sch_comp = ''
if not GS.sch_file:
return
re_val = re.compile(r"(\w+)\s+\"([^\"]+)\"")
with open(GS.sch_file) as f:
for line in f:
m = re_val.match(line)
if not m:
continue
name, val = m.groups()
if name == "Title":
GS.sch_title = val
elif name == "Date":
GS.sch_date = val
elif name == "Rev":
GS.sch_rev = val
elif name == "Comp":
GS.sch_comp = val
elif name == "$EndDescr":
break
if not GS.sch_date:
file_mtime = os.path.getmtime(GS.sch_file)
GS.sch_file = datetime.fromtimestamp(file_mtime).strftime('%Y-%m-%d_%H-%M-%S')
GS.sch_basename = os.path.splitext(os.path.basename(GS.sch_file))[0]
if not GS.sch_title:
GS.sch_title = GS.sch_basename
logger.debug("SCH title: `{}`".format(GS.sch_title))
logger.debug("SCH date: `{}`".format(GS.sch_date))
logger.debug("SCH revision: `{}`".format(GS.sch_rev))
logger.debug("SCH company: `{}`".format(GS.sch_comp))
@staticmethod
def load_pcb_title_block():
if GS.pcb_title is not None:
return
GS.pcb_title = ''
GS.pcb_date = ''
GS.pcb_rev = ''
GS.pcb_comp = ''
if not GS.board:
return
# This is based on InterativeHtmlBom expansion
title_block = GS.board.GetTitleBlock()
GS.pcb_date = title_block.GetDate()
if not GS.pcb_date:
file_mtime = os.path.getmtime(GS.pcb_file)
GS.pcb_date = datetime.fromtimestamp(file_mtime).strftime('%Y-%m-%d_%H-%M-%S')
GS.pcb_basename = os.path.splitext(os.path.basename(GS.pcb_file))[0]
GS.pcb_title = title_block.GetTitle()
if not GS.pcb_title:
GS.pcb_title = GS.pcb_basename
GS.pcb_rev = title_block.GetRevision()
GS.pcb_comp = title_block.GetCompany()
logger.debug("PCB title: `{}`".format(GS.pcb_title))
logger.debug("PCB date: `{}`".format(GS.pcb_date))
logger.debug("PCB revision: `{}`".format(GS.pcb_rev))
logger.debug("PCB company: `{}`".format(GS.pcb_comp))
@staticmethod
def check_pcb():

View File

@ -150,31 +150,38 @@ class Optionable(object):
return ((k, v) for k, v in attrs.items() if k[0] != '_')
def expand_filename(self, out_dir, name, id='', ext=''):
""" Expands %x values in filenames """
""" Expands %* values in filenames.
Uses data from the PCB. """
if GS.board:
# This is based on InterativeHtmlBom expansion
title_block = GS.board.GetTitleBlock()
file_date = title_block.GetDate()
if not file_date:
file_mtime = os.path.getmtime(GS.pcb_file)
file_date = datetime.fromtimestamp(file_mtime).strftime('%Y-%m-%d_%H-%M-%S')
pcb_file_name = os.path.splitext(os.path.basename(GS.pcb_file))[0]
title = title_block.GetTitle()
if not title:
title = pcb_file_name
revision = title_block.GetRevision()
company = title_block.GetCompany()
n = datetime.now()
today = n.strftime('%Y-%m-%d')
time = n.strftime('%H-%M-%S')
GS.load_pcb_title_block()
# Do the replacements
name = name.replace('%f', pcb_file_name)
name = name.replace('%p', title)
name = name.replace('%c', company)
name = name.replace('%r', revision)
name = name.replace('%d', file_date)
name = name.replace('%D', today)
name = name.replace('%T', time)
name = name.replace('%f', GS.pcb_basename)
name = name.replace('%p', GS.pcb_title)
name = name.replace('%c', GS.pcb_comp)
name = name.replace('%r', GS.pcb_rev)
name = name.replace('%d', GS.pcb_date)
name = name.replace('%D', GS.today)
name = name.replace('%T', GS.time)
name = name.replace('%i', id)
name = name.replace('%x', ext)
# sanitize the name to avoid characters illegal in file systems
name = name.replace('\\', '/')
name = re.sub(r'[?%*:|"<>]', '_', name)
return os.path.abspath(os.path.join(out_dir, name))
def expand_filename_sch(self, out_dir, name, id='', ext=''):
""" Expands %* values in filenames.
Uses data from the SCH. """
if GS.sch_file:
GS.load_sch_title_block()
# Do the replacements
name = name.replace('%f', GS.sch_basename)
name = name.replace('%p', GS.sch_title)
name = name.replace('%c', GS.sch_comp)
name = name.replace('%r', GS.sch_rev)
name = name.replace('%d', GS.sch_date)
name = name.replace('%D', GS.today)
name = name.replace('%T', GS.time)
name = name.replace('%i', id)
name = name.replace('%x', ext)
# sanitize the name to avoid characters illegal in file systems

View File

@ -14,8 +14,8 @@ class PDF_Sch_PrintOptions(BaseOptions):
def __init__(self):
super().__init__()
with document:
self.output = ''
""" filename for the output PDF (the name of the schematic if empty) """ # pragma: no cover
self.output = '%f-%i.%x'
""" filename for the output PDF (%i=schematic %x=pdf) """ # pragma: no cover
def run(self, output_dir, board):
check_eeschema_do()
@ -29,8 +29,10 @@ class PDF_Sch_PrintOptions(BaseOptions):
logger.error(CMD_EESCHEMA_DO+' returned %d', ret)
exit(PDF_SCH_PRINT)
if self.output:
cur = os.path.abspath(os.path.join(output_dir, os.path.splitext(os.path.basename(GS.pcb_file))[0]) + '.pdf')
new = os.path.abspath(os.path.join(output_dir, self.output))
id = 'schematic'
ext = 'pdf'
cur = self.expand_filename_sch(output_dir, '%f.%x', id, ext)
new = self.expand_filename_sch(output_dir, self.output, id, ext)
logger.debug('Moving '+cur+' -> '+new)
os.rename(cur, new)

View File

@ -4,10 +4,10 @@ EELAYER END
$Descr A4 11693 8268
encoding utf-8
Sheet 1 1
Title ""
Date ""
Rev ""
Comp ""
Title "BoM Test"
Date "13/07/2020"
Rev "r1"
Comp "INTI-CMNB"
Comment1 ""
Comment2 ""
Comment3 ""

View File

@ -23,7 +23,7 @@ PDF_DIR = ''
PDF_FILE = 'Schematic.pdf'
def test_print_sch():
def test_print_sch_ok():
prj = 'bom'
ctx = context.TestContext('PrSCH', prj, 'print_sch', PDF_DIR)
ctx.run()