| #!/usr/bin/env python
|
| # vim: noet nowrap number ts=4
|
|
|
| import barcode
|
| from lxml import etree
|
| from lxml.builder import E
|
| #import bytes_as_braille as bab
|
|
|
| #from bs4 import BeautifulSoup
|
|
|
| def enc(string):
|
| return string.encode('utf-8')
|
|
|
| def dec(byt):
|
| return byt.decode('utf-8')
|
|
|
|
|
| class MakeAnInt(Exception): pass
|
|
|
| barcode.Code128.default_writer_options = {
|
| "module_width": 0.2,
|
| "module_height": 10.0,
|
| "quiet_zone": 6.5,
|
| "font_size": 10,
|
| "text_distance": 3.0,
|
| "background": None,
|
| "foreground": "black",
|
| "write_text": True,
|
| "text": "",
|
| }
|
|
|
| def mkBar( byte_content, ASCII = True, fname = '/tmp/barcode.svg' ):
|
| try:
|
| if not ASCII:
|
| raise MakeAnInt
|
| else:
|
| try:
|
| int(byte_content)
|
| raise MakeAnInt
|
| except ValueError:
|
| string_content = byte_content.decode('ascii')
|
| except (MakeAnInt, UnicodeDecodeError):
|
| string_content = str(int.from_bytes(byte_content,'big'))
|
| #print(f"Encoded: {string_content}")
|
| b = barcode.Code128( string_content )
|
| b.write(open(fname,'wb'), text = byte_content.decode('utf-8'))
|
| return fname
|
|
|
| def parseXML(xmlFile, year):
|
| """
|
| Parse the xml
|
| """
|
| with open(xmlFile,'rb') as fobj:
|
| xml = fobj.read()
|
|
|
| root = etree.fromstring(xml)
|
|
|
| #newsvg = etree.Element('svg')
|
|
|
| with open('/tmp/new_barcodes.svg','wb') as newfile:
|
| for appt in root.getchildren():
|
| for elem in appt.getchildren():
|
| #
|
| # for each barcode in the template
|
| #
|
| if elem.get('id').startswith('barcode_group'):
|
| group = etree.Element('g')
|
|
|
| for obj in elem.getchildren():
|
| # get seed text (utf-8)
|
| if obj.tag == '{http://www.w3.org/2000/svg}text':
|
| # generate new barcode
|
| try:
|
| obj.text = str(year)+obj.text
|
| except:
|
| print('ERROR: may have encountered multiline text (TODO: not supported in current version)', obj[:])
|
| raise
|
|
|
| with open(mkBar( enc(obj.text), fname = f"/tmp/{obj.text}.svg" ),'rb') as barf:
|
| newbar = etree.fromstring( barf.read() )
|
| for appt2 in newbar.getchildren():
|
| if appt2.tag == '{http://www.w3.org/2000/svg}g' and appt2.get('id') == 'barcode_group':
|
| bars = []
|
| for obj2 in appt2.getchildren():
|
| bars.append(obj2) if obj2.tag == '{http://www.w3.org/2000/svg}rect' else None
|
| break
|
| group.append(obj)
|
| # we know it's the last item, we can break (TODO: change order in python-barcode, put text first and rectangles last)
|
| break
|
|
|
| #print(f"n bars: {len(bars)}")
|
| for bar in bars:
|
| group.append(bar)
|
|
|
| elem = group
|
|
|
| newfile.write( etree.tostring(root, pretty_print=True) )
|
|
|
| if __name__ == '__main__':
|
| #while True:
|
| # #mkBar( bab.input() )
|
| # mkBar( input('> ').encode('utf-8') )
|
|
|
| ## all good
|
| #mkBar(b'gdgdggdgd')
|
| #mkBar('ddddddé'.encode('utf-8'))
|
| ## why is "converting to int" not being displayed?!?!" that except clause is not being used!
|
| #mkBar(b'12345689')
|
|
|
| from sys import argv
|
| svg_templates = (argv[1],)
|
| #svg_templates = ("00_admin.svg",)
|
| year = int(argv[2])
|
|
|
|
|
| for t in svg_templates:
|
| #svg = BeautifulSoup( open(t,'r'), features = 'xml' )
|
| parseXML(t, year=year)
|
|
|
| #layer = svg.find("svg:g", {'id':'layer1'})
|
| #codes = layer.find_all("svg:g")
|
| #for code in codes:
|
| # if code.get('id').startswith( 'barcode_group' ):
|
| # transform = code.get('transform') # this allows us to place the new barcode at the same position as the template
|
| # text = code.get('transform')
|
| # newcontent = enc(str(year)+code.find('text').text)
|
| # print(newcontent, transform)
|
| # # content of the new barcode, as bs4 object
|
| # bar = BeautifulSoup( open(mkBar(newcontent),'rb').read(), features='xml' ).find('g',{'id': 'barcode_group'})
|
| # # we could basically write this for each barcode to a blank SVG, but all other features of the original SVG
|
| # # (typically groups that have id != "barcode_group"*) would be lost
|