"""
###########################################
like extract.py for memos, but also get
event date info from datebook dbase file;
similar dbase structure to memos, but recs
start with binary data giving time and date
info packed in bits, followed by null term
event text; ignores repeating event start/
stop, and times; run me in .pdb file's dir;
makes one text file per event, filenames
sort by ascending date, and include date 
and event text prefix for filename, like:
DatebookDB\1999-04-Apr-15-[LP_Release].txt
###########################################
"""

monthname = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 
             'jul', 'aug', 'sep', 'oct', 'nov', 'dec']

import struct, os
fname = 'DatebookDB.pdb'

file = open(fname, 'rb')            # binary mode
bytes = file.read()                 # load file to str
print fname, len(bytes)

eos = bytes.find(chr(0))
dbname = bytes[:min(32,eos)]
print dbname

if not os.path.exists(dbname):
    os.mkdir(dbname)
else:
    os.system('rm %s/*' % dbname)

# see extract.py for basic dbase format
frec = 77
(nrec,) = struct.unpack('>H',bytes[frec-1:frec+1])
print nrec

flst = 70
for rec in range(1, nrec+1):

    floc = flst + (rec * 8)
    (rloc,) = struct.unpack('>I', bytes[floc:floc+4])

    fend = flst + ((rec+1) * 8)
    (rend,) = struct.unpack('>I', bytes[fend:fend+4])

    try:
        event = bytes[rloc:rend]
       #xname = '%s/event%d' % (dnbname, rec)

        hdr, text = event[:8], event[8:]    # 1st 8 byte are time, date
        hm  = hdr[:4]                       # skip start,stop times
        ymd = hdr[4:]
        ymd12, ymd3, ymd4 = struct.unpack('>HBB', ymd)  

        yyyy = (ymd12 >> 9) & 0x7F          # top 7 bits, 0..127, & needed?
        yyyy += 1904                        # to 2031, 4 in ymd3 low byte?
        mm   = (ymd12 >> 5) & 0xF           # middle 4 bits, 0..15
        dd   = (ymd12 & 0x1F)               # low 5 bits, 0..31

        if ymd3 & 0xF0:                     # high byte nonzero
            text = text[8:]                 # repeating evt-skip end info  
        if text[-1] == '\x00': 
            text = text[:-1]                # text null terminated

        for c in text[:2]:                  # some repeating have extra bytes
            if  not c.isalnum() and not c in ['-',' ','?','\n']:
                print 'skipping'
                text = text[6:]             # this is just a heuristic
                break                       # but works for my repeat events

        # use part of text in filename
        text0 = ''
        text1 = text[:30]                   # up to 30 chars at front
        for c in text1:
            if c.isalnum() or c in ['-', '_']:
                text0 += c
            else:
                text0 += '_'

        xname = ('%s/%4d-%02d-%s-%02d-[%s].txt' % 
                          (dbname, yyyy, mm, monthname[mm-1], dd, text0))

        print rec, yyyy, mm, dd
        print text
        print xname
        print '-'*40

        # to the file we go
        xtract = open(xname, 'wb')
        xtract.write(text)           
        xtract.close()

    except KeyboardInterrupt:
        raise  # propogate it

    except:
        import sys  # ignore it
        print sys.exc_type, sys.exc_value
        print 'BAD'

print 'Done.'