diff --git a/pass2csv.py b/pass2csv.py index dc5c0a0..8ff8daf 100644 --- a/pass2csv.py +++ b/pass2csv.py @@ -1,8 +1,20 @@ +#!/usr/bin/env python import csv import os import sys import gnupg +import re +import logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# A list of possible fields (in order) that could be converted to login fields +LOGIN_FIELDS=['login', 'user', 'username', 'email'] +# Set to True to extract url fields +GET_URL=True +# A regular expression list of lines that should be excluded from the notes field +EXCLUDE_ROWS=['^---$', '^autotype ?: ?'] def traverse(path): for root, dirs, files in os.walk(path): @@ -11,14 +23,60 @@ def traverse(path): for name in files: yield os.path.join(root, name) +def getMetadata(notes): + lines = notes.split('\n') + + # A list of lines to keep as notes (will be joined by newline) + ret = [] + user = '' + url = '' + + # This will extract each field name (for example, if a line in notes was `user: user1`, fields should contain 'user') + all_fields = set() + for line in lines: + field_search = re.search('^(.*) ?: ?.*$', line, re.I) + if field_search: + all_fields.add(field_search.group(1)) + + # Check if any of the fields match the login names + login_fields = [field for field in LOGIN_FIELDS if field in all_fields] + # Get the field to use for the login. Since LOGIN_FIELDS is in order, the 0th element will contain the first match + login_field = None if not login_fields else login_fields[0] + + # Iterate through the file again to build the return array + for line in lines: + + # If any of the exclusion patterns match, ignore the line + if len([pattern for pattern in EXCLUDE_ROWS if re.search(pattern, line, re.I)]) != 0: + continue + + if login_field: + user_search = re.search('^' + login_field + ' ?: ?(.*)$', line, re.I) + if user_search: + user = user_search.group(1) + # The user was matched, don't add it to notes + continue + + if GET_URL: + url_search = re.search('^url ?: ?(.*)$', line, re.I) + if url_search: + url = url_search.group(1) + # The url was matched, don't add it to notes + continue + + ret.append(line) + + return (user, url, '\n'.join(ret).strip()) def parse(basepath, path, data): name = os.path.splitext(os.path.basename(path))[0] group = os.path.dirname(os.path.os.path.relpath(path, basepath)) split_data = data.split('\n', maxsplit=1) password = split_data[0] - notes = split_data[1] - return [group, name, password, notes] + notes = split_data[1] if len(split_data) > 1 else "" + user, url, notes = getMetadata(notes) + logger.info("Processed %s" % (name,)) + return [group, name, user, password, url, notes] def main(path):