mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-04-04 00:17:06 +00:00
This adds a new section to the admin panel called "Activity", that supplies charts, graphs and details about messages entering and leaving the host. A new daemon captures details of system mail activity by monitoring the /var/log/mail.log file, summarizing it into a sqllite database that's kept in user-data.
126 lines
3.7 KiB
Python
126 lines
3.7 KiB
Python
|
|
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=<alice@post.com>, status=sent (250 2.0.0 <user@domain.tld> 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 <user@domain.tld> 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)
|
|
}
|