tab2html.py

'''\
TAB file to HTML file.

commands:
    main            - Main function (normal use)
    demo            - Demo function (show off and test app)
    test            - Test function (development)

usage:
    module.dispatch({command}, args={arguments})    -- calling module from code

    $PYTHON module_name {command} {arguments}       -- executing module externally

Developer@Sonnack.com
April 2016
'''
####################################################################################################
from __future__ import print_function
from sys import argvexc_info
from traceback import extract_tb
from os import path
from files import get_file_tabget_file_csv
from htmlpage import htmlpage
from logger import loggerinfodebugtrace
####################################################################################################
Log = logger('app')
####################################################################################################
##TODO## Make sure 'get_file_tab' can read ALL tab files (i.e. quotes and escapes).
##TODO## Add CSV files.

BasePath = r'C:\CJS\prj\Python\app'
HtmlPath = r'C:\CJS\www\root\tmp'


##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
class TabPageWriter (object):
    '''PageWriter object for writing TAB files.'''

    def __init__ (selftab_data):
        self.hdrs = tab_data[0]
        self.data = tab_data[1]
        self.write_head = True
        self.write_foot = True

    def writepage (selffp):
        print('<table class="TabData">'file=fp)
        # THEAD...
        if self.write_head:
            print('<thead>'file=fp)
            print('<tr>'file=fp)
            for cx,hdr in enumerate(self.hdrs):
                print('<th class="C%d">%s</th>' % (1+cx,hdr), file=fp)
            print('</tr>'file=fp)
            print('</thead>'file=fp)
        # TFOOT...
        if self.write_foot:
            print('<tfoot>'file=fp)
            print('<tr>'file=fp)
            for cx,hdr in enumerate(self.hdrs):
                print('<th class="C%d">%s</th>' % (1+cx,hdr), file=fp)
            print('</tr>'file=fp)
            print('</tfoot>'file=fp)
        # TBODY...
        print('<tbody>'file=fp)
        for rx,row in enumerate(self.data):
            print('<tr class="R%d">' % (1+rx), file=fp)
            for cx,col in enumerate(row):
                print('<td class="C%d">%s</td>' % (1+cx,col), file=fp)
            print('</tr>'file=fp)
        print('</tbody>'file=fp)
        print('</table>'file=fp)

##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~##
class TabListPageWriter (object):
    '''PageWriter object for writing TAB list files.'''

    def __init__ (selftab_datancol):
        self.hdrs = tab_data[0]
        self.data = tab_data[1]
        self.ncol = ncol

    def writepage (selffp):
        print('<table class="TabData">'file=fp)
        print('<tbody>'file=fp)
        # For each header...
        for cx,hdr in enumerate(self.hdrs):
            Log.debug('%d: %s' % (cx,hdr))
            print('<tr class="R%d">' % (2+cx), file=fp)
            print('<th class="C0">%s</th>' % hdrfile=fp)
            # For each row, print the column...
            for rx in range(self.ncol):
                row = self.data[rx]
                print('<td class="C%d">%s</td>' % (2+rx,row[cx]), file=fp)
            print('</tr>'file=fp)

        print('</tbody>'file=fp)
        print('</table>'file=fp)


##================================================================================================##
def tab_to_html (tab_filenamehtml_filenamemaxrows=-1use_csv=False):
    Log.info('data-file: %s' % tab_filename)
    Log.info('html-file: %s' % html_filename)
    Log.info('max-rows: %d' % maxrows)
    Log.info('use-csv: %d' % use_csv)
    if not path.isfile(tab_filename):
        raise RuntimeError('Bad file: %s' % tab_filename)

    css = ['/basic.css''tab2html.css']
    H1 = 'Sonnack.com'
    H2 = 'TAB&ndash;to&ndash;HTML'
    H3 = path.basename(tab_filename)

    # Get data...
    ftn = get_file_csv if use_csv else get_file_tab
    data = ftn(tab_filenamemaxrows)
    fp = open(html_filename'w')
    Log.info('hdrs read: %d' % len(data[0]))
    Log.info('rows read: %d' % len(data[1]))

    try:
        pw = TabPageWriter(data)
        pg = htmlpage(H3h1=H1,h2=H2csspages=cssjspages=[])
        pg.writepage(fppw)

        print('wrote: %s' % html_filename)
    except:
        raise
    finally:
        fp.close()

##================================================================================================##
def tab_to_html_list (tab_filenamehtml_filenamemaxrows=5use_csv=False):
    Log.info('data-file: %s' % tab_filename)
    Log.info('html-file: %s' % html_filename)
    Log.info('max-rows: %d' % maxrows)
    Log.info('use-csv: %d' % use_csv)
    if not path.isfile(tab_filename):
        raise RuntimeError('Bad file: %s' % tab_filename)

    css = ['/basic.css''tab2html.css']
    H1 = 'Sonnack.com'
    H2 = 'TAB&ndash;to&ndash;HTML'
    H3 = path.basename(tab_filename)

    # Get data...
    ftn = get_file_csv if use_csv else get_file_tab
    data = ftn(tab_filenamemaxrows)
    Log.info('hdrs read: %d' % len(data[0]))
    Log.info('rows read: %d' % len(data[1]))

    fp = open(html_filename'w')
    try:
        pw = TabListPageWriter(datamaxrows)
        pg = htmlpage(H3h1=H1,h2=H2csspages=cssjspages=[])
        pg.writepage(fppw)

        print('wrote: %s' % html_filename)
    except:
        raise
    finally:
        fp.close()


##================================================================================================##
def do_list (*args):
    '''Rotate table; only show a few rows (as cols).'''
    Log.info('list/arguments: %s' % str(args))
    iname = args[0]
    oname = args[1if 1 < len(argselse path.join(HtmlPath,'tab2html.html')
    lines = args[2if 2 < len(argselse '5'
    tab_to_html_list(inameonamemaxrows=int(lines))
    return 'Done!'
##================================================================================================##
def do_test (*args):
    Log.info('test/arguments: %s' % str(args))
    iname = args[0if 0 < len(argselse path.join(BasePath,'tab2html.tab')
    oname = args[1if 1 < len(argselse path.join(HtmlPath,'tab2html.html')
    tab_to_html(inameoname)
    return 'Done!'
##================================================================================================##
def do_demo (*args):
    Log.info('demo/arguments: %s' % str(args))
    iname = args[0if 0 < len(argselse path.join(BasePath,'benford.tab')
    oname = args[1if 1 < len(argselse path.join(HtmlPath,'benford.html')
    tab_to_html(inameoname)
    return 'Done!'
##================================================================================================##
def do_main (*args):
    Log.info('main/arguments: %s' % str(args))
    iname = args[0]
    oname = args[1if 1 < len(argselse path.join(HtmlPath,'tab2html.html')
    lines = args[2if 2 < len(argselse '-1'
    tab_to_html(inameonamemaxrows=int(lines))
    return 'Done!'
####################################################################################################
def dispatch (cmd, *args):
    Log.info('command: %s' % cmd)
    Log.info('arguments: %d' % len(args))
    if cmd == 'list': return do_list(*args)
    if cmd == 'test': return do_test(*args)
    if cmd == 'demo': return do_demo(*args)
    if cmd == 'main': return do_main(*args)
    return 'Nothing to do!'
####################################################################################################
if __name__ == '__main__':
    print('autorun: %s' % argv[0])
    Log.start(path.join(BasePath,'tab2html.log'))
    Log.level(info())
    cmd = argv[1if 1 < len(argvelse ''
    etc = argv[2:if 2 < len(argvelse []
    try:
        obj = dispatch(cmd, *etc)
        print(obj)
        Log.info(obj)
    except:
        etypeevaluetb = exc_info()
        ts = extract_tb(tb)
        Log.error('%s: %s' % (etype.__name__,str(evalue)))
        for t in ts[-3:]:
            Log.error('[%d] %s  (%s)' % (t[1], t[2], t[0]))
            Log.error('    %s' % t[3])
        raise
    finally:
        Log.end()
####################################################################################################
'''eof'''