[WIP] hw_escpos: printing client-side defined xml templates
authorFrédéric van der Essen <fva@openerp.com>
Mon, 17 Mar 2014 13:29:06 +0000 (14:29 +0100)
committerFrédéric van der Essen <fva@openerp.com>
Mon, 17 Mar 2014 13:29:06 +0000 (14:29 +0100)
bzr revid: fva@openerp.com-20140317132906-uyr7h1oce8pptny9

addons/hw_escpos/controllers/main.py
addons/hw_escpos/escpos/escpos.py

index e950950..52036fc 100644 (file)
@@ -118,6 +118,8 @@ class EscposDriver(Thread):
                         self.open_cashbox(printer)
                 elif task == 'printstatus':
                     self.print_status(printer)
+                elif task == 'testprint':
+                    printer.receipt(testreceipt)
                 elif task == 'status':
                     pass
 
@@ -280,7 +282,7 @@ driver = EscposDriver()
 
 hw_proxy.drivers['escpos'] = driver
 
-driver.push_task('printstatus')
+driver.push_task('testprint')
         
 class EscposProxy(hw_proxy.Proxy):
     
@@ -293,4 +295,9 @@ class EscposProxy(hw_proxy.Proxy):
     def print_receipt(self, receipt):
         _logger.info('ESC/POS: PRINT RECEIPT') 
         driver.push_task('receipt',receipt)
+
+    @http.route('/hw_proxy/print_xml_receipt', type='json', auth='none', cors='*')
+    def print_receipt(self, receipt):
+        _logger.info('ESC/POS: PRINT XML RECEIPT') 
+        driver.push_task('xml_receipt',receipt)
     
index a494201..08864ec 100644 (file)
@@ -17,6 +17,8 @@ import io
 import base64
 import math
 import md5
+import re
+import xml.etree.ElementTree as ET
 
 from PIL import Image
 
@@ -30,13 +32,20 @@ except ImportError:
 from constants import *
 from exceptions import *
 
+# class RBuffer:
+#     def __init__(self,width=40,margin=10,tabwidth=2,indent=0):
+#         self.width = width 
+#         self.margin = margin
+#         self.tabwidth = tabwidth
+#         self.indent = indent
+#         self.lines  = []
+
 class Escpos:
     """ ESC/POS Printer object """
     device    = None
     encoding  = None
     img_cache = {}
 
-
     def _check_image_size(self, size):
         """ Check and fix the size of the image to 32 bits """
         if size % 32 == 0:
@@ -48,7 +57,6 @@ class Escpos:
             else:
                 return (image_border / 2, (image_border / 2) + 1)
 
-
     def _print_image(self, line, size):
         """ Print formatted image """
         i = 0
@@ -101,7 +109,6 @@ class Escpos:
 
         return raw
 
-
     def _convert_image(self, im):
         """ Parse image and prepare it to a printable format """
         pixels   = []
@@ -197,8 +204,7 @@ class Escpos:
         # Convert the RGB image in printable image
         self._convert_image(im)
 
-
-    def barcode(self, code, bc, width, height, pos, font):
+    def barcode(self, code, bc, width=255, height=2, pos='below', font='a'):
         """ Print Barcode """
         # Align Bar Code()
         self._raw(TXT_ALIGN_CT)
@@ -249,6 +255,168 @@ class Escpos:
         else:
             raise exception.BarcodeCodeError()
 
+    def receipt(self,xml):
+        root = ET.fromstring(xml)
+        open_cashdrawer = False
+        cut_receipt  = True
+
+        width  = 48
+        ratio  = 0.5
+        indent = 0
+        tabwidth = 2
+
+        if root.tag != 'receipt':
+            print 'Error: expecting receipt xml and not '+str(root.tag)
+            return
+        if 'open-cashdrawer' in root.attrib:
+            open_cashdrawer = root.attrib['open-cashdrawer'] == 'true'
+        if 'cut' in root.attrib:
+            cut_receipt = root.attrib['cut'] == 'true'
+
+#        def justify(string,width):
+#            words = string.split()
+#            lines = []
+#            line  = ''
+#            linew = 0
+#            for w in words:
+#                if len(w) <= width - len(line):
+#                    if len(line) > 0:
+#                        line += ' '
+#                    line += w
+#                else:
+#                    if len(line) > 0:
+#                        lines.append(line.ljust(width))
+#                        line = ''
+#                    line += w
+#            if len(line) > 0:
+#                lines.append(line.ljust(width))
+#            return lines
+#
+#        def strindent(indent,string):
+#            ind = tabwidth * indent
+#            rem = width - ind
+#            lines = justify(string,rem)
+#            txt = ''
+#            for l in lines:
+#                txt += ' '*ind + '\n'
+#
+#            return txt
+
+        def strclean(string):
+            if not string:
+                string = ''
+            string = string.strip()
+            string = re.sub('\s+',' ',string)
+            return string
+
+
+        def print_ul(elem, indent=0):
+            bullets = ['-','-']
+            bullet  = ' '+bullets[indent % 2]+' '
+            if elem.tag == 'ul':
+                for lelem in elem:
+                    if lelem.tag == 'li':
+                        self.text(' ' * indent * tabwidth + bullet + strclean(lelem.text)+'\n')
+                    elif lelem.tag == 'ul':
+                        print_ul(lelem,indent+1)
+                    elif lelem.tag == 'ol':
+                        print_old(lelem,indent+1)
+
+        def print_ol(elem, indent=0):
+            cwidth = len(str(len(elem))) + 2
+            i = 1
+            for lelem in elem:
+                if lelem.tag == 'li':
+                    self.text(' ' * indent * tabwidth + ' ' + (str(i)+'.').ljust(cwidth)+strclean(lelem.text)+'\n')
+                    i += 1
+                elif lelem.tag == 'ul':
+                    print_ul(lelem,indent+1)
+                elif lelem.tag == 'ol':
+                    print_ol(lelem,indent+1)
+        
+        
+        for elem in root:
+            if elem.tag == 'line':
+                left = strclean(elem.text)
+                right = ''
+                for lelem in elem:
+                    if lelem.tag == 'left':
+                        left = strclean(lelem.text)
+                        print 'left:'+left
+                    elif lelem.tag == 'right':
+                        right = strclean(lelem.text)
+                        print 'right:'+right
+                lwidth = int(width * ratio)
+                rwidth = width - lwidth
+                lwidth = lwidth - indent
+
+                left = left[:lwidth]
+                if len(left) != lwidth:
+                    left = left + ' ' * (lwidth - len(left))
+
+                right = right[-rwidth:]
+                if len(right) != rwidth:
+                    right = ' ' * (rwidth - len(right)) + right
+                line = ' ' * indent + left + right + '\n'
+                print line
+                self.text(line)
+            elif elem.tag == 'img':
+                if src in elem.attrib and 'data:' in elem.attrib['src']:
+                    self.print_base64_image(elem.attrib['src'])
+            elif elem.tag == 'p':
+                self.text(strclean(elem.text)+'\n')
+            elif elem.tag == 'h1':
+                self.set(align='left', font='a', type='b', width=2, height=2)
+                self._raw('\x1b\x21\x30')
+                self._raw('\x1b\x45\x01')
+                self.text(strclean(elem.text)+'\n')
+                self.set()
+            elif elem.tag == 'h2':
+                self.set(align='left', font='a', type='bu', width=1, height=2)
+                self._raw('\x1b\x21\x30')
+                self.text(strclean(elem.text)+'\n')
+                self.set()
+            elif elem.tag == 'h3':
+                self.set(align='left', font='a', type='u', width=1, height=2)
+                self._raw('\x1b\x45\x01')
+                self.text(strclean(elem.text)+'\n')
+                self.set()
+            elif elem.tag == 'h4':
+                self.set(align='left', font='a', type='bu', width=1, height=2)
+                self.text(strclean(elem.text)+'\n')
+                self.set()
+            elif elem.tag == 'h5':
+                self.set(align='left', font='a', type='u', width=1, height=1)
+                self._raw('\x1b\x45\x01')
+                self.text(strclean(elem.text)+'\n')
+                self.set()
+            elif elem.tag == 'pre':
+                self.text(elem.text)
+            elif elem.tag == 'cut':
+                self.cut()
+            elif elem.tag == 'ul':
+                print_ul(elem)
+            elif elem.tag == 'ol':
+                print_ol(elem)
+            elif elem.tag == 'hr':
+                self.text('-'*width+'\n')
+            elif elem.tag == 'br':
+                self.text('\n')
+            elif elem.tag == 'barcode' and 'encoding' in elem.attrib:
+                self.barcode(strclean(elem.text),elem.attrib['encoding'])
+            elif elem.tag == 'partialcut':
+                self.cut(mode='part')
+            elif elem.tag == 'cashdraw':
+                self.cashdraw(2)
+                self.cashdraw(5)
+
+        if cut_receipt:
+            self.cut()
+        if open_cashdrawer:
+            self.cashdraw(2)
+            self.cashdraw(5)
+
+
     def text(self,txt):
         """ Print Utf8 encoded alpha-numeric text """
         if not txt: