Skip to content

Commit 723df30

Browse files
committed
#479 - Working in Progress to work on scancode scan as the input
* Added a license score field * Trying to create a custom template for the scancode input Note that it's not working as the template is becoming so complex which is very hard to use and understand. In addition, the the list for the license score and license name doesn't seem to sync correctly. In order to solve it, instead of digging deep to create a more complex code and template, we need to use a license object to "group" all the licenses. Signed-off-by: Chin Yeung Li <[email protected]>
1 parent 9e3c3ad commit 723df30

File tree

7 files changed

+152
-9
lines changed

7 files changed

+152
-9
lines changed

src/attributecode/attrib.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ def generate(abouts, is_about_input, license_dict, min_license_score, template=N
114114
# Add the license name expression string into the about object as a list
115115
about.license_name_expression = lic_name_expression
116116

117+
# Sort the license object by key
118+
licenses_list = sorted(licenses_list, key=lambda x: x.key)
119+
117120
rendered = template.render(
118121
abouts=abouts,
119122
common_licenses=COMMON_LICENSES,

src/attributecode/gen.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,17 @@ def load_inventory(location, from_attrib=False, base_dir=None, scancode=False, r
226226
if not e in errors:
227227
errors.extend(ld_errors)
228228
abouts.append(about)
229-
229+
# Covert the license_score value from string to list of int
230+
# The licesne_score is not in the spec but is specify in the scancode license scan.
231+
# This key will be treated as a custom string field. Therefore, we need to
232+
# convert back to the list with float type for score.
233+
if scancode:
234+
for about in abouts:
235+
try:
236+
score_list = list(map(float, about.license_score.value.replace('[', '').replace(']', '').split(',')))
237+
about.license_score.value = score_list
238+
except:
239+
pass
230240
return unique(errors), abouts
231241

232242

src/attributecode/model.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,7 @@ def load_dict(self, fields_dict, base_dir, from_attrib=False, running_inventory=
10291029
continue
10301030
if key == u'licenses':
10311031
# FIXME: use a license object instead
1032-
lic_key, lic_name, lic_file, lic_url = ungroup_licenses(value)
1032+
lic_key, lic_name, lic_file, lic_url, lic_score = ungroup_licenses(value)
10331033
if lic_key:
10341034
fields.append(('license_key', lic_key))
10351035
if lic_name:
@@ -1038,6 +1038,9 @@ def load_dict(self, fields_dict, base_dir, from_attrib=False, running_inventory=
10381038
fields.append(('license_file', lic_file))
10391039
if lic_url:
10401040
fields.append(('license_url', lic_url))
1041+
# The license score is a key from scancode license scan
1042+
if lic_score:
1043+
fields.append(('license_score', lic_score))
10411044
# The licenses field has been ungrouped and can be removed.
10421045
# Otherwise, it will gives the following INFO level error
10431046
# 'Field licenses is a custom field.'

src/attributecode/util.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ def ungroup_licenses(licenses):
472472
lic_name = []
473473
lic_file = []
474474
lic_url = []
475+
lic_score = []
475476
for lic in licenses:
476477
if 'key' in lic:
477478
lic_key.append(lic['key'])
@@ -481,7 +482,9 @@ def ungroup_licenses(licenses):
481482
lic_file.append(lic['file'])
482483
if 'url' in lic:
483484
lic_url.append(lic['url'])
484-
return lic_key, lic_name, lic_file, lic_url
485+
if 'score' in lic:
486+
lic_score.append(lic['score'])
487+
return lic_key, lic_name, lic_file, lic_url, lic_score
485488

486489

487490
# FIXME: add docstring

templates/default_html.template

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
{#
2-
about object and license dictionary are passed.
3-
See https://scancode-licensedb.aboutcode.org/
4-
Read the JSON file to see what information can be extracted from the licenses.
5-
#}
61
<!doctype html>
72
<html>
83
<head>

templates/scancode_html.template

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<style type="text/css">
5+
div.additional-license-text-list {display:block}
6+
body {font-family: Helvetica, Arial, sans-serif;}
7+
pre {white-space: pre-wrap;}
8+
</style>
9+
<title>Open Source Software Information</title>
10+
</head>
11+
12+
<body>
13+
<h1>OPEN SOURCE SOFTWARE INFORMATION</h1>
14+
<h2> {{ variables['subtitle'] }} </h2>
15+
<div>
16+
<p>Licenses, acknowledgments and required copyright notices for
17+
open source components:</p>
18+
</div>
19+
20+
<div class="oss-table-of-contents">
21+
{% set index = namespace(value=0) %}
22+
{% for about_object in abouts %}
23+
{% set captured = {} %}
24+
{% if about_object.license_expression.value %}
25+
{% for lic_score in about_object.license_score.value %}
26+
{% if lic_score | float >= min_license_score %}
27+
{% if not captured[about_object.name.value] %}
28+
<p><a href="#component_{{ index.value }}">{{ about_object.name.value }}{% if about_object.version.value %} {{ about_object.version.value }}{% endif %}</a></p>
29+
{% set _ = captured.update({ about_object.name.value: true }) %}
30+
{% set index.value = index.value + 1 %}
31+
{% endif %}
32+
{% endif %}
33+
{% endfor %}
34+
{% endif %}
35+
{% endfor %}
36+
</div>
37+
38+
<hr/>
39+
40+
{% set common_licenses_meet_score = {} %}
41+
{% set index = namespace(value=0) %}
42+
{% for about_object in abouts %}
43+
{% set captured = {} %}
44+
{% if about_object.license_expression.value %}
45+
{% set count = namespace(value=0) %}
46+
{{ about_object.license_key.value }}
47+
{{ about_object.license_score.value }}
48+
{% for lic_score in about_object.license_score.value %}
49+
{% if lic_score | float >= min_license_score %}
50+
{% if not captured[about_object.name.value] %}
51+
<div class="oss-component" id="component_{{ index.value }}">
52+
<h3 class="component-name">{{ about_object.name.value }} {% if about_object.version.value %}{{ about_object.version.value }}{% endif %} </h3>
53+
{% set _ = captured.update({ about_object.name.value: true }) %}
54+
{% set index.value = index.value + 1 %}
55+
{% endif %}
56+
<p>This component is licensed under {{ about_object.license_name.value[count.value] }}</p>
57+
{% endif %}
58+
{% set count.value = count.value + 1 %}
59+
{% endfor %}
60+
{% if about_object.copyright.value %}
61+
<pre>{{about_object.copyright.value}}</pre>
62+
{% endif %}
63+
{% if about_object.notice_file.value %}
64+
{% for notice in about_object.notice_file.value %}
65+
<pre class="component-notice">{{ about_object.notice_file.value[notice] }}</pre>
66+
{% endfor %}
67+
{% endif %}
68+
{% if about_object.license_key.value %}
69+
{% if about_object.license_file.value %}
70+
{% for lic_file_name in about_object.license_file.value %}
71+
{% for license in licenses_list %}
72+
{% if license.filename == lic_file_name %}
73+
{% if not license.key in common_licenses %}
74+
<pre> {{ license.text | e}} </pre>
75+
{% endif %}
76+
{% endif %}
77+
{% endfor %}
78+
{% endfor %}
79+
{% else %}
80+
{% set count = namespace(value=0) %}
81+
{% for lic_score in about_object.license_score.value %}
82+
{% if lic_score | float >= min_license_score %}
83+
{% if about_object.license_key.value[count.value] in common_licenses %}
84+
{% if not about_object.license_key.value[count.value] in common_licenses_meet_score %}
85+
{% set _ = common_licenses_meet_score.update({ about_object.license_key.value[count.value]: true }) %}
86+
<p>Full text of <a class="{{ about_object.license_key.value[count.value] }}" href="#component-license-{{ about_object.license_key.value[count.value] }}"> {{ about_object.license_key.value[count.value] }}</a> is available at the end of this document.</p>
87+
{% endif %}
88+
{% else %}
89+
{% for license in licenses_list %}
90+
{% if about_object.license_key.value[count.value] == license.key %}
91+
<h3 id="component-license-{{ license.key }}">{{ license.key }}</h3>
92+
<pre> {{ license.text | e }} </pre>
93+
{% endif %}
94+
{% endfor %}
95+
{% endif %}
96+
{% endif %}
97+
{% endfor %}
98+
{% endif %}
99+
{% else %}
100+
{% if about_object.license_file.value %}
101+
{% for lic_file_name in about_object.license_file.value %}
102+
{% if about_object.license_file.value[lic_file_name] %}
103+
<pre> {{ about_object.license_file.value[lic_file_name] | e}} </pre>
104+
{% endif %}
105+
{% endfor %}
106+
{% endif %}
107+
{% endif %}
108+
{% endif %}
109+
</div>
110+
{% endfor %}
111+
112+
<hr/>
113+
114+
<h3>Common Licenses Used in This Product</h3>
115+
{% for license in licenses_list %}
116+
{% if license.key in common_licenses %}
117+
{% if license.key in common_licenses_meet_score %}
118+
<h3 id="component-license-{{ license.key }}">{{ license.key }}</h3>
119+
<pre> {{ license.text | e }} </pre>
120+
{% endif %}
121+
{% endif %}
122+
{% endfor %}
123+
124+
<h3><a id="End">End</a></h3>
125+
126+
<i>This file was generated with AttributeCode version: {{ tkversion }} on: {{ utcnow }} (UTC)</i>
127+
</body>
128+
</html>
129+

tests/test_util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ def test_ungroup_licenses(self):
569569
expected_lic_url = [
570570
u'https://enterprise.dejacode.com/urn/?urn=urn:dje:license:mit',
571571
u'https://enterprise.dejacode.com/urn/?urn=urn:dje:license:bsd-new']
572-
lic_key, lic_name, lic_file, lic_url = util.ungroup_licenses(about)
572+
lic_key, lic_name, lic_file, lic_url, lic_score = util.ungroup_licenses(about)
573573
assert expected_lic_key == lic_key
574574
assert expected_lic_name == lic_name
575575
assert expected_lic_file == lic_file

0 commit comments

Comments
 (0)