summaryrefslogtreecommitdiffstats
path: root/Doc/tools
diff options
context:
space:
mode:
authorFred Drake <fdrake@acm.org>2000-10-03 22:10:25 (GMT)
committerFred Drake <fdrake@acm.org>2000-10-03 22:10:25 (GMT)
commit1654b43ef79f81ce1ae6049f93db4a68f8408e3d (patch)
treeb3b2958a7b5fe0d066275ffba516a3e0f7b82c24 /Doc/tools
parent5b4c22806fe6bdd7cb2d6c01e0a09e10c90be0bc (diff)
downloadcpython-1654b43ef79f81ce1ae6049f93db4a68f8408e3d.zip
cpython-1654b43ef79f81ce1ae6049f93db4a68f8408e3d.tar.gz
cpython-1654b43ef79f81ce1ae6049f93db4a68f8408e3d.tar.bz2
Preliminary tool to troll through the CVS logs and LaTeX sources for
the names of people that should be in the ACKS file. This relies on some personal code that is not yet available, but should be by the time we release 2.0c1.
Diffstat (limited to 'Doc/tools')
-rwxr-xr-xDoc/tools/findacks162
1 files changed, 162 insertions, 0 deletions
diff --git a/Doc/tools/findacks b/Doc/tools/findacks
new file mode 100755
index 0000000..d35859b
--- /dev/null
+++ b/Doc/tools/findacks
@@ -0,0 +1,162 @@
+#!/usr/bin/env python
+"""Script to locate email addresses in the CVS logs."""
+__version__ = '$Revision$'
+
+import os
+import re
+import sys
+import UserDict
+
+import fdrake.cvstools.info
+cvstools = fdrake.cvstools
+
+
+class Acknowledgements(UserDict.UserDict):
+ def add(self, email, name, path):
+ d = self.data
+ d.setdefault(email, {})[path] = name
+
+
+def open_cvs_log(info, paths=None):
+ cvsroot = info.get_cvsroot()
+ cmd = "cvs -q -d%s log " % cvsroot
+ if paths:
+ cmd += " ".join(paths)
+ return os.popen(cmd, "r")
+
+
+email_rx = re.compile("<([a-z][-a-z0-9._]*@[-a-z0-9.]+)>", re.IGNORECASE)
+
+def find_acks(f, acks):
+ prev = ''
+ filename = None
+ MAGIC_WORDS = ('van', 'von')
+ while 1:
+ line = f.readline()
+ if not line:
+ break
+ if line.startswith("Working file: "):
+ filename = line.split(None, 2)[2].strip()
+ prev = line
+ continue
+ m = email_rx.search(line)
+ if m:
+ words = prev.split() + line[:m.start()].split()
+ L = []
+ while words \
+ and (words[-1][0].isupper() or words[-1] in MAGIC_WORDS):
+ L.insert(0, words.pop())
+ name = " ".join(L)
+ email = m.group(1).lower()
+ acks.add(email, name, filename)
+ prev = line
+
+
+def load_cvs_log_acks(acks, args):
+ repolist = cvstools.info.get_repository_list(args or [""])
+ for info, paths in repolist:
+ print >>sys.stderr, "Repository:", info.get_cvsroot()
+ f = open_cvs_log(info, paths)
+ find_acks(f, acks)
+ f.close()
+
+
+def load_tex_source_acks(acks, args):
+ for path in args:
+ path = path or os.curdir
+ if os.path.isfile(path):
+ read_acks_from_tex_file(acks, path)
+ else:
+ read_acks_from_tex_dir(acks, path)
+
+
+def read_acks_from_tex_file(acks, path):
+ f = open(path)
+ while 1:
+ line = f.readline()
+ if not line:
+ break
+ if line.startswith(r"\sectionauthor{"):
+ line = line[len(r"\sectionauthor"):]
+ name, line = extract_tex_group(line)
+ email, line = extract_tex_group(line)
+ acks.add(email, name, path)
+
+
+def read_acks_from_tex_dir(acks, path):
+ stack = [path]
+ while stack:
+ p = stack.pop()
+ for n in os.listdir(p):
+ n = os.path.join(p, n)
+ if os.path.isdir(n):
+ stack.insert(0, n)
+ elif os.path.normpath(n).endswith(".tex"):
+ read_acks_from_tex_file(acks, n)
+
+
+def extract_tex_group(s):
+ c = 0
+ for i in range(len(s)):
+ if s[i] == '{':
+ c += 1
+ elif s[i] == '}':
+ c -= 1
+ if c == 0:
+ return s[1:i], s[i+1:]
+
+
+def print_acks(acks):
+ first = 1
+ for email, D in acks.items():
+ if first:
+ first = 0
+ else:
+ print
+ L = D.items()
+ L.sort()
+ prefname = L[0][1]
+ for file, name in L[1:]:
+ if name != prefname:
+ prefname = ""
+ break
+ if prefname:
+ print prefname, "<%s>:" % email
+ else:
+ print email + ":"
+ for file, name in L:
+ if name == prefname:
+ print " " + file
+ else:
+ print " %s (as %s)" % (file, name)
+
+
+def print_ack_names(acks):
+ names = []
+ for email, D in acks.items():
+ L = D.items()
+ L.sort()
+ prefname = L[0][1]
+ for file, name in L[1:]:
+ prefname = prefname or name
+ names.append(prefname or email)
+ def f(s1, s2):
+ s1 = s1.lower()
+ s2 = s2.lower()
+ return cmp((s1.split()[-1], s1),
+ (s2.split()[-1], s2))
+ names.sort(f)
+ for name in names:
+ print name
+
+
+def main():
+ args = sys.argv[1:]
+ acks = Acknowledgements()
+ load_cvs_log_acks(acks, args)
+ load_tex_source_acks(acks, args)
+ print_ack_names(acks)
+
+
+if __name__ == "__main__":
+ main()