Changeset - 11e295cfe42d
[Not reviewed]
0 1 0
Lance Edgar (lance) - 12 years ago 2012-08-11 11:06:11
lance@edbob.org
improve sil.val(), add sil.write_rows()
1 file changed with 95 insertions and 55 deletions:
0 comments (0 inline, 0 general)
rattail/sil.py
Show inline comments
 
@@ -27,44 +27,51 @@
 

	
 
Please see the `Standard Interchange Language Specifications
 
<http://productcatalog.gs1us.org/Store/tabid/86/CategoryID/21/List/1/catpageindex/2/Level/a/ProductID/46/Default.aspx>`_
 
for more information.
 
"""
 

	
 
import datetime
 
from decimal import Decimal
 

	
 
import edbob
 

	
 
import rattail
 

	
 

	
 
def val(value):
 
    """
 
    Returns a string version of ``value``, suitable for inclusion within a data
 
    row of a SIL batch.  The conversion is done as follows:
 

	
 
    If ``value`` is ``None``, an empty string is returned.
 

	
 
    If it is an integer, it is converted directly to a string (i.e. not
 
    quoted).
 
    If it is an ``int`` or ``decimal.Decimal`` instance, it is converted
 
    directly to a string (i.e. not quoted).
 

	
 
    If it is a ``datetime.date`` instance, it will be formatted as ``'%Y%j'``.
 

	
 
    If it is a ``datetime.time`` instance, it will be formatted as ``'%H%M'``.
 

	
 
    If it is a string, but contains only digits, it is wrapped in single
 
    quotes.  If the string contains any apostrophes or commas, it is wrapped in
 
    single quotes with the apostrophes escaped.  Otherwise it is is returned
 
    as-is without quoting.
 
    Otherwise, it is converted to a string if necessary, and quoted with
 
    apostrophes escaped.
 
    """
 

	
 
    if value is None:
 
        return ''
 
    if isinstance(value, int):
 
        return str(value)
 
    if isinstance(value, Decimal):
 
        return str(value)
 
    if isinstance(value, datetime.date):
 
        return value.strftime('%Y%j')
 
    if isinstance(value, datetime.time):
 
        return value.strftime('%H%M')
 
    if not isinstance(value, basestring):
 
        value = str(value)
 
    if value.isdigit():
 
        return "'%s'" % value
 
    if value.find("'") > -1 or value.find(',') > -1:
 
        return "'%s'" % value.replace("'", "''")
 
    return value
 
    return "'%s'" % value.replace("'", "''")
 

	
 

	
 
def consume_batch_id():
 
    """
 
    Returns the next available batch identifier, incrementing the number to
 
    preserve uniqueness.
 
@@ -89,15 +96,14 @@ def consume_batch_id():
 
def write_batch_header(fileobj, H03='RATAIL', **kwargs):
 
    """
 
    Writes a SIL batch header string to ``fileobj``.  All keyword arguments
 
    correspond to the SIL specification for the Batch Header Dictionary.
 

	
 
    If you do not override ``H03`` (Source Identifier), then Rattail will
 
    provide defaults for ``H02`` (Batch Identifier) and ``H20`` (Software
 
    Revision) - that is, unless you've supplied those yourself..  If you do
 
    override ``H03`` then you must also provide values for ``H02`` and ``H20``.
 
    provide a default value for ``H20`` (Software Revision) - that is, unless
 
    you've supplied it yourself.
 

	
 
    **Batch Header Dictionary:**
 

	
 
    ====  ====    ====  ===========
 
    Name  Type    Size  Description
 
    ====  ====    ====  ===========
 
@@ -125,60 +131,94 @@ def write_batch_header(fileobj, H03='RATAIL', **kwargs):
 
    H22   CHAR     512  System Specific Command
 
    H23   CHAR       8  Dictionary Revision
 

	
 
    Consult the SIL Specification for more information.
 
    """
 

	
 
    H02 = kwargs.get('H02')
 
    H20 = kwargs.get('H20')
 
    if H03 == 'RATAIL':
 
        if not H02:
 
            H02 = consume_batch_id()
 
        if not H20:
 
            H20 = rattail.__version__[:4]
 

	
 
    kw = kwargs
 
    fileobj.write('INSERT INTO HEADER_DCT VALUES\n(' + ','.join((
 
                val(kw.get('H01')),
 
                val(H02),
 
                val(H03),
 
                val(kw.get('H04')),
 
                val(kw.get('H05')),
 
                val(kw.get('H06')),
 
                val(kw.get('H07')),
 
                val(kw.get('H08')),
 
                val(kw.get('H09')),
 
                val(kw.get('H10')),
 
                val(kw.get('H11')),
 
                val(kw.get('H12')),
 
                val(kw.get('H13')),
 
                val(kw.get('H14')),
 
                val(kw.get('H15')),
 
                val(kw.get('H16')),
 
                val(kw.get('H17')),
 
                val(kw.get('H18')),
 
                val(kw.get('H19')),
 
                val(H20),
 
                val(kw.get('H21')),
 
                val(kw.get('H22')),
 
                val(kw.get('H23')),
 
                )) + ');\n')
 

	
 

	
 
def write_row(fileobj, row, last=False):
 

	
 
    # Provide default for H20 if batch origin is 'RATAIL'.
 
    H20 = kw.get('H20')
 
    if H03 == 'RATAIL' and H20 is None:
 
        H20 = rattail.__version__[:4]
 

	
 
    # Don't quote H09 if special "immediate" value.
 
    H09 = kw.get('H09')
 
    if H09 != '0000000':
 
        H09 = val(H09)
 

	
 
    # Don't quote H10 if special "immediate" value.
 
    H10 = kw.get('H10')
 
    if H10 != '0000':
 
        H10 = val(H10)
 
    
 
    row = [
 
        val(kw.get('H01')),
 
        val(kw.get('H02')),
 
        val(H03),
 
        val(kw.get('H04')),
 
        val(kw.get('H05')),
 
        val(kw.get('H06')),
 
        val(kw.get('H07')),
 
        val(kw.get('H08')),
 
        H09,
 
        H10,
 
        val(kw.get('H11')),
 
        val(kw.get('H12')),
 
        val(kw.get('H13')),
 
        val(kw.get('H14')),
 
        val(kw.get('H15')),
 
        val(kw.get('H16')),
 
        val(kw.get('H17')),
 
        val(kw.get('H18')),
 
        val(kw.get('H19')),
 
        val(H20),
 
        val(kw.get('H21')),
 
        val(kw.get('H22')),
 
        val(kw.get('H23')),
 
        ]
 
        
 
    fileobj.write('INSERT INTO HEADER_DCT VALUES\n')
 
    write_row(fileobj, row, quote=False, last=True)
 
    fileobj.write('\n')
 

	
 

	
 
def write_row(fileobj, row, quote=True, last=False):
 
    """
 
    Writes a SIL row string to ``fileobj``.
 

	
 
    ``row`` should be a sequence of values.  If ``last`` is ``True``, then
 
    ``';'`` will be used as the statement terminator; otherwise ``','`` is
 
    used.
 
    ``row`` should be a sequence of values.
 

	
 
    If ``quote`` is ``True``, each value in ``row`` will be ran through the
 
    :func:`val()` function before being written.  If it is ``False``, the
 
    values are written as-is.
 

	
 
    If ``last`` is ``True``, then ``';'`` will be used as the statement
 
    terminator; otherwise ``','`` is used.
 
    """
 

	
 
    terminator = ';' if last else ','
 
    fileobj.write('(' + ','.join([val(x) for x in row]) + ')'
 
                  + terminator + '\n')
 
    if quote:
 
        row = [val(x) for x in row]
 
    fileobj.write('(' + ','.join(row) + ')' + terminator + '\n')
 

	
 

	
 
def write_rows(fileobj, rows):
 
    """
 
    Writes a set of SIL row strings to ``fileobj``.
 

	
 
    ``rows`` should be a sequence of sequences, each of which should be
 
    suitable for use with :func:`write_row()`.
 

	
 
    (This funcion primarily exists to handle the mundane task of setting the
 
    ``last`` flag when calling :func:`write_row()`.)
 
    """
 

	
 
    last = len(rows) - 1
 
    for i, row in enumerate(rows):
 
        write_row(fileobj, row, last=i == last)
 

	
 

	
 
# # from pkg_resources import iter_entry_points
 

	
 
# # import rattail
 
# # from rattail.batch import make_batch, RattailBatchTerminal
0 comments (0 inline, 0 general)