#!/usr/bin/python3 import os import sys default_copyright = 'The Qt Company Ltd.' default_licenses = ( 'BSD-3-clause', 'LGPL-3 or GPL-2', 'GPL-3 with Qt-1.0 exception', 'GFDL-NIV-1.3', ) licenses_map = { 'BSD': 'BSD-3-clause', 'FDL': 'GFDL-NIV-1.3', 'GPL-EXCEPT': 'GPL-3 with Qt-1.0 exception', 'LGPL': 'LGPL-3 or GPL-2', 'LGPL21': 'LGPL-2.1-or-3 with Qt-1.1 exception', 'LGPL3': 'LGPL-3 or GPL-2+', 'LGPL3-COMM': 'LGPL-3', } exclude_prefixes = ( 'header', '.git', ) start_header = '## BEGIN AUTO GENERATED BLOCK' end_header = '## END AUTO GENERATED BLOCK' class CopyrightInfo(): def __init__(self): self.min_years = {} self.max_years = {} self.files = [] def add_file(self, authors, file): for min_year, max_year, author in authors: if author in self.min_years: self.min_years[author] = min(self.min_years[author], min_year) else: self.min_years[author] = min_year if author in self.max_years: self.max_years[author] = max(self.max_years[author], max_year) else: self.max_years[author] = max_year self.files.append(file) def get_strings(self, authors): for author in authors: min_year = self.min_years[author] max_year = self.max_years[author] if min_year == max_year: yield '%d %s' % (min_year, author) else: yield '%d-%d %s' % (min_year, max_year, author) def canonicalize_author_name(author): if 'The Qt Company.' in author: return 'The Qt Company Ltd.' if 'KDAB' in author: return 'Klarälvdalens Datakonsult AB, a KDAB Group company' if 'BlackBerry' in author: return 'BlackBerry Limited (formerly Research In Motion)' if 'Research In Motion' in author or 'Research in Motion' in author: return 'BlackBerry Limited (formerly Research In Motion)' if 'Green Hills Software' in author: return 'Green Hills Software' if 'Ivan Komissarov' in author: return 'Ivan Komissarov ' if 'Martsum - tmartsum[at]gmail.com' in author: return 'Thorbjørn Lund Martsum ' if 'Olivier Goffart' in author: return 'Olivier Goffart ' if 'Robin Burchell' in author: return 'Robin Burchell ' return author def parse_file(filename): print(filename, file=sys.stderr) license = None authors = [] with open(filename) as file: try: data = file.readlines(500) except UnicodeDecodeError: return None, None for line in data: if line[3:16] == 'Copyright (C)' and line[0] != ' ': copyright = line[17:-1] max_year = min_year = int(copyright[:4]) if copyright[4] == '-': max_year = int(copyright[5:9]) author = copyright[10:] elif copyright[4:7] == ' - ': max_year = int(copyright[7:11]) author = copyright[12:] else: author = copyright[5:] author = canonicalize_author_name(author) authors.append((min_year, max_year, author)) if line[3:21] == '$QT_BEGIN_LICENSE:': license = licenses_map[line[21:-2]] return license, authors def get_source_files(root_directory): for dirpath, dirnames, filenames in os.walk(root_directory): for filename in filenames: full_path = os.path.join(dirpath, filename) if full_path.startswith('./'): full_path = full_path[2:] if any(full_path.startswith(prefix) for prefix in exclude_prefixes): continue yield full_path def format_list(title, strings): return title + ('\n' + ' ' * len(title)).join(strings) def main(root_directory): with open('debian/copyright') as copyright_file: current_copyright = copyright_file.read() start_pos = current_copyright.find(start_header) + len(start_header) + 1 start_data = current_copyright[:start_pos] end_pos = current_copyright.find(end_header) - 1 end_data = current_copyright[end_pos:] with open('debian/copyright', 'w') as output_file: output_file.write(start_data) write_output(root_directory, output_file) output_file.write(end_data) def write_output(root_directory, output_file): data = {} for filename in get_source_files(root_directory): license, authors = parse_file(filename) if license is None: continue if license not in data: data[license] = {} license_dict = data[license] authors_tuple = tuple(sorted(author[2] for author in authors)) if authors_tuple not in license_dict: license_dict[authors_tuple] = CopyrightInfo() license_dict[authors_tuple].add_file(authors, filename) for license in sorted(data.keys()): output_file.write('\n## ' + license + '\n') license_dict = data[license] for authors in sorted(license_dict.keys()): if authors == (default_copyright,) and license in default_licenses: continue copyright_info = license_dict[authors] output_file.write('\n') output_file.write(format_list('Files: ', sorted(copyright_info.files)) + '\n') output_file.write(format_list('Copyright: ', copyright_info.get_strings(authors)) + '\n') output_file.write('License: ' + license + '\n') if __name__ == '__main__': main('.')