Index: mps2ois/trunk/mypasswordsafe_to_oisafe.py
===================================================================
--- mps2ois/trunk/mypasswordsafe_to_oisafe.py	(revision 13)
+++ mps2ois/trunk/mypasswordsafe_to_oisafe.py	(revision 13)
@@ -0,0 +1,81 @@
+#!/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'.
+"""
+
+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()
+
