2 # Stuff for dealing with configuration files.
5 # This code is part of the LWN git data miner.
7 # Copyright 2007-11 Eklektix, Inc.
8 # Copyright 2007-11 Jonathan Corbet <corbet@lwn.net>
10 # This file may be distributed under the terms of the GNU General
11 # Public License, version 2.
13 import sys
, re
, datetime
, os
.path
17 # Read a line and strip out junk.
19 def ReadConfigLine (file):
20 line
= file.readline ()
23 line
= line
.split('#')[0] # Get rid of any comments
24 line
= line
.strip () # and extra white space
25 if len (line
) == 0: # we got rid of everything
26 return ReadConfigLine (file)
33 sys
.stderr
.write (message
+ '\n')
37 # Read a list of email aliases.
39 def ReadEmailAliases (name
):
41 file = open (name
, 'r')
43 croak ('Unable to open email alias file %s' % (name
))
44 line
= ReadConfigLine (file)
46 m
= re
.match ('^("[^"]+"|\S+)\s+(.+)$', line
)
47 if not m
or len (m
.groups ()) != 2:
48 croak ('Funky email alias line "%s"' % (line
))
49 if m
and m
.group (2).find ('@') <= 0:
50 croak ('Non-addresses in email alias "%s"' % (line
))
51 database
.AddEmailAlias (m
.group (1).replace ('"', ''), m
.group (2))
52 line
= ReadConfigLine (file)
56 # The Email/Employer map
58 EMMpat
= re
.compile (r
'^([^\s]+)\s+([^<]+)\s*(<\s*(\d+-\d+-\d+)\s*)?$')
60 def ReadEmailEmployers (name
):
62 file = open (name
, 'r')
64 croak ('Unable to open email/employer file %s' % (name
))
65 line
= ReadConfigLine (file)
67 m
= EMMpat
.match (line
)
69 croak ('Funky email/employer line "%s"' % (line
))
71 company
= m
.group (2).strip ()
72 enddate
= ParseDate (m
.group (4))
73 database
.AddEmailEmployerMapping (email
, company
, enddate
)
74 line
= ReadConfigLine (file)
77 def ParseDate (cdate
):
80 sdate
= cdate
.split ('-')
81 return datetime
.date (int (sdate
[0]), int (sdate
[1]), int (sdate
[2]))
84 def ReadGroupMap (fname
, employer
):
86 file = open (fname
, 'r')
88 croak ('Unable to open group map file %s' % (fname
))
89 line
= ReadConfigLine (file)
91 database
.AddEmailEmployerMapping (line
, employer
)
92 line
= ReadConfigLine (file)
96 # Read in a virtual employer description.
98 def ReadVirtual (file, name
):
99 ve
= database
.VirtualEmployer (name
)
100 line
= ReadConfigLine (file)
102 sl
= line
.split (None, 1)
108 # Zap the "%" syntactic sugar if it's there
113 percent
= int (first
)
115 croak ('Bad split value "%s" for virtual empl %s' % (first
, name
))
116 if not (0 < percent
<= 100):
117 croak ('Bad split value "%s" for virtual empl %s' % (first
, name
))
118 ve
.addsplit (' '.join (sl
[1:]), percent
/100.0)
119 line
= ReadConfigLine (file)
121 # We should never get here
123 croak ('Missing "end" line for virtual employer %s' % (name
))
126 # Read file type patterns for more fine graned reports
128 def ReadFileType (filename
):
130 file = open (filename
, 'r')
132 croak ('Unable to open file type mapping file %s' % (filename
))
135 regex_order
= re
.compile ('^order\s+(.*)$')
136 regex_file_type
= re
.compile ('^filetype\s+(\S+)\s+(.+)$')
137 line
= ReadConfigLine (file)
139 o
= regex_order
.match (line
)
141 # Consider only the first definition in the config file
142 elements
= o
.group(1).replace (' ', '')
143 order
= order
or elements
.split(',')
144 line
= ReadConfigLine (file)
147 m
= regex_file_type
.match (line
)
148 if not m
or len (m
.groups ()) != 2:
149 ConfigFile
.croak ('Funky file type line "%s"' % (line
))
150 if not patterns
.has_key (m
.group (1)):
151 patterns
[m
.group (1)] = []
152 if m
.group (1) not in order
:
153 print '%s not found, appended to the last order' % m
.group (1)
154 order
.append (m
.group (1))
156 patterns
[m
.group (1)].append (re
.compile (m
.group (2), re
.IGNORECASE
))
158 line
= ReadConfigLine (file)
160 return patterns
, order
163 # Read an overall config file.
166 def ConfigFile (name
, confdir
):
168 file = open (name
, 'r')
171 file = open (os
.path
.join (confdir
, name
), 'r')
173 croak ('Unable to open config file %s' % (name
))
174 line
= ReadConfigLine (file)
176 sline
= line
.split (None, 2)
178 croak ('Funky config line: "%s"' % (line
))
179 if sline
[0] == 'EmailAliases':
180 ReadEmailAliases (os
.path
.join (confdir
, sline
[1]))
181 elif sline
[0] == 'EmailMap':
182 ReadEmailEmployers (os
.path
.join (confdir
, sline
[1]))
183 elif sline
[0] == 'GroupMap':
185 croak ('Funky group map line "%s"' % (line
))
186 ReadGroupMap (os
.path
.join (confdir
, sline
[1]), sline
[2])
187 elif sline
[0] == 'VirtualEmployer':
188 ReadVirtual (file, ' '.join (sline
[1:]))
189 elif sline
[0] == 'FileTypeMap':
190 patterns
, order
= ReadFileType (os
.path
.join (confdir
, sline
[1]))
191 database
.FileTypes
= database
.FileType (patterns
, order
)
193 croak ('Unrecognized config line: "%s"' % (line
))
194 line
= ReadConfigLine (file)