From b5c886cf37bd9d866bc5ecfc6cf12d7178a28f54 Mon Sep 17 00:00:00 2001 From: majouda Date: Fri, 13 Sep 2024 17:17:31 -0400 Subject: [PATCH] TA#67305 [IMP] aeroo_reports: Correct flake8 Errors --- report_aeroo/__init__.py | 20 +- report_aeroo/__manifest__.py | 16 +- report_aeroo/barcode/EANBarCode.py | 346 +++++++++++------- report_aeroo/barcode/__init__.py | 1 - report_aeroo/barcode/barcode.py | 22 +- report_aeroo/barcode/code128.py | 90 +++-- report_aeroo/barcode/code39.py | 148 ++++---- report_aeroo/check_deps.py | 6 +- report_aeroo/controllers/__init__.py | 2 +- report_aeroo/controllers/main.py | 12 +- report_aeroo/demo/__init__.py | 3 +- report_aeroo/demo/parser.py | 2 +- report_aeroo/docs_client_lib.py | 54 +-- report_aeroo/exceptions.py | 7 +- report_aeroo/models/report.py | 164 +++++---- report_aeroo/report/test_aeroo_report_file.py | 1 - report_aeroo/report_parser.py | 100 ++--- report_aeroo/wizard/__init__.py | 2 +- report_aeroo/wizard/installer.py | 69 ++-- 19 files changed, 578 insertions(+), 487 deletions(-) diff --git a/report_aeroo/__init__.py b/report_aeroo/__init__.py index 60166c0..6211379 100755 --- a/report_aeroo/__init__.py +++ b/report_aeroo/__init__.py @@ -1,19 +1,19 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ -check_list = [ - 'import aeroolib', - 'import genshi', - 'from genshi.template import NewTextTemplate', - 'from xml.dom import minidom', - 'from pyPdf import PdfFileWriter, PdfFileReader', -] +# check_list = [ +# 'import aeroolib', +# 'import genshi', +# 'from genshi.template import NewTextTemplate', +# 'from xml.dom import minidom', +# 'from pyPdf import PdfFileWriter, PdfFileReader', +# ] -#from . import check_deps -#check_deps(check_list) +# from . import check_deps +# check_deps(check_list) from . import controllers from . import models diff --git a/report_aeroo/__manifest__.py b/report_aeroo/__manifest__.py index 5c9f59e..7fc754d 100644 --- a/report_aeroo/__manifest__.py +++ b/report_aeroo/__manifest__.py @@ -1,6 +1,6 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ @@ -14,16 +14,16 @@ 'complexity': "easy", 'depends': ['base', 'web', 'mail'], 'data': [ - "views/report_view.xml", - "data/report_aeroo_data.xml", - "wizard/installer.xml", - "security/ir.model.access.csv", - "demo/report_sample.xml", - ], + "views/report_view.xml", + "data/report_aeroo_data.xml", + "wizard/installer.xml", + "security/ir.model.access.csv", + "demo/report_sample.xml", + ], 'assets': { 'web.assets_backend': [ 'report_aeroo/static/src/js/report/reportactionmanager.js', - ], + ], }, "license": "GPL-3 or any later version", 'installable': True, diff --git a/report_aeroo/barcode/EANBarCode.py b/report_aeroo/barcode/EANBarCode.py index 17ffbc3..682c672 100755 --- a/report_aeroo/barcode/EANBarCode.py +++ b/report_aeroo/barcode/EANBarCode.py @@ -2,6 +2,7 @@ # General contacts from odoo.tools import config, ustr + fontsize = 12 """ @@ -11,149 +12,210 @@ If the code has not checksum (12 digits), it added automatically. Create bar code sample : - from EANBarCode import EanBarCode - bar = EanBarCode() - bar.getImage("9782212110708",50,"gif") + from EANBarCode import EanBarCode + bar = EanBarCode() + bar.getImage("9782212110708",50,"gif") """ -class EanBarCode: - """ Compute the EAN bar code """ - def __init__(self): - A = {0 : "0001101", 1 : "0011001", 2 : "0010011", 3 : "0111101", 4 : "0100011", - 5 : "0110001", 6 : "0101111", 7 : "0111011", 8 : "0110111", 9 : "0001011"} - B = {0 : "0100111", 1 : "0110011", 2 : "0011011", 3 : "0100001", 4 : "0011101", - 5 : "0111001", 6 : "0000101", 7 : "0010001", 8 : "0001001", 9 : "0010111"} - C = {0 : "1110010", 1 : "1100110", 2 : "1101100", 3 : "1000010", 4 : "1011100", - 5 : "1001110", 6 : "1010000", 7 : "1000100", 8 : "1001000", 9 : "1110100"} - self.groupC = C - - self.family = {0 : (A,A,A,A,A,A), 1 : (A,A,B,A,B,B), 2 : (A,A,B,B,A,B), 3 : (A,A,B,B,B,A), 4 : (A,B,A,A,B,B), - 5 : (A,B,B,A,A,B), 6 : (A,B,B,B,A,A), 7 : (A,B,A,B,A,B), 8 : (A,B,A,B,B,A), 9 : (A,B,B,A,B,A)} - - - def makeCode(self, code): - """ Create the binary code - return a string which contains "0" for white bar, "1" for black bar, "L" for long bar """ - - # Convert code string in integer list - self.EAN13 = [] - for digit in code: - self.EAN13.append(int(digit)) - - # If the code has already a checksum - if len(self.EAN13) == 13: - # Verify checksum - self.verifyChecksum(self.EAN13) - # If the code has not yet checksum - elif len(self.EAN13) == 12: - # Add checksum value - self.EAN13.append(self.computeChecksum(self.EAN13)) - - # Get the left codage class - left = self.family[self.EAN13[0]] - - # Add start separator - strCode = 'L0L' - - # Compute the left part of bar code - for i in range(0,6): - strCode += left[i][self.EAN13[i+1]] - - # Add middle separator - strCode += '0L0L0' - - # Compute the right codage class - for i in range (7,13): - strCode += self.groupC[self.EAN13[i]] - - # Add stop separator - strCode += 'L0L' - - return strCode - - - def computeChecksum(self, arg): - """ Compute the checksum of bar code """ - # UPCA/EAN13 - weight=[1,3]*6 - magic=10 - sum = 0 - - for i in range(12): # checksum based on first 12 digits. - sum = sum + int(arg[i]) * weight[i] - z = ( magic - (sum % magic) ) % magic - if z < 0 or z >= magic: - return None - return z - - - def verifyChecksum(self, bits): - """ Verify the checksum """ - computedChecksum = self.computeChecksum(bits[:12]) - codeBarChecksum = bits[12] - - if codeBarChecksum != computedChecksum: - raise Exception ("Bad checksum is %s and should be %s"%(codeBarChecksum, computedChecksum)) - - - def getImage(self, value, height = 50, xw=1, rotate=None, extension = "PNG"): - """ Get an image with PIL library - value code barre value - height height in pixel of the bar code - extension image file extension""" - from PIL import Image, ImageFont, ImageDraw - import os - from string import lower, upper - - # Get the bar code list - bits = self.makeCode(value) - - # Get thee bar code with the checksum added - code = "" - for digit in self.EAN13: - code += "%d"%digit - - # Create a new image - position = 8 - im = Image.new("L",(len(bits)+position,height+2)) - - # Load font - ad = os.path.abspath(os.path.join(ustr(config['root_path']), u'addons')) - mod_path_list = map(lambda m: os.path.abspath(ustr(m.strip())), config['addons_path'].split(',')) - mod_path_list.append(ad) - - for mod_path in mod_path_list: - font_file = mod_path+os.path.sep+ \ - "report_aeroo"+os.path.sep+"barcode"+os.path.sep+"FreeMonoBold.ttf"#"courB08.pil" - if os.path.lexists(font_file): - font = ImageFont.truetype(font_file, fontsize) - #font = ImageFont.load(font_file) - - # Create drawer - draw = ImageDraw.Draw(im) - - # Erase image - draw.rectangle(((0,0),(im.size[0],im.size[1])),fill=256) - - # Draw first part of number - draw.text((0, height-9), code[0], font=font, fill=0) - - # Draw first part of number - draw.text((position+3, height-9), code[1:7], font=font, fill=0) - - # Draw second part of number - draw.text((len(bits)/2+2+position, height-9), code[7:], font=font, fill=0) - - # Draw the bar codes - for bit in range(len(bits)): - # Draw normal bar - if bits[bit] == '1': - draw.rectangle(((bit+position,0),(bit+position,height-10)),fill=0) - # Draw long bar - elif bits[bit] == 'L': - draw.rectangle(((bit+position,0),(bit+position,height-3)),fill=0) - - # Save the result image - return im +class EanBarCode: + """Compute the EAN bar code""" + + def __init__(self): + A = { + 0: "0001101", + 1: "0011001", + 2: "0010011", + 3: "0111101", + 4: "0100011", + 5: "0110001", + 6: "0101111", + 7: "0111011", + 8: "0110111", + 9: "0001011", + } + B = { + 0: "0100111", + 1: "0110011", + 2: "0011011", + 3: "0100001", + 4: "0011101", + 5: "0111001", + 6: "0000101", + 7: "0010001", + 8: "0001001", + 9: "0010111", + } + C = { + 0: "1110010", + 1: "1100110", + 2: "1101100", + 3: "1000010", + 4: "1011100", + 5: "1001110", + 6: "1010000", + 7: "1000100", + 8: "1001000", + 9: "1110100", + } + self.groupC = C + + self.family = { + 0: (A, A, A, A, A, A), + 1: (A, A, B, A, B, B), + 2: (A, A, B, B, A, B), + 3: (A, A, B, B, B, A), + 4: (A, B, A, A, B, B), + 5: (A, B, B, A, A, B), + 6: (A, B, B, B, A, A), + 7: (A, B, A, B, A, B), + 8: (A, B, A, B, B, A), + 9: (A, B, B, A, B, A), + } + + def makeCode(self, code): + """ + Create the binary code + return a string which contains : + "0" for white bar, + "1" for black bar, + "L" for long bar. + """ + + # Convert code string in integer list + self.EAN13 = [] + for digit in code: + self.EAN13.append(int(digit)) + + # If the code has already a checksum + if len(self.EAN13) == 13: + # Verify checksum + self.verifyChecksum(self.EAN13) + # If the code has not yet checksum + elif len(self.EAN13) == 12: + # Add checksum value + self.EAN13.append(self.computeChecksum(self.EAN13)) + + # Get the left codage class + left = self.family[self.EAN13[0]] + + # Add start separator + strCode = "L0L" + + # Compute the left part of bar code + for i in range(0, 6): + strCode += left[i][self.EAN13[i + 1]] + + # Add middle separator + strCode += "0L0L0" + + # Compute the right codage class + for i in range(7, 13): + strCode += self.groupC[self.EAN13[i]] + + # Add stop separator + strCode += "L0L" + + return strCode + + def computeChecksum(self, arg): + """Compute the checksum of bar code""" + # UPCA/EAN13 + weight = [1, 3] * 6 + magic = 10 + sum = 0 + + for i in range(12): # checksum based on first 12 digits. + sum = sum + int(arg[i]) * weight[i] + z = (magic - (sum % magic)) % magic + if z < 0 or z >= magic: + return None + return z + + def verifyChecksum(self, bits): + """Verify the checksum""" + computedChecksum = self.computeChecksum(bits[:12]) + codeBarChecksum = bits[12] + + if codeBarChecksum != computedChecksum: + raise Exception( + "Bad checksum is %s and should be %s" + % (codeBarChecksum, computedChecksum) + ) + + def getImage(self, value, height=50, xw=1, rotate=None, extension="PNG"): + """Get an image with PIL library + value code barre value + height height in pixel of the bar code + extension image file extension""" + from PIL import Image, ImageFont, ImageDraw + import os + + # Get the bar code list + bits = self.makeCode(value) + + # Get thee bar code with the checksum added + code = "" + for digit in self.EAN13: + code += "%d" % digit + + # Create a new image + position = 8 + im = Image.new("L", (len(bits) + position, height + 2)) + + # Load font + ad = os.path.abspath(os.path.join(ustr(config["root_path"]), "addons")) + mod_path_list = list( + map( + lambda m: os.path.abspath(ustr(m.strip())), + config["addons_path"].split(","), + ) + ) + mod_path_list.append(ad) + + for mod_path in mod_path_list: + font_file = ( + mod_path + + os.path.sep + + "report_aeroo" + + os.path.sep + + "barcode" + + os.path.sep + + "FreeMonoBold.ttf" + ) # "courB08.pil" + if os.path.lexists(font_file): + font = ImageFont.truetype(font_file, fontsize) + + # Create drawer + draw = ImageDraw.Draw(im) + + # Erase image + draw.rectangle(((0, 0), (im.size[0], im.size[1])), fill=256) + + # Draw first part of number + draw.text((0, height - 9), code[0], font=font, fill=0) + + # Draw first part of number + draw.text((position + 3, height - 9), code[1:7], font=font, fill=0) + + # Draw second part of number + draw.text( + (len(bits) / 2 + 2 + position, height - 9), code[7:], font=font, fill=0 + ) + + # Draw the bar codes + for bit in range(len(bits)): + # Draw normal bar + if bits[bit] == "1": + draw.rectangle( + ((bit + position, 0), (bit + position, height - 10)), fill=0 + ) + # Draw long bar + elif bits[bit] == "L": + draw.rectangle( + ((bit + position, 0), (bit + position, height - 3)), fill=0 + ) + + # Save the result image + return im diff --git a/report_aeroo/barcode/__init__.py b/report_aeroo/barcode/__init__.py index 51db505..64fcc48 100755 --- a/report_aeroo/barcode/__init__.py +++ b/report_aeroo/barcode/__init__.py @@ -30,4 +30,3 @@ ############################################################################## from . import barcode - diff --git a/report_aeroo/barcode/barcode.py b/report_aeroo/barcode/barcode.py index 0c61d33..e464b87 100755 --- a/report_aeroo/barcode/barcode.py +++ b/report_aeroo/barcode/barcode.py @@ -34,26 +34,26 @@ from .EANBarCode import EanBarCode from io import StringIO + def make_barcode(code, code_type='ean13', rotate=None, height=50, xw=1): if code: - if code_type.lower()=='ean13': - bar=EanBarCode() - im = bar.getImage(code,height) - elif code_type.lower()=='code128': + if code_type.lower() == 'ean13': + bar = EanBarCode() + im = bar.getImage(code, height) + elif code_type.lower() == 'code128': im = get_code(code, xw, height) - elif code_type.lower()=='code39': + elif code_type.lower() == 'code39': im = create_c39(height, xw, code) else: return StringIO(), 'image/png' tf = StringIO() try: - if rotate!=None: - im=im.rotate(int(rotate)) - except Exception as e: + if rotate is not None: + im = im.rotate(int(rotate)) + except BaseException: pass im.save(tf, 'png') - size_x = str(im.size[0]/96.0)+'in' - size_y = str(im.size[1]/96.0)+'in' + size_x = str(im.size[0] / 96.0) + 'in' + size_y = str(im.size[1] / 96.0) + 'in' return tf, 'image/png', size_x, size_y - diff --git a/report_aeroo/barcode/code128.py b/report_aeroo/barcode/code128.py index a6efb3f..7f6cc9e 100755 --- a/report_aeroo/barcode/code128.py +++ b/report_aeroo/barcode/code128.py @@ -3,7 +3,10 @@ # This list was cut'n'pasted verbatim from the "Code 128 Specification Page" # at http://www.adams1.com/pub/russadam/128code.html -codelist="""0 SP SP 00 2 1 2 2 2 2 + +from PIL import Image + +codelist = """0 SP SP 00 2 1 2 2 2 2 1 ! ! 01 2 2 2 1 2 2 2 " " 02 2 2 2 2 2 1 3 # # 03 1 2 1 2 2 3 @@ -108,78 +111,69 @@ 102 (Hex 86) FNC 1 FNC 1 FNC 1 4 1 1 1 3 1""" - - -other="""103 (Hex 87) START (Code A) 2 1 1 4 1 2 +other = """103 (Hex 87) START (Code A) 2 1 1 4 1 2 104 (Hex 88) START (Code B) 2 1 1 2 1 4 105 (Hex 89) START (Code C) 2 1 1 2 3 2 106 STOP 2 3 3 1 1 1 2""" +codes = {} +values = {} +for lst in codelist.split('\n'): + lst.strip() + num, a1, b1, c1, code = lst.split('\t') + num = int(num.split(' ')[0]) + values[num] = [int(x) for x in code.split()] + codes[b1.strip()] = num -codes={} -values={} -for l in codelist.split('\n'): - l.strip() - num,a1,b1,c1,code=l.split('\t') - num=int(num.split(' ')[0]) - values[num]=[int(x) for x in code.split()] - codes[b1.strip()]=num +codes[' '] = codes['SP'] -codes[' ']=codes['SP'] +for lst in other.split('\n'): + lst.strip() + num, name, code = lst.split('\t') + num = int(num.split(' ')[0]) + values[num] = [int(x) for x in code.split()] + codes[name.strip()] = num -for l in other.split('\n'): - l.strip() - num,name,code=l.split('\t') - num=int(num.split(' ')[0]) - values[num]=[int(x) for x in code.split()] - codes[name.strip()]=num def encode_message(msg): - startnum=codes['START (Code B)'] - message=values[startnum][:] - chksum=startnum - mult=1 + startnum = codes['START (Code B)'] + message = values[startnum][:] + chksum = startnum + mult = 1 for c in msg: - if not codes.has_key(c): - raise "No code for "+c - chksum=chksum+mult*codes[c] - mult=mult+1 - message=message+values[codes[c]] + if c not in codes: + raise "No code for " + c + chksum = chksum + mult * codes[c] + mult = mult + 1 + message = message + values[codes[c]] - chksum=chksum%103 - - message=message+values[chksum] - message=message+values[codes['STOP']] + chksum = chksum % 103 + + message = message + values[chksum] + message = message + values[codes['STOP']] return message -import os -from PIL import Image -def get_code(message,xw=1,h=100,rotate=None): +def get_code(message, xw=1, h=100, rotate=None): """ message is message to code. xw is horizontal multiplier (in pixels width of narrowest bar) h is height in pixels. Returns a Python Imaging Library object.""" - widths=[xw*20]+encode_message(message)+[xw*20] - - bits=[] - i=1 + widths = [xw * 20] + encode_message(message) + [xw * 20] + + bits = [] + i = 1 for w in widths: - bits=bits+[i]*w*xw - i=1-i + bits = bits + [i] * w * xw + i = 1 - i - #print len(bits) - #print bits - - i=Image.new('1',(len(bits),h),1) + i = Image.new('1', (len(bits), h), 1) for b in range(len(bits)): for y in range(h): - i.putpixel((b,y),255*bits[b]) + i.putpixel((b, y), 255 * bits[b]) return i - - diff --git a/report_aeroo/barcode/code39.py b/report_aeroo/barcode/code39.py index 833efcb..381491a 100755 --- a/report_aeroo/barcode/code39.py +++ b/report_aeroo/barcode/code39.py @@ -4,7 +4,7 @@ # General contacts # Code39.py v1 -# Requires Python and Python Imaging Library (PIL), +# Requires Python and Python Imaging Library (PIL), # has been tested with Python v2.6 and PIL v1.1.6 # Usage example: @@ -15,59 +15,60 @@ from PIL import Image, ImageDraw, ImageFont from odoo.tools import config, ustr -import os, sys +import os marginx = 10 marginy = 10 fontsize = 15 charmap = { -'*':[0,3,0,1,2,1,2,1,0], -'-':[0,3,0,1,0,1,2,1,2], -'$':[0,3,0,3,0,3,0,1,0], -'%':[0,1,0,3,0,3,0,3,0], -' ':[0,3,2,1,0,1,2,1,0], -'.':[2,3,0,1,0,1,2,1,0], -'/':[0,3,0,3,0,1,0,3,0], -'+':[0,3,0,1,0,3,0,3,0], -'0':[0,1,0,3,2,1,2,1,0], -'1':[2,1,0,3,0,1,0,1,2], -'2':[0,1,2,3,0,1,0,1,2], -'3':[2,1,2,3,0,1,0,1,0], -'4':[0,1,0,3,2,1,0,1,2], -'5':[2,1,0,3,2,1,0,1,0], -'6':[0,1,2,3,2,1,0,1,0], -'7':[0,1,0,3,0,1,2,1,2], -'8':[2,1,0,3,0,1,2,1,0], -'9':[0,1,2,3,0,1,2,1,0], -'A':[2,1,0,1,0,3,0,1,2], -'B':[0,1,2,1,0,3,0,1,2], -'C':[2,1,2,1,0,3,0,1,0], -'D':[0,1,0,1,2,3,0,1,2], -'E':[2,1,0,1,2,3,0,1,0], -'F':[0,1,2,1,2,3,0,1,0], -'G':[0,1,0,1,0,3,2,1,2], -'H':[2,1,0,1,0,3,2,1,0], -'I':[0,1,2,1,0,3,2,1,0], -'J':[0,1,0,1,2,3,2,1,0], -'K':[2,1,0,1,0,1,0,3,2], -'L':[0,1,2,1,0,1,0,3,2], -'M':[2,1,2,1,0,1,0,3,0], -'N':[0,1,0,1,2,1,0,3,2], -'O':[2,1,0,1,2,1,0,3,0], -'P':[0,1,2,1,2,1,0,3,0], -'Q':[0,1,0,1,0,1,2,3,2], -'R':[2,1,0,1,0,1,2,3,0], -'S':[0,1,2,1,0,1,2,3,0], -'T':[0,1,0,1,2,1,2,3,0], -'U':[2,3,0,1,0,1,0,1,2], -'V':[0,3,2,1,0,1,0,1,2], -'W':[2,3,2,1,0,1,0,1,0], -'X':[0,3,0,1,2,1,0,1,2], -'Y':[2,3,0,1,2,1,0,1,0], -'Z':[0,3,2,1,2,1,0,1,0] + "*": [0, 3, 0, 1, 2, 1, 2, 1, 0], + "-": [0, 3, 0, 1, 0, 1, 2, 1, 2], + "$": [0, 3, 0, 3, 0, 3, 0, 1, 0], + "%": [0, 1, 0, 3, 0, 3, 0, 3, 0], + " ": [0, 3, 2, 1, 0, 1, 2, 1, 0], + ".": [2, 3, 0, 1, 0, 1, 2, 1, 0], + "/": [0, 3, 0, 3, 0, 1, 0, 3, 0], + "+": [0, 3, 0, 1, 0, 3, 0, 3, 0], + "0": [0, 1, 0, 3, 2, 1, 2, 1, 0], + "1": [2, 1, 0, 3, 0, 1, 0, 1, 2], + "2": [0, 1, 2, 3, 0, 1, 0, 1, 2], + "3": [2, 1, 2, 3, 0, 1, 0, 1, 0], + "4": [0, 1, 0, 3, 2, 1, 0, 1, 2], + "5": [2, 1, 0, 3, 2, 1, 0, 1, 0], + "6": [0, 1, 2, 3, 2, 1, 0, 1, 0], + "7": [0, 1, 0, 3, 0, 1, 2, 1, 2], + "8": [2, 1, 0, 3, 0, 1, 2, 1, 0], + "9": [0, 1, 2, 3, 0, 1, 2, 1, 0], + "A": [2, 1, 0, 1, 0, 3, 0, 1, 2], + "B": [0, 1, 2, 1, 0, 3, 0, 1, 2], + "C": [2, 1, 2, 1, 0, 3, 0, 1, 0], + "D": [0, 1, 0, 1, 2, 3, 0, 1, 2], + "E": [2, 1, 0, 1, 2, 3, 0, 1, 0], + "F": [0, 1, 2, 1, 2, 3, 0, 1, 0], + "G": [0, 1, 0, 1, 0, 3, 2, 1, 2], + "H": [2, 1, 0, 1, 0, 3, 2, 1, 0], + "I": [0, 1, 2, 1, 0, 3, 2, 1, 0], + "J": [0, 1, 0, 1, 2, 3, 2, 1, 0], + "K": [2, 1, 0, 1, 0, 1, 0, 3, 2], + "L": [0, 1, 2, 1, 0, 1, 0, 3, 2], + "M": [2, 1, 2, 1, 0, 1, 0, 3, 0], + "N": [0, 1, 0, 1, 2, 1, 0, 3, 2], + "O": [2, 1, 0, 1, 2, 1, 0, 3, 0], + "P": [0, 1, 2, 1, 2, 1, 0, 3, 0], + "Q": [0, 1, 0, 1, 0, 1, 2, 3, 2], + "R": [2, 1, 0, 1, 0, 1, 2, 3, 0], + "S": [0, 1, 2, 1, 0, 1, 2, 3, 0], + "T": [0, 1, 0, 1, 2, 1, 2, 3, 0], + "U": [2, 3, 0, 1, 0, 1, 0, 1, 2], + "V": [0, 3, 2, 1, 0, 1, 0, 1, 2], + "W": [2, 3, 2, 1, 0, 1, 0, 1, 0], + "X": [0, 3, 0, 1, 2, 1, 0, 1, 2], + "Y": [2, 3, 0, 1, 2, 1, 0, 1, 0], + "Z": [0, 3, 2, 1, 2, 1, 0, 1, 0], } + def create_c39(height, smallest, text): pixel_length = 0 i = 0 @@ -81,41 +82,36 @@ def create_c39(height, smallest, text): cmap = charmap[char] if len(cmap) != 9: continue - j = 0 while j < 9: seg = int(cmap[j]) - if seg == 0 or seg == 1: pixel_length = pixel_length + smallest seglist.append(seg) elif seg == 2 or seg == 3: pixel_length = pixel_length + smallest * 3 seglist.append(seg) - j = j + 1 - newtext += char - except: + except BaseException: continue - - pixel_length = pixel_length + 2*marginx + len(newtext) * smallest - pixel_height = height + 2*marginy + fontsize - + pixel_length = pixel_length + 2 * marginx + len(newtext) * smallest + pixel_height = height + 2 * marginy + fontsize + barcode_img = Image.new('RGB', [pixel_length, pixel_height], "white") - + if len(seglist) == 0: return barcode_img - + i = 0 draw = ImageDraw.Draw(barcode_img) current_x = marginx - + while i < len(seglist): seg = seglist[i] color = (255, 255, 255) wdth = smallest - + if seg == 0 or seg == 2: color = 0 if seg == 0: @@ -128,35 +124,37 @@ def create_c39(height, smallest, text): wdth = smallest else: wdth = smallest * 3 - + j = 1 - + while j <= wdth: - draw.line((current_x, marginy, current_x, marginy+height), fill=color) - current_x = current_x + 1 + draw.line((current_x, marginy, current_x, marginy + height), fill=color) + current_x = current_x + 1 j = j + 1 - - if ((i+1) % 9) == 0: + + if ((i + 1) % 9) == 0: j = 1 while j <= smallest: - draw.line((current_x, marginy, current_x, marginy+height), fill=(255,255,255)) + draw.line((current_x, marginy, current_x, marginy + height), + fill=(255, 255, 255)) current_x = current_x + 1 - j = j + 1 + j = j + 1 i = i + 1 ad = os.path.abspath(os.path.join(ustr(config['root_path']), u'addons')) - mod_path_list = map(lambda m: os.path.abspath(ustr(m.strip())), config['addons_path'].split(',')) + mod_path_list = map(lambda m: os.path.abspath(ustr(m.strip())), + config['addons_path'].split(',')) mod_path_list.append(ad) for mod_path in mod_path_list: - font_file = mod_path+os.path.sep+ \ - "report_aeroo"+os.path.sep+"barcode"+os.path.sep+"FreeMonoBold.ttf" + font_file = (mod_path + os.path.sep + "report_aeroo" + os.path.sep + + "barcode" + os.path.sep + "FreeMonoBold.ttf") if os.path.lexists(font_file): font = ImageFont.truetype(font_file, fontsize) - - draw.text((pixel_length/2 - len(newtext)*(fontsize/2)/2-len(newtext), height+fontsize), newtext, font=font, fill=0) - + + draw.text((pixel_length / 2 - len(newtext) * (fontsize / 2) / 2 - len(newtext), + height + fontsize), newtext, font=font, fill=0) + del draw - - return barcode_img + return barcode_img diff --git a/report_aeroo/check_deps.py b/report_aeroo/check_deps.py index fe46c45..9590a7f 100755 --- a/report_aeroo/check_deps.py +++ b/report_aeroo/check_deps.py @@ -36,6 +36,7 @@ 'check_deps', ] + def check_deps(check_list): error = False import_errors = [] @@ -46,4 +47,7 @@ def check_deps(check_list): error = True import_errors.append(str(e)) if error: - raise osv.except_osv(_('Warning!')+' '+_('Unmet python dependencies!'), '\n'.join(import_errors)) + raise osv.except_osv( + _('Warning!') + ' ' + _('Unmet python dependencies!'), '\n'.join( + import_errors) + ) diff --git a/report_aeroo/controllers/__init__.py b/report_aeroo/controllers/__init__.py index 6799fd4..806dfff 100644 --- a/report_aeroo/controllers/__init__.py +++ b/report_aeroo/controllers/__init__.py @@ -1,6 +1,6 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ diff --git a/report_aeroo/controllers/main.py b/report_aeroo/controllers/main.py index 6f8c77e..08aed9c 100644 --- a/report_aeroo/controllers/main.py +++ b/report_aeroo/controllers/main.py @@ -2,7 +2,6 @@ # Copyright 2018 - Brain-tec AG - Carlos Jesus Cebrian # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) import json -import mimetypes from werkzeug.urls import url_decode from odoo import http @@ -53,7 +52,8 @@ def report_routes(self, reportname, docids=None, converter=None, **data): report = report.sudo() context['report_name'] = reportname context['return_filename'] = True - res, extension, filename = report.with_context(context)._render_aeroo(reportname, docids, data=data) + res, extension, filename = report.with_context(context)._render_aeroo( + reportname, docids, data=data) mimetype = self.MIMETYPES.get(res, 'application/octet-stream') httpheaders = [ ('Content-Disposition', content_disposition(filename)), @@ -82,11 +82,13 @@ def report_download(self, data, context=None): reportname, docids = reportname.split('/') # on aeroo we support docids + data data = url_decode(url.split('?')[1]).items() - # TODO deberiamos ver si podemos mejorar esto que va de la mano con algo que comentamos en js - # y no parece ser lo que hacen otros. Basicamente estamos obteniendo lo que mandamos en context al imprimir + # TODO deberiamos ver si podemos mejorar esto que va de la mano con algo + # que comentamos en js y no parece ser lo que hacen otros. Basicamente + # estamos obteniendo lo que mandamos en context al imprimir # el reporte, desde la URl context = dict(data).get('context', context) - response = self.report_routes(reportname, docids=docids, converter='aeroo', context=context) + response = self.report_routes(reportname, docids=docids, converter='aeroo', + context=context) # if docids: # # Generic report: # response = self.report_routes( diff --git a/report_aeroo/demo/__init__.py b/report_aeroo/demo/__init__.py index 0ffe6cb..111c09b 100644 --- a/report_aeroo/demo/__init__.py +++ b/report_aeroo/demo/__init__.py @@ -1,8 +1,7 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ from . import parser - diff --git a/report_aeroo/demo/parser.py b/report_aeroo/demo/parser.py index f53b4f0..737a00f 100644 --- a/report_aeroo/demo/parser.py +++ b/report_aeroo/demo/parser.py @@ -1,6 +1,6 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ diff --git a/report_aeroo/docs_client_lib.py b/report_aeroo/docs_client_lib.py index cc252a4..af41861 100755 --- a/report_aeroo/docs_client_lib.py +++ b/report_aeroo/docs_client_lib.py @@ -33,9 +33,10 @@ # without prior notice import json +import os import requests from base64 import b64encode, b64decode -CHUNK_LENGTH = 32*1024 +CHUNK_LENGTH = 32 * 1024 HEADERS = {'content-type': 'application/json'} DOCSHOST = 'localhost' DOCSPORT = 8989 @@ -44,8 +45,9 @@ class ServerException(Exception): pass + class DOCSConnection(): - + def __init__(self, host=DOCSHOST, port=DOCSPORT, username=None, password=None): assert isinstance(host, str) and isinstance(port, (str, int)) self.host = host @@ -55,26 +57,23 @@ def __init__(self, host=DOCSHOST, port=DOCSPORT, username=None, password=None): self.url = 'http://%s:%s/' % (self.host, self.port) self.username = username self.password = password - + def _initpack(self, method): return { - "jsonrpc": "2.0", - "method": method, - "id": 1, - "params": { - 'username': self.username, - 'password': self.password - }, - } - + "jsonrpc": "2.0", + "method": method, + "id": 1, + "params": {'username': self.username, 'password': self.password}, + } + def test(self, ctd=None): # ctd stands for crash test dummy file path = ctd or os.path.join('report_aeroo', 'test_temp.odt') with open(path, "r") as testfile: - data=testfile.read() + data = testfile.read() identifier = self.upload(data) if not identifier: - raise ServerException('Upload failded, no upload identifier '\ + raise ServerException('Upload failded, no upload identifier ' 'returned from server.') conv_result = self.convert(identifier) if not conv_result: @@ -83,7 +82,7 @@ def test(self, ctd=None): if not join_result: raise ServerException("Document join error.") return True - + def upload(self, data, filename=False): assert len(data) > 0 data = b64encode(data).decode('utf8') @@ -91,13 +90,15 @@ def upload(self, data, filename=False): data_size = len(data) upload_complete = False for i in range(0, data_size, CHUNK_LENGTH): - chunk = data[i:i+CHUNK_LENGTH] - is_last = (i+CHUNK_LENGTH) >= data_size + chunk = data[i: i + CHUNK_LENGTH] + is_last = (i + CHUNK_LENGTH) >= data_size payload = self._initpack('upload') - payload['params'].update({'data':chunk, 'identifier':identifier, - 'is_last': is_last}) + payload['params'].update( + {'data': chunk, 'identifier': identifier, 'is_last': is_last} + ) response = requests.post( - self.url, data = json.dumps(payload), headers=HEADERS).json() + self.url, data=json.dumps(payload), headers=HEADERS + ).json() self._checkerror(response) if 'result' not in response: break @@ -108,7 +109,6 @@ def upload(self, data, filename=False): identifier = identifier or response['result']['identifier'] return identifier or False - def convert(self, data=False, identifier=False, in_mime=False, out_mime=False): payload = self._initpack('convert') if identifier: @@ -122,22 +122,22 @@ def convert(self, data=False, identifier=False, in_mime=False, out_mime=False): if out_mime: payload['params'].update({'out_mime': out_mime}) response = requests.post( - self.url, data = json.dumps(payload), headers=HEADERS).json() + self.url, data=json.dumps(payload), headers=HEADERS).json() self._checkerror(response) return 'result' in response and b64decode(response['result']) or False - + def join(self, idents, in_mime=False, out_mime=False): payload = self._initpack('join') payload['params'].update({'idents': idents}) if in_mime: - payload['params'].update({'in_mime':in_mime}) + payload['params'].update({'in_mime': in_mime}) if out_mime: - payload['params'].update({'out_mime':out_mime}) + payload['params'].update({'out_mime': out_mime}) response = requests.post( - self.url, data = json.dumps(payload), headers=HEADERS).json() + self.url, data=json.dumps(payload), headers=HEADERS).json() self._checkerror(response) return 'result' in response and b64decode(response['result']) or False - + def _checkerror(self, response): if 'error' in response: raise ServerException(response['error']['message']) diff --git a/report_aeroo/exceptions.py b/report_aeroo/exceptions.py index e898e5a..e9e1d50 100644 --- a/report_aeroo/exceptions.py +++ b/report_aeroo/exceptions.py @@ -1,18 +1,19 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ from odoo.exceptions import except_orm + class ConnectionError(except_orm): """ Basic connection error. Example: When try to connect Aeroo DOCS and connection fails.""" def __init__(self, msg): super(ConnectionError, self).__init__(msg) - - + + class ProgrammingError(except_orm): """ Basic programming error. Example: When python code can not be compiled due to some error.""" diff --git a/report_aeroo/models/report.py b/report_aeroo/models/report.py index 2f4207c..f526936 100644 --- a/report_aeroo/models/report.py +++ b/report_aeroo/models/report.py @@ -1,6 +1,6 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ @@ -15,7 +15,7 @@ _logger = logging.getLogger(__name__) -# ------------------------------------------------------------------------------ + class ReportStylesheets(models.Model): ''' Aeroo Report Stylesheets @@ -23,23 +23,19 @@ class ReportStylesheets(models.Model): _name = 'report.stylesheets' _description = 'Report Stylesheets' - ### Fields name = fields.Char('Name', size=64, required=True) report_styles = fields.Binary('Template Stylesheet', - help='OpenOffice.org / LibreOffice stylesheet (.odt)') - ### ends Fields + help='OpenOffice.org / LibreOffice stylesheet (.odt)') + -# ------------------------------------------------------------------------------ class ResCompany(models.Model): _name = 'res.company' _inherit = 'res.company' - ### Fields - stylesheet_id = fields.Many2one('report.stylesheets', - 'Aeroo Reports Global Stylesheet') - ### ends Fields + stylesheet_id = fields.Many2one('report.stylesheets', + 'Aeroo Reports Global Stylesheet') + -# ------------------------------------------------------------------------------ class ReportMimetypes(models.Model): ''' Aeroo Report Mime-Type @@ -47,15 +43,12 @@ class ReportMimetypes(models.Model): _name = 'report.mimetypes' _description = 'Report Mime-Types' - ### Fields name = fields.Char('Name', size=64, required=True, readonly=True) code = fields.Char('Code', size=16, required=True, readonly=True) - compatible_types = fields.Char('Compatible Mime-Types', size=128, - readonly=True) + compatible_types = fields.Char('Compatible Mime-Types', size=128, readonly=True) filter_name = fields.Char('Filter Name', size=128, readonly=True) - ### ends Fields -# ------------------------------------------------------------------------------ + class ReportAeroo(models.Model): _inherit = 'ir.actions.report' @@ -64,7 +57,8 @@ def _render_aeroo(self, report_ref, docids, data=None): report = self._get_report(report_ref) report_parser = self.env[report.parser_model or 'report.report_aeroo.abstract'] return report_parser.with_context( - active_model=report.model, report_name=report.report_name).aeroo_report(docids, data) + active_model=report.model, report_name=report.report_name + ).aeroo_report(docids, data) @api.model def _get_report_from_name(self, report_name): @@ -92,7 +86,7 @@ def _read_template(self): "Error in '_read_template' method", exc_info=True) except Exception as e: _logger.exception( - "Error in '_read_template' method", exc_info=True) + "Error in '_read_template' method \n %s" % str(e), exc_info=True) fp = False data = False finally: @@ -102,26 +96,26 @@ def _read_template(self): @api.model def _get_encodings(self): - l = list(set(encodings._aliases.values())) - l.sort() - return zip(l, l) + lst = list(set(encodings._aliases.values())) + lst.sort() + return zip(lst, lst) @api.model def _get_default_outformat(self): - res = self.env['report.mimetypes'].search([('code','=','oo-odt')]) + res = self.env['report.mimetypes'].search([('code', '=', 'oo-odt')]) return res and res[0].id or False def _get_extras(recs): result = [] if recs.aeroo_docs_enabled(): result.append('aeroo_ooo') - ##### Check deferred_processing module ##### + # Check deferred_processing module recs.env.cr.execute("SELECT id, state FROM ir_module_module WHERE \ name='deferred_processing'") deferred_proc_module = recs.env.cr.dictfetchone() - if deferred_proc_module and deferred_proc_module['state'] in ('installed', 'to upgrade'): + if (deferred_proc_module and deferred_proc_module['state'] in + ('installed', 'to upgrade')): result.append('deferred_processing') - ############################################ result = ','.join(result) for rec in recs: rec.extras = result @@ -138,42 +132,61 @@ def aeroo_docs_enabled(self): @api.model def _get_in_mimetypes(self): mime_obj = self.env['report.mimetypes'] - domain = self.env.context.get('allformats') and [] or [('filter_name','=',False)] + domain = ( + self.env.context.get('allformats') and [] or [('filter_name', '=', False)] + ) res = mime_obj.search(domain).read(['code', 'name']) return [(r['code'], r['name']) for r in res] - ### Fields charset = fields.Selection('_get_encodings', string='Charset', - required=True, default='utf_8') + required=True, default='utf_8') styles_mode = fields.Selection([ - ('default','Not used'), - ('global','Global'), - ('specified','Specified'), - ], string='Stylesheet', default='default') + ('default', 'Not used'), + ('global', 'Global'), + ('specified', 'Specified'), + ], string='Stylesheet', default='default') stylesheet_id = fields.Many2one('report.stylesheets', 'Template Stylesheet') preload_mode = fields.Selection([ - ('static',_('Static')), - ('preload',_('Preload')), - ], string='Preload Mode', default='static') + ('static', _('Static')), + ('preload', _('Preload')), + ], string='Preload Mode', default='static') tml_source = fields.Selection([ - ('database','Database'), - ('file','File'), - ('parser','Parser'), - ('attachment','Attachment'), - ], string='Template source', default='database', index=True) - attachment_id = fields.Many2one('ir.attachment', domain=[("res_model", "=", "report.aeroo")], ondelete='set null') + ('database', 'Database'), + ('file', 'File'), + ('parser', 'Parser'), + ('attachment', 'Attachment'), + ], string='Template source', default='database', index=True) + attachment_id = fields.Many2one( + 'ir.attachment', + domain=[("res_model", "=", "report.aeroo")], + ondelete='set null' + ) parser_model = fields.Char( - help='Optional model to be used as parser, if not configured "report.report_aeroo.abstract" will be used') - report_type = fields.Selection(selection_add=[('aeroo', _('Aeroo Reports'))], ondelete={'aeroo': 'cascade'}) - process_sep = fields.Boolean('Process Separately', + help="Optional model to be used as parser, \ + if not configured 'report.report_aeroo.abstract' will be used" + ) + report_type = fields.Selection( + selection_add=[('aeroo', _('Aeroo Reports'))], + ondelete={'aeroo': 'cascade'} + ) + process_sep = fields.Boolean( + 'Process Separately', help='Generate the report for each object separately, \ - then merge reports.') - in_format = fields.Selection(selection='_get_in_mimetypes', - string='Template Mime-type',) - out_format = fields.Many2one('report.mimetypes', 'Output Mime-type', - default=_get_default_outformat) - report_wizard = fields.Boolean('Report Wizard', - help='Adds a standard wizard when the report gets invoked.') + then merge reports.' + ) + in_format = fields.Selection( + selection='_get_in_mimetypes', + string='Template Mime-type' + ) + out_format = fields.Many2one( + 'report.mimetypes', + 'Output Mime-type', + default=_get_default_outformat + ) + report_wizard = fields.Boolean( + 'Report Wizard', + help='Adds a standard wizard when the report gets invoked.' + ) copies = fields.Integer( string='Number of Copies', default=1, @@ -181,37 +194,44 @@ def _get_in_mimetypes(self): copies_intercalate = fields.Boolean( help='If true, then page order will be like "1, 2, 3; 1, 2, 3", if ' 'not it will be like "1, 1; 2, 2; 3, 3"') - disable_fallback = fields.Boolean('Disable Format Fallback', + disable_fallback = fields.Boolean( + 'Disable Format Fallback', help='Raises error on format convertion failure. Prevents returning \ - original report file type if no convertion is available.') - extras = fields.Char('Extra options', compute='_get_extras', - size=256) - deferred = fields.Selection([ - ('off',_('Off')), - ('adaptive',_('Adaptive')), - ],'Deferred', - help='Deferred (aka Batch) reporting, for reporting on large amount \ - of data.', - default='off') - deferred_limit = fields.Integer('Deferred Records Limit', - help='Records limit at which you are invited to start the deferred \ - process.', + original report file type if no convertion is available.' + ) + extras = fields.Char('Extra options', compute='_get_extras', size=256) + deferred = fields.Selection( + [('off', _('Off')), + ('adaptive', _('Adaptive'))], + 'Deferred', + help='Deferred (aka Batch) reporting, for reporting on large amount of data.', + default='off' + ) + deferred_limit = fields.Integer( + 'Deferred Records Limit', + help='Records limit at which you are invited to start the deferred process.', default=80 - ) - replace_report_id = fields.Many2one('ir.actions.report', 'Replace Report', - help='Select a report that should be replaced.') + ) + replace_report_id = fields.Many2one( + 'ir.actions.report', + 'Replace Report', + help='Select a report that should be replaced.' + ) wizard_id = fields.Many2one('ir.actions.act_window', 'Wizard Action') report_data = fields.Binary(string='Template Content', attachment=True) - ### ends Fields @api.constrains('parser_model') def _check_parser_model(self): for rec in self.filtered('parser_model'): - if not rec.env['ir.model'].search([('name', '=', rec.parser_model)], limit=1): - raise UserError(_('Parser model %s not found on database.') % (rec.parser_model)) + if not rec.env['ir.model'].search( + [('name', '=', rec.parser_model)], limit=1): + raise UserError( + _('Parser model %s not found on database.') % (rec.parser_model) + ) def read(self, fields=None, load='_classic_read'): - # ugly hack to avoid report being read when we enter a view with report added on print menu + # ugly hack to avoid report being read when + # we enter a view with report added on print menu if not fields: fields = list(self._fields) fields.remove('report_data') diff --git a/report_aeroo/report/test_aeroo_report_file.py b/report_aeroo/report/test_aeroo_report_file.py index 4f5e562..e6d5627 100644 --- a/report_aeroo/report/test_aeroo_report_file.py +++ b/report_aeroo/report/test_aeroo_report_file.py @@ -7,7 +7,6 @@ class TestAerooReport(models.AbstractModel): _name = 'report.product_template_printer' _description = 'report.product_template_printer' -#=============================================================================== @api.model def get_report_values(self, docids, data=None): report = self.env['ir.actions.report']._get_report_from_name(self._name) diff --git a/report_aeroo/report_parser.py b/report_aeroo/report_parser.py index 6937f3c..f74030c 100644 --- a/report_aeroo/report_parser.py +++ b/report_aeroo/report_parser.py @@ -12,14 +12,12 @@ import time import datetime import base64 -import aeroolib as aeroolib from aeroolib.plugins.opendocument import Template, OOSerializer, _filter from aeroolib import __version__ as aeroolib_version from currency2text import supported_language from .docs_client_lib import DOCSConnection from .exceptions import ConnectionError from PyPDF2 import PdfFileWriter, PdfFileReader -from io import BytesIO from genshi.template.eval import StrictLookup @@ -38,20 +36,20 @@ from odoo.tools.misc import DATE_LENGTH import babel.dates import pytz -import datetime -def format_datetime(env, value, lang_code=False, date_format=False, tz='America/Argentina/Buenos_Aires'): +def format_datetime(env, value, lang_code=False, date_format=False, + tz='America/Argentina/Buenos_Aires'): ''' This is an adaptation of odoo format_date method but to format datetimes TODO we should move it to another plase or make it simpler :param env: an environment. :param date, datetime or string value: the date to format. - :param string lang_code: the lang code, if not specified it is extracted from the - environment context. - :param string date_format: the format or the date (LDML format), if not specified the - default format of the lang. + :param string lang_code: the lang code, if not specified it is extracted from + the environment context. + :param string date_format: the format or the date (LDML format), if not + specified the default format of the lang. :return: date formatted in the specified format. :rtype: string ''' @@ -70,9 +68,12 @@ def format_datetime(env, value, lang_code=False, date_format=False, tz='America/ lang = env['res.lang']._lang_get(lang_code or env.context.get('lang') or 'en_US') locale = babel.Locale.parse(lang.code) if not date_format: - date_format = posix_to_ldml('%s %s' % (lang.date_format, lang.time_format), locale=locale) + date_format = posix_to_ldml( + '%s %s' % (lang.date_format, lang.time_format), locale=locale + ) - return babel.dates.format_datetime(value, format=date_format, locale=locale, tzinfo=tz) + return babel.dates.format_datetime(value, format=date_format, + locale=locale, tzinfo=tz) _logger = logging.getLogger(__name__) @@ -158,20 +159,21 @@ def _average(self, attr, field): exec(expr, localspace) x = sum(localspace['value_list']) y = len(localspace['value_list']) - return float(x)/float(y) + return float(x) / float(y) - def _asimage(self, field_value, rotate=None, size_x=None, size_y=None, dpix=96, dpiy=96, + def _asimage(self, field_value, rotate=None, size_x=None, + size_y=None, dpix=96, dpiy=96, uom='px', hold_ratio=False): """ Prepare image for inserting into OpenOffice.org document """ def size_by_uom(val, uom, dpi): if uom == 'px': - result = str(val/dpi)+'in' + result = str(val / dpi) + 'in' elif uom == 'cm': - result = str(val/2.54)+'in' + result = str(val / 2.54) + 'in' elif uom == 'in': - result = str(val)+'in' + result = str(val) + 'in' return result ############################################## if not field_value: @@ -186,12 +188,12 @@ def size_by_uom(val, uom, dpi): # dpi_x, dpi_y = map(float, im.info.get('dpi', (96, 96))) dpi_x, dpi_y = map(float, (dpix, dpiy)) try: - if rotate != None: + if rotate is not None: im = im.rotate(int(rotate)) tf.seek(0) im.save(tf, format) except Exception as e: - _logger.exception("Error in '_asimage' method") + _logger.exception("Error in '_asimage' method \n %s" % str(e)) if hold_ratio: img_ratio = im.size[0] / float(im.size[1]) @@ -208,9 +210,9 @@ def size_by_uom(val, uom, dpi): size_y = size_y2 size_x = size_x and size_by_uom(size_x, uom, dpi_x) \ - or str(im.size[0]/dpi_x)+'in' + or str(im.size[0] / dpi_x) + 'in' size_y = size_y and size_by_uom(size_y, uom, dpi_y) \ - or str(im.size[1]/dpi_y)+'in' + or str(im.size[1] / dpi_y) + 'in' return tf, 'image/%s' % format, size_x, size_y def _currency_to_text(self, currency): @@ -241,7 +243,7 @@ def get_selection_item(obj, field, value=None): return '' except Exception as e: _logger.exception( - "Error in '_get_selection_item' method", exc_info=True) + "Error in '_get_selection_item' method \n %s" % str(e), exc_info=True) return '' return get_selection_item @@ -251,12 +253,6 @@ def _get_log(self, obj, field=None): else: return obj.get_metadata()[0] - def _asarray(self, attr, field): - expr = "for o in objects:\n\tvalue_list.append(o.%s)" % field - localspace = {'objects': attr, 'value_list': []} - exec(expr, localspace) - return localspace['value_list'] - # / Extra Functions ======================================================== def get_docs_conn(self): @@ -332,7 +328,8 @@ def _set_lang(self, lang, obj=None): def _format_lang( self, value, digits=None, grouping=True, monetary=False, dp=False, - currency_obj=False, date=False, date_time=False, lang_code=False, date_format=False): + currency_obj=False, date=False, date_time=False, lang_code=False, + date_format=False): """ We add date and date_time for backwards compatibility. Odoo has split the method in two (formatlang and format_date) """ @@ -340,9 +337,11 @@ def _format_lang( # we force the timezone of the user if the value is datetime if isinstance(value, (datetime.datetime)): value = value.astimezone(pytz.timezone(self.env.user.tz or 'UTC')) - return odoo_fd(self.env, value, lang_code=lang_code, date_format=date_format) + return odoo_fd(self.env, value, lang_code=lang_code, + date_format=date_format) elif date_time: - return format_datetime(self.env, value, lang_code=lang_code, date_format=date_format, tz=self.env.user.tz) + return format_datetime(self.env, value, lang_code=lang_code, + date_format=date_format, tz=self.env.user.tz) return odoo_fl( self.env, value, digits, grouping, monetary, dp, currency_obj) @@ -397,9 +396,9 @@ def complex_report(self, docids, data, report, ctx): self.env.model = ctx.get('active_model', False) self.env.report = report - #======================================================================= def barcode( - barcode_type, value, width=600, height=100, dpi_x=96, dpi_y=96, humanreadable=0): + barcode_type, value, width=600, height=100, dpi_x=96, dpi_y=96, + humanreadable=0): # TODO check that asimage and barcode both accepts width and height img = self.env['ir.actions.report'].barcode( barcode_type, value, width=width, height=height, @@ -410,13 +409,13 @@ def barcode( 'myget': self.myget, 'partner_address': self.partner_address, 'storage': {}, - 'user': self.env.user, + 'user': self.env.user, 'user_lang': ctx.get('lang', self.env.user.lang), - 'data': data, + 'data': data, 'time': time, 'datetime': datetime, - 'average': self._average, + 'average': self._average, 'currency_to_text': self._currency_to_text, 'asimage': self._asimage, 'get_selection_item': self._get_selection_items('item'), @@ -425,14 +424,14 @@ def barcode( 'asarray': self._asarray, '__filter': self.__filter, # Don't use in the report template! - 'getLang': self._get_lang, - 'setLang': self._set_lang, + 'getLang': self._get_lang, + 'setLang': self._set_lang, 'formatLang': self._format_lang, - 'test': self.test, - 'fields': fields, - 'company': self.env.company, - 'barcode': barcode, - 'tools': tools, + 'test': self.test, + 'fields': fields, + 'company': self.env.company, + 'barcode': barcode, + 'tools': tools, } self.env.localcontext.update(ctx) self._set_lang(self.env.company.partner_id.lang) @@ -492,9 +491,7 @@ def barcode( ser.add_creation_date(time.strftime('%Y-%m-%dT%H:%M:%S')) file_data = basic.generate(**self.env.localcontext).render().getvalue() - #======================================================================= code = mime_dict[report.in_format] - #_logger.info("End process %s (%s), elapsed time: %s" % (self.name, self.env.model, time.time() - aeroo_print.start_time), logging.INFO) # debug mode return file_data, code @@ -503,7 +500,7 @@ def simple_report(self, docids, data, report, ctx, output='raw'): def single_report(self, docids, data, report, ctx): code = report.out_format.code - ext = mime_dict[code] + mime_dict[code] if code.startswith('oo-'): return self.complex_report(docids, data, report, ctx) elif code == 'genshi-raw': @@ -523,13 +520,15 @@ def assemble_tasks(self, docids, data, report, ctx): if report.in_format == code: filename = '%s.%s' % ( print_report_name, mime_dict[report.in_format]) - return return_filename and (result[0], result[1], filename) or (result[0], result[1]) + return (return_filename and (result[0], result[1], filename) + or (result[0], result[1])) else: try: result = self._generate_doc(result[0], report) filename = '%s.%s' % ( print_report_name, mime_dict[report.out_format.code]) - return return_filename and (result, mime_dict[code], filename) or (result, mime_dict[code]) + return (return_filename and (result, mime_dict[code], filename) + or (result, mime_dict[code])) except Exception as e: _logger.exception(_("Aeroo DOCS error!\n%s") % str(e)) if report.disable_fallback: @@ -538,14 +537,16 @@ def assemble_tasks(self, docids, data, report, ctx): raise ConnectionError(_('Could not connect Aeroo DOCS!')) # only if fallback filename = '%s.%s' % (print_report_name, mime_dict[report.in_format]) - return return_filename and (result[0], result[1], filename) or (result[0], result[1]) + return (return_filename and (result[0], result[1], filename) + or (result[0], result[1])) @api.model def aeroo_report(self, docids, data): report_name = self._context.get('report_name') report = self.env['ir.actions.report']._get_report_from_name(report_name) # TODO - #_logger.info("Start Aeroo Reports %s (%s)" % (name, ctx.get('active_model')), logging.INFO) # debug mode + # _logger.info("Start Aeroo Reports %s (%s)" % (name, ctx.get('active_model')), + # logging.INFO) # debug mode if 'tz' not in self._context: self = self.with_context(tz=self.env.user.tz) @@ -579,7 +580,8 @@ def aeroo_report(self, docids, data): else: res = self.assemble_tasks(docids, data, report, self._context) # TODO - #_logger.info("End Aeroo Reports %s (%s), total elapsed time: %s" % (name, model), time() - aeroo_print.start_total_time), logging.INFO) # debug mode + # _logger.info("End Aeroo Reports %s (%s), total elapsed time: %s" + # % (name, model), time() - aeroo_print.start_total_time), logging.INFO) return res diff --git a/report_aeroo/wizard/__init__.py b/report_aeroo/wizard/__init__.py index 7c2bd28..79bd59e 100755 --- a/report_aeroo/wizard/__init__.py +++ b/report_aeroo/wizard/__init__.py @@ -1,6 +1,6 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ diff --git a/report_aeroo/wizard/installer.py b/report_aeroo/wizard/installer.py index 1e4fdbd..f6165b5 100644 --- a/report_aeroo/wizard/installer.py +++ b/report_aeroo/wizard/installer.py @@ -1,10 +1,12 @@ ################################################################################ # -# This file is part of Aeroo Reports software - for license refer LICENSE file +# This file is part of Aeroo Reports software - for license refer LICENSE file # ################################################################################ import os +import urllib3 + from base64 import b64encode from odoo.addons.report_aeroo.docs_client_lib import DOCSConnection @@ -12,8 +14,12 @@ from odoo import api, fields, models, _ from odoo.tools import file_open +import logging +_logger = logging.getLogger(__name__) + _url = 'xhttp://www.alistek.com/aeroo_banner/v11_1_report_aeroo.png' + class DocsConfigInstaller(models.TransientModel): _name = 'docs_config.installer' _description = 'docs_config.installer' @@ -26,13 +32,13 @@ def _get_image(self): if self._logo_image: return self._logo_image try: - im = urllib2.urlopen(_url.encode("UTF-8")) + im = urllib3.urlopen(_url.encode("UTF-8")) if im.headers.maintype != 'image': raise TypeError(im.headers.maintype) except Exception as e: - path = os.path.join('report_aeroo','config_pixmaps', - 'module_banner_1.png') - image_file = file_data = file_open(path,'rb') + _logger.info(e) + path = os.path.join('report_aeroo', 'config_pixmaps', 'module_banner_1.png') + image_file = file_data = file_open(path, 'rb') try: file_data = image_file.read() self._logo_image = b64encode(file_data) @@ -46,25 +52,28 @@ def _get_image(self): def _get_image_fn(recs): recs.config_logo = recs._get_image() - ### Fields enabled = fields.Boolean('Enabled', default=False) host = fields.Char('Host', size=64, required=True, default='localhost') port = fields.Integer('Port', required=True, default=8989) - auth_type = fields.Selection([ - ('simple','Simple Authentication') - ],'Authentication', default=False) + auth_type = fields.Selection( + [('simple', 'Simple Authentication')], + 'Authentication', + default=False + ) username = fields.Char('Username', size=32, default='anonymous') password = fields.Char('Password', size=32, default='anonymous') - state = fields.Selection([ - ('init','Init'), - ('error','Error'), - ('done','Done'), - ],'State', index=True, readonly=True, default='init') + state = fields.Selection( + [('init', 'Init'), ('error', 'Error'), ('done', 'Done')], + 'State', + index=True, + readonly=True, + default='init' + ) msg = fields.Text('Message', readonly=True) error_details = fields.Text('Error Details', readonly=True) - config_logo = fields.Binary(compute='_get_image_fn', string='Image', - default=_get_image) - ### ends Fields + config_logo = fields.Binary( + compute='_get_image_fn', string='Image', default=_get_image + ) @api.model def default_get(self, allfields): @@ -94,29 +103,31 @@ def check(self): try: fp = file_open('report_aeroo/test_temp.odt', mode='rb') file_data = fp.read() - docs_client = DOCSConnection(self.host, self.port, - username=self.username, password=self.password) + docs_client = DOCSConnection( + self.host, self.port, username=self.username, password=self.password + ) token = docs_client.upload(file_data) - data = docs_client.convert(identifier=token, out_mime='pdf') + docs_client.convert(identifier=token, out_mime='pdf') except Exception as e: error_details = str(e) state = 'error' - if state=='error': - msg = _('Failure! Connection to DOCS service was not established ' + - 'or convertion to PDF unsuccessful!') - elif state=='done' and not self.enabled: + if state == 'error': + msg = _('Failure! Connection to DOCS service was not established ' + + 'or convertion to PDF unsuccessful!') + elif state == 'done' and not self.enabled: msg = _('Connection to Aeroo DOCS disabled!') else: - msg = _('Success! Connection to the DOCS service was successfully '+ - 'established and PDF convertion is working.') + msg = _('Success! Connection to the DOCS service was successfully ' + + 'established and PDF convertion is working.') self.msg = msg self.error_details = error_details self.state = state mod_obj = self.env['ir.model.data'] act_obj = self.env['ir.actions.act_window'] - result = mod_obj.check_object_reference('report_aeroo', - 'action_docs_config_wizard') + result = mod_obj.check_object_reference( + 'report_aeroo', 'action_docs_config_wizard' + ) act_id = result and result[1] or False - result = act_obj.search([('id','=',act_id)]).read()[0] + result = act_obj.search([('id', '=', act_id)]).read()[0] result['res_id'] = self.id return result