class PostfixLogParser(object): @staticmethod def split_host(str): ''' split string in form HOST[IP] and return HOST and IP ''' ip_start = str.find('[') ip_end = -1 if ip_start>=0: ip_end = str.find(']', ip_start) if ip_start<0 or ip_end<0: return str, str return str[0:ip_start], str[ip_start+1:ip_end] @staticmethod def strip_brackets(str, bracket_l='<', bracket_r='>'): # strip enclosing '<>' if len(str)>=2 and str[0]==bracket_l and str[-1]==bracket_r: return str[1:-1] return str class SplitList(object): ''' split a postfix name=value list. For example: "delay=4.7, to=, status=sent (250 2.0.0 YB5nM1eS01+lSgAAlWWVsw Saved)" returns: { "delay": { "name": "delay", "value": "4.7" }, "to": { "name": "to", "value": "alice@post.com" }, "status": { "name": "status", "value": "sent", "comment": "250 2.0.0 YB5nM1eS01+lSgAAlWWVsw Saved" } } ''' def __init__(self, str, delim=',', strip_brackets=True): self.str = str self.delim = delim self.strip_brackets = True self.pos = 0 def asDict(self): d = {} for pair in self: d[pair['name']] = pair return d def __iter__(self): self.pos = 0 return self def __next__(self): if self.pos >= len(self.str): raise StopIteration # name eq = self.str.find('=', self.pos) if eq<0: self.pos = len(self.str) raise StopIteration name = self.str[self.pos:eq].strip() # value and comment self.pos = eq+1 value = [] comment = [] while self.pos < len(self.str): c = self.str[self.pos] self.pos += 1 if c=='<': idx = self.str.find('>', self.pos) if idx>=0: value.append(self.str[self.pos-1:idx+1]) self.pos = idx+1 continue if c=='(': # parens may be nested... open_count = 1 begin = self.pos while self.pos < len(self.str) and open_count>0: c = self.str[self.pos] self.pos += 1 if c=='(': open_count += 1 elif c==')': open_count -= 1 if open_count == 0: comment.append(self.str[begin:self.pos-1]) else: comment.append(self.str[begin:len(self.str)]) continue if c==self.delim: break begin = self.pos-1 while self.pos < len(self.str): lookahead = self.str[self.pos] if lookahead in [self.delim,'<','(']: break self.pos += 1 value.append(self.str[begin:self.pos]) if self.strip_brackets and len(value)==1: value[0] = PostfixLogParser.strip_brackets(value[0]) return { 'name': name, 'value': ''.join(value), 'comment': None if len(comment)==0 else '; '.join(comment) }