+#!/usr/bin/env python
+#
+# Copyright (C) 2013 W. Trevor King <wking@tremily.us>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program. If not, see
+# <http://www.gnu.org/licenses/>.
+
+import glob as _glob
+import logging as _logging
+
+import portage as _portage
+import portage.dep as _portage_dep
+import portage.versions as _portage_versions
+
+
+def get_db():
+ """Get a database of installed packages
+ """
+ db = _portage.db
+ for key in ['/', 'vartree']:
+ if key not in db:
+ raise KeyError('{0} not found (choices: {1})'.format(
+ key, list(db.keys())))
+ db = db[key]
+ return db
+
+def get_license_lists():
+ """Iterate through installed packages with licenses
+
+ Yields (category-package-version, license-list) tuples
+ """
+ db = get_db()
+ for cpv in db.dbapi.cpv_all():
+ licenses,use = db.dbapi.aux_get(cpv, ['LICENSE', 'USE'])
+ category = _portage_versions.catsplit(cpv)[0]
+ if category == 'virtual':
+ if licenses:
+ _logging.warn('license for {0}: {1}'.format(cpv, licenses))
+ continue
+ elif not licenses:
+ _logging.warn('no license for {0}'.format(cpv))
+ continue
+ license_list = _portage_dep.use_reduce(
+ licenses, uselist=use, opconvert=True)
+ yield (cpv, license_list)
+
+def incorperate_or_dependencies(license_set, or_dependencies):
+ while or_dependencies:
+ or_dependencies = set(
+ or_set for or_set in or_dependencies
+ if not license_set.union(or_set))
+ if or_dependencies:
+ raise NotImplementedError('select best subset of or_dependencies')
+ return license_set
+
+def get_all_licenses():
+ license_set = set()
+ or_dependencies = set()
+ for cpv,license_list in get_license_lists():
+ for token in license_list:
+ if isinstance(token, str):
+ license_set.add(token)
+ elif token[0] == '||':
+ or_dependencies.add(tuple(token[1:]))
+ else:
+ raise NotImplementedError((licenses, token))
+ license_set = incorperate_or_dependencies(license_set, or_dependencies)
+ return license_set
+
+
+if __name__ == '__main__':
+ licenses = get_all_licenses()
+ print('\n'.join(sorted(licenses)))