[pmmail-list] Leaving PMMail for Thunderbird

Tim Roberts pmmail-list@blueprintsoftwareworks.com
Mon, 05 Jan 2004 09:30:34 -0800


This is a multi-part message in MIME format.
--------------090801040904060903030801
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Andrew Pitonyak wrote:

>
> Tim,
>
> I don't suppose that you would mind sharing a copy of your Python scripts?
>

I'm not sure whether they'll be of any use, but here they are.  
"import.py" does the mailboxes, "importab.py" does the address books.  
You'll have to modify both of them to supply the PMMail path, and the 
Thunderbird mail account name.  "import.py" has some customizations for 
my particular layout, you'll probably need to customize it if you have a 
deeply nested tree.  My mail tree is short and fat.

"importab.py" creates local files that can then be imported by 
Thunderbird's CSV import.

-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.


- pmmail-list - The PMMail Discussion List ---------------------------
To POST to the list, send your message to:
pmmail-list@blueprintsoftwareworks.com

To UNSUBSCRIBE, send a message to mdaemon@bmtmicro.com 
with the first line of the message body being...
UNSUBSCRIBE pmmail-list@blueprintsoftwareworks.com
---------------------------------------------------------------------
--------------090801040904060903030801
Content-Type: text/plain;
 name="import.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="import.py"

# vim: sw=4 ts=4
#
# Import the accumulated PMMail archive into Thunderbird.

import os
import sys
from calendar import day_abbr, month_abbr
import time
from mx import DateTime

# Identify the source directory.  I should do ALL of the directories.

SRC = "C:\\Apps\\PMMail\\TIMR_0.ACT"

# Figure out the destination directory.

dest = os.path.join(
    os.environ["USERPROFILE"],
    "Application Data",
    "Thunderbird",
    "Profiles",
    "default")

random = os.listdir(dest)

dest = os.path.join( dest, random[0], "Mail" )

dest1 = os.path.join( dest, "mail.probo.com" )

dest = os.path.join( dest, "Local Folders", "PMMail.sbd" )

print dest

# Given the PMMail folder name, figure out the Thunderbird file name.

def ArchiveDir( folder ):
    pmname = file(os.path.join(SRC,folder,'FOLDER.INI')).read().split('\xde')[0]
    tmpdst = dest

    # Translate "Sent Mail" to "Sent" within the main account.

    if pmname == 'Sent Mail':
        pmname = pmname[:4]
        tmpdst = dest1

    # Copy inbox to the main account.

    if pmname == 'Inbox':
        tmpdst = dest1

    # If it is a subfolder, make sure the folder exists.

    if '/' in folder or '\\' in folder:
#        p1,folder = os.path.split(folder)
#        p1,ext = os.path.splitext(p1)
#        tmpdst = os.path.join( dest, p1 + '.sbd' )
        tmpdst = os.path.join( dest, pmname + '.sbd' )
        if not os.path.isdir( tmpdst ):
            os.mkdir( tmpdst )

    return os.path.join( tmpdst, pmname )


def ProcessFolder( dir ):
    print "Scanning %s...\r" % dir,
    if dir in ('TRASH.FLD','OUTBOX.FLD'):
        return
    if not os.path.isfile(os.path.join(SRC,dir,'FOLDER.BAG')):
        return
    list = []
    for ln in file(os.path.join(SRC,dir,'FOLDER.BAG')):
        bag = ln.split('\xde')
        # Field 0 is status: 0 = unread, 1 = read, 2 = replied; 11 = important
        # Field 1 is a boolean attachment flag
        # Field 2 and 3 are date/time in yyyy-mm-dd hh:mm:ss format.
        # Field 4 is subject
        # Field 5, 6, 7, 8 are recipient and sender, e-mail and nickname
        # Field 9 is size
        # Field 10 is filename
        # Fields 11 and 12 are not known

        filenm = os.path.join( SRC, dir, bag[10] )
        ln1 = file(filenm).readline()
        if ln.lower().startswith('from '):
            hasfromline = '1'
        else:
            hasfromline = '0'

        dow = DateTime.DateFrom( bag[2], bag[3] ).day_of_week

        list.append("%s=%s=%s=%d=%s=%s" % (
            bag[2].replace('-','='), bag[3], bag[0], dow, hasfromline, filenm
        ))

    list.sort()

    archive = ArchiveDir( dir )
    farchive = file( archive, "w" )
    archivefile = os.path.split(archive)[-1]

    for msg in list:
        (yr, mo, day, hhmm, state, dow, hasfromline, messagefile) = msg.split('=')

        print "Copying", messagefile[len(SRC)+1:], "to", archivefile, "...\r",

        # If it doesn't have a From line, add one.

        if hasfromline == "0":
            farchive.write(
                "From - %s %s %s %s %s\n" % (
                    day_abbr[int(dow)], month_abbr[int(mo)], day, hhmm, yr )
                )
        
        # Copy the file data.  We scan the headers looking for "Status".
        # What we want is "Status: R" if the message is marked read, and 
        # no Status at all otherwise.

        fin = file(messagefile,"r")  # "rb"?

        for ln in fin:
            if ln[0] == '\n':
                break
            if not ln.startswith("Status:"):
                farchive.write(ln)

        if state != '0':
            farchive.write("Status: R\n")

        farchive.write(ln)

        map( farchive.write, fin )

    print


def main():
    for dir in os.listdir(SRC):
        if dir[-4:] == '.FLD':
            ProcessFolder( dir )
    for dir in os.listdir(SRC + "\\TVCB.FLD"):
        if dir[-4:] == '.FLD':
            ProcessFolder( 'TVCB.FLD\\' + dir)
    for dir in os.listdir(SRC + "\\OldStuff.FLD"):
        if dir[-4:] == '.FLD':
            ProcessFolder( 'OldStuff.FLD\\' + dir)

if __name__=="__main__":
    wall = time.time()
    main()
    wall = time.time() - wall
    print wall,"seconds wall clock time"

- pmmail-list - The PMMail Discussion List ---------------------------
To POST to the list, send your message to:
pmmail-list@blueprintsoftwareworks.com

To UNSUBSCRIBE, send a message to mdaemon@bmtmicro.com 
with the first line of the message body being...
UNSUBSCRIBE pmmail-list@blueprintsoftwareworks.com
---------------------------------------------------------------------
--------------090801040904060903030801
Content-Type: text/plain;
 name="importab.py"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="importab.py"

import os


SRCPATH = r'c:\apps\tools'

# First, read in the book names.

books = {}

for ln in file(os.path.join(SRCPATH, 'BOOKS.DB')):
    f = ln[:-1].split('\xde')
    books[f[3]] = file(f[0]+'.csv','w')
    books[f[3]].write( 'Email,NickName,FullName\n' )

# Now, read in and translate the books.

for ln in file(os.path.join(SRCPATH, 'ADDR.DB')):
    f = ln[:-1].split('\xde')
    books[f[23]].write( '%s,%s,%s\n' % tuple(f[0:3]) )

- pmmail-list - The PMMail Discussion List ---------------------------
To POST to the list, send your message to:
pmmail-list@blueprintsoftwareworks.com

To UNSUBSCRIBE, send a message to mdaemon@bmtmicro.com 
with the first line of the message body being...
UNSUBSCRIBE pmmail-list@blueprintsoftwareworks.com
---------------------------------------------------------------------
--------------090801040904060903030801--