00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 from __future__ import with_statement
00037
00038 import cStringIO
00039 import time
00040
00041 import roslib.rospack
00042
00043 from rosdoc.rdcore import *
00044
00045 canonicalize = {
00046 'lgpl': 'LGPL',
00047 'unknown': 'Unknown',
00048 'BSD and GPL': 'BSD/GPL',
00049 'Commercial': 'Proprietary',
00050 'Closed': 'Commercial',
00051 'BSD.': 'BSD',
00052 'new BSD': 'BSD (new)',
00053 'GPL v3': "GPLv3",
00054 'GNU GPL V3': 'GPLv3',
00055 'GPL 3.0': 'GPLv3',
00056 '?': 'Unknown',
00057 }
00058
00059 bsdstyle = ['bsd', 'bsd-style', 'new bsd', 'bsd (new)', 'zlib', 'zlib-style', 'mit', 'wxwindows', 'lgpl', 'free', 'python', 'python-style', 'bsl1.0', 'boost', 'apache', 'apache license, version 2.0', 'boost software license', 'public domain', 'apache license', 'BSD, Boost Software License (Poco)', 'BSD, Boost']
00060 contaminated = ['gpl', 'creativecommons-by-nc-sa-2.0', 'commercial', 'proprietary']
00061
00062 _already_unknown = []
00063
00064 contam_suffix = " (contaminated)"
00065
00066
00067 license_urls = {
00068 'boost': 'http://www.boost.org/users/license.html',
00069 'bsl1.0': 'http://www.boost.org/LICENSE_1_0.txt',
00070 'boost software license': 'http://www.boost.org/users/license.html',
00071 'mit': 'http://www.opensource.org/licenses/mit-license.php',
00072 'new bsd': 'http://www.opensource.org/licenses/bsd-license.php',
00073 'bsd': 'http://www.opensource.org/licenses/bsd-license.php',
00074 'zlib': 'http://www.gzip.org/zlib/zlib_license.html',
00075 'lgpl': 'http://www.opensource.org/licenses/lgpl-2.1.php',
00076 'lgplv3': 'http://www.opensource.org/licenses/lgpl-3.0.html',
00077 'gpl': 'http://www.opensource.org/licenses/gpl-2.0.php',
00078 'gplv3': 'http://www.opensource.org/licenses/gpl-3.0.html',
00079 'nosa': 'http://www.opensource.org/licenses/nasa1.3.php',
00080 'creativecommons-by-nc-sa-2.0': 'http://creativecommons.org/licenses/by-nc-sa/2.0/',
00081 }
00082
00083 license_template = load_tmpl('license-index.html')
00084
00085
00086
00087
00088
00089
00090 def _check_contaminated(package, license, manifests):
00091 depslist = roslib.rospack.rospackexec(['deps', package])
00092 blame = []
00093 for dep in [d for d in depslist.split('\n') if d]:
00094 m = manifests[dep]
00095 dl = m.license or 'unknown'
00096 dl = dl.lower()
00097 if dl not in bsdstyle:
00098 blame.append(dep)
00099 if 0:
00100 if dl in contaminated:
00101 blame.append(dep)
00102 elif not dl in bsdstyle:
00103 if not dl in _already_unknown:
00104 print "UNKNOWN", dl
00105 _already_unknown.append(dl)
00106 if blame:
00107 return license + contam_suffix, blame
00108 else:
00109 return license, blame
00110
00111
00112
00113 def _generate_licenses_map(ctx):
00114 blamelist = {}
00115 licenses = {}
00116 licenses['unknown'] = []
00117
00118 manifests = ctx.manifests
00119
00120 for package in ctx.doc_packages:
00121
00122 if not package in manifests:
00123 licenses['unknown'].append(package)
00124 continue
00125
00126 manifest = manifests[package]
00127 license = manifest.license or 'unknown'
00128 license = canonicalize.get(license, license)
00129
00130 if 'Copyright' in license:
00131 license = 'unknown'
00132 license_url = manifest.license_url
00133 if license_url and not license in license_urls:
00134 license_urls[license.lower()] = license_url
00135 if license.lower() in bsdstyle:
00136 license, blame = _check_contaminated(package, license, manifests)
00137 if blame:
00138 blamelist[package] = blame
00139 if license in licenses:
00140 licenses[license].append(package)
00141 else:
00142 licenses[license] = [package]
00143 return licenses, blamelist
00144
00145
00146
00147
00148
00149 def li_license_links(packages, blamelist, docdir):
00150 list = []
00151 for p in packages:
00152 path = html_path(p, docdir)
00153 blame = blamelist.get(p, None)
00154 blamestr = ': (%s)'%(', '.join(blame)) if blame else ''
00155 list.append(' <li><a href="%s/index.html">%s</a>%s</li>'%(path, p, blamestr))
00156 return '<ul>\n'+'\n'.join(list)+'</ul>\n'
00157
00158
00159
00160 def generate_license_index(ctx):
00161 docdir = ctx.docdir
00162 license_index = os.path.join(docdir, 'licenses.html')
00163
00164 licenses, blamelist = _generate_licenses_map(ctx)
00165
00166 buff = cStringIO.StringIO()
00167 keys = licenses.keys()
00168 keys.sort()
00169
00170 strs = ['<a href="#%s">%s</a> (%s)'%(k, k, len(licenses[k])) for k in keys if licenses[k]]
00171 contents = ', '.join(strs)
00172
00173 for license in keys:
00174 list = licenses[license]
00175 if not list:
00176 continue
00177
00178
00179
00180 real_license = license[:-len(contam_suffix)] if license.endswith(contam_suffix) else license
00181 real_license = real_license.lower()
00182 if real_license in license_urls:
00183 buff.write('<h3><a name="%s"></a><a href="%s">%s</a></h2>\n'%\
00184 (license, license_urls[real_license], license))
00185 else:
00186 buff.write('<h3><a name="%s"></a>%s</h2>\n'%(license, license))
00187 list.sort()
00188 buff.write(li_license_links(list, blamelist, docdir))
00189
00190 vars = {'$name': ctx.name, '$licenselist' : buff.getvalue(),
00191 '$date': time.strftime("%a, %d %b %Y %H:%M:%S"), '$toc': contents }
00192 with open(license_index, 'w') as f:
00193 f.write(instantiate_template(license_template, vars))
00194 return [license_index]