Unreviewed, updated my email information.
[WebKit-https.git] / Tools / Scripts / webkitpy / common / config / committers.py
1 # Copyright (c) 2011, Apple Inc. All rights reserved.
2 # Copyright (c) 2009, 2011, 2012 Google Inc. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 #     * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 #     * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
13 # distribution.
14 #     * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #
30 # WebKit's Python module for committer and reviewer validation.
31
32 from webkitpy.common.editdistance import edit_distance
33 import fnmatch
34
35 class Account(object):
36     def __init__(self, name, email_or_emails, irc_nickname_or_nicknames=None):
37         assert(name)
38         assert(email_or_emails)
39         self.full_name = name
40         if isinstance(email_or_emails, str):
41             self.emails = [email_or_emails]
42         else:
43             self.emails = email_or_emails
44         self.emails = map(lambda email: email.lower(), self.emails)  # Emails are case-insensitive.
45         if isinstance(irc_nickname_or_nicknames, str):
46             self.irc_nicknames = [irc_nickname_or_nicknames]
47         else:
48             self.irc_nicknames = irc_nickname_or_nicknames
49         self.can_commit = False
50         self.can_review = False
51
52     def bugzilla_email(self):
53         # FIXME: We're assuming the first email is a valid bugzilla email,
54         # which might not be right.
55         return self.emails[0]
56
57     def __str__(self):
58         return '"%s" <%s>' % (self.full_name, self.emails[0])
59
60     def contains_string(self, search_string):
61         string = search_string.lower()
62         if string in self.full_name.lower():
63             return True
64         if self.irc_nicknames:
65             for nickname in self.irc_nicknames:
66                 if string in nickname.lower():
67                     return True
68         for email in self.emails:
69             if string in email:
70                 return True
71         return False
72
73     def matches_glob(self, glob_string):
74         if fnmatch.fnmatch(self.full_name, glob_string):
75             return True
76         if self.irc_nicknames:
77             for nickname in self.irc_nicknames:
78                 if fnmatch.fnmatch(nickname, glob_string):
79                     return True
80         for email in self.emails:
81             if fnmatch.fnmatch(email, glob_string):
82                 return True
83         return False
84
85
86 class Contributor(Account):
87     def __init__(self, name, email_or_emails, irc_nickname=None):
88         Account.__init__(self, name, email_or_emails, irc_nickname)
89         self.is_contributor = True
90
91
92 class Committer(Contributor):
93     def __init__(self, name, email_or_emails, irc_nickname=None):
94         Contributor.__init__(self, name, email_or_emails, irc_nickname)
95         self.can_commit = True
96
97
98 class Reviewer(Committer):
99     def __init__(self, name, email_or_emails, irc_nickname=None):
100         Committer.__init__(self, name, email_or_emails, irc_nickname)
101         self.can_review = True
102
103
104 # This is a list of email addresses that have bugzilla accounts but are not
105 # used for contributing (such as mailing lists).
106
107
108 watchers_who_are_not_contributors = [
109     Account("Chromium Compositor Bugs", ["cc-bugs@chromium.org"], ""),
110     Account("Chromium Media Reviews", ["feature-media-reviews@chromium.org"], ""),
111     Account("David Levin", ["levin+threading@chromium.org"], ""),
112     Account("David Levin", ["levin+watchlist@chromium.org"], ""),
113     Account("Kent Tamura", ["tkent+wkapi@chromium.org"], ""),
114     Account("Mike West", ["mkwst+watchlist@chromium.org"], ""),
115 ]
116
117
118 # This is a list of people (or bots) who are neither committers nor reviewers, but get
119 # frequently CC'ed by others on Bugzilla bugs, so their names should be
120 # supported by autocomplete. No review needed to add to the list.
121
122
123 contributors_who_are_not_committers = [
124     Contributor("Adobe Bug Tracker", "WebkitBugTracker@adobe.com"),
125     Contributor("Aharon Lanin", "aharon@google.com"),
126     Contributor("Alan Cutter", "alancutter@chromium.org", "alancutter"),
127     Contributor("Alan Stearns", "stearns@adobe.com", "astearns"),
128     Contributor("Alejandro Pineiro", "apinheiro@igalia.com"),
129     Contributor("Alexey Marinichev", ["amarinichev@chromium.org", "amarinichev@google.com"], "amarinichev"),
130     Contributor("Andras Piroska", "pandras@inf.u-szeged.hu", "andris88"),
131     Contributor("Andrei Bucur", "abucur@adobe.com", "abucur"),
132     Contributor("Anne van Kesteren", "annevk@annevk.nl", "annevk"),
133     Contributor("Annie Sullivan", "sullivan@chromium.org", "annie"),
134     Contributor("Anton Vayvod", "avayvod@chromium.org", "avayvod"),
135     Contributor("Antoine Quint", "graouts@apple.com", "graouts"),
136     Contributor("Aryeh Gregor", "ayg@aryeh.name", "AryehGregor"),
137     Contributor("Balazs Ankes", "bank@inf.u-szeged.hu", "abalazs"),
138     Contributor("Brian Salomon", "bsalomon@google.com"),
139     Contributor("Commit Queue", "commit-queue@webkit.org"),
140     Contributor("Daniel Sievers", "sievers@chromium.org"),
141     Contributor("David Dorwin", "ddorwin@chromium.org", "ddorwin"),
142     Contributor("David Reveman", "reveman@chromium.org", "reveman"),
143     Contributor("Dongsung Huang", "luxtella@company100.net", "Huang"),
144     Contributor("Douglas Davidson", "ddavidso@apple.com"),
145     Contributor("Edward O'Connor", "eoconnor@apple.com", "hober"),
146     Contributor("Eric Penner", "epenner@chromium.org", "epenner"),
147     Contributor("Felician Marton", ["felician@inf.u-szeged.hu", "marton.felician.zoltan@stud.u-szeged.hu"], "Felician"),
148     Contributor("Finnur Thorarinsson", ["finnur@chromium.org", "finnur.webkit@gmail.com"], "finnur"),
149     Contributor("Forms Bugs", "forms-bugs@chromium.org"),
150     Contributor("Glenn Adams", "glenn@skynav.com", "gasubic"),
151     Contributor("Gabor Ballabas", "gaborb@inf.u-szeged.hu", "bgabor"),
152     Contributor("Grace Kloba", "klobag@chromium.org", "klobag"),
153     Contributor("Greg Simon", "gregsimon@chromium.org", "gregsimon"),
154     Contributor("Hao Zheng", "zhenghao@chromium.org"),
155     Contributor("Harald Alvestrand", "hta@google.com", "hta"),
156     Contributor("Ian Hickson", "ian@hixie.ch", "hixie"),
157     Contributor("Jonathan Backer", "backer@chromium.org", "backer"),
158     Contributor("Jeff Timanus", ["twiz@chromium.org", "twiz@google.com"], "twiz"),
159     Contributor("Jing Zhao", "jingzhao@chromium.org"),
160     Contributor("Joanmarie Diggs", "jdiggs@igalia.com"),
161     Contributor("John Bates", ["jbates@google.com", "jbates@chromium.org"], "jbates"),
162     Contributor("John Bauman", ["jbauman@chromium.org", "jbauman@google.com"], "jbauman"),
163     Contributor("John Mellor", "johnme@chromium.org", "johnme"),
164     Contributor("Kulanthaivel Palanichamy", "kulanthaivel@codeaurora.org", "kvel"),
165     Contributor("Kiran Muppala", "cmuppala@apple.com", "kiranm"),
166     Contributor("Koji Ishii", "kojiishi@gmail.com"),
167     Contributor("Michael Pruett", "michael@68k.org", "mpruett"),
168     Contributor("Mihai Balan", "mibalan@adobe.com", "miChou"),
169     Contributor("Mihai Maerean", "mmaerean@adobe.com", "mmaerean"),
170     Contributor("Min Qin", "qinmin@chromium.org"),
171     Contributor("Nandor Huszka", "hnandor@inf.u-szeged.hu", "hnandor"),
172     Contributor("Oliver Varga", ["voliver@inf.u-szeged.hu", "Varga.Oliver@stud.u-szeged.hu"], "TwistO"),
173     Contributor("Peter Gal", "galpeter@inf.u-szeged.hu", "elecro"),
174     Contributor("Peter Linss", "peter.linss@hp.com", "plinss"),
175     Contributor("Radar WebKit Bug Importer", "webkit-bug-importer@group.apple.com"),
176     Contributor("Raul Hudea", "rhudea@adobe.com", "rhudea"),
177     Contributor("Roland Takacs", "rtakacs@inf.u-szeged.hu", "rtakacs"),
178     Contributor(u"Sami Ky\u00f6stil\u00e4", "skyostil@chromium.org", "skyostil"),
179     Contributor("Silvia Pfeiffer", "silviapf@chromium.org", "silvia"),
180     Contributor("Szilard Ledan-Muntean", "szledan@inf.u-szeged.hu", "szledan"),
181     Contributor("Tab Atkins", ["tabatkins@google.com", "jackalmage@gmail.com"], "tabatkins"),
182     Contributor("Tamas Czene", ["tczene@inf.u-szeged.hu", "Czene.Tamas@stud.u-szeged.hu"], "tczene"),
183     Contributor("Tien-Ren Chen", "trchen@chromium.org", "trchen"),
184     Contributor("Tim 'mithro' Ansell", "mithro@mithis.com", "mithro"),
185     Contributor("Tim Volodine", "timvolodine@chromium.org", "timvolodine"),
186     Contributor("WebKit Review Bot", "webkit.review.bot@gmail.com", "sheriff-bot"),
187     Contributor("Web Components Team", "webcomponents-bugzilla@chromium.org"),
188     Contributor("Wyatt Carss", ["wcarss@chromium.org", "wcarss@google.com"], "wcarss"),
189     Contributor("Zeev Lieber", "zlieber@chromium.org"),
190     Contributor("Zoltan Arvai", "zarvai@inf.u-szeged.hu", "azbest_hu"),
191     Contributor("Zsolt Feher", "feherzs@inf.u-szeged.hu", "Smith"),
192 ]
193
194
195 # This is intended as a canonical, machine-readable list of all non-reviewer
196 # committers for WebKit.  If your name is missing here and you are a committer,
197 # please add it.  No review needed.  All reviewers are committers, so this list
198 # is only of committers who are not reviewers.
199
200
201 committers_unable_to_review = [
202     Committer("Aaron Boodman", "aa@chromium.org", "aboodman"),
203     Committer("Aaron Colwell", "acolwell@chromium.org", "acolwell"),
204     Committer("Adam Bergkvist", "adam.bergkvist@ericsson.com", "adambe"),
205     Committer("Adam Kallai", "kadam@inf.u-szeged.hu", "kadam"),
206     Committer("Adam Klein", "adamk@chromium.org", "aklein"),
207     Committer("Adam Langley", "agl@chromium.org", "agl"),
208     Committer("Ademar de Souza Reis Jr", ["ademar.reis@gmail.com", "ademar@webkit.org"], "ademar"),
209     Committer("Albert J. Wong", "ajwong@chromium.org"),
210     Committer("Alec Flett", ["alecflett@chromium.org", "alecflett@google.com"], "alecf"),
211     Committer(u"Alexander F\u00e6r\u00f8y", ["ahf@0x90.dk", "alexander.faeroy@nokia.com"], "ahf"),
212     Committer("Alexander Kellett", ["lypanov@mac.com", "a-lists001@lypanov.net", "lypanov@kde.org"], "lypanov"),
213     Committer("Alexandre Elias", ["aelias@chromium.org", "aelias@google.com"], "aelias"),
214     Committer("Alexandru Chiculita", "achicu@adobe.com", "achicu"),
215     Committer("Alice Boxhall", "aboxhall@chromium.org", "aboxhall"),
216     Committer("Alok Priyadarshi", "alokp@chromium.org", "alokp"),
217     Committer("Ami Fischman", ["fischman@chromium.org", "fischman@google.com"], "fischman"),
218     Committer("Amruth Raj", "amruthraj@motorola.com", "amruthraj"),
219     Committer("Andre Boule", "aboule@apple.com"),
220     Committer("Andrei Popescu", "andreip@google.com", "andreip"),
221     Committer("Andrew Wellington", ["andrew@webkit.org", "proton@wiretapped.net"], "proton"),
222     Committer("Andrew Scherkus", "scherkus@chromium.org", "scherkus"),
223     Committer("Andrey Adaykin", "aandrey@chromium.org", "aandrey"),
224     Committer("Andrey Kosyakov", "caseq@chromium.org", "caseq"),
225     Committer("Andras Becsi", ["abecsi@webkit.org", "andras.becsi@digia.com"], "bbandix"),
226     Committer("Andy Wingo", "wingo@igalia.com", "wingo"),
227     Committer("Anna Cavender", "annacc@chromium.org", "annacc"),
228     Committer("Anthony Ricaud", "rik@webkit.org", "rik"),
229     Committer("Antoine Labour", "piman@chromium.org", "piman"),
230     Committer("Anton D'Auria", "adauria@apple.com", "antonlefou"),
231     Committer("Anton Muhin", "antonm@chromium.org", "antonm"),
232     Committer("Arko Saha", "arko@motorola.com", "arkos"),
233     Committer("Arvid Nilsson", "anilsson@rim.com", "anilsson"),
234     Committer("Balazs Kelemen", "kbalazs@webkit.org", "kbalazs"),
235     Committer("Ben Murdoch", "benm@google.com", "benm"),
236     Committer("Ben Wells", "benwells@chromium.org", "benwells"),
237     Committer("Benjamin C Meyer", ["ben@meyerhome.net", "ben@webkit.org", "bmeyer@rim.com"], "icefox"),
238     Committer("Benjamin Kalman", ["kalman@chromium.org", "kalman@google.com"], "kalman"),
239     Committer("Benjamin Otte", ["otte@gnome.org", "otte@webkit.org"], "otte"),
240     Committer("Bill Budge", ["bbudge@chromium.org", "bbudge@gmail.com"], "bbudge"),
241     Committer("Brett Wilson", "brettw@chromium.org", "brettx"),
242     Committer("Bruno de Oliveira Abinader", ["bruno.abinader@basyskom.com", "brunoabinader@gmail.com"], "abinader"),
243     Committer("Cameron McCormack", ["cam@mcc.id.au", "cam@webkit.org"], "heycam"),
244     Committer("Carol Szabo", ["carol@webkit.org", "carol.szabo@nokia.com"], "cszabo1"),
245     Committer("Cary Clark", ["caryclark@google.com", "caryclark@chromium.org"], "caryclark"),
246     Committer("Charles Reis", "creis@chromium.org", "creis"),
247     Committer("Charles Wei", ["charles.wei@torchmobile.com.cn"], "cswei"),
248     Committer("Chris Evans", ["cevans@google.com", "cevans@chromium.org"]),
249     Committer("Chris Guillory", ["ctguil@chromium.org", "chris.guillory@google.com"], "ctguil"),
250     Committer("Chris Petersen", "cpetersen@apple.com", "cpetersen"),
251     Committer("Christian Dywan", ["christian@twotoasts.de", "christian@webkit.org", "christian@lanedo.com"]),
252     Committer("Christophe Dumez", ["christophe.dumez@intel.com", "dchris@gmail.com"], "chris-qBT"),
253     Committer("Collin Jackson", "collinj@webkit.org", "collinjackson"),
254     Committer("Cris Neckar", "cdn@chromium.org", "cneckar"),
255     Committer("Dan Winship", "danw@gnome.org", "danw"),
256     Committer("Dana Jansens", "danakj@chromium.org", "danakj"),
257     Committer("Daniel Cheng", "dcheng@chromium.org", "dcheng"),
258     Committer("Dave Barton", "dbarton@mathscribe.com", "davebarton"),
259     Committer("Dave Tharp", "dtharp@codeaurora.org", "dtharp"),
260     Committer("David Michael Barr", ["davidbarr@chromium.org", "davidbarr@google.com", "b@rr-dav.id.au"], "barrbrain"),
261     Committer("David Grogan", ["dgrogan@chromium.org", "dgrogan@google.com"], "dgrogan"),
262     Committer("David Smith", ["catfish.man@gmail.com", "dsmith@webkit.org"], "catfishman"),
263     Committer("Diego Gonzalez", ["diegohcg@webkit.org", "diego.gonzalez@openbossa.org"], "diegohcg"),
264     Committer("Dinu Jacob", "dinu.s.jacob@intel.com", "dsjacob"),
265     Committer("Dmitry Lomov", ["dslomov@google.com", "dslomov@chromium.org"], "dslomov"),
266     Committer("Dominic Cooney", ["dominicc@chromium.org", "dominicc@google.com"], "dominicc"),
267     Committer("Dominic Mazzoni", ["dmazzoni@google.com", "dmazzoni@chromium.org"], "dmazzoni"),
268     Committer(u"Dominik R\u00f6ttsches", ["dominik.rottsches@intel.com", "d-r@roettsches.de"], "drott"),
269     Committer("Drew Wilson", "atwilson@chromium.org", "atwilson"),
270     Committer("Eli Fidler", ["eli@staikos.net", "efidler@rim.com"], "efidler"),
271     Committer("Elliot Poger", "epoger@chromium.org", "epoger"),
272     Committer("Elliott Sprehn", "esprehn@chromium.org", "esprehn"),
273     Committer("Erik Arvidsson", "arv@chromium.org", "arv"),
274     Committer("Eric Roman", "eroman@chromium.org", "eroman"),
275     Committer("Eric Uhrhane", "ericu@chromium.org", "ericu"),
276     Committer("Evan Martin", "evan@chromium.org", "evmar"),
277     Committer("Evan Stade", "estade@chromium.org", "estade"),
278     Committer("Fady Samuel", "fsamuel@chromium.org", "fsamuel"),
279     Committer("Feng Qian", "feng@chromium.org"),
280     Committer("Florin Malita", ["fmalita@chromium.org", "fmalita@google.com"], "fmalita"),
281     Committer("Fumitoshi Ukai", "ukai@chromium.org", "ukai"),
282     Committer("Gabor Loki", "loki@webkit.org", "loki04"),
283     Committer("Gabor Rapcsanyi", ["rgabor@webkit.org", "rgabor@inf.u-szeged.hu"], "rgabor"),
284     Committer("Gavin Peters", ["gavinp@chromium.org", "gavinp@webkit.org", "gavinp@google.com"], "gavinp"),
285     Committer("Girish Ramakrishnan", ["girish@forwardbias.in", "ramakrishnan.girish@gmail.com"], "girishr"),
286     Committer("Graham Dennis", ["Graham.Dennis@gmail.com", "gdennis@webkit.org"]),
287     Committer("Greg Bolsinga", "bolsinga@apple.com"),
288     Committer("Gregg Tavares", ["gman@google.com", "gman@chromium.org"], "gman"),
289     Committer("Grzegorz Czajkowski", "g.czajkowski@samsung.com", "grzegorz"),
290     Committer("Hans Wennborg", "hans@chromium.org", "hwennborg"),
291     Committer("Hayato Ito", "hayato@chromium.org", "hayato"),
292     Committer("Hironori Bono", "hbono@chromium.org", "hbono"),
293     Committer("Helder Correia", "helder.correia@nokia.com", "helder"),
294     Committer("Hin-Chung Lam", ["hclam@google.com", "hclam@chromium.org"]),
295     Committer("Hugo Parente Lima", "hugo.lima@openbossa.org", "hugopl"),
296     Committer("Ian Vollick", "vollick@chromium.org", "vollick"),
297     Committer("Igor Trindade Oliveira", ["igor.oliveira@webkit.org", "igor.o@sisa.samsung.com"], "igoroliveira"),
298     Committer("Ilya Sherman", "isherman@chromium.org", "isherman"),
299     Committer("Ilya Tikhonovsky", "loislo@chromium.org", "loislo"),
300     Committer("Ivan Krsti\u0107", "ike@apple.com"),
301     Committer("Jacky Jiang", ["jkjiang@webkit.org", "zkjiang008@gmail.com", "zhajiang@rim.com"], "jkjiang"),
302     Committer("Jakob Petsovits", ["jpetsovits@rim.com", "jpetso@gmx.at"], "jpetso"),
303     Committer("Jakub Wieczorek", "jwieczorek@webkit.org", "fawek"),
304     Committer("James Hawkins", ["jhawkins@chromium.org", "jhawkins@google.com"], "jhawkins"),
305     Committer("James Kozianski", ["koz@chromium.org", "koz@google.com"], "koz"),
306     Committer("James Simonsen", "simonjam@chromium.org", "simonjam"),
307     Committer("Janos Badics", "jbadics@inf.u-szeged.hu", "dicska"),
308     Committer("Jarred Nicholls", ["jarred@webkit.org", "jarred@sencha.com"], "jarrednicholls"),
309     Committer("Jason Liu", ["jason.liu@torchmobile.com.cn", "jasonliuwebkit@gmail.com"], "jasonliu"),
310     Committer("Jay Civelli", "jcivelli@chromium.org", "jcivelli"),
311     Committer("Jeff Miller", "jeffm@apple.com", "jeffm7"),
312     Committer("Jeffrey Pfau", ["jeffrey@endrift.com", "jpfau@apple.com"], "jpfau"),
313     Committer("Jenn Braithwaite", "jennb@chromium.org", "jennb"),
314     Committer("Jens Alfke", ["snej@chromium.org", "jens@apple.com"]),
315     Committer("Jer Noble", "jer.noble@apple.com", "jernoble"),
316     Committer("Jeremy Moskovich", ["playmobil@google.com", "jeremy@chromium.org"], "jeremymos"),
317     Committer("Jesus Sanchez-Palencia", ["jesus@webkit.org", "jesus.palencia@openbossa.org"], "jeez_"),
318     Committer("Jia Pu", "jpu@apple.com"),
319     Committer("Joe Thomas", "joethomas@motorola.com", "joethomas"),
320     Committer("John Abd-El-Malek", "jam@chromium.org", "jam"),
321     Committer("John Gregg", ["johnnyg@google.com", "johnnyg@chromium.org"], "johnnyg"),
322     Committer("John Knottenbelt", "jknotten@chromium.org", "jknotten"),
323     Committer("Johnny Ding", ["jnd@chromium.org", "johnnyding.webkit@gmail.com"], "johnnyding"),
324     Committer("Jon Lee", "jonlee@apple.com", "jonlee"),
325     Committer("Jonathan Dong", ["jonathan.dong.webkit@gmail.com"], "jondong"),
326     Committer("Joone Hur", ["joone@webkit.org", "joone.hur@intel.com"], "joone"),
327     Committer("Joost de Valk", ["joost@webkit.org", "webkit-dev@joostdevalk.nl"], "Altha"),
328     Committer("Joshua Bell", ["jsbell@chromium.org", "jsbell@google.com"], "jsbell"),
329     Committer("Julie Parent", ["jparent@google.com", "jparent@chromium.org"], "jparent"),
330     Committer("Jungshik Shin", "jshin@chromium.org"),
331     Committer("Justin Novosad", ["junov@google.com", "junov@chromium.org"], "junov"),
332     Committer("Justin Schuh", "jschuh@chromium.org", "jschuh"),
333     Committer("Kaustubh Atrawalkar", ["kaustubh@motorola.com"], "silverroots"),
334     Committer("Keishi Hattori", "keishi@webkit.org", "keishi"),
335     Committer("Kelly Norton", "knorton@alum.mit.edu"),
336     Committer("Ken Buchanan", "kenrb@chromium.org", "kenrb"),
337     Committer("Kenichi Ishibashi", "bashi@chromium.org", "bashi"),
338     Committer("Kenji Imasaki", "imasaki@chromium.org", "imasaki"),
339     Committer("Kent Hansen", "kent.hansen@nokia.com", "khansen"),
340     Committer("Kihong Kwon", "kihong.kwon@samsung.com", "kihong"),
341     Committer(u"Kim Gr\u00f6nholm", "kim.1.gronholm@nokia.com"),
342     Committer("Kimmo Kinnunen", ["kimmo.t.kinnunen@nokia.com", "kimmok@iki.fi", "ktkinnun@webkit.org"], "kimmok"),
343     Committer("Kinuko Yasuda", "kinuko@chromium.org", "kinuko"),
344     Committer("Konrad Piascik", "kpiascik@rim.com", "kpiascik"),
345     Committer("Kristof Kosztyo", "kkristof@inf.u-szeged.hu", "kkristof"),
346     Committer("Krzysztof Kowalczyk", "kkowalczyk@gmail.com"),
347     Committer("Kwang Yul Seo", ["skyul@company100.net", "kseo@webkit.org"], "kseo"),
348     Committer("Lauro Neto", "lauro.neto@openbossa.org", "lmoura"),
349     Committer("Leandro Gracia Gil", "leandrogracia@chromium.org", "leandrogracia"),
350     Committer("Leandro Pereira", ["leandro@profusion.mobi", "leandro@webkit.org"], "acidx"),
351     Committer("Leo Yang", ["leoyang@rim.com", "leoyang@webkit.org", "leoyang.webkit@gmail.com"], "leoyang"),
352     Committer("Li Yin", ["li.yin@intel.com"], "liyin"),
353     Committer("Lucas De Marchi", ["demarchi@webkit.org", "lucas.demarchi@profusion.mobi"], "demarchi"),
354     Committer("Lucas Forschler", ["lforschler@apple.com"], "lforschler"),
355     Committer("Luciano Wolf", "luciano.wolf@openbossa.org", "luck"),
356     Committer("Luke Macpherson", ["macpherson@chromium.org", "macpherson@google.com"], "macpherson"),
357     Committer("Mads Ager", "ager@chromium.org"),
358     Committer("Mahesh Kulkarni", ["mahesh.kulkarni@nokia.com", "maheshk@webkit.org"], "maheshk"),
359     Committer("Marcus Voltis Bulach", "bulach@chromium.org"),
360     Committer("Mario Sanchez Prada", ["mario@webkit.org", "mario.prada@samsung.com"], "msanchez"),
361     Committer("Mark Lam", "mark.lam@apple.com", "mlam"),
362     Committer("Mark Pilgrim", "pilgrim@chromium.org", "pilgrim_google"),
363     Committer("Mary Wu", ["mary.wu@torchmobile.com.cn", "wwendy2007@gmail.com"], "marywu"),
364     Committer("Matt Delaney", "mdelaney@apple.com"),
365     Committer("Matt Falkenhagen", "falken@chromium.org", "falken"),
366     Committer("Matt Lilek", ["mlilek@apple.com", "webkit@mattlilek.com", "pewtermoose@webkit.org"], "pewtermoose"),
367     Committer("Matt Perry", "mpcomplete@chromium.org"),
368     Committer("Max Vujovic", ["mvujovic@adobe.com", "maxvujovic@gmail.com"], "mvujovic"),
369     Committer("Maxime Britto", ["maxime.britto@gmail.com", "britto@apple.com"]),
370     Committer("Maxime Simon", ["simon.maxime@gmail.com", "maxime.simon@webkit.org"], "maxime.simon"),
371     Committer(u"Michael Br\u00fcning", ["michael.bruning@digia.com", "michaelbruening@gmail.com"], "mibrunin"),
372     Committer("Michael Nordman", "michaeln@google.com", "michaeln"),
373     Committer("Michelangelo De Simone", "michelangelo@webkit.org", "michelangelo"),
374     Committer("Mihnea Ovidenie", "mihnea@adobe.com", "mihnea"),
375     Committer("Mike Belshe", ["mbelshe@chromium.org", "mike@belshe.com"]),
376     Committer("Mike Fenton", ["mifenton@rim.com", "mike.fenton@torchmobile.com"], "mfenton"),
377     Committer("Mike Lawther", "mikelawther@chromium.org", "mikelawther"),
378     Committer("Mike Reed", "reed@google.com", "reed"),
379     Committer("Mike Thole", ["mthole@mikethole.com", "mthole@apple.com"]),
380     Committer("Mike West", ["mkwst@chromium.org", "mike@mikewest.org"], "mkwst"),
381     Committer("Mikhail Naganov", "mnaganov@chromium.org"),
382     Committer("Mikhail Pozdnyakov", "mikhail.pozdnyakov@intel.com", "MPozdnyakov"),
383     Committer("Naoki Takano", ["honten@chromium.org", "takano.naoki@gmail.com"], "honten"),
384     Committer("Nat Duca", ["nduca@chromium.org", "nduca@google.com"], "nduca"),
385     Committer("Nayan Kumar K", ["nayankk@motorola.com", "nayankk@gmail.com"], "xc0ffee"),
386     Committer("Nico Weber", ["thakis@chromium.org", "thakis@google.com"], "thakis"),
387     Committer("Nima Ghanavatian", ["nghanavatian@rim.com", "nima.ghanavatian@gmail.com"], "nghanavatian"),
388     Committer("Noel Gordon", ["noel.gordon@gmail.com", "noel@chromium.org", "noel@google.com"], "noel"),
389     Committer("Pam Greene", "pam@chromium.org", "pamg"),
390     Committer("Patrick Gansterer", ["paroga@paroga.com", "paroga@webkit.org"], "paroga"),
391     Committer("Pavel Podivilov", "podivilov@chromium.org", "podivilov"),
392     Committer("Peter Beverloo", ["peter@chromium.org", "peter@webkit.org", "beverloo@google.com"], "beverloo"),
393     Committer("Peter Kasting", ["pkasting@google.com", "pkasting@chromium.org"], "pkasting"),
394     Committer("Peter Varga", ["pvarga@webkit.org", "pvarga@inf.u-szeged.hu"], "stampho"),
395     Committer("Philip Rogers", ["pdr@google.com", "pdr@chromium.org"], "pdr"),
396     Committer("Pierre d'Herbemont", ["pdherbemont@free.fr", "pdherbemont@apple.com"], "pdherbemont"),
397     Committer("Pierre-Olivier Latour", "pol@apple.com", "pol"),
398     Committer("Pierre Rossi", "pierre.rossi@gmail.com", "elproxy"),
399     Committer("Pratik Solanki", "psolanki@apple.com", "psolanki"),
400     Committer("Pravin D", ["pravin.d@samsung.com", "pravind@webkit.org"], "pravind"),
401     Committer("Qi Zhang", "qi.zhang02180@gmail.com", "qi"),
402     Committer("Rafael Antognolli", "antognolli@profusion.mobi", "antognolli"),
403     Committer("Rafael Brandao", "rafael.lobo@openbossa.org", "rafaelbrandao"),
404     Committer("Rafael Weinstein", "rafaelw@chromium.org", "rafaelw"),
405     Committer("Raphael Kubo da Costa", ["rakuco@webkit.org", "rakuco@FreeBSD.org", "raphael.kubo.da.costa@intel.com"], "rakuco"),
406     Committer("Ravi Kasibhatla", "ravi.kasibhatla@motorola.com", "kphanee"),
407     Committer("Raymond Toy", "rtoy@google.com", "rtoy"),
408     Committer("Renata Hodovan", "reni@webkit.org", "reni"),
409     Committer("Robert Hogan", ["robert@webkit.org", "robert@roberthogan.net", "lists@roberthogan.net"], "mwenge"),
410     Committer("Robert Kroeger", "rjkroege@chromium.org", "rjkroege"),
411     Committer("Roger Fong", "roger_fong@apple.com", "rfong"),
412     Committer("Roland Steiner", "rolandsteiner@chromium.org"),
413     Committer("Ryuan Choi", "ryuan.choi@samsung.com", "ryuan"),
414     Committer("Satish Sampath", "satish@chromium.org"),
415     Committer("Scott Violet", "sky@chromium.org", "sky"),
416     Committer("Sergio Villar Senin", ["svillar@igalia.com", "sergio@webkit.org"], "svillar"),
417     Committer("Shawn Singh", "shawnsingh@chromium.org", "shawnsingh"),
418     Committer("Shinya Kawanaka", "shinyak@chromium.org", "shinyak"),
419     Committer("Siddharth Mathur", "siddharth.mathur@nokia.com", "simathur"),
420     Committer("Simon Pena", "spena@igalia.com", "spenap"),
421     Committer("Stephen Chenney", "schenney@chromium.org", "schenney"),
422     Committer("Steve Lacey", "sjl@chromium.org", "stevela"),
423     Committer("Sudarsana Nagineni", ["naginenis@gmail.com", "sudarsana.nagineni@linux.intel.com", "sudarsana.nagineni@intel.com"], "babu"),
424     Committer("Taiju Tsuiki", "tzik@chromium.org", "tzik"),
425     Committer("Takashi Sakamoto", "tasak@google.com", "tasak"),
426     Committer("Takashi Toyoshima", "toyoshim@chromium.org", "toyoshim"),
427     Committer("Terry Anderson", "tdanderson@chromium.org", "tdanderson"),
428     Committer("Thiago Marcos P. Santos", ["tmpsantos@gmail.com", "thiago.santos@intel.com"], "tmpsantos"),
429     Committer("Thomas Sepez", "tsepez@chromium.org", "tsepez"),
430     Committer("Tom Hudson", ["tomhudson@google.com", "tomhudson@chromium.org"], "tomhudson"),
431     Committer("Tom Zakrajsek", "tomz@codeaurora.org", "tomz"),
432     Committer("Tommy Widenflycht", "tommyw@google.com", "tommyw"),
433     Committer("Trey Matteson", "trey@usa.net", "trey"),
434     Committer("Tristan O'Tierney", ["tristan@otierney.net", "tristan@apple.com"]),
435     Committer("Vangelis Kokkevis", "vangelis@chromium.org", "vangelis"),
436     Committer("Viatcheslav Ostapenko", ["ostap73@gmail.com", "v.ostapenko@samsung.com", "v.ostapenko@sisa.samsung.com"], "ostap"),
437     Committer("Victor Carbune", ["vcarbune@chromium.org", "victor@rosedu.org"], "vcarbune"),
438     Committer("Victor Wang", "victorw@chromium.org", "victorw"),
439     Committer("Victoria Kirst", ["vrk@chromium.org", "vrk@google.com"], "vrk"),
440     Committer("Vincent Scheib", "scheib@chromium.org", "scheib"),
441     Committer("Vineet Chaudhary", "rgf748@motorola.com", "vineetc"),
442     Committer("Vitaly Repeshko", "vitalyr@chromium.org"),
443     Committer("Vivek Galatage", ["vivek.vg@samsung.com", "vivekg@webkit.org"], "vivekg"),
444     Committer("William Siegrist", "wsiegrist@apple.com", "wms"),
445     Committer("W. James MacLean", "wjmaclean@chromium.org", "seumas"),
446     Committer("Xianzhu Wang", ["wangxianzhu@chromium.org", "phnixwxz@gmail.com", "wangxianzhu@google.com"], "wangxianzhu"),
447     Committer("Xiaohai Wei", ["james.wei@intel.com", "wistoch@chromium.org"], "wistoch"),
448     Committer("Xiaomei Ji", "xji@chromium.org", "xji"),
449     Committer("Xingnan Wang", "xingnan.wang@intel.com", "xingnan"),
450     Committer("Yael Aharon", "yael@webkit.org", "yael"),
451     Committer("Yaar Schnitman", ["yaar@chromium.org", "yaar@google.com"]),
452     Committer("Yi Shen", ["yi.4.shen@nokia.com", "shenyi2006@gmail.com"]),
453     Committer("Yongjun Zhang", ["yongjun.zhang@nokia.com", "yongjun_zhang@apple.com"]),
454     Committer("Yoshifumi Inoue", "yosin@chromium.org", "yosin"),
455     Committer("Yuqiang Xian", "yuqiang.xian@intel.com"),
456     Committer("Yuzo Fujishima", "yuzo@google.com", "yuzo"),
457     Committer("Zalan Bujtas", ["zbujtas@gmail.com", "zalan.bujtas@nokia.com"], "zalan"),
458     Committer("Zeno Albisser", ["zeno@webkit.org", "zeno.albisser@nokia.com"], "zalbisser"),
459     Committer("Zhenyao Mo", "zmo@google.com", "zhenyao"),
460     Committer("Zoltan Horvath", ["zoltan@webkit.org", "hzoltan@inf.u-szeged.hu", "horvath.zoltan.6@stud.u-szeged.hu"], "zoltan"),
461     Committer(u"\u017dan Dober\u0161ek", "zandobersek@gmail.com", "zdobersek"),
462 ]
463
464
465 # This is intended as a canonical, machine-readable list of all reviewers for
466 # WebKit.  If your name is missing here and you are a reviewer, please add it.
467 # No review needed.
468
469
470 reviewers_list = [
471     Reviewer("Abhishek Arya", "inferno@chromium.org", "inferno-sec"),
472     Reviewer("Ada Chan", "adachan@apple.com", "chanada"),
473     Reviewer("Adam Barth", "abarth@webkit.org", "abarth"),
474     Reviewer("Adam Roben", ["aroben@webkit.org", "aroben@apple.com"], "aroben"),
475     Reviewer("Adam Treat", ["treat@kde.org", "treat@webkit.org", "atreat@rim.com"], "manyoso"),
476     Reviewer("Adele Peterson", "adele@apple.com", "adele"),
477     Reviewer("Adrienne Walker", ["enne@google.com", "enne@chromium.org"], "enne"),
478     Reviewer("Alejandro G. Castro", ["alex@igalia.com", "alex@webkit.org"], "alexg__"),
479     Reviewer("Alexander Pavlov", ["apavlov@chromium.org", "pavlov81@gmail.com"], "apavlov"),
480     Reviewer("Alexey Proskuryakov", ["ap@webkit.org", "ap@apple.com"], "ap"),
481     Reviewer("Alexis Menard", ["alexis@webkit.org", "menard@kde.org"], "darktears"),
482     Reviewer("Alice Liu", "alice.liu@apple.com", "aliu"),
483     Reviewer("Allan Sandfeld Jensen", ["allan.jensen@digia.com", "kde@carewolf.com", "sandfeld@kde.org", "allan.jensen@nokia.com"], "carewolf"),
484     Reviewer("Alp Toker", ["alp@nuanti.com", "alp@atoker.com", "alp@webkit.org"], "alp"),
485     Reviewer("Anders Carlsson", ["andersca@apple.com", "acarlsson@apple.com"], "andersca"),
486     Reviewer("Andreas Kling", ["akling@apple.com", "kling@webkit.org", "awesomekling@apple.com", "andreas.kling@nokia.com"], "kling"),
487     Reviewer("Andy Estes", "aestes@apple.com", "estes"),
488     Reviewer("Antonio Gomes", ["tonikitoo@webkit.org", "agomes@rim.com"], "tonikitoo"),
489     Reviewer("Antti Koivisto", ["koivisto@iki.fi", "antti@apple.com", "antti.j.koivisto@nokia.com"], "anttik"),
490     Reviewer("Ariya Hidayat", ["ariya.hidayat@gmail.com", "ariya@sencha.com", "ariya@webkit.org"], "ariya"),
491     Reviewer("Benjamin Poulain", ["benjamin@webkit.org", "benjamin.poulain@nokia.com", "ikipou@gmail.com"], "benjaminp"),
492     Reviewer("Beth Dakin", "bdakin@apple.com", "dethbakin"),
493     Reviewer("Brady Eidson", "beidson@apple.com", "bradee-oh"),
494     Reviewer("Brent Fulgham", "bfulgham@webkit.org", "bfulgham"),
495     Reviewer("Brian Weinstein", "bweinstein@apple.com", "bweinstein"),
496     Reviewer("Caio Marcelo de Oliveira Filho", ["cmarcelo@webkit.org", "caio.oliveira@openbossa.org"], "cmarcelo"),
497     Reviewer("Cameron Zwarich", ["zwarich@apple.com", "cwzwarich@apple.com", "cwzwarich@webkit.org"]),
498     Reviewer("Carlos Garcia Campos", ["cgarcia@igalia.com", "carlosgc@gnome.org", "carlosgc@webkit.org"], "KaL"),
499     Reviewer("Chang Shu", ["cshu@webkit.org", "c.shu@sisa.samsung.com"], "cshu"),
500     Reviewer("Chris Blumenberg", "cblu@apple.com", "cblu"),
501     Reviewer("Chris Marrin", "cmarrin@apple.com", "cmarrin"),
502     Reviewer("Chris Fleizach", "cfleizach@apple.com", "cfleizach"),
503     Reviewer("Chris Jerdonek", "cjerdonek@webkit.org", "cjerdonek"),
504     Reviewer("Chris Rogers", "crogers@google.com", "crogers"),
505     Reviewer(u"Csaba Osztrogon\u00e1c", "ossy@webkit.org", "ossy"),
506     Reviewer("Dan Bernstein", ["mitz@webkit.org", "mitz@apple.com"], "mitzpettel"),
507     Reviewer("Daniel Bates", ["dbates@webkit.org", "dbates@rim.com"], "dydz"),
508     Reviewer("Darin Adler", "darin@apple.com", "darin"),
509     Reviewer("Darin Fisher", ["fishd@chromium.org", "darin@chromium.org"], "fishd"),
510     Reviewer("David Harrison", "harrison@apple.com", "harrison"),
511     Reviewer("David Hyatt", "hyatt@apple.com", ["dhyatt", "hyatt"]),
512     Reviewer("David Kilzer", ["ddkilzer@webkit.org", "ddkilzer@apple.com"], "ddkilzer"),
513     Reviewer("David Levin", "levin@chromium.org", "dave_levin"),
514     Reviewer("Dean Jackson", "dino@apple.com", "dino"),
515     Reviewer("Dimitri Glazkov", "dglazkov@chromium.org", "dglazkov"),
516     Reviewer("Dirk Pranke", "dpranke@chromium.org", "dpranke"),
517     Reviewer("Dirk Schulze", "krit@webkit.org", "krit"),
518     Reviewer("Dmitry Titov", "dimich@chromium.org", "dimich"),
519     Reviewer("Don Melton", "gramps@apple.com", "gramps"),
520     Reviewer("Dumitru Daniliuc", "dumi@chromium.org", "dumi"),
521     Reviewer("Emil A Eklund", "eae@chromium.org", "eae"),
522     Reviewer("Enrica Casucci", "enrica@apple.com", "enrica"),
523     Reviewer("Eric Carlson", "eric.carlson@apple.com", "eric_carlson"),
524     Reviewer("Eric Seidel", "eric@webkit.org", "eseidel"),
525     Reviewer("Filip Pizlo", "fpizlo@apple.com", "pizlo"),
526     Reviewer("Gavin Barraclough", "barraclough@apple.com", "gbarra"),
527     Reviewer("Geoffrey Garen", "ggaren@apple.com", "ggaren"),
528     Reviewer("George Staikos", ["staikos@kde.org", "staikos@webkit.org"]),
529     Reviewer("Gustavo Noronha Silva", ["gns@gnome.org", "kov@webkit.org", "gustavo.noronha@collabora.co.uk", "gustavo.noronha@collabora.com"], "kov"),
530     Reviewer("Gyuyoung Kim", ["gyuyoung.kim@samsung.com", "gyuyoung.kim@webkit.org"], "gyuyoung"),
531     Reviewer("Hajime Morita", ["morrita@google.com", "morrita@chromium.org"], "morrita"),
532     Reviewer("Holger Freyther", ["zecke@selfish.org", "zecke@webkit.org"], "zecke"),
533     Reviewer("James Robinson", ["jamesr@chromium.org", "jamesr@google.com"], "jamesr"),
534     Reviewer("Jan Alonzo", ["jmalonzo@gmail.com", "jmalonzo@webkit.org"], "janm"),
535     Reviewer("Jeremy Orlow", ["jorlow@webkit.org", "jorlow@chromium.org"], "jorlow"),
536     Reviewer("Jessie Berlin", ["jberlin@webkit.org", "jberlin@apple.com"], "jessieberlin"),
537     Reviewer("Jian Li", "jianli@chromium.org", "jianli"),
538     Reviewer("Jocelyn Turcotte", ["jocelyn.turcotte@digia.com", "jocelyn.turcotte@nokia.com"], "jturcotte"),
539     Reviewer("Jochen Eisinger", "jochen@chromium.org", "jochen__"),
540     Reviewer("John Sullivan", "sullivan@apple.com", "sullivan"),
541     Reviewer("Jon Honeycutt", "jhoneycutt@apple.com", "jhoneycutt"),
542     Reviewer("Joseph Pecoraro", ["joepeck@webkit.org", "pecoraro@apple.com"], "JoePeck"),
543     Reviewer("Julien Chaffraix", ["jchaffraix@webkit.org", "julien.chaffraix@gmail.com", "jchaffraix@google.com", "jchaffraix@codeaurora.org"], "jchaffraix"),
544     Reviewer("Justin Garcia", "justin.garcia@apple.com", "justing"),
545     Reviewer("Ken Kocienda", "kocienda@apple.com"),
546     Reviewer("Kenneth Rohde Christiansen", ["kenneth@webkit.org", "kenneth.r.christiansen@intel.com", "kenneth.christiansen@gmail.com"], ["kenneth_", "kenneth", "kenne"]),
547     Reviewer("Kenneth Russell", ["kbr@google.com", "kbr@chromium.org"], ["kbr_google", "kbrgg"]),
548     Reviewer("Kent Tamura", ["tkent@chromium.org", "tkent@google.com"], "tkent"),
549     Reviewer("Kentaro Hara", ["haraken@chromium.org"], "haraken"),
550     Reviewer("Kevin Decker", "kdecker@apple.com", "superkevin"),
551     Reviewer("Kevin McCullough", "kmccullough@apple.com", "maculloch"),
552     Reviewer("Kevin Ollivier", ["kevino@theolliviers.com", "kevino@webkit.org"], "kollivier"),
553     Reviewer("Lars Knoll", ["lars@trolltech.com", "lars@kde.org", "lars.knoll@nokia.com"], "lars"),
554     Reviewer("Laszlo Gombos", ["laszlo.gombos@webkit.org", "l.gombos@samsung.com", "laszlo.1.gombos@nokia.com"], "lgombos"),
555     Reviewer("Levi Weintraub", ["leviw@chromium.org", "leviw@google.com", "lweintraub@apple.com"], "leviw"),
556     Reviewer("Luiz Agostini", ["luiz@webkit.org", "luiz.agostini@openbossa.org"], "lca"),
557     Reviewer("Maciej Stachowiak", "mjs@apple.com", "othermaciej"),
558     Reviewer("Mark Hahnenberg", "mhahnenberg@apple.com", "mhahnenberg"),
559     Reviewer("Mark Rowe", "mrowe@apple.com", "bdash"),
560     Reviewer("Martin Robinson", ["mrobinson@webkit.org", "mrobinson@igalia.com", "martin.james.robinson@gmail.com"], "mrobinson"),
561     Reviewer("Michael Saboff", "msaboff@apple.com", "msaboff"),
562     Reviewer("Mihai Parparita", "mihaip@chromium.org", "mihaip"),
563     Reviewer("Nate Chapin", "japhet@chromium.org", ["japhet", "natechapin"]),
564     Reviewer("Nikolas Zimmermann", ["zimmermann@kde.org", "zimmermann@physik.rwth-aachen.de", "zimmermann@webkit.org", "nzimmermann@rim.com"], "wildfox"),
565     Reviewer("Noam Rosenthal", ["noam@webkit.org", "noam.rosenthal@nokia.com"], "noamr"),
566     Reviewer("Ojan Vafai", ["ojan@chromium.org", "ojan.autocc@gmail.com"], "ojan"),
567     Reviewer("Oliver Hunt", "oliver@apple.com", "olliej"),
568     Reviewer("Pavel Feldman", ["pfeldman@chromium.org", "pfeldman@google.com"], "pfeldman"),
569     Reviewer("Philippe Normand", ["pnormand@igalia.com", "philn@webkit.org", "philn@igalia.com"], ["philn-tp", "pnormand"]),
570     Reviewer("Richard Williamson", "rjw@apple.com", "rjw"),
571     Reviewer("Rob Buis", ["rwlbuis@gmail.com", "rwlbuis@webkit.org", "rbuis@rim.com"], "rwlbuis"),
572     Reviewer("Ryosuke Niwa", "rniwa@webkit.org", "rniwa"),
573     Reviewer("Sam Weinig", ["sam@webkit.org", "weinig@apple.com"], "weinig"),
574     Reviewer("Shinichiro Hamaji", "hamaji@chromium.org", "hamaji"),
575     Reviewer("Simon Fraser", "simon.fraser@apple.com", "smfr"),
576     Reviewer("Simon Hausmann", ["hausmann@webkit.org", "hausmann@kde.org", "simon.hausmann@digia.com"], "tronical"),
577     Reviewer("Stephanie Lewis", "slewis@apple.com", "sundiamonde"),
578     Reviewer("Stephen White", "senorblanco@chromium.org", "senorblanco"),
579     Reviewer("Steve Block", ["steveblock@chromium.org", "steveblock@google.com"], "steveblock"),
580     Reviewer("Steve Falkenburg", "sfalken@apple.com", "sfalken"),
581     Reviewer("Tim Omernick", "timo@apple.com"),
582     Reviewer("Timothy Hatcher", ["timothy@apple.com", "timothy@hatcher.name"], "xenon"),
583     Reviewer("Tim Horton", "timothy_horton@apple.com", "thorton"),
584     Reviewer("Tony Chang", "tony@chromium.org", "tony^work"),
585     Reviewer("Tony Gentilcore", "tonyg@chromium.org", "tonyg-cr"),
586     Reviewer(u"Tor Arne Vestb\u00f8", ["vestbo@webkit.org", "tor.arne.vestbo@nokia.com"], "torarne"),
587     Reviewer("Vicki Murley", "vicki@apple.com"),
588     Reviewer("Vsevolod Vlasov", "vsevik@chromium.org", "vsevik"),
589     Reviewer("Xan Lopez", ["xan.lopez@gmail.com", "xan@gnome.org", "xan@webkit.org", "xlopez@igalia.com"], "xan"),
590     Reviewer("Yong Li", ["yoli@rim.com", "yong.li.webkit@gmail.com"], "yoli"),
591     Reviewer("Yury Semikhatsky", "yurys@chromium.org", "yurys"),
592     Reviewer("Yuta Kitamura", "yutak@chromium.org", "yutak"),
593     Reviewer("Zack Rusin", "zack@kde.org", "zackr"),
594     Reviewer("Zoltan Herczeg", ["zherczeg@webkit.org", "zherczeg@inf.u-szeged.hu"], "zherczeg"),
595 ]
596
597 class CommitterList(object):
598
599     # Committers and reviewers are passed in to allow easy testing
600     def __init__(self,
601                  committers=committers_unable_to_review,
602                  reviewers=reviewers_list,
603                  contributors=contributors_who_are_not_committers,
604                  watchers=watchers_who_are_not_contributors):
605         self._accounts = watchers + contributors + committers + reviewers
606         self._contributors = contributors + committers + reviewers
607         self._committers = committers + reviewers
608         self._reviewers = reviewers
609         self._contributors_by_name = {}
610         self._accounts_by_email = {}
611         self._accounts_by_login = {}
612
613     def accounts(self):
614         return self._accounts
615
616     def contributors(self):
617         return self._contributors
618
619     def committers(self):
620         return self._committers
621
622     def reviewers(self):
623         return self._reviewers
624
625     def _name_to_contributor_map(self):
626         if not len(self._contributors_by_name):
627             for contributor in self._contributors:
628                 assert(contributor.full_name)
629                 assert(contributor.full_name.lower() not in self._contributors_by_name)  # We should never have duplicate names.
630                 self._contributors_by_name[contributor.full_name.lower()] = contributor
631         return self._contributors_by_name
632
633     def _email_to_account_map(self):
634         if not len(self._accounts_by_email):
635             for account in self._accounts:
636                 for email in account.emails:
637                     assert(email not in self._accounts_by_email)  # We should never have duplicate emails.
638                     self._accounts_by_email[email] = account
639         return self._accounts_by_email
640
641     def _login_to_account_map(self):
642         if not len(self._accounts_by_login):
643             for account in self._accounts:
644                 if account.emails:
645                     login = account.bugzilla_email()
646                     assert(login not in self._accounts_by_login)  # We should never have duplicate emails.
647                     self._accounts_by_login[login] = account
648         return self._accounts_by_login
649
650     def _contributor_only(self, record):
651         if record and not record.is_contributor:
652             return None
653         return record
654
655     def _committer_only(self, record):
656         if record and not record.can_commit:
657             return None
658         return record
659
660     def _reviewer_only(self, record):
661         if record and not record.can_review:
662             return None
663         return record
664
665     def committer_by_name(self, name):
666         return self._committer_only(self.contributor_by_name(name))
667
668     def contributor_by_irc_nickname(self, irc_nickname):
669         for contributor in self.contributors():
670             # FIXME: This should do case-insensitive comparison or assert that all IRC nicknames are in lowercase
671             if contributor.irc_nicknames and irc_nickname in contributor.irc_nicknames:
672                 return contributor
673         return None
674
675     def contributors_by_search_string(self, string):
676         glob_matches = filter(lambda contributor: contributor.matches_glob(string), self.contributors())
677         return glob_matches or filter(lambda contributor: contributor.contains_string(string), self.contributors())
678
679     def contributors_by_email_username(self, string):
680         string = string + '@'
681         result = []
682         for contributor in self.contributors():
683             for email in contributor.emails:
684                 if email.startswith(string):
685                     result.append(contributor)
686                     break
687         return result
688
689     def _contributor_name_shorthands(self, contributor):
690         if ' ' not in contributor.full_name:
691             return []
692         split_fullname = contributor.full_name.split()
693         first_name = split_fullname[0]
694         last_name = split_fullname[-1]
695         return first_name, last_name, first_name + last_name[0], first_name + ' ' + last_name[0]
696
697     def _tokenize_contributor_name(self, contributor):
698         full_name_in_lowercase = contributor.full_name.lower()
699         tokens = [full_name_in_lowercase] + full_name_in_lowercase.split()
700         if contributor.irc_nicknames:
701             return tokens + [nickname.lower() for nickname in contributor.irc_nicknames if len(nickname) > 5]
702         return tokens
703
704     def contributors_by_fuzzy_match(self, string):
705         string_in_lowercase = string.lower()
706
707         # 1. Exact match for fullname, email and irc_nicknames
708         account = self.contributor_by_name(string_in_lowercase) or self.account_by_email(string_in_lowercase) or self.contributor_by_irc_nickname(string_in_lowercase)
709         if account:
710             return [account], 0
711
712         # 2. Exact match for email username (before @)
713         accounts = self.contributors_by_email_username(string_in_lowercase)
714         if accounts and len(accounts) == 1:
715             return accounts, 0
716
717         # 3. Exact match for first name, last name, and first name + initial combinations such as "Dan B" and "Tim H"
718         accounts = [contributor for contributor in self.contributors() if string in self._contributor_name_shorthands(contributor)]
719         if accounts and len(accounts) == 1:
720             return accounts, 0
721
722         # 4. Finally, fuzzy-match using edit-distance
723         string = string_in_lowercase
724         contributorWithMinDistance = []
725         minDistance = len(string) / 2 - 1
726         for contributor in self.contributors():
727             tokens = self._tokenize_contributor_name(contributor)
728             editdistances = [edit_distance(token, string) for token in tokens if abs(len(token) - len(string)) <= minDistance]
729             if not editdistances:
730                 continue
731             distance = min(editdistances)
732             if distance == minDistance:
733                 contributorWithMinDistance.append(contributor)
734             elif distance < minDistance:
735                 contributorWithMinDistance = [contributor]
736                 minDistance = distance
737         if not len(contributorWithMinDistance):
738             return [], len(string)
739         return contributorWithMinDistance, minDistance
740
741     def account_by_login(self, login):
742         return self._login_to_account_map().get(login.lower()) if login else None
743
744     def account_by_email(self, email):
745         return self._email_to_account_map().get(email.lower()) if email else None
746
747     def contributor_by_name(self, name):
748         return self._name_to_contributor_map().get(name.lower()) if name else None
749
750     def contributor_by_email(self, email):
751         return self._contributor_only(self.account_by_email(email))
752
753     def committer_by_email(self, email):
754         return self._committer_only(self.account_by_email(email))
755
756     def reviewer_by_email(self, email):
757         return self._reviewer_only(self.account_by_email(email))