0001 """An object-oriented interface to .netrc files.""" 0002 0003 # Module and documentation by Eric S. Raymond, 21 Dec 1998 0004 0005 import os, shlex 0006 0007 __all__ = ["netrc", "NetrcParseError"] 0008 0009 0010 class NetrcParseError(Exception): 0011 """Exception raised on syntax errors in the .netrc file.""" 0012 def __init__(self, msg, filename=None, lineno=None): 0013 self.filename = filename 0014 self.lineno = lineno 0015 self.msg = msg 0016 Exception.__init__(self, msg) 0017 0018 def __str__(self): 0019 return "%s (%s, line %s)" % (self.msg, self.filename, self.lineno) 0020 0021 0022 class netrc: 0023 def __init__(self, file=None): 0024 if file is None: 0025 try: 0026 file = os.path.join(os.environ['HOME'], ".netrc") 0027 except KeyError: 0028 raise IOError("Could not find .netrc: $HOME is not set") 0029 fp = open(file) 0030 self.hosts = {} 0031 self.macros = {} 0032 lexer = shlex.shlex(fp) 0033 lexer.wordchars += r"""!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~""" 0034 while 1: 0035 # Look for a machine, default, or macdef top-level keyword 0036 toplevel = tt = lexer.get_token() 0037 if not tt: 0038 break 0039 elif tt == 'machine': 0040 entryname = lexer.get_token() 0041 elif tt == 'default': 0042 entryname = 'default' 0043 elif tt == 'macdef': # Just skip to end of macdefs 0044 entryname = lexer.get_token() 0045 self.macros[entryname] = [] 0046 lexer.whitespace = ' \t' 0047 while 1: 0048 line = lexer.instream.readline() 0049 if not line or line == '\012': 0050 lexer.whitespace = ' \t\r\n' 0051 break 0052 self.macros[entryname].append(line) 0053 continue 0054 else: 0055 raise NetrcParseError( 0056 "bad toplevel token %r" % tt, file, lexer.lineno) 0057 0058 # We're looking at start of an entry for a named machine or default. 0059 login = '' 0060 account = password = None 0061 self.hosts[entryname] = {} 0062 while 1: 0063 tt = lexer.get_token() 0064 if (tt=='' or tt == 'machine' or 0065 tt == 'default' or tt =='macdef'): 0066 if password: 0067 self.hosts[entryname] = (login, account, password) 0068 lexer.push_token(tt) 0069 break 0070 else: 0071 raise NetrcParseError( 0072 "malformed %s entry %s terminated by %s" 0073 % (toplevel, entryname, repr(tt)), 0074 file, lexer.lineno) 0075 elif tt == 'login' or tt == 'user': 0076 login = lexer.get_token() 0077 elif tt == 'account': 0078 account = lexer.get_token() 0079 elif tt == 'password': 0080 password = lexer.get_token() 0081 else: 0082 raise NetrcParseError("bad follower token %r" % tt, 0083 file, lexer.lineno) 0084 0085 def authenticators(self, host): 0086 """Return a (user, account, password) tuple for given host.""" 0087 if host in self.hosts: 0088 return self.hosts[host] 0089 elif 'default' in self.hosts: 0090 return self.hosts['default'] 0091 else: 0092 return None 0093 0094 def __repr__(self): 0095 """Dump the class data in the format of a .netrc file.""" 0096 rep = "" 0097 for host in self.hosts.keys(): 0098 attrs = self.hosts[host] 0099 rep = rep + "machine "+ host + "\n\tlogin " + repr(attrs[0]) + "\n" 0100 if attrs[1]: 0101 rep = rep + "account " + repr(attrs[1]) 0102 rep = rep + "\tpassword " + repr(attrs[2]) + "\n" 0103 for macro in self.macros.keys(): 0104 rep = rep + "macdef " + macro + "\n" 0105 for line in self.macros[macro]: 0106 rep = rep + line 0107 rep = rep + "\n" 0108 return rep 0109 0110 if __name__ == '__main__': 0111 print netrc() 0112
Generated by PyXR 0.9.4