@@ -511,7 +511,22 @@ def open_file(filename):
511511 logwarn ('Failed to open browser: {}' .format (oe .message ))
512512
513513
514- def generate_file (pcb_file_dir , pcbdata , config ):
514+ def process_substitutions (bom_name_format , pcb_file_name , metadata ):
515+ # type: (str, str, dict)->str
516+ name = bom_name_format .replace ('%f' , os .path .splitext (pcb_file_name )[0 ])
517+ name = name .replace ('%p' , metadata ['title' ])
518+ name = name .replace ('%c' , metadata ['company' ])
519+ name = name .replace ('%r' , metadata ['revision' ])
520+ name = name .replace ('%d' , metadata ['date' ].replace (':' , '-' ))
521+ now = datetime .now ()
522+ name = name .replace ('%D' , now .strftime ('%Y-%m-%d' ))
523+ name = name .replace ('%T' , now .strftime ('%H-%M-%S' ))
524+ # sanitize the name to avoid characters illegal in file systems
525+ name = re .sub (r'[/\\?%*:|"<>]' , '_' , name )
526+ return name + '.html'
527+
528+
529+ def generate_file (pcb_file_dir , pcb_file_name , pcbdata , config ):
515530 def get_file_content (file_name ):
516531 path = os .path .join (os .path .dirname (__file__ ), "web" , file_name )
517532 with open (path , "r" ) as f :
@@ -520,12 +535,14 @@ def get_file_content(file_name):
520535 loginfo ("Dumping pcb json data" )
521536
522537 if os .path .isabs (config .bom_dest_dir ):
523- bom_file_name = config .bom_dest_dir
538+ bom_file_dir = config .bom_dest_dir
524539 else :
525- bom_file_name = os .path .join (pcb_file_dir , config .bom_dest_dir )
526- if not os .path .isdir (bom_file_name ):
527- os .makedirs (bom_file_name )
528- bom_file_name = os .path .join (bom_file_name , "ibom.html" )
540+ bom_file_dir = os .path .join (pcb_file_dir , config .bom_dest_dir )
541+ if not os .path .isdir (bom_file_dir ):
542+ os .makedirs (bom_file_dir )
543+ bom_file_name = process_substitutions (
544+ config .bom_name_format , pcb_file_name , pcbdata ['metadata' ])
545+ bom_file_name = os .path .join (bom_file_dir , bom_file_name )
529546 pcbdata_js = "var pcbdata = " + json .dumps (pcbdata )
530547 config_js = "var config = " + config .get_html_config ()
531548 html = get_file_content ("ibom.html" )
@@ -579,10 +596,10 @@ def main(pcb, config):
579596 file_date = datetime .fromtimestamp (file_mtime ).strftime (
580597 '%Y-%m-%d %H:%M:%S' )
581598 title = title_block .GetTitle ()
599+ pcb_file_name = os .path .basename (pcb_file_name )
582600 if not title :
583- title = os .path .basename (pcb_file_name )
584601 # remove .kicad_pcb extension
585- title = os .path .splitext (title )[0 ]
602+ title = os .path .splitext (pcb_file_name )[0 ]
586603 edges , bbox = parse_edges (pcb )
587604 if bbox is None :
588605 logerror ('Please draw pcb outline on the edges '
@@ -619,7 +636,7 @@ def main(pcb, config):
619636 pcbdata ["bom" ]["F" if layer == pcbnew .F_Cu else "B" ] = bom_table
620637
621638 pcbdata ["font_data" ] = font_parser .get_parsed_font ()
622- bom_file = generate_file (pcb_file_dir , pcbdata , config )
639+ bom_file = generate_file (pcb_file_dir , pcb_file_name , pcbdata , config )
623640
624641 if config .open_browser :
625642 loginfo ("Opening file in browser" )
@@ -689,7 +706,8 @@ def Run(self):
689706 formatter_class = argparse .ArgumentDefaultsHelpFormatter )
690707 parser .add_argument ('file' , type = str , help = "KiCad PCB file" )
691708 config = Config ()
692- config .add_options (parser )
709+ config .add_options (
710+ parser , dialog .GeneralSettingsPanel .FILE_NAME_FORMAT_HINT )
693711 args = parser .parse_args ()
694712 if not os .path .isfile (args .file .decode ('utf8' )):
695713 print ("File %s does not exist." % args .file )
0 commit comments