Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from getopt to argparse to get more reasonable error messages … #3

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 14 additions & 23 deletions Eudora2Unix.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from os.path import *
import re
import string
import getopt
import argparse

if sys.hexversion < 33686000:
sys.stderr.write( "Aborted: Python version must be at least 2.2.1" \
Expand All @@ -42,12 +42,6 @@
embedded_dir = None

# --------------------- Comments & complaints ----------------------
def usage_complaint( arg ):
return [
'Usage error; specify Eudora directory to be converted:',
' ' + arg + ' [-a attachments directory] [-f mbox|maildir|mmdf|mh|babyl] [-d target directory] eudora_directory [kmail|pine]'
]

def target_directory_already_exists_complaint( maildir ):
return [
'Directory ' + maildir + ' already exits. Rename it, e.g. to ',
Expand Down Expand Up @@ -595,7 +589,7 @@ def convert_files( avoid_dirlist, dir, names ):
# os.spawnlpe( os.P_WAIT, 'etoc', 'etoc',
# f_toc, f_toc + '.txt',
# os.environ )
EudoraTOC.parse( f_toc, f_toc + '.txt' )
EudoraTOC.parse( f_toc, isMac, f_toc + '.txt' )
except OSError, ( errno, str ):
complain( toc_complaint( f_toc, str ) )
moveFile( fpath, f_nombx )
Expand Down Expand Up @@ -707,18 +701,15 @@ def fix_file_permissions( arg, dir, names ):
elif isdir( f ):
os.chmod( fpath, 0700 )

# --------------------- START HERE --------------------------------
# Note: in this rather stupid implementation of getopts, has to go
# program flags args, or else
try:
opts, args = getopt.getopt( sys.argv[1:], 'a:d:t:' )
except getopt.GetoptError:
complain( usage_complaint( sys.argv[0] ) )
sys.exit( 1 )

if len( args ) < 1 or len( args[0].strip() ) == 0:
complain( usage_complaint( sys.argv[0] ) )
sys.exit( 1 )
else:
eudoradir = args[0].strip()
convert_directory( eudoradir, opts )
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('source_directory', help='Eudora directory to be converted')
parser.add_argument('-a', required=True, metavar='attach_dir', help='attachments directory')
parser.add_argument('-f', help='mailbox format', type=str, choices=('mbox','maildir','mmdf','mh','babyl'))
parser.add_argument('-d', metavar='target_dir', help='target directory')
parser.add_argument('-t', help='target client', type=str, choices=('kmail', 'pine'))
command_line_args = parser.parse_args()
eudoradir = command_line_args.source_directory
del command_line_args.source_directory
opts = [ ('-'+k, v) for k,v in vars(command_line_args).items() if v != None] # hack to convert to a getopts-style list
convert_directory( eudoradir, opts )
84 changes: 32 additions & 52 deletions EudoraTOC.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,6 @@
'26x', # (all 0)
), '' )

# Eudora toc file versions I've seen:
# MAC_EUDORA_LITE_3 = 0x0001
# MAC_EUDORA_LITE_131 = 0x0000 # (a Poor choice!)
# WIN_EUDORA_LITE_1 = 0x2a00
# WIN_EUDORA_5 = 0x0300

# Just a guess: maybe Mac and Windows are distinguished thus (with 0 being Mac)
def isMac( version ):
MAC = 0x00FF
return version & MAC or version == 0

def isWin( version ):
WIN = 0xFF00
return version & WIN

# Big-Endian integer conversions

def toIntBig( c ):
Expand Down Expand Up @@ -220,8 +205,7 @@ def printMacEntry( out, entry ):
print >> out

def printWinEntry( out, entry ):
( offset, length, status, priority, date, to, subject ) \
= unpack( win_entry, entry )
( offset, length, status, priority, date, to, subject ) = unpack( win_entry, entry )
print >> out, "offset: %d" % ( toIntLittle( offset ), )
print >> out, "length: %d" % ( toIntLittle( length ), )

Expand Down Expand Up @@ -258,17 +242,6 @@ def printWinEntry( out, entry ):
print >> out, "priority: %d" % ( priority, )
print >> out

def readVersionAndRewind( file ):
verbuf = file.read( 2 )
v = unpack( 'BB', verbuf )

file.seek( 0 )

if len( verbuf ) > 0:
return ( v[0] << 8 ) | v[1]

return 0

class TOCError(Exception):
""" Problem occurred concerning a Eudora TOC file. """
def __init__(self, value):
Expand All @@ -278,7 +251,7 @@ def __str__(self):
def args(self):
return self.args

def parse( infile, outfile = None ):
def parse( infile, isMac, outfile ):
"""
Parse a Eudora '.toc' file, and pull out important info into a text
file '.toc.txt'
Expand All @@ -291,10 +264,22 @@ def parse( infile, outfile = None ):
Mac Eudora Lite 3.x has version 0001, Windows Eudora Pro 5.o has 0030
As a guess, if the upper byte is nonzero, it's Windows, otherwise,
it's Mac.

From prior list:
Eudora toc file versions I've seen:
MAC_EUDORA_LITE_3 = 0x0001
MAC_EUDORA_LITE_131 = 0x0000 # (a Poor choice!)
WIN_EUDORA_LITE_1 = 0x2a00
WIN_EUDORA_5 = 0x0300
Windows 6.1.0.6 used 0x0000 also. It's possible that no file format identifier shows Mac vs Windows?

Note that Windows Eudora 6.1.0.6 invalidates all this theory, so we rely on the passed-in isMac variable instead.

"""
file = None
returnVal = 0
out = sys.stdout
print >> out, ('Parsing %s ...' % infile)

try:
file = open( infile, "rb" )
Expand All @@ -308,54 +293,49 @@ def parse( infile, outfile = None ):
except IOError, ( errno, strerror ):
raise TOCError( "EudoraTOC: couldn't open file "
+ outfile )
version = readVersionAndRewind( file )

if isMac( version ):
if isMac:
foldersize = calcsize( mac_folder )
entrysize = calcsize( mac_entry )
elif isWin( version ):
else:
foldersize = calcsize( win_folder );
entrysize = calcsize( win_entry );
else:
raise TOCError( "EudoraTOC: unknown toc version: 0x%x" \
% version )
print >> out, "Expect folder and entry sizes %d %d" \
% ( foldersize, entrysize )
print >> out, "Expect sizes: folder %d %x, entry %d %x" % ( foldersize, foldersize, entrysize, entrysize )
file.read(18)
'''
folder = file.read( foldersize )

if len( folder ) == 0:
raise TOCError( "EudoraTOC: couldn't read header" )

if isMac( version ):
if isMac:
printMacFolder( out, folder )
elif isWin( version ):
else:
printWinFolder( out, folder )

'''
while True:
entry = file.read( entrysize )

if len( entry ) <= 0:
break

if isMac( version ):
printMacEntry( out, entry )
elif isWin( version ):
printWinEntry( out, entry )
try:
if isMac:
printMacEntry( out, entry )
else:
printWinEntry( out, entry )
except:
sys.stderr.write('Error parsing %s - corrupt?\n' % infile)


if file:
file.close()

return returnVal

if sys.argv[0].find( 'EudoraTOC.py' ) > -1: # i.e. if script called directly
if len( sys.argv ) < 2:
raise TOCError( "EudoraTOC: insufficient arguments" )
if len( sys.argv ) >= 3:
outfile = sys.argv[2]
else:
outfile = None
if __name__ == '__main__': # i.e. if script called directly
try:
sys.exit( parse( sys.argv[1], outfile ) )
sys.exit( parse( sys.argv[1], int(sys.argv[2]), sys.argv[3] ) )
except TOCError, errstr:
print errstr
sys.exit( 1 )