Skip to content

Commit 6b728ac

Browse files
committed
Added licence and package flag summary pages
1 parent 5dff90e commit 6b728ac

File tree

9 files changed

+735
-0
lines changed

9 files changed

+735
-0
lines changed

scriptmodules/admin/licences.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
3+
# This file is part of The RetroPie Project
4+
#
5+
# The RetroPie Project is the legal property of its developers, whose names are
6+
# too numerous to list here. Please refer to the COPYRIGHT.md file distributed with this source.
7+
#
8+
# See the LICENSE.md file at the top-level directory of this distribution and
9+
# at https://raw.githubusercontent.com/RetroPie/RetroPie-Setup/master/LICENSE.md
10+
#
11+
12+
rp_module_id="licences"
13+
rp_module_desc="Collect package licences and generate statistics"
14+
rp_module_section=""
15+
16+
function build_licences() {
17+
mkdir -p "$md_build"
18+
pushd "$md_build"
19+
20+
local idx
21+
local mod_id
22+
local mod_desc
23+
local mod_section
24+
local mod_licence
25+
26+
echo > packages.csv
27+
for idx in ${__mod_idx[@]}; do
28+
mod_section="${__mod_section[$idx]}"
29+
mod_id="${__mod_id[$idx]}"
30+
mod_desc="${__mod_desc[$idx]}"
31+
mod_licence="${__mod_licence[$idx]}"
32+
echo "$mod_section;$mod_id;$mod_desc;$mod_licence;" >> packages.csv
33+
done
34+
35+
local git_hash=$(git -C "$scriptdir" log -1 --format=%h)
36+
local git_date=$(git -C "$scriptdir" log -1 --format=%cd --date=iso-strict)
37+
local git_branch=$(git -C "$scriptdir" rev-parse --abbrev-ref HEAD)
38+
echo "$git_hash;$git_date;$git_branch;" > commit.csv
39+
40+
cp -v "$md_data/"* ./
41+
popd
42+
}
43+
44+
function install_licences() {
45+
rsync -a --delete "$md_build/" "$__tmpdir/licences/"
46+
chown -R $user:$user "$__tmpdir/licences"
47+
}
48+
49+
function upload_licences() {
50+
rsync -av --delete "$__tmpdir/licences/" "retropie@$__binary_host:licences/"
51+
}

scriptmodules/admin/licences/Chart.min.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
body {
2+
font-family: sans-serif;
3+
line-height: 1.25;
4+
}
5+
.center {
6+
display: flex;
7+
flex-flow: column;
8+
align-items: center;
9+
}
10+
h1, body > p {
11+
max-width: 600px;
12+
text-align: center;
13+
}
14+
15+
16+
canvas {
17+
max-width: 500px;
18+
margin: 1em 0;
19+
}
20+
21+
22+
23+
#packages h3 {
24+
margin: 0;
25+
padding: .25em;
26+
margin-bottom: .25em;
27+
}
28+
#packages table {
29+
width: 100%;
30+
max-width: 1280px;
31+
border-collapse: collapse;
32+
}
33+
#packages thead {
34+
border-bottom: 1px solid rgba(0,0,0,30%);
35+
}
36+
#packages td {
37+
padding: .25em;
38+
}
39+
#packages tr td:first-child {
40+
font-family: monospace;
41+
min-width: 15%;
42+
}
43+
#packages tr td:last-child {
44+
text-align: center;
45+
min-width: 5%;
46+
}
47+
#packages thead td:nth-child(3),
48+
#packages tr td:nth-child(3) {
49+
text-align: center;
50+
min-width: 8%;
51+
}
52+
#packages tr:hover {
53+
background-color: #fffe;
54+
}
55+
#packages section {
56+
margin: 2em 0;
57+
padding: .5em;
58+
}
59+
60+
61+
#commit {
62+
font-size: 90%;
63+
margin-top: 0;
64+
}
65+
#commit code {
66+
font-size: 110%;
67+
}
68+
69+
70+
footer {
71+
font-size: 85%;
72+
width: 100%;
73+
max-width: 900px;
74+
text-align: center;
75+
margin-top: 2em;
76+
border-top: 1px solid #ccc;
77+
padding: 1.5em 0;
78+
display: flex;
79+
flex-flow: column;
80+
align-items: center;
81+
}
82+
footer p {
83+
max-width: 800px;
84+
margin-bottom: 0;
85+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
async function fetch_packages() {
2+
const resp = await fetch('packages.csv');
3+
const data = await resp.text();
4+
5+
return data
6+
.split('\n')
7+
.map(line => line.split(';'))
8+
.filter(fields => fields.length >= 4)
9+
.map(fields => ({
10+
section: fields[0],
11+
id: fields[1],
12+
desc: fields[2],
13+
licence: fields[3],
14+
}));
15+
}
16+
17+
async function fetch_commit_info() {
18+
const resp = await fetch('commit.csv');
19+
const data = await resp.text();
20+
const fields = data.split(';');
21+
return {
22+
sha: fields[0] || '',
23+
when: fields[1] || '',
24+
branch: fields[2] || '',
25+
};
26+
}
27+
28+
function create_commit_info(commit) {
29+
const date = commit.when.slice(0, 10);
30+
const time = commit.when.slice(11, 16);
31+
const text = `Last update: ${date} ${time}, <code>${commit.branch}</code> branch at <code>${commit.sha}</code>`;
32+
document.getElementById('commit').innerHTML = text;
33+
}
34+
35+
function get_pkg_licence_name(pkg) {
36+
return pkg.licence
37+
? pkg.licence.split(' ', 1)[0]
38+
: 'Unknown';
39+
}
40+
41+
function get_pkg_licence_link(pkg) {
42+
if (pkg.licence) {
43+
const url = pkg.licence.split(' ', 2)[1];
44+
if (url) {
45+
const anchor = document.createElement('a');
46+
anchor.href = url;
47+
anchor.target = '_blank';
48+
anchor.innerText = 'link';
49+
return anchor.outerHTML;
50+
}
51+
}
52+
return null;
53+
}
54+
55+
const CATEGORIES = [
56+
'copyleft',
57+
'permissive',
58+
'nonfree',
59+
'other',
60+
'unknown',
61+
];
62+
const CATEGORY_COLORS = {
63+
unknown: '#555',
64+
copyleft: '#d11',
65+
permissive: '#1d1',
66+
nonfree: '#fc0',
67+
other: '#aaa',
68+
};
69+
70+
function categorize_licence(licence) {
71+
if (licence == 'Unknown')
72+
return 'unknown';
73+
74+
if (/^L?GPL/.test(licence) || /^MPL/.test(licence))
75+
return 'copyleft';
76+
77+
if (['ZLIB', 'MIT', 'BSD'].includes(licence))
78+
return 'permissive';
79+
80+
if (['PROP', 'NONCOM'].includes(licence))
81+
return 'nonfree';
82+
83+
return 'other';
84+
}
85+
86+
function create_pie(packages) {
87+
const counts = new Map();
88+
packages
89+
.map(get_pkg_licence_name)
90+
.map(categorize_licence)
91+
.forEach(lic => counts.set(lic, (counts.get(lic) || 0) + 1));
92+
93+
const categories = CATEGORIES.filter(cat => counts.has(cat));
94+
const canvas = document.getElementById('pie');
95+
const chart = new Chart(canvas, {
96+
type: 'doughnut',
97+
data: {
98+
labels: CATEGORIES,
99+
datasets: [{
100+
data: categories.map(cat => counts.get(cat)),
101+
backgroundColor: categories.map(cat => CATEGORY_COLORS[cat]),
102+
}],
103+
},
104+
options: {
105+
legend: {
106+
position: 'bottom',
107+
},
108+
},
109+
});
110+
}
111+
112+
function append_cell(parent, html) {
113+
const cell = document.createElement('td');
114+
cell.innerHTML = html;
115+
parent.appendChild(cell);
116+
}
117+
118+
function create_section_row(type, cell_htmls) {
119+
const row = document.createElement(type);
120+
cell_htmls.forEach(str => append_cell(row, str))
121+
return row;
122+
}
123+
124+
function create_package_tables(packages) {
125+
const pkg_licences = new Map();
126+
packages.forEach(pkg => {
127+
const licence = get_pkg_licence_name(pkg);
128+
const packages = pkg_licences.get(licence) || [];
129+
packages.push(pkg);
130+
pkg_licences.set(licence, packages);
131+
});
132+
133+
const fragment = new DocumentFragment();
134+
135+
const licence_names = [...pkg_licences.keys()].sort();
136+
licence_names.forEach(lic => {
137+
const lic_category = categorize_licence(lic);
138+
const lic_color = CATEGORY_COLORS[lic_category];
139+
140+
const container = document.createElement('section');
141+
container.style.backgroundColor = lic_color + '2';
142+
143+
const title = document.createElement('h3');
144+
title.innerText = lic;
145+
container.appendChild(title);
146+
147+
const table = document.createElement('table');
148+
const thead = create_section_row('thead', ['Package', 'Description', 'Section', 'Licence']);
149+
table.appendChild(thead);
150+
151+
pkg_licences
152+
.get(lic)
153+
.sort((a, b) => a.id.localeCompare(b.id))
154+
.map(pkg => [
155+
pkg.id,
156+
pkg.desc,
157+
pkg.section || '&mdash;',
158+
get_pkg_licence_link(pkg) || '&mdash;',
159+
])
160+
.map(fields => create_section_row('tr', fields))
161+
.forEach(row => table.appendChild(row));
162+
163+
container.appendChild(table);
164+
fragment.appendChild(container);
165+
});
166+
167+
document.getElementById('packages').appendChild(fragment);
168+
}
169+
170+
window.onload = async () => {
171+
const packages = await fetch_packages();
172+
const commit = await fetch_commit_info();
173+
create_pie(packages);
174+
create_commit_info(commit);
175+
create_package_tables(packages);
176+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset='utf-8'>
5+
<meta name='viewport' content='width=device-width,initial-scale=1'>
6+
<meta http-equiv='x-ua-compatible' content='ie=edge'>
7+
<title>RetroPie package licences</title>
8+
<link rel='stylesheet' type='text/css' href='app.css'>
9+
<script defer type='text/javascript' src='Chart.min.js'></script>
10+
<script defer type='text/javascript' src='app.js'></script>
11+
</head>
12+
<body class='center'>
13+
<h1>RetroPie package licences</h1>
14+
<p>This page shows an up-to-date list of all RetroPie packages and the licences they use.</p>
15+
<canvas id='pie' width='550' height='400'></canvas>
16+
<p id='commit'></p>
17+
<div id='packages'></div>
18+
<footer>
19+
<p>This page is provided merely for informational purposes and should not be taken as a legal advice. Always check the licences of the individual softwares and the local laws if you have legal question.</p>
20+
<p>Copyright &copy; 2019 The RetroPie Project</p>
21+
</footer>
22+
</body>
23+
</html>

scriptmodules/admin/pkgflags.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env bash
2+
3+
# This file is part of The RetroPie Project
4+
#
5+
# The RetroPie Project is the legal property of its developers, whose names are
6+
# too numerous to list here. Please refer to the COPYRIGHT.md file distributed with this source.
7+
#
8+
# See the LICENSE.md file at the top-level directory of this distribution and
9+
# at https://raw.githubusercontent.com/RetroPie/RetroPie-Setup/master/LICENSE.md
10+
#
11+
12+
rp_module_id="pkgflags"
13+
rp_module_desc="Collect package flags and generate statistics"
14+
rp_module_section=""
15+
16+
function build_pkgflags() {
17+
mkdir -p "$md_build"
18+
pushd "$md_build"
19+
20+
local idx
21+
local mod_id
22+
local mod_desc
23+
local mod_section
24+
local mod_flags
25+
26+
echo > packages.csv
27+
for idx in ${__mod_idx[@]}; do
28+
mod_section="${__mod_section[$idx]}"
29+
mod_id="${__mod_id[$idx]}"
30+
mod_desc="${__mod_desc[$idx]}"
31+
mod_flags="${__mod_flags[$idx]}"
32+
echo "$mod_section;$mod_id;$mod_desc;$mod_flags;" >> packages.csv
33+
done
34+
35+
local git_hash=$(git -C "$scriptdir" log -1 --format=%h)
36+
local git_date=$(git -C "$scriptdir" log -1 --format=%cd --date=iso-strict)
37+
local git_branch=$(git -C "$scriptdir" rev-parse --abbrev-ref HEAD)
38+
echo "$git_hash;$git_date;$git_branch;" > commit.csv
39+
40+
cp -v "$md_data/"* ./
41+
popd
42+
}
43+
44+
function install_pkgflags() {
45+
rsync -a --delete "$md_build/" "$__tmpdir/pkgflags/"
46+
chown -R $user:$user "$__tmpdir/pkgflags"
47+
}
48+
49+
function upload_pkgflags() {
50+
rsync -av --delete "$__tmpdir/pkgflags/" "retropie@$__binary_host:pkgflags/"
51+
}

0 commit comments

Comments
 (0)