+++ /dev/null
-"""An object-oriented interface to .netrc files."""\r
-\r
-# Module and documentation by Eric S. Raymond, 21 Dec 1998\r
-\r
-import os, shlex\r
-\r
-__all__ = ["netrc", "NetrcParseError"]\r
-\r
-\r
-class NetrcParseError(Exception):\r
- """Exception raised on syntax errors in the .netrc file."""\r
- def __init__(self, msg, filename=None, lineno=None):\r
- self.filename = filename\r
- self.lineno = lineno\r
- self.msg = msg\r
- Exception.__init__(self, msg)\r
-\r
- def __str__(self):\r
- return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno)\r
-\r
-\r
-class netrc:\r
- def __init__(self, file=None):\r
- if file is None:\r
- try:\r
- file = os.path.join(os.environ['HOME'], ".netrc")\r
- except KeyError:\r
- raise IOError("Could not find .netrc: $HOME is not set")\r
- self.hosts = {}\r
- self.macros = {}\r
- with open(file) as fp:\r
- self._parse(file, fp)\r
-\r
- def _parse(self, file, fp):\r
- lexer = shlex.shlex(fp)\r
- lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"""\r
- lexer.commenters = lexer.commenters.replace('#', '')\r
- while 1:\r
- # Look for a machine, default, or macdef top-level keyword\r
- toplevel = tt = lexer.get_token()\r
- if not tt:\r
- break\r
- elif tt[0] == '#':\r
- # seek to beginning of comment, in case reading the token put\r
- # us on a new line, and then skip the rest of the line.\r
- pos = len(tt) + 1\r
- lexer.instream.seek(-pos, 1)\r
- lexer.instream.readline()\r
- continue\r
- elif tt == 'machine':\r
- entryname = lexer.get_token()\r
- elif tt == 'default':\r
- entryname = 'default'\r
- elif tt == 'macdef': # Just skip to end of macdefs\r
- entryname = lexer.get_token()\r
- self.macros[entryname] = []\r
- lexer.whitespace = ' \t'\r
- while 1:\r
- line = lexer.instream.readline()\r
- if not line or line == '\012':\r
- lexer.whitespace = ' \t\r\n'\r
- break\r
- self.macros[entryname].append(line)\r
- continue\r
- else:\r
- raise NetrcParseError(\r
- "bad toplevel token %r" % tt, file, lexer.lineno)\r
-\r
- # We're looking at start of an entry for a named machine or default.\r
- login = ''\r
- account = password = None\r
- self.hosts[entryname] = {}\r
- while 1:\r
- tt = lexer.get_token()\r
- if (tt.startswith('#') or\r
- tt in {'', 'machine', 'default', 'macdef'}):\r
- if password:\r
- self.hosts[entryname] = (login, account, password)\r
- lexer.push_token(tt)\r
- break\r
- else:\r
- raise NetrcParseError(\r
- "malformed %s entry %s terminated by %s"\r
- % (toplevel, entryname, repr(tt)),\r
- file, lexer.lineno)\r
- elif tt == 'login' or tt == 'user':\r
- login = lexer.get_token()\r
- elif tt == 'account':\r
- account = lexer.get_token()\r
- elif tt == 'password':\r
- password = lexer.get_token()\r
- else:\r
- raise NetrcParseError("bad follower token %r" % tt,\r
- file, lexer.lineno)\r
-\r
- def authenticators(self, host):\r
- """Return a (user, account, password) tuple for given host."""\r
- if host in self.hosts:\r
- return self.hosts[host]\r
- elif 'default' in self.hosts:\r
- return self.hosts['default']\r
- else:\r
- return None\r
-\r
- def __repr__(self):\r
- """Dump the class data in the format of a .netrc file."""\r
- rep = ""\r
- for host in self.hosts.keys():\r
- attrs = self.hosts[host]\r
- rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n"\r
- if attrs[1]:\r
- rep = rep + "account " + repr(attrs[1])\r
- rep = rep + "\tpassword " + repr(attrs[2]) + "\n"\r
- for macro in self.macros.keys():\r
- rep = rep + "macdef " + macro + "\n"\r
- for line in self.macros[macro]:\r
- rep = rep + line\r
- rep = rep + "\n"\r
- return rep\r
-\r
-if __name__ == '__main__':\r
- print netrc()\r