#!/usr/bin/python
"""This script will take the plaintext export file from MyPasswordSafe (named
'mypasswordsafe.txt' in the current directory) and convert it to the CSV import
format expected by OI Safe (for the Android phone platform) and write it to
'oisafe.csv'.

Copyright 2009, Eli Carter
GPLv2 or later
"""

class PasswordData(object):
    """Holds all information about the passwords.

    Can load from MyPasswordSafe exports, and save to a form OISafe can import.
    """
    def __init__(self):
        self.master_password = None
        self.passwords = None

    def load_mps(self, filename):
        """Expects a plain text export from mypasswordsafe as input
        That file is kind of a tab-delimitted file, with the master password as
        the only content of the first line.
        The fields are:
        name, user, password, created, modified, accessed, lifetime, uuid
        notes

        Where the notes field is the content of the second line, with \n indicating newlines.
        """
        lines = open(filename).readlines()
        self.master_password = lines[:-1]
        self.passwords = []
        field_names = ['name', 'user', 'password', 'group', 'created',
                       'modified', 'accessed', 'lifetime', 'uuid']
        for i in range(1, len(lines), 2):
            entry = {}
            fields = lines[i].split('\t')
            entry['notes'] = lines[i+1].replace('\\n', '\n')
            for fname, fvalue in zip(field_names, fields):
                #print fname, fvalue
                entry[fname] = fvalue
            self.passwords.append(entry)
            
    def save_oisafe(self, filename):
        """Writes out the password information stored in this object to the
        named file in a format that OI Safe can import.
        """
        out = open(filename, 'w')
        out.write('"Category","Description","Website","Username","Password",'
                  '"Notes"\n')
        for entry in self.passwords:
            category = csv_escape_quotes(entry['group'].lstrip('/'))
            description = csv_escape_quotes(entry['name'])
            website = ''
            username = csv_escape_quotes(entry['user'])
            password = csv_escape_quotes(entry['password'])
            full_notes = entry['notes'].strip('\n') + '\n\n'
            for extra_field in ['created', 'modified', 'accessed', 'lifetime',
                                'uuid']:
                full_notes += '%s: %s\n' % (extra_field, entry[extra_field])
            notes = csv_escape_quotes(full_notes.rstrip('\n'))

            line = '","'.join([category, description, website, username,
                               password, notes])
            out.write('"%s"\n' % line)


def csv_escape_quotes(text):
    """Quote the " characters in the provided text by doubling them.
    """
    return text.replace('"', '""')


def main():
    """Converts a MyPasswordSafe export to an OI Safe import.
    """
    database = PasswordData()
    database.load_mps('mypasswordsafe.txt')
    database.save_oisafe('oisafe.csv')


if __name__ == '__main__':
    main()

