- bin/svgconvert.sh ist jetzt ein Wrapper wie svgconvert.bat (gleiche Optionen unter Linux und Windows) - svgconvert.py: Endung .cfg/.csv bei -c/-i optional - bin/generationlib (nur von svgconvert.sh benutzt) entfernt - doc/README.md angepasst Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
261 lines
9.8 KiB
Python
261 lines
9.8 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('$PICCREATE_OUT')
|
|
if options.svgfolder:
|
|
work_path = os.path.expandvars(options.svgfolder)
|
|
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,
|
|
'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
|
|
pic_config = dict(config.items(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", dest="config",
|
|
help="config file with all data for jobs",
|
|
action='store')
|
|
parser.add_option("-f", "--force", dest="force", default=False,
|
|
help="create the pictures, no matter if they alreads exist",
|
|
action='store_true')
|
|
parser.add_option("--format", dest="format", default='jpg',
|
|
help="format of the picture",
|
|
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("-s", "--svgfolder", dest="svgfolder",
|
|
help="path to the folder with the svg-files",
|
|
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 success",
|
|
action='store_true')
|
|
|
|
(options, args) = parser.parse_args()
|
|
if options.test:
|
|
cProfile.run('main()')
|
|
else:
|
|
main()
|