mirror of
				https://github.com/python/cpython.git
				synced 2025-10-26 11:14:33 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			161 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			161 lines
		
	
	
	
		
			3.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #!/usr/bin/env python
 | |
| """Script to locate email addresses in the CVS logs."""
 | |
| __version__ = '$Revision$'
 | |
| 
 | |
| import os
 | |
| import re
 | |
| import sys
 | |
| import UserDict
 | |
| 
 | |
| import cvsinfo
 | |
| 
 | |
| 
 | |
| 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 = cvsinfo.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()
 | 
