Files
Michael StanglandClaude Opus 5.5 6bdaa62a7d Optionsschalter vereinheitlicht, .sh-Skripte von überall aufrufbar
- gleiche Aufgabe = gleicher Schalter in allen Programmen:
  -c/--config (Alias --cfg), -i, -o/--outdir, --section, --format,
  -f/--force, -j, -t/--test, -y/--dry, -v
- svgconvert: -o statt -s (Alias --svgfolder), --section statt --format
  für die Sektion (Standard png), --format überschreibt das Bildformat
- webscan: --timeout und --browser nur noch lang (kollidierten mit -t/-b)
- glyphextract: -i nimmt Glyph oder Font, -e extrahiert (statt -f/-t)
- setenv.sh ermittelt das Projektverzeichnis selbst, alle .sh laden es
  relativ zum Skript; extract-font/fonttest reichen weitere Optionen durch
- Hilfetexte korrigiert, doc/README.md: Abschnitt "Gemeinsame Optionen"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 09:37:20 +02:00

268 lines
10 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__version__ = "0.0.1"
__author__ = "Kamil Bugajski (kamil@bugajski.de)"
__copyright__ = "Copyright 2012, Kamil bugajski"
__license__ = "BSD"
import os
import cProfile
import optparse
import configparser
import re
import shutil
import subprocess
import csv
from string import Template
from concurrent import futures
from progressbar import EasyProgressBar
from utils import CompleteEnding
# ImageMagick 7 heisst "magick"; unter Windows ist "convert" ein Systemprogramm
IMAGEMAGICK = shutil.which('magick') or shutil.which('convert')
def get_translation(cfg_path, sec_name):
""" lädt die Zuordnung zwischen einem .csv Eingabefile und den Attributen"""
config = configparser.RawConfigParser()
config.read(cfg_path, encoding='utf-8')
trans = dict(config.items(sec_name))
return dict([[v,k] for k,v in trans.items()])
def getfilelist(path):
""" Receives a path and returns a list with all svg-files in this path."""
svgnames = []
allfiles = os.listdir(path)
for i in allfiles:
if re.findall('.svg', i):
svgnames.append(os.path.splitext(i)[0])
return svgnames
def convertSVG(in_path,filename,pic_config):
"""Create a svg-file for conversion-testing"""
inpath = os.path.join(in_path,str(filename)+".svg")
jpgpath = os.path.join(in_path,str(filename)+"." + pic_config['format'])
if (not options.force) and os.path.isfile(jpgpath):
if options.verbose:
print (filename, 'already exist!')
else:
cmdline = [IMAGEMAGICK,
'-density', pic_config['density'],
'-background', pic_config['background'],
inpath,
'-resize', pic_config['width'] + "x" + pic_config['height'],
jpgpath]
if not options.dry:
subprocess.check_call(cmdline)
if options.verbose:
print ('start converting', filename)
Epb.slide_progbar()
def startThreading(filelist,pic_config,work_path):
"""Start the threads for the conversion"""
if not filelist:
print ('filelist is empty - nothing to convert')
return True
executor = futures.ThreadPoolExecutor(max_workers = int(options.jobs))
global Epb
Epb = EasyProgressBar(array = filelist, show=options.progress)
for svg in filelist:
executor.submit(convertSVG,work_path,svg,pic_config)
executor.shutdown(wait=True)
def createTestFiles(in_path,filenumber):
"""Create a svg-file for conversion-testing"""
if options.verbose:
print ('creating:',filenumber)
path = os.path.join(in_path,str(filenumber)+".svg")
svgfile = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="531.49603"
height="531.49603"
id="svg2">
<defs
id="defs4" />
<g
transform="translate(0,-520.86597)"
id="layer1">
<text
x="174.28572"
y="806.64789"
id="text2985"
xml:space="preserve"
style="font-size:72px;font-style:normal;font-weight:normal;line-height:\
125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;\
stroke:none;font-family:Sans">
<tspan
x="174.28572"
y="806.64789"
id="tspan2987"
style="font-size:72px;font-style:normal;font-variant:normal;\
font-weight:normal;font-stretch:normal;font-family:Ubuntu;\
-inkscape-font-specification:Ubuntu">$sub</tspan></text>
</g>
</svg>
'''
s = Template(svgfile)
f = open(path,'w')
writefile = s.substitute(sub = filenumber)
f.write(writefile)
f.close
def main():
"""get all information from the switches an start the parallel conversion"""
if not IMAGEMAGICK and not options.dry:
print('ImageMagick not found. Please install it (https://imagemagick.org).')
return None
#set the workpath and the default config
work_path = os.path.expandvars(options.outdir)
if not os.path.exists(work_path):
print('\"'+ work_path +'\" does not exist. Please give the name of the folder with the svg-files!')
return None
pic_config = {
'width' : '600',
'height' : '200',
'format' : options.format or 'jpg',
'density' : '150',
'background' : 'white',
'folder' : work_path,
'customerid' : 'customerid'
}
if options.test:
filelist = []
if options.verbose:
print ('---- Start of test-sequence ----')
print ('---- creating testfiles: ----')
for filenumber in range(0, int(options.test),1):
createTestFiles(work_path,filenumber)
filelist.append(filenumber)
if options.verbose:
print ('---- starting the conversion: ----')
startThreading(filelist,pic_config,work_path)
if options.verbose:
print ('---- test completed ----')
return True
filelist = getfilelist(work_path)
#load and override the default config if we receive an config file
if options.config:
config_path = os.path.expandvars(os.path.join('$PICCREATE_CFG', CompleteEnding(options.config, 'cfg')))
if not os.path.exists(config_path):
print('\"'+ config_path +'\" does not exist. Please give the name of a config file!')
return None
config = configparser.RawConfigParser()
config.read(config_path, encoding='utf-8')
# fill the config
if not config.has_section(options.section):
print('section [' + options.section + '] is missing in ' + config_path)
return None
pic_config = dict(config.items(options.section))
if options.format:
pic_config['format'] = options.format
if options.background:
pic_config['background'] = options.background
elif 'background' in pic_config:
pass
else:
pic_config['background'] = 'transparent'
#get the translation for reading the csv
Trans = get_translation(config_path, 'translation')
for origin,translation in Trans.items():
if re.match(translation,'customerid'):
pic_config['customerid'] = origin
#chek if all files from the csv were successfully created and in the workfolder
if options.infile:
csv_path = os.path.expandvars(os.path.join('$PICCREATE_IN', CompleteEnding(options.infile, 'csv')))
if not os.path.exists(csv_path):
print('\"'+ csv_path +'\" does not exist. Please give the correct name of a csv file!')
return None
if not options.config:
print ("you must give a config file for checking the svg files")
return None
svglist = []
with open(csv_path, newline='', encoding='utf-8') as csvfile:
reader = csv.DictReader(csvfile,delimiter = ';')
for row in reader:
if row[pic_config['customerid']] not in filelist:
print ('Bild', row[pic_config['customerid']], 'fehlt')
else:
svglist.append(row[pic_config['customerid']])
filelist = svglist
#start conversion in multiple threads
if options.verbose:
print ('---- starting the conversion: ----')
startThreading(filelist,pic_config,work_path)
if options.verbose:
print ("---- conversion completed ----")
if options.dry:
print ("Dry option selected. No file was converted!")
if __name__ == '__main__':
parser = optparse.OptionParser(usage="""%prog [options]
Example usage
-------------
If no switch is given all svg files in the output folder will be converted.
Full help:
$ %prog -h (or --help for possible options)
Read Confg, create wakeup and scale this kind of jiffy box
$ %prog -c test -i test
""", version='%prog ' + __version__)
parser.add_option("-b", "--background", dest="background",
help="set the backgroundcolor. 'none' for transparent",
action='store')
parser.add_option("-c", "--config", "--cfg", dest="config",
help="config file in cfg/ with the picture sizes",
action='store')
parser.add_option("-f", "--force", dest="force", default=False,
help="create the pictures, no matter if they already exist",
action='store_true')
parser.add_option("--section", dest="section", default='png',
help="section in the config file. default is png",
action='store')
parser.add_option("--format", dest="format",
help="jpg or png, overrides the config",
action='store')
parser.add_option("-i", "--infile", dest="infile",
help="csv file with input of names/content",
action='store')
parser.add_option("-j", "--jobs", dest="jobs", default=8,
help="number of parallel jobs. default is 8",
action='store')
parser.add_option("-p", "--progress", dest="progress",
help="print a progression bar",
action='store_true')
parser.add_option("-o", "--outdir", "--svgfolder", dest="outdir",
default=os.path.expandvars('$PICCREATE_OUT'),
help="folder with the svg files, the pictures are written there too. "
"default is $PICCREATE_OUT",
action='store')
parser.add_option("-t", "--test", dest="test",
help="number of default svg-files that will be created and tested",
action='store')
parser.add_option("-v", "--verbose", dest="verbose",
help="print the status of the conversion",
action='store_true')
parser.add_option("-y", "--dry", dest="dry",
help="dont generate images, just try if the conversion would succeed",
action='store_true')
(options, args) = parser.parse_args()
if options.test:
cProfile.run('main()')
else:
main()