def templatify(tpl, values): """ Custom wrapper around the YAPTU template engine. Does the usual job. """ class DecoyFile: def __init__(self): self.data = [] def write(self, line): self.data.append(line) def read(self): return "".join(self.data) rex=re.compile('%([^@]+)s') rbe=re.compile('\+') ren=re.compile('-') rco=re.compile('= ') decoy = DecoyFile() cop = copier(rex, values, rbe, ren, rco, ouf=decoy) lines_block = [line+'\n' for line in tpl.split('\n')] cop.copy(lines_block) return decoy.read()
def print_template(template_path, namespace, ouf=sys.stdout): f = open(template_path, 'r') s = f.readlines() f.close() if 'templater' not in namespace: import templater as __templater namespace.update({'templater':__templater}) cop = yaptu.copier(__rex, namespace, __rbe, __ren, __rco, ouf=ouf) cop.copy(s)
def main(): parser = optparse.OptionParser() parser.add_option("-o", dest="outfile") options, args = parser.parse_args() cop = yaptu.copier(globals()) if not options.outfile is None: cop.ouf = open(options.outfile, 'wt') inp = sys.stdin if len(args) >= 1: inp = open(args[0]) cop.copy(inp) if inp != sys.stdin: inp.close() if cop.ouf != sys.stdout: cop.ouf.flush() cop.ouf.close() return 0
def testYaptu(self): """Test of the YAPTU templating engine.""" rex = re.compile('@\\{([^}]+)\\}') rbe = re.compile('%\\+ ') ren = re.compile('%-') rco = re.compile('%= ') temp_dict = {'a': 'a1', 'b': '\u01222', 'c': 5, 'li': [5, 4, 3], 'di': dict(x=1, y=2)} templ_out = io.StringIO() testdata_in = io.open( 'testdata/yaptu_testYaptu_in.txt', 'r', encoding='utf-8').read() templ_in = [(line+'\n') for line in testdata_in.split('\n')] yaptu = copier(rex, temp_dict, rbe, ren, rco, ouf=templ_out) yaptu.copy(templ_in) result = templ_out.getvalue() templ_out.close() self.assertTrue(isinstance(result, str)) testdata_out = io.open( 'testdata/yaptu_testYaptu_out.txt', 'r', encoding='utf-8').read() self.assertEqual(result, testdata_out)
def templatify(tpl, values): """ Custom wrapper around the YAPTU template engine. Does the usual job. """ class DecoyFile: def __init__(self): self.data = [] def write(self, line): self.data.append(line) def read(self): return "".join(self.data) rex = re.compile('%([^@]+)s') rbe = re.compile('\+') ren = re.compile('-') rco = re.compile('= ') decoy = DecoyFile() cop = copier(rex, values, rbe, ren, rco, ouf=decoy) lines_block = [line + '\n' for line in tpl.split('\n')] cop.copy(lines_block) return decoy.read()
table3 = LinkBox(header='Other', links=( ('Credits', 'credits.html'), ('License', 'license.html'), )) params = { 'myemail': '<a href=mailto:[email protected]> ([email protected])</a>', 'tables': (news1, table1, table2, table3), 'default_table': 'border=1 cellpadding=3 cellspacing=2', } headerBuffer = StringIO() cop = yaptu.copier(rex, params, rbe, ren, rco, ouf=headerBuffer) lines = file('header.html.template').readlines() cop.copy(lines) params['header'] = headerBuffer.getvalue() footerBuffer = StringIO() cop = yaptu.copier(rex, params, rbe, ren, rco, ouf=footerBuffer) lines = file('footer.html.template').readlines() cop.copy(lines) params['footer'] = footerBuffer.getvalue() docs = [modname + '.html.template' for modname in modules] files = [ 'backends.html.template', 'classdocs.html.template',
)) table3 = LinkBox(header='Other', links=( ('Credits', 'credits.html'), ('License', 'license.html'), )) params = { 'myemail' : '<a href=mailto:[email protected]> ([email protected])</a>', 'tables' : (news1, table1, table2, table3), 'default_table' : 'border=1 cellpadding=3 cellspacing=2', } headerBuffer = StringIO() cop = yaptu.copier(rex, params, rbe, ren, rco, ouf=headerBuffer) lines = file('header.html.template').readlines() cop.copy(lines) params['header'] = headerBuffer.getvalue() footerBuffer = StringIO() cop = yaptu.copier(rex, params, rbe, ren, rco, ouf=footerBuffer) lines = file('footer.html.template').readlines() cop.copy(lines) params['footer'] = footerBuffer.getvalue() docs = [modname + '.html.template' for modname in modules] files = [ 'backends.html.template',
def copier_fun(outf): return copier(rex, invoice, rbe, ren, rco, ouf=outf, handle=handle)
def createInvoice(self, invoiceid, template=None, outfile=None): """Create an invoice from the parsed Gnucash data. Arguments: invoiceid -- Id of the invoice to extract from Gnucash. A string or an integer. template -- Name of the invoice template file, or list of lines. outfile -- File name for the generated invoice, default is stdout. Options from self.options used by this method: quantities_uselocale -- Format quantity values using the locale setting. currency_uselocale -- Format currency values using the locale setting. quantities_precision -- Used decimal precision for quantities. currency_precision -- Used decimal precision for currencies. quantities_dashsymb -- Replace a zero fractional part of quantity values with this symbol, but only if not None, and if uselocale. Example: '12.00' -> '12.-'. currency_dashsymb -- As quantities_dashsymb for currency values. qformat -- Function to format quantity values, overrides quantities_*, should take a Decimal as argument and return an unicode string. cformat -- Function to format currency values, overrides currency_*, should take a Decimal as argument and return an unicode string. templates -- Dictionary of invoice template file names; keys are the 'owner' values of the invoice, or 'default'. outfile -- Name of the file to write the invoice out. regex_rex -- Expression regex used by the template engine. regex_rbe -- Begin statement regex. regex_ren -- End statement regex. regex_rco -- Continuation statement regex. """ invoiceid = Convert.readint(invoiceid) try: invoice = self.invoices[invoiceid] except KeyError: self.logger.error("No invoice found for invoiceid [%s]" % invoiceid) raise GcinvoiceError("No invoice found for invoiceid [%s]" % invoiceid) invc = copy.deepcopy(invoice) if invc.get('_warndiscount', False): self.logger.warn("The invoice contains POSTTAX discounts, which " "are calculated differenty in gcinvoice and Gnucash") invc['amountNet'] = sum(x['amountNet'] for x in invc['entries']) invc['amountGross'] = sum(x['amountGross'] for x in invc['entries']) invc['amountTaxes'] = sum(x['amountTaxes'] for x in invc['entries']) uselocale_qty = getattr(self.options, 'quantities_uselocale', True) precision_qty = getattr(self.options, 'quantities_precision', None) dashsymb_qty = getattr(self.options, 'quantities_dashsymb', None) qformat = getattr(self.options, 'qformat', None) uselocale_curr = getattr(self.options, 'currency_uselocale', True) precision_curr = getattr(self.options, 'currency_precision', None) dashsymb_curr = getattr(self.options, 'currency_dashsymb', None) cformat = getattr(self.options, 'cformat', None) invc['currencyformatting'] = Format.currencyformatting invc['quantityformatting'] = Format.quantityformatting cformat = invc['cformat'] = cformat or functools.partial( Format.currencyformatting, uselocale=uselocale_curr, precision=precision_curr, dashsymb=dashsymb_curr) qformat = invc['qformat'] = qformat or functools.partial( Format.quantityformatting, uselocale=uselocale_qty, precision=precision_qty, dashsymb=dashsymb_qty) invc['Decimal'] = Decimal for x in ['amountNet', 'amountGross', 'amountTaxes']: invc["%sInt" % x] = invc[x] invc[x] = cformat(invc[x]) for e in invc['entries']: for x in ['price', 'amountRaw', 'amountNet', 'amountGross', 'amountTaxes', 'amountDiscount']: e["%sInt" % x] = e[x] e[x] = cformat(e[x]) for x in ['qty']: e["%sInt" % x] = e[x] e[x] = qformat(e[x]) if e['discount'] is not None: e['discountInt'] = e['discount'] if e['discountType'] == 'PERCENT': e['discount'] = cformat(e['discount']) else: e['discount'] = qformat(e['discount']) rex = re.compile(getattr(self.options, 'regex_rex', None) or '@\\{([^}]+)\\}') rbe = re.compile(getattr(self.options, 'regex_rbe', None) or '%\\+') ren = re.compile(getattr(self.options, 'regex_ren', None) or '%-') rco = re.compile(getattr(self.options, 'regex_rco', None) or '%= ') try: ownername = invc['owner']['name'] except Exception: ownername = None template = template or \ self.options.templates.get(ownername, None) or \ self.options.templates.get('default', None) if template is None: self.logger.error("No template given.") raise GcinvoiceError("No template given.") readfromfile = True if isinstance(template, basestring): # The name of the template file is itself a template in order to # select different templates depending on the invoice. templ_ = StringIO.StringIO() cop = copier(rex, invc, rbe, ren, rco, ouf=templ_, encoding=self._gcfile_encoding) cop.copy([template]) templ = templ_.getvalue() templ_.close() try: templ = file(templ) self.logger.info("Using file [%s] as template" % templ) except Exception: self.logger.info("The given template [%s] is not readable, " "trying to use it directly as string..." % templ, exc_info=True) try: templ = [(line + '\n') for line in template.split('\n')] readfromfile = False except Exception: self.logger.error("The given template [%s] is neither a " "readable file, nor a readable string" % template, exc_info=True) raise GcinvoiceError("The template is neither a file nor a" " string") else: templ = template if readfromfile: self.logger.info("Using [%s] as file object" % templ) try: templ = [line.decode(self._gcfile_encoding) for line in templ.readlines()] except UnicodeDecodeError: self.logger.error("The template file [%s] cannot be " "decoded using the encoding [%s] of Gnucash data files" % (template, self._gcfile_encoding), exc_info=True) raise GcinvoiceError("The given template cannot be decoded") outfile = outfile or \ self.options.outfiles.get(ownername, None) or \ self.options.outfiles.get('default', None) if isinstance(outfile, basestring): # The name of the outfile is itself a template in order to # select different outfiles depending on the invoice. outf_ = StringIO.StringIO() cop = copier(rex, invc, rbe, ren, rco, ouf=outf_, encoding=self._gcfile_encoding) cop.copy([outfile]) outfile = outf_.getvalue() outf_.close() try: outf = file(outfile, "w") except Exception: self.logger.error("Cannot open [%s] for writing" % outfile, exc_info=True) raise self.logger.info("Using [%s] as outfile" % outfile) elif not outfile: outf = sys.stdout self.logger.info("Using stdout as outfile") else: outf = outfile self.logger.info("Using [%s] directly as outfile object") # now the very templating def handle(expr): self.logger.warn("Cannot do template for expression [%s]" % expr, exc_info=True) return expr cop = copier(rex, invc, rbe, ren, rco, ouf=outf, handle=handle, encoding=self._gcfile_encoding) try: cop.copy(templ) outf.close() except Exception: self.logger.error("Error in template", exc_info=True) raise