Add advanced features
This commit is contained in:
parent
ccf3ece8da
commit
355ec2b183
1 changed files with 60 additions and 2 deletions
62
pass2csv.py
62
pass2csv.py
|
@ -1,8 +1,20 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
import csv
|
import csv
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import gnupg
|
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):
|
def traverse(path):
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
|
@ -11,14 +23,60 @@ def traverse(path):
|
||||||
for name in files:
|
for name in files:
|
||||||
yield os.path.join(root, name)
|
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):
|
def parse(basepath, path, data):
|
||||||
name = os.path.splitext(os.path.basename(path))[0]
|
name = os.path.splitext(os.path.basename(path))[0]
|
||||||
group = os.path.dirname(os.path.os.path.relpath(path, basepath))
|
group = os.path.dirname(os.path.os.path.relpath(path, basepath))
|
||||||
split_data = data.split('\n', maxsplit=1)
|
split_data = data.split('\n', maxsplit=1)
|
||||||
password = split_data[0]
|
password = split_data[0]
|
||||||
notes = split_data[1]
|
notes = split_data[1] if len(split_data) > 1 else ""
|
||||||
return [group, name, password, notes]
|
user, url, notes = getMetadata(notes)
|
||||||
|
logger.info("Processed %s" % (name,))
|
||||||
|
return [group, name, user, password, url, notes]
|
||||||
|
|
||||||
|
|
||||||
def main(path):
|
def main(path):
|
||||||
|
|
Loading…
Reference in a new issue