# HG changeset patch # User Erik Grinaker # Date 1088536269 0 # Node ID ca47b6d25ebe2ebf223b80b2f1cbe3e2bbe9f4e1 # Parent 030d8c23231da1fba7a207177d4553cf6a9fe466 added .netrc datahandler diff -r 030d8c23231da1fba7a207177d4553cf6a9fe466 -r ca47b6d25ebe2ebf223b80b2f1cbe3e2bbe9f4e1 ChangeLog --- a/ChangeLog Tue Jun 29 18:03:09 2004 +0000 +++ b/ChangeLog Tue Jun 29 19:11:09 2004 +0000 @@ -9,6 +9,8 @@ * updated the fpm datahandler to use new Entry class, and rewrote conversions routines + * added importer/exporter for .netrc files + 2004-06-22 Erik Grinaker * rewrote internal data handling routines to use an Entry diff -r 030d8c23231da1fba7a207177d4553cf6a9fe466 -r ca47b6d25ebe2ebf223b80b2f1cbe3e2bbe9f4e1 TODO --- a/TODO Tue Jun 29 18:03:09 2004 +0000 +++ b/TODO Tue Jun 29 19:11:09 2004 +0000 @@ -10,7 +10,6 @@ - add info about file as cmdline-arg in --help text - string cleanups - program-launchers for misc account types -- import/export of .netrc files - use xpath for xml handling instead of plain dom? - add autosaving of files (needs a preference) - add docstrings to all objects, methods and functions diff -r 030d8c23231da1fba7a207177d4553cf6a9fe466 -r ca47b6d25ebe2ebf223b80b2f1cbe3e2bbe9f4e1 src/lib/datafile.py --- a/src/lib/datafile.py Tue Jun 29 18:03:09 2004 +0000 +++ b/src/lib/datafile.py Tue Jun 29 19:11:09 2004 +0000 @@ -27,6 +27,7 @@ TYPE_AUTO = "autodetect" TYPE_FPM = "fpm" +TYPE_NETRC = "netrc" TYPE_REVELATION = "revelation" TYPE_XML = "xml" @@ -46,6 +47,14 @@ "defaultfile" : "~/.fpm/fpm" }, + TYPE_NETRC : { + "name" : ".netrc", + "import" : gtk.TRUE, + "export" : gtk.TRUE, + "datahandler" : revelation.datahandler.NetRC, + "defaultfile" : None + }, + TYPE_REVELATION : { "name" : "Revelation", "import" : gtk.TRUE, @@ -169,8 +178,12 @@ def check_format(self): - data = self.__read(self.file, CHECKBUFFER) - self.handler.check_data(data) + try: + data = self.__read(self.file, CHECKBUFFER) + self.handler.check_data(data) + + except AttributeError: + pass def detect_type(self): diff -r 030d8c23231da1fba7a207177d4553cf6a9fe466 -r ca47b6d25ebe2ebf223b80b2f1cbe3e2bbe9f4e1 src/lib/datahandler/__init__.py --- a/src/lib/datahandler/__init__.py Tue Jun 29 18:03:09 2004 +0000 +++ b/src/lib/datahandler/__init__.py Tue Jun 29 19:11:09 2004 +0000 @@ -25,5 +25,6 @@ from base import * from fpm import * +from netrc import * from rvl import * diff -r 030d8c23231da1fba7a207177d4553cf6a9fe466 -r ca47b6d25ebe2ebf223b80b2f1cbe3e2bbe9f4e1 src/lib/datahandler/netrc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/datahandler/netrc.py Tue Jun 29 19:11:09 2004 +0000 @@ -0,0 +1,135 @@ +# +# Revelation 0.3.0 - a password manager for GNOME 2 +# http://oss.codepoet.no/revelation/ +# $Id$ +# +# Module for handling .netrc files +# +# +# Copyright (c) 2003-2004 Erik Grinaker +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + + +import revelation, base, StringIO, shlex, time + + +class NetRC(base.Handler): + + def __init__(self): + base.Handler.__init__(self) + + + def export_data(self, entrystore): + + iter = None + data = "" + + while 1: + iter = entrystore.iter_traverse_next(iter) + + if iter is None: + break + + entry = entrystore.get_entry(iter) + + if not entry.has_field(revelation.entry.FIELD_GENERIC_HOSTNAME) or not entry.has_field(revelation.entry.FIELD_GENERIC_USERNAME) or not entry.has_field(revelation.entry.FIELD_GENERIC_PASSWORD): + continue + + hostname = entry.get_field(revelation.entry.FIELD_GENERIC_HOSTNAME).value + username = entry.get_field(revelation.entry.FIELD_GENERIC_USERNAME).value + password = entry.get_field(revelation.entry.FIELD_GENERIC_PASSWORD).value + + if hostname == "" or username == "" or password == "": + continue + + if entry.name != "": + data += "# " + entry.name + "\n" + + if entry.description != "": + data += "# " + entry.description + "\n" + + data += "machine " + hostname + "\n" + data += " login " + username + "\n" + data += " password " + password + "\n" + data += "\n" + + return data + + + def import_data(self, entrystore, data): + datafp = StringIO.StringIO(data) + lexer = shlex.shlex(datafp) + lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" + + while 1: + # look for a machine, default or macdef top-level keyword + tt = lexer.get_token() + + if not tt: + break + + elif tt == "machine": + name = lexer.get_token() + + elif tt == "default": + name = "default" + + elif tt == "macdef": + lexer.whitespace = ' \t' + + while 1: + line = lexer.instream.readline() + if not line or line == '\012': + lexer.whitespace = ' \t\r\n' + break + continue + + else: + print "invtoken1", tt + raise base.FormatError + + + # we're looking at an entry, so fetch data + entry = revelation.entry.Entry(revelation.entry.ENTRY_ACCOUNT_GENERIC) + entry.name = name + entry.updated = time.time() + + if name != "default": + entry.set_field(revelation.entry.FIELD_GENERIC_HOSTNAME, name) + + while 1: + tt = lexer.get_token() + if tt == "" or tt == "machine" or tt == "default" or tt == "macdef": + entrystore.add_entry(None, entry) + lexer.push_token(tt) + break + + elif tt == "login" or tt == "user": + entry.set_field(revelation.entry.FIELD_GENERIC_USERNAME, lexer.get_token()) + + elif tt == "account": + lexer.get_token() + + elif tt == "password": + entry.set_field(revelation.entry.FIELD_GENERIC_PASSWORD, lexer.get_token()) + + else: + print "invtoken2", tt + raise FormatError + + datafp.close() + diff -r 030d8c23231da1fba7a207177d4553cf6a9fe466 -r ca47b6d25ebe2ebf223b80b2f1cbe3e2bbe9f4e1 src/lib/entry.py --- a/src/lib/entry.py Tue Jun 29 18:03:09 2004 +0000 +++ b/src/lib/entry.py Tue Jun 29 19:11:09 2004 +0000 @@ -303,6 +303,10 @@ return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.updated)) + def has_field(self, id): + return self.fields.has_key(id) + + def set_field(self, id, value): if not self.fields.has_key(id): raise EntryFieldError