From 1654b43ef79f81ce1ae6049f93db4a68f8408e3d Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Tue, 3 Oct 2000 22:10:25 +0000 Subject: 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. --- Doc/tools/findacks | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100755 Doc/tools/findacks 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() -- cgit v0.12