"""Module that creates barcode image from product UPC from database. generate_barcode uses elaphe library to create barcode from 12 or 13 digit number and Pillow to create image with created barcode. """ import os from elaphe.ean import Ean13 from elaphe.upc import UpcA from oto import response from salessheets import config from salessheets.connectors import loggly from salessheets.constants import barcode from salessheets.constants import errors logger = loggly.get_current_logger() def generate_barcode( upc, scale=barcode.DEFAULT_SCALE, margin=barcode.DEFAULT_MARGIN, options=None): """ Main function, that generate barcode from product upc. If product has 12 digit upc it generates UPC-A-type barcode. If product has 13 digit upc it generates EAN-13 barcode. If it has other length return error. Args: upc (str): upc of product which should become a barcode. scale (int): scale of barcode, impact on size of image. margin (int): margin of barcode in image. options (dict): dict of options for elaphe generating. Returns: Response: Response with barcode data of error message. """ upc = str(upc) barcode_path = os.path.join( config.PDF_RENDERING_DIR, barcode.BARCODES_DIRECTORY) if not os.path.exists(barcode_path): os.makedirs(barcode_path) barcode_file = os.path.join(barcode_path, '{upc}.png'.format(upc=upc)) render_options = { barcode.INCLUDE_TEXT: barcode.DEFAULT_INCLUDE_TEXT } validated_barcode = validate_barcode_data(upc) if not validated_barcode: return validated_barcode if options: render_options.update(options) if len(upc) == 12: barcode_renderer = UpcA() barcode_type = barcode.UPC_A else: barcode_renderer = Ean13() barcode_type = barcode.EAN_13 brcd_img = barcode_renderer.render( upc, options=render_options, scale=scale, margin=margin) barcode_data = { barcode.BARCODE_TYPE: barcode_type, barcode.BARCODE: barcode_file } try: brcd_img.save(barcode_file) except OSError as e: return response.create_error_response( code=errors.ERROR_BARCODE_GENERATING_CODE, message=e) return response.Response(message=barcode_data) def validate_barcode_data(upc): """ Validation of upc for barcode, it should be 12-digit or 13-digit number. Args: upc (str): upc of product which should become a barcode. Returns: Response: Response with barcode validation data. """ if not upc.isdigit(): return response.create_error_response( code=errors.ERROR_BARCODE_IS_NOT_NUMERIC, message=errors.ERROR_INVALID_BARCODE_MESSAGE ) if len(upc) not in [12, 13]: return response.create_error_response( code=errors.ERROR_BARCODE_INVALID_LENGTH, message=errors.ERROR_INVALID_BARCODE_MESSAGE ) return response.Response()