Erster Commit: nativer Linux-Port aus macOS-Bytecode
Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/ scipy/PortAudio) kommen nativ aus Debian stretch. Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per .gitignore ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
import sys,os
|
||||
from pyfpdf import FPDF
|
||||
|
||||
class Form:
|
||||
def __init__(self, infile):
|
||||
keys = ('name','type','x1','y1','x2','y2','font','size',
|
||||
'bold','italic','underline','foreground','background',
|
||||
'align','text','priority')
|
||||
# parse form format file and create fields dict
|
||||
self.fields = {}
|
||||
for linea in open(infile).readlines():
|
||||
kargs = {}
|
||||
for i,v in enumerate(linea.split(";")):
|
||||
if not v.startswith("'"):
|
||||
v = v.replace(",",".")
|
||||
else:
|
||||
v = v#.decode('latin1')
|
||||
if v=='':
|
||||
v = None
|
||||
else:
|
||||
v = eval(v.strip())
|
||||
kargs[keys[i]] = v
|
||||
self.fields[kargs['name'].lower()] = kargs
|
||||
self.handlers = {'T': self.text, 'L': self.line, 'I': self.image,
|
||||
'B': self.rect, 'BC': self.barcode}
|
||||
|
||||
def set(self, name, value):
|
||||
if name.lower() in self.fields:
|
||||
self.fields[name.lower()]['text'] = value
|
||||
|
||||
def render(self, outfile):
|
||||
pdf = FPDF()
|
||||
pdf.add_page();
|
||||
pdf.set_font('Arial','B',16);
|
||||
|
||||
for field in self.fields.values():
|
||||
self.handlers[field['type'].upper()](pdf, **field)
|
||||
|
||||
pdf.output(outfile,"F")
|
||||
|
||||
def text(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=10,
|
||||
bold=False, italic=False, underline=False, align="", *args, **kwargs):
|
||||
if text:
|
||||
font = font.strip().lower()
|
||||
if font == 'arial black':
|
||||
font = 'arial'
|
||||
style = ""
|
||||
if bold: style += "B"
|
||||
if italic: style += "I"
|
||||
if underline: style += "U"
|
||||
align = {'I':'L','D':'R','C':'C','':'',None:None}[align]
|
||||
pdf.set_font(font,style,size)
|
||||
##m_k = 72 / 2.54
|
||||
##h = (size/m_k)
|
||||
pdf.set_xy(x1,y1)
|
||||
pdf.cell(w=x2-x1,h=y2-y1,txt=text,border=0,ln=0,align=align)
|
||||
#pdf.Text(x=x1,y=y1,txt=text)
|
||||
|
||||
def line(self, pdf, x1=0, y1=0, x2=0, y2=0, size=0, *args, **kwargs):
|
||||
pdf.set_line_width(size)
|
||||
pdf.line(x1, y1, x2, y2)
|
||||
|
||||
def rect(self, pdf, x1=0, y1=0, x2=0, y2=0, size=0, *args, **kwargs):
|
||||
pdf.set_line_width(size)
|
||||
pdf.rect(x1, y1, x2-x1, y2-y1)
|
||||
|
||||
def image(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', *args,**kwargs):
|
||||
pdf.image(text,x1,y1,w=x2-x1,h=y2-y1,type='',link='')
|
||||
|
||||
def barcode(self, pdf, x1=0, y1=0, x2=0, y2=0, text='', font="arial", size=1,
|
||||
*args, **kwargs):
|
||||
font = font.lower().strip()
|
||||
if font == 'interleaved 2of5 nt':
|
||||
pdf.interleaved2of5(text,x1,y1,w=size)
|
||||
|
||||
if __name__ == "__main__":
|
||||
f = Form("invoice.csv")
|
||||
f.set("EMPRESA","Saraza")
|
||||
f.set("logo","logo.png")
|
||||
f.render("./invoice.pdf")
|
||||
if sys.platform.startswith("linux"):
|
||||
os.system("evince ./invoice.pdf")
|
||||
else:
|
||||
os.system("./invoice.pdf")
|
||||
@@ -0,0 +1,136 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
|
||||
import os
|
||||
from pyfpdf import FPDF
|
||||
|
||||
pdf = FPDF()
|
||||
pdf.add_page()
|
||||
pdf.set_font('helvetica', '', 13.0)
|
||||
pdf.set_xy(105.0, 8.0)
|
||||
pdf.cell(ln=0, h=22.0, align='C', w=75.0, txt='Sample Invoice', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.rect(15.0, 15.0, 170.0, 245.0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.rect(95.0, 15.0, 10.0, 10.0)
|
||||
pdf.image('../tutorial/logo.png', 20.0, 17.0, link='', type='', w=13.0, h=13.0)
|
||||
pdf.set_font('arial', 'B', 16.0)
|
||||
pdf.set_xy(95.0, 18.0)
|
||||
pdf.cell(ln=0, h=2.0, align='C', w=10.0, txt='X', border=0)
|
||||
pdf.set_font('arial', '', 8.0)
|
||||
pdf.set_xy(105.0, 21.0)
|
||||
pdf.cell(ln=0, h=4.0, align='C', w=75.0, txt='Original', border=0)
|
||||
pdf.set_font('arial', 'B', 7.0)
|
||||
pdf.set_xy(95.0, 21.5)
|
||||
pdf.cell(ln=0, h=4.5, align='C', w=10.0, txt='COD.00', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(100.0, 25.0, 100.0, 57.0)
|
||||
pdf.set_font('arial', 'B', 14.0)
|
||||
pdf.set_xy(125.0, 25.5)
|
||||
pdf.cell(ln=0, h=9.5, align='L', w=60.0, txt='00000001', border=0)
|
||||
pdf.set_xy(115.0, 27.5)
|
||||
pdf.cell(ln=0, h=5.5, align='L', w=10.0, txt='N\xba: ', border=0)
|
||||
pdf.set_font('arial', 'B', 12.0)
|
||||
pdf.set_xy(17.0, 32.5)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=98.0, txt='COMPANY', border=0)
|
||||
pdf.set_font('arial', '', 12.0)
|
||||
pdf.set_xy(115.0, 33.0)
|
||||
pdf.cell(ln=0, h=7.0, align='L', w=60.0, txt='Date:', border=0)
|
||||
pdf.set_xy(135.0, 33.0)
|
||||
pdf.cell(ln=0, h=7.0, align='L', w=40.0, txt='19/02/2009', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(15.0, 57.0, 185.0, 57.0)
|
||||
pdf.set_font('times', '', 10.0)
|
||||
pdf.set_xy(17.0, 59.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=13.0, txt='Mr.(s):', border=0)
|
||||
pdf.set_xy(35.0, 59.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=140.0, txt='Mariano Reingart', border=0)
|
||||
pdf.set_xy(17.0, 64.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Address:', border=0)
|
||||
pdf.set_xy(35.0, 64.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=125.0, txt='Siempreviva 12345', border=0)
|
||||
pdf.set_xy(17.0, 69.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='Tel\xe9fono:', border=0)
|
||||
pdf.set_xy(35.0, 69.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=80.0, txt='+1-5555-5555', border=0)
|
||||
pdf.set_xy(115.0, 69.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=18.0, txt='City:', border=0)
|
||||
pdf.set_xy(133.0, 69.0)
|
||||
pdf.cell(ln=0, h=6.0, align='L', w=42.0, txt='Springfield', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(15.0, 77.0, 185.0, 77.0)
|
||||
pdf.set_xy(17.0, 80.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=15.0, txt='VAT:', border=0)
|
||||
pdf.set_xy(35.0, 80.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=70.0, txt='Responsable', border=0)
|
||||
pdf.set_xy(115.0, 80.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='Tax ID:', border=0)
|
||||
pdf.set_xy(135.0, 80.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=40.0, txt='10-12345678-9', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(15.0, 88.0, 185.0, 88.0)
|
||||
pdf.set_xy(17.0, 90.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=48.0, txt='Due Date:', border=0)
|
||||
pdf.set_xy(65.0, 90.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='23/07/1978', border=0)
|
||||
pdf.set_xy(92.0, 90.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=43.0, txt='Period', border=0)
|
||||
pdf.set_xy(125.0, 90.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='01/01/2009', border=0)
|
||||
pdf.set_xy(150.0, 90.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=20.0, txt='31/01/2009', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(15.0, 95.0, 185.0, 95.0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(155.0, 95.0, 155.0, 230.0)
|
||||
pdf.set_xy(20.0, 97.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=125.0, txt='Description', border=0)
|
||||
pdf.set_xy(160.0, 97.0)
|
||||
pdf.cell(ln=0, h=5.0, align='R', w=20.0, txt='Amount', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(15.0, 102.0, 185.0, 102.0)
|
||||
pdf.set_xy(20.0, 103.0)
|
||||
pdf.cell(ln=0, h=7.0, align='L', w=125.0, txt='Esto es una prueba y no es v\xe1lido como factura', border=0)
|
||||
pdf.set_xy(160.0, 103.0)
|
||||
pdf.cell(ln=0, h=7.0, align='R', w=20.0, txt='100,00', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.line(15.0, 230.0, 185.0, 230.0)
|
||||
pdf.set_xy(20.0, 233.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=95.0, txt='CAE N\xba', border=0)
|
||||
pdf.set_xy(45.0, 233.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=30.0, txt='01234567890', border=0)
|
||||
pdf.set_font('arial', '', 12.0)
|
||||
pdf.set_xy(105.0, 234.0)
|
||||
pdf.cell(ln=0, h=9.0, align='R', w=45.0, txt='Subtotal:', border=0)
|
||||
pdf.set_font('arial', 'B', 12.0)
|
||||
pdf.set_xy(145.0, 234.0)
|
||||
pdf.cell(ln=0, h=9.0, align='R', w=33.0, txt='100,00', border=0)
|
||||
pdf.set_font('arial', '', 10.0)
|
||||
pdf.set_xy(20.0, 238.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=95.0, txt='Fecha Vto. CAE:', border=0)
|
||||
pdf.set_xy(55.0, 238.0)
|
||||
pdf.cell(ln=0, h=5.0, align='L', w=30.0, txt='19/02/2009', border=0)
|
||||
pdf.set_font('arial', '', 12.0)
|
||||
pdf.set_xy(125.0, 241.0)
|
||||
pdf.cell(ln=0, h=9.0, align='R', w=25.0, txt='VAT 21%:', border=0)
|
||||
pdf.set_font('arial', 'B', 12.0)
|
||||
pdf.set_xy(145.0, 241.0)
|
||||
pdf.cell(ln=0, h=9.0, align='R', w=33.0, txt='21,00', border=0)
|
||||
pdf.interleaved2of5('012345678905', 20.0, 243.5, w=0.75)
|
||||
pdf.set_font('arial', 'B', 12.0)
|
||||
pdf.set_xy(105.0, 251.0)
|
||||
pdf.cell(ln=0, h=9.0, align='R', w=73.0, txt='121,00', border=0)
|
||||
pdf.set_font('arial', '', 12.0)
|
||||
pdf.set_xy(125.0, 251.0)
|
||||
pdf.cell(ln=0, h=9.0, align='R', w=25.0, txt='Total:', border=0)
|
||||
pdf.set_line_width(0.0)
|
||||
pdf.rect(155.0, 252.0, 25.0, 7.0)
|
||||
pdf.set_font('courier', '', 10.0)
|
||||
pdf.set_xy(20.0, 253.0)
|
||||
pdf.cell(ln=0, h=7.0, align='L', w=120.0, txt='012345678905', border=0)
|
||||
pdf.output('./invoice.pdf', 'F')
|
||||
|
||||
import sys
|
||||
if sys.platform.startswith("linux"):
|
||||
os.system("evince ./invoice.pdf")
|
||||
else:
|
||||
os.system("./invoice.pdf")
|
||||
@@ -0,0 +1,26 @@
|
||||
# -*- coding: iso-8859-1 -*-
|
||||
import sys,os
|
||||
sys.path.append("..")
|
||||
import pyfpdf
|
||||
|
||||
customer = {'name':'John Doe','tax_id':'00-0000000-0','vat':True}
|
||||
items = [
|
||||
{'qty':12,'description':'Eggs','price':1.00},
|
||||
{'qty':20,'description':'Spam','price':3.00},
|
||||
{'qty':1,'description':'Varios','price':0.50},
|
||||
]
|
||||
|
||||
pdf = pyfpdf.FPDF()
|
||||
pdf.add_page();
|
||||
pdf.set_font('Arial','B',16);
|
||||
for line in open("simple-csv-invoice.txt").readlines():
|
||||
print line
|
||||
args = eval(line.strip())
|
||||
pdf.text(x=args[0],y=args[1],txt=str(args[2]).decode('latin1'));
|
||||
|
||||
pdf.output(r"./invoice.pdf","F")
|
||||
import sys
|
||||
if sys.platform.startswith("linux"):
|
||||
os.system("evince ./invoice.pdf")
|
||||
else:
|
||||
os.system("./invoice.pdf")
|
||||
@@ -0,0 +1,20 @@
|
||||
100, 10, 'INVOICE'
|
||||
10, 46, 'VAT:'
|
||||
53, 46, customer['vat'] and 'X' or ''
|
||||
63, 46, not customer['vat'] and 'X' or ''
|
||||
10, 20, customer['name']
|
||||
100, 20, customer['tax_id']
|
||||
10, 60, items[0]['qty']
|
||||
40, 60, items[0]['description']
|
||||
150, 60, items[0]['price']
|
||||
190, 60, items[0]['qty']*items[0]['price']
|
||||
10, 65, items[1]['qty']
|
||||
40, 65, items[1]['description']
|
||||
150, 65, items[1]['price']
|
||||
190, 65, items[1]['qty']*items[1]['price']
|
||||
10, 70, items[2]['qty']
|
||||
40, 70, items[2]['description']
|
||||
150, 70, items[2]['price']
|
||||
190, 70, items[2]['qty']*items[2]['price']
|
||||
100,100, 'Total:'
|
||||
120,100, sum([item['qty']*item['price'] for item in items])
|
||||
Reference in New Issue
Block a user