bin2html.py
'''\
Binary file to HTML "Hex" Dump file.
commands:
main - Main function (normal use)
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 argv, exc_info
from traceback import extract_tb
from os import path
from htmlpage import htmlpage
from logger import logger, info, debug, trace
Log = logger('BIN2HTML')
BasePath = r'C:\CJS\prj\Python\app'
HtmlPath = r'C:\CJS\www\root\tmp'
HtmlCss = '''\
<style type="text/css">
#PageBody h3 {
font-size: 11pt;
font-weight: bold;
margin-bottom: 3pt;
}
#PageBody h4 {
font-size: 11pt;
font-weight: normal;
text-decoration: underline;
margin-top: 3pt;
margin-bottom: 18pt;
}
#PageBody table {
background-color: #3f3f3f;
text-height: 1.0;
border-spacing: 3px 0;
padding: 0 2px;
border: 2px solid black;
margin: 18pt auto 18pt 24pt;
}
#PageBody table thead th {
background-color: #000000;
color: #ffffff;
font-family: serif;
font-size: 13pt;
font-weight: bold;
font-style: normal;
text-align: center;
vertical-align: bottom;
padding: 3px auto 5px auto;
}
#PageBody table tbody tr {
background-color: #7f7f7f;
}
#PageBody table tbody td {
font-family: monospace;
font-size: 10pt;
font-weight: bold;
font-style: normal;
border-bottom: 1px solid black;
}
#PageBody table tbody td.Addrs {
white-space: nowrap;
background-color: #ffffbf;
}
#PageBody table tbody td.Bytes {
background-color: #f0fff0;
}
#PageBody table tbody td.Chars {
white-space: nowrap;
background-color: #f0f0ff;
}
</style>
'''
def HtmlCssSender (obj, fp):
fp.write(HtmlCss)
def SafeChar (c):
if c <= 32: return '.'
if c in [127, 129, 141, 143, 144, 157, 160, 173]: return '.'
if 127 < c: return ('&#%d;' % c)
ch = chr(c)
if ch == '&': return '&'
if ch == '<': return '<'
if ch == '>': return '>'
if ch == '"': return '"'
return ch
class BinDumpPage (object):
def __init__ (self, data, fname):
self.data = data
self.fname = fname
self.dcols = 16
self.fmt_addr = lambda n:('%08d' % n)
self.fmt_data = lambda n:('%02x' % n)
def writepage (self, fp):
try:
Log.trace('WritePage::ENTER')
self.my_writepage(fp)
except:
raise
finally:
Log.trace('WritePage::EXIT')
def my_writepage (self, fp):
fp.write('<h4>%s</h4>\n' % self.fname)
fp.write('\n')
self.my_write_byte_block(fp)
fp.write('\n')
def my_write_byte_block (self, fp):
fp.write('<table>\n')
fp.write('<thead>\n')
fp.write('<tr><th>Address</th><th>Bytes</th><th>Chars</th></tr>\n')
fp.write('</thead><tbody>\n')
for bx in range(0, len(self.data), self.dcols):
fp.write('<tr><td class="Addrs">%s</td>' % self.fmt_addr(bx))
buf = self.data[bx:bx+self.dcols]
bt = [self.fmt_data(ord(b)) for b in buf]
fp.write('<td class="Bytes">%s</td>' % (' '.join(bt)))
ct = [SafeChar(ord(c)) for c in buf]
fp.write('<td class="Chars">%s</td></tr>\n' % ''.join(ct))
fp.write('</tbody></table>\n')
def binary_file_to_html_file (infilename, outfilename):
Log.info('bin2html::ifname: %s' % infilename)
Log.info('bin2html::ofname: %s' % outfilename)
fp = open(infilename, 'rb')
try:
bs = fp.read()
Log.debug('read: %s' % infilename)
except:
raise
finally:
fp.close()
pw = BinDumpPage(bs,infilename)
pg = htmlpage('Bin2HTML', h2='Python WebApps')
pg.cb_htmlhead = HtmlCssSender
pg.writefile(outfilename, pw)
Log.debug('wrote: %s' % outfilename)
def do_test (*args):
Log.info('test:: %s' % str(args))
ifname = args[0] if 0 < len(args) else path.join(BasePath, 'img.png')
ofname = args[1] if 1 < len(args) else path.join(HtmlPath, 'bin2html.html')
binary_file_to_html_file(ifname, ofname)
return 'Done!'
def do_main (*args):
Log.info('main:: %s' % str(args))
ifname = args[0]
ofname = args[1] if 1 < len(args) else path.join(HtmlPath, 'bin2html.html')
binary_file_to_html_file(ifname, ofname)
return 'Done!'
def dispatch (cmd, *args):
Log.info('command: %s' % cmd)
Log.info('arguments: %d' % len(args))
if cmd == 'test': return do_test(*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,'bin2html.log'))
Log.level(trace())
cmd = argv[1] if 1 < len(argv) else 'test'
etc = argv[2:] if 2 < len(argv) else []
try:
obj = dispatch(cmd, *etc)
print(obj)
Log.info(obj)
except:
etype, evalue, tb = 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'''