cookutils diff lighttpd/index.cgi @ rev 1090

Working with "i486", "x86_64" and "any" architecture; post-check with badges; new icons, tag cloud, and other improvements
author Aleksej Bobylev <al.bobylev@gmail.com>
date Sat Nov 24 13:28:02 2018 +0200 (2018-11-24)
parents 01e5c3e760d7
children c0b06e1eb456
line diff
     1.1 --- a/lighttpd/index.cgi	Sat Aug 25 17:30:05 2018 +0300
     1.2 +++ b/lighttpd/index.cgi	Sat Nov 24 13:28:02 2018 +0200
     1.3 @@ -95,7 +95,8 @@
     1.4  
     1.5  	if [ -n "$pkg" ]; then
     1.6  		case "$pkg" in
     1.7 -			~) pretitle="Tag \"$cmd\" - ";;
     1.8 +			~) if [ -z "$cmd" ]; then pretitle="Tag cloud - "; else pretitle="Tag \"$cmd\" - "; fi;;
     1.9 +			%) if [ -z "$cmd" ]; then pretitle="Badges - "; else pretitle="Badge \"$cmd\" - "; fi;;
    1.10  			*) pretitle="$pkg - ";;
    1.11  		esac
    1.12  	else
    1.13 @@ -180,21 +181,21 @@
    1.14  	date_now=$(date +%s)
    1.15  	sec_now=$(date +%S); sec_now=${sec_now#0} # remove one leading zero
    1.16  	wait_sec=$(( 60 - $sec_now ))
    1.17 -	cat <<EOT
    1.18 -</main>
    1.19 +	cat <<-EOT
    1.20 +	</main>
    1.21  
    1.22 -<footer>
    1.23 -	<a href="http://www.slitaz.org/">SliTaz Website</a>
    1.24 -	<a href="http://tank.slitaz.org/graphs.php">Server status</a>
    1.25 -	<a href="$base/doc/cookutils/cookutils.html">Documentation</a>
    1.26 -	<a href="$base/?theme">Theme</a>
    1.27 -</footer>
    1.28 -</div>
    1.29 -<script src="/cooker.js"></script>
    1.30 -<script>refreshDate(${wait_sec}000, ${date_now}000)</script>
    1.31 -</body>
    1.32 -</html>
    1.33 -EOT
    1.34 +	<footer>
    1.35 +		<a href="http://www.slitaz.org/">SliTaz Website</a>
    1.36 +		<a href="http://tank.slitaz.org/graphs.php">Server status</a>
    1.37 +		<a href="$base/doc/cookutils/cookutils.html">Documentation</a>
    1.38 +		<a href="$base/?theme">Theme</a>
    1.39 +	</footer>
    1.40 +	</div>
    1.41 +	<script src="/cooker.js"></script>
    1.42 +	<script>refreshDate(${wait_sec}000, ${date_now}000)</script>
    1.43 +	</body>
    1.44 +	</html>
    1.45 +	EOT
    1.46  }
    1.47  
    1.48  
    1.49 @@ -258,7 +259,7 @@
    1.50  # Problems:
    1.51  # 1. Function "latest packaged version" widely used here and it has no JSON API, but only SVG badge.
    1.52  # 2. So, all version comparisons can be only visual and not automated.
    1.53 -# 3. Of the thousands of badges present on the web page, many of them are broken (maybe server
    1.54 +# 3. If the thousands of badges present on the web page, many of them are broken (maybe server
    1.55  #    drops requests), while our server displays status icons well.
    1.56  # 4. Default badges are wide and not customizable.
    1.57  # Solution:
    1.58 @@ -347,7 +348,7 @@
    1.59  	# argument <pkg> is in $cmd variable
    1.60  	echo -en "Content-Type: image/svg+xml\n\n<svg xmlns='http://www.w3.org/2000/svg' height='12' width='8'><path d='"
    1.61  	# packages.info updates with each new package, so we'll find actual info here
    1.62 -	if grep -q "^$cmd"$'\t' $PKGS/packages.info; then
    1.63 +	if grep -q "^$cmd"$'\t' $PKGS/packages-$ARCH.info; then
    1.64  		echo "m1 2-1 1v8l1 1h6l1-1v-8l-1-1z' fill='#090'/></svg>"
    1.65  	else
    1.66  		echo "m0 3v8l1 1h6l1-1v-8l-1-1h-6zm3 0h2v5h-2zm0 6h2v2h-2z' fill='#d00'/></svg>"
    1.67 @@ -365,19 +366,17 @@
    1.68  		theme)
    1.69  			current=$(COOKIE theme)
    1.70  			page_header
    1.71 -			cat <<EOT
    1.72 -<section>
    1.73 -	<h2>Change theme</h2>
    1.74 -	<p>Current theme: “${current:-default}”. Select other:</p>
    1.75 -	<ul>
    1.76 -		$(
    1.77 -			for i in default emerald sky goldenrod midnight like2016 terminal; do
    1.78 -				[ "$i" == "${current:-default}" ] || echo "<li><a href=\"$base/?theme=$i&amp;ref=$ref\">$i</a></li>"
    1.79 -			done
    1.80 -		)
    1.81 -	</ul>
    1.82 -</section>
    1.83 -EOT
    1.84 +			cat <<-EOT
    1.85 +				<section>
    1.86 +					<h2>Change theme</h2>
    1.87 +					<p>Current theme: “${current:-default}”. Select other:</p>
    1.88 +					<ul>$(
    1.89 +							for i in default emerald sky goldenrod midnight like2016 terminal; do
    1.90 +								[ "$i" == "${current:-default}" ] || echo "<li><a href=\"$base/?theme=$i&amp;ref=$ref\">$i</a></li>"
    1.91 +							done
    1.92 +					)</ul>
    1.93 +				</section>
    1.94 +			EOT
    1.95  			page_footer
    1.96  			exit 0
    1.97  			;;
    1.98 @@ -426,26 +425,27 @@
    1.99  	limit=$(GET limit); limit="${limit:-12}"; [ "$limit" -gt 100 ] && limit='100'
   1.100  	pubdate=$(date -Rur$(ls -t $FEEDS/*.xml | head -n1) | sed 's|UTC|GMT|')
   1.101  	cooker_url="http://$HTTP_HOST$base/"
   1.102 -	cat <<EOT
   1.103 -Content-Type: application/rss+xml
   1.104 +	cat <<-EOT
   1.105 +		Content-Type: application/rss+xml
   1.106  
   1.107 -<?xml version="1.0" encoding="utf-8" ?>
   1.108 -<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
   1.109 -<channel>
   1.110 -	<title>$title</title>
   1.111 -	<description>The SliTaz packages cooker feed</description>
   1.112 -	<link>$cooker_url</link>
   1.113 -	<lastBuildDate>$pubdate</lastBuildDate>
   1.114 -	<pubDate>$pubdate</pubDate>
   1.115 -	<atom:link href="$cooker_url?rss" rel="self" type="application/rss+xml" />
   1.116 -EOT
   1.117 +		<?xml version="1.0" encoding="utf-8" ?>
   1.118 +		<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
   1.119 +		<channel>
   1.120 +			<title>$title</title>
   1.121 +			<description>The SliTaz packages cooker feed</description>
   1.122 +			<link>$cooker_url</link>
   1.123 +			<lastBuildDate>$pubdate</lastBuildDate>
   1.124 +			<pubDate>$pubdate</pubDate>
   1.125 +			<atom:link href="$cooker_url?rss" rel="self" type="application/rss+xml" />
   1.126 +		EOT
   1.127  	for rss in $(ls -t $FEEDS/*.xml | head -n$limit); do
   1.128 -		sed "s|http[^=]*=|$cooker_url|; s|<guid|& isPermaLink=\"false\"|g; s|</pubDate| GMT&|g" $rss
   1.129 +		sed -e "/\?pkg=/s|http[^=]*=|$cooker_url|;" \
   1.130 +			-e "s|\([0-9]\)</pubDate>|\1 GMT</pubDate>|" $rss
   1.131  	done
   1.132 -	cat <<EOT
   1.133 -</channel>
   1.134 -</rss>
   1.135 -EOT
   1.136 +	cat <<-EOT
   1.137 +		</channel>
   1.138 +		</rss>
   1.139 +	EOT
   1.140  	exit 0
   1.141  fi
   1.142  
   1.143 @@ -455,22 +455,22 @@
   1.144  # Query '/os.xml': get OpenSearch Description
   1.145  
   1.146  if [ "$pkg" == 'os.xml' ]; then
   1.147 -	cat <<EOT
   1.148 -Content-Type: application/xml; charset=UTF-8
   1.149 +	cat <<-EOT
   1.150 +		Content-Type: application/xml; charset=UTF-8
   1.151  
   1.152 -<?xml version="1.0" encoding="UTF-8"?>
   1.153 -<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
   1.154 -	<ShortName>$title</ShortName>
   1.155 -	<Description>SliTaz packages search</Description>
   1.156 -	<Image width="16" height="16" type="image/png">http://$HTTP_HOST/images/logo.png</Image>
   1.157 -	<Url type="text/html" method="GET" template="http://$HTTP_HOST$base/{searchTerms}"/>
   1.158 -	<Url type="application/x-suggestions+json" method="GET" template="http://$HTTP_HOST$base/">
   1.159 -		<Param name="oss" value="{searchTerms}"/>
   1.160 -	</Url>
   1.161 -	<SearchForm>http://$HTTP_HOST$base/</SearchForm>
   1.162 -	<InputEncoding>UTF-8</InputEncoding>
   1.163 -</OpenSearchDescription>
   1.164 -EOT
   1.165 +		<?xml version="1.0" encoding="UTF-8"?>
   1.166 +		<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
   1.167 +			<ShortName>$title</ShortName>
   1.168 +			<Description>SliTaz packages search</Description>
   1.169 +			<Image width="16" height="16" type="image/png">http://$HTTP_HOST/images/logo.png</Image>
   1.170 +			<Url type="text/html" method="GET" template="http://$HTTP_HOST$base/{searchTerms}"/>
   1.171 +			<Url type="application/x-suggestions+json" method="GET" template="http://$HTTP_HOST$base/">
   1.172 +				<Param name="oss" value="{searchTerms}"/>
   1.173 +			</Url>
   1.174 +			<SearchForm>http://$HTTP_HOST$base/</SearchForm>
   1.175 +			<InputEncoding>UTF-8</InputEncoding>
   1.176 +		</OpenSearchDescription>
   1.177 +	EOT
   1.178  	exit 0
   1.179  fi
   1.180  
   1.181 @@ -512,7 +512,9 @@
   1.182  
   1.183  info2html() {
   1.184  	sed \
   1.185 -		-e 's|&|\&amp;|g; s|<|\&lt;|g; s|>|\&gt;|g' \
   1.186 +		-e 's|&|\&amp;|g; s|<|\&lt;|g; s|>|\&gt;|g;' \
   1.187 +		-e "s|\`\([^']*\)'|<b>\1</b>|g" \
   1.188 +		-e 's|"\([A-Za-z0-9]\)|“\1|g; s|"|”|g' \
   1.189  		-e 's|^\* \(.*\)::|* <a href="#\1">\1</a>  |' \
   1.190  		-e 's|\*note \(.*\)::|<a href="#\1">\1</a>|' \
   1.191  		-e '/^File: / s|(dir)|Top|g' \
   1.192 @@ -520,7 +522,8 @@
   1.193  		-e '/^File: / s|Prev: \([^,]*\)|<a class="button icon prev" href="#\1">Prev: \1</a>|' \
   1.194  		-e '/^File: / s|Up: \([^,]*\)|<a class="button icon up" href="#\1">Up: \1</a>|' \
   1.195  		-e '/^File: / s|^.* Node: \([^,]*\), *\(.*\)$|<pre id="\1">\2|' \
   1.196 -		-e '/^<pre id=/ s|^\([^>]*>\)\(<a[^>]*>Next: [^,]*\), *\(<a[^>]*>Prev: [^,]*\), *\(<a[^>]*>Up: .*\)|\1 \3 \4 \2|' \
   1.197 +		-e '/^<pre id=/ s|^\([^>]*>\)\(<a[^>]*>Next: [^,]*\), *\(<a[^>]*>Prev: [^,]*\), *\(<a[^>]*>Up: .*\)|\1<div class="buttonbar">\3 \4 \2</div>|' \
   1.198 +		-e '/^<pre id=/ s|^\([^>]*>\)*\(<a[^>]*>Prev: [^,]*\), *\(<a[^>]*>Up: .*\)|\1<div class="buttonbar">\2 \3 <a class="button icon next" href="#">Next</a></div>|' \
   1.199  		-e '/^Tag Table:$/,/^End Tag Table$/d' \
   1.200  		-e '/INFO-DIR/,/^END-INFO-DIR/d' \
   1.201  		-e "s|https*://[^>),'\"\`’ ]*|<a href=\"&\">&</a>|g" \
   1.202 @@ -631,12 +634,18 @@
   1.203  					s|\[39m|</span>|;
   1.204  					#s|\[1m|<span class='c01'>|g;
   1.205  					s|\[1m|<span style='font-weight:bold'>|g; s|(B|</span>|g;
   1.206 -					s|\[m||g;
   1.207 -					" \
   1.208 +					s|\[m||g;" \
   1.209 +				\
   1.210  				-e "s!^|\(+.*\)!|<span class='c20'>\1</span>!;
   1.211  					s!^|\(-.*\)!|<span class='c10'>\1</span>!;
   1.212 -					s!^|\(@@.*@@\)\$!|<span class='c30'>\1</span>!;"
   1.213 +					s!^|\(@@.*@@\)\$!|<span class='c30'>\1</span>!;" \
   1.214  				\
   1.215 +				-e "s|^Successfully installed [^ ][^ ]*$|<i>\0</i>|;
   1.216 +					s|^Successfully installed .*$|<b>\0</b>|;
   1.217 +					s|^\(Requirement already satisfied: .*\) in|<i>\1</i> in|;
   1.218 +					s|^Collecting .* (from .*$|<b>\0</b>|;
   1.219 +					s|^  Could not find.*|<b>\0</b>|;
   1.220 +					s|^No matching distribution found for.*|<b>\0</b>|;"
   1.221  
   1.222  			;;
   1.223  
   1.224 @@ -697,7 +706,9 @@
   1.225  
   1.226  	if [ -f "$log" ]; then
   1.227  		if grep -q "cook:$pkg$" $command; then
   1.228 -			show_note i "The Cooker is currently building $pkg"
   1.229 +			show_note i "The Cooker is currently building $pkg" \
   1.230 +			| sed 's|>|&<progress id="gauge" class="meter-small" max="100" value="0"></progress> |'
   1.231 +			echo "<script>updatePkg = '${pkg//+/%2B}';</script>"
   1.232  		elif fgrep -q "Summary for:" $log; then
   1.233  			sed '/^Summary for:/,$!d' $log | awk '
   1.234  			BEGIN { print "<section>" }
   1.235 @@ -728,7 +739,8 @@
   1.236  			END { print "</tbody></table></section>" }
   1.237  			'
   1.238  		elif fgrep -q "Debug information" $log; then
   1.239 -			echo -e '<section>\n<h3>Debug information</h3>'
   1.240 +			# second line of log is "Cook: <package> <version>"
   1.241 +			echo -e "<section>\n<h3>Debug information for $(sed '2!d; s|.*: ||' $log)</h3>"
   1.242  			sed -e '/^Debug information/,$!d; /^===/d; /^$/d' $log | sed -n '1!p' | \
   1.243  			if [ -n "$2" ]; then
   1.244  				syntax_highlighter log | sed 's|\([^0-9 ]\)\([0-9][0-9]*\):|\1<a href="#l\2">\2</a>:|'
   1.245 @@ -754,9 +766,9 @@
   1.246  
   1.247  	echo -n "<div id=\"hdr\"><a href=\"$base/${requested_pkg:-$pkg}\">"
   1.248  	if [ -e $wok/$pkg/.icon.png ]; then
   1.249 -		echo -n "<img src=\"$base/$pkg/browse/.icon.png\"/>"
   1.250 +		echo -n "<img src=\"$base/$pkg/browse/.icon.png\" alt=\"$pkg icon\"/>"
   1.251  	else
   1.252 -		echo -n "<img src=\"/tazpkg.png\"/>"
   1.253 +		echo -n "<img src=\"/tazpkg.png\" alt=\"package icon\"/>"
   1.254  	fi
   1.255  	echo -n "</a>"
   1.256  	echo -n "<h2><a href=\"$base/${requested_pkg:-$pkg}\">${requested_pkg:-$pkg}</a>"
   1.257 @@ -792,7 +804,7 @@
   1.258  		echo "<a class='button icon desc$(active description)' href='$base/$pkg/description'>description</a>"
   1.259  
   1.260  	[ -n "$TARBALL" -a -s "$SRC/$TARBALL" -o -d "$wok/$pkg/taz" ] &&
   1.261 -		echo "<a class='button icon download' href='$base/$pkg/download'>download</a>"
   1.262 +		echo "<a class='button icon download' href='$base/$pkg/download'>downloads</a>"
   1.263  
   1.264  	echo "<a class='button icon browse' href='$base/$pkg/browse/'>browse</a>"
   1.265  
   1.266 @@ -806,7 +818,7 @@
   1.267  		echo "<a class='button icon doc$(active info)' href='$base/$pkg/info/#Top'>info</a>"
   1.268  
   1.269  	if [ -n "$LFS" ]; then
   1.270 -		printf "<a class='button icon doc' href='%s' target='_blank' rel='noopener noreferrer'>" "$LFS"
   1.271 +		printf "<a class='button icon lfs' href='%s' target='_blank' rel='noopener noreferrer'>" "$LFS"
   1.272  		[ "${LFS/blfs/}" != "$LFS" ] && printf "B"
   1.273  		printf "LFS</a>\n"
   1.274  	fi
   1.275 @@ -917,10 +929,145 @@
   1.276  			sed "/^$i\t/!d" $CACHE/split.db
   1.277  		done < $broken | cut -d$'\t' -f2 | tr ' ' '\n' | wc -l)
   1.278  
   1.279 -	cat > $webstat <<EOT
   1.280 -rtotal="$rtotal"; rcooked="$rcooked"; runbuilt="$runbuilt"; rblocked="$rblocked"; rbroken="$rbroken"
   1.281 -ptotal="$ptotal"; pcooked="$pcooked"; punbuilt="$punbuilt"; pblocked="$pblocked"; pbroken="$pbroken"
   1.282 -EOT
   1.283 +	cat > $webstat <<-EOT
   1.284 +		rtotal="$rtotal"; rcooked="$rcooked"; runbuilt="$runbuilt"; rblocked="$rblocked"; rbroken="$rbroken"
   1.285 +		ptotal="$ptotal"; pcooked="$pcooked"; punbuilt="$punbuilt"; pblocked="$pblocked"; pbroken="$pbroken"
   1.286 +	EOT
   1.287 +}
   1.288 +
   1.289 +
   1.290 +# Show badges for specified package
   1.291 +
   1.292 +show_badges() {
   1.293 +	local t p s # title problem solution
   1.294 +
   1.295 +	case $layout in
   1.296 +		table)
   1.297 +			echo "<section><h2>Badges</h2><table class=\"badges\"><thead><tr><th></th><th>Problem</th><th>Solution</th></tr></thead><tbody>"
   1.298 +			;;
   1.299 +		list)
   1.300 +			echo "<section><h2>Badges list</h2><p>Click on badge to get list of packages</p><table class=\"badges\"><thead><tr><th></th><th>Problem</th></tr></thead><tbody>"
   1.301 +			;;
   1.302 +	esac
   1.303 +
   1.304 +	for badge in $@; do
   1.305 +		case $badge in
   1.306 +			bdbroken)
   1.307 +				t="Broken bdeps"
   1.308 +				p="This package cannot be built because its creation depends on broken packages"
   1.309 +				s="Fix broken build dependencies"
   1.310 +				;;
   1.311 +			broken)
   1.312 +				t="Broken package"
   1.313 +				p="Package is broken"
   1.314 +				s="Fix package build: analyze <a href=\"log/\">logs</a>, upgrade the version, search for patches"
   1.315 +				;;
   1.316 +			any)
   1.317 +				t="“Any” arch"
   1.318 +				p="This package contains only architecture-less <a href=\"files\">files</a>, it does not make sense to make it several times in each build environment"
   1.319 +				s="Add the line <code>HOST_ARCH=\"any\"</code> to <a href=\"receipt\">receipt</a>"
   1.320 +				;;
   1.321 +			noany)
   1.322 +				t="No “any” arch"
   1.323 +				p="This package contains architecture dependent <a href=\"files\">files</a>"
   1.324 +				s="Remove the line <code>HOST_ARCH=\"any\"</code> from <a href=\"receipt\">receipt</a>"
   1.325 +				;;
   1.326 +			libtool)
   1.327 +				t="Libtool isn't fixed"
   1.328 +				p="This package use <code>libtool</code> that likes to add unnecessary dependencies to programs and libraries"
   1.329 +				s="Add the <code>fix libtool</code> command to the <a href=\"receipt\">receipt</a> between the <code>configure</code> and <code>make</code> commands invocation"
   1.330 +				;;
   1.331 +			nolibtool)
   1.332 +				t="Libtool is absent"
   1.333 +				p="This package does not use <code>libtool</code>, nothing to fix"
   1.334 +				s="Remove the command <code>fix libtool</code> from <a href=\"receipt\">receipt</a>"
   1.335 +				;;
   1.336 +			own)
   1.337 +				t="Ownership problems"
   1.338 +				p="Some files of this package have <a href=\"files\">ownership problems</a>"
   1.339 +				s="Correct the ownership or add problem files to the “<a href=\"stuff/overrides\">overrides</a>” list if you believe it is OK"
   1.340 +				;;
   1.341 +			ownover)
   1.342 +				t="Ownership overridden"
   1.343 +				p="This package contains files with <a href=\"files\">ownership problems</a> that have been overridden"
   1.344 +				s="<abbr title=\"For your information\">FYI</abbr> only, you may want to revise <a href=\"stuff/overrides\">the list</a>"
   1.345 +				;;
   1.346 +			perm)
   1.347 +				t="Permissions problems"
   1.348 +				p="Some files of this package have <a href=\"files\">unusual permissions</a>"
   1.349 +				s="Correct the permissions or add problem files to the “<a href=\"stuff/overrides\">overrides</a>” list if you believe it is OK"
   1.350 +				;;
   1.351 +			permover)
   1.352 +				t="Permissions overridden"
   1.353 +				p="This package contains files with <a href=\"files\">unusual permissions</a> that have been recorded"
   1.354 +				s="<abbr title=\"For your information\">FYI</abbr> only, you may want to revise <a href=\"stuff/overrides\">the list</a>"
   1.355 +				;;
   1.356 +			symlink)
   1.357 +				t="Broken symlink"
   1.358 +				p="This package contains one or more <a href=\"files\">broken symlinks</a>"
   1.359 +				s="Fix the symlinks destination; you may use <code>fix symlinks</code> when symlinks have absolute path"
   1.360 +				;;
   1.361 +			ss)
   1.362 +				t="Site script"
   1.363 +				p="This autotools-based building system use site script; most of paths (like <var>prefix</var>, <var>sysconfdir</var> and <var>mandir</var>) are defined there with correct default values"
   1.364 +				s="You may remove your paths from <code>configure</code> invocation"
   1.365 +				;;
   1.366 +			fadd)
   1.367 +				t="Files have been added"
   1.368 +				p="Some files absent in <var>\$install</var> was <a href=\"files#outoftree\">directly added</a> to <var>\$fs</var>"
   1.369 +				s="Rework your <code>compile_rules()</code> to add all the required files to <var>\$install</var> there"
   1.370 +				;;
   1.371 +			frem)
   1.372 +				t="Files have been removed"
   1.373 +				p="Some files existing in <var>\$install</var> <a href=\"files#orphans\">not belong to any package</a>"
   1.374 +				s="Revise <code>genpkg_rules()</code> or add files to “<a href=\"stuff/overrides\">overrides</a>” list"
   1.375 +				;;
   1.376 +			fdup)
   1.377 +				t="Files are duplicated"
   1.378 +				p="Some files existing in <var>\$install</var> was added to <a href=\"files#repeats\">more than one</a> package"
   1.379 +				s="Check your copy rules in <code>genpkg_rules()</code>"
   1.380 +				;;
   1.381 +			old)
   1.382 +				t="Oldie"
   1.383 +				p="According to Repology, this package may be <a href=\"https://repology.org/metapackage/${REPOLOGY:-$pkg}\" target=\"_blank\" rel=\"noopener noreferrer\">outdated</a>"
   1.384 +				s="Update the package"
   1.385 +				;;
   1.386 +			win)
   1.387 +				t="Winner"
   1.388 +				p="This package has no problems"
   1.389 +				s="Well done, keep it up!"
   1.390 +				;;
   1.391 +			orphan)
   1.392 +				t="Orphaned package"
   1.393 +				p="It seems that no other package depends on this one"
   1.394 +				s="See if anyone needs it"
   1.395 +				;;
   1.396 +			patch)
   1.397 +				t="Patch"
   1.398 +				p="Patch has been applied"
   1.399 +				s="<abbr title=\"For your information\">FYI</abbr> only, you may want to revise <a href=\"$base/$PACKAGE/stuff/patches/series\">the list of patches</a>"
   1.400 +				;;
   1.401 +		esac
   1.402 +		case $layout in
   1.403 +			table)
   1.404 +				echo "<tr><td><span class=\"badge $badge\" title=\"$t\"/></td><td>$p</td><td>$s</td></tr>"
   1.405 +				;;
   1.406 +			list)
   1.407 +				p=$(echo $p | sed 's|<a [^>]*>\([^<]*\)</a>|\1|g')
   1.408 +				s=$(echo $s | sed 's|<a [^>]*>\([^<]*\)</a>|\1|g|')
   1.409 +				echo "<tr><td><a href=\"$badge\"><span class=\"badge $badge\" title=\"$t\"/></a></td><td>$p</td></tr>"
   1.410 +				;;
   1.411 +			*)
   1.412 +				echo -n "<span class=\"badge $badge\" title=\"$t\"/>"
   1.413 +				;;
   1.414 +		esac
   1.415 +	done
   1.416 +
   1.417 +	case $layout in
   1.418 +		table|list)
   1.419 +			echo "</tbody></table></section>"
   1.420 +			;;
   1.421 +	esac
   1.422  }
   1.423  
   1.424  
   1.425 @@ -959,16 +1106,40 @@
   1.426  
   1.427  			pct=0; [ "$rtotal" -gt 0 ] && pct=$(( ($rcooked * 100) / $rtotal ))
   1.428  
   1.429 -			cat <<EOT
   1.430 -<div class="meter"><progress max="100" value="$pct">${pct}%</progress><span>${pct}%</span></div>
   1.431 +			cat <<-EOT
   1.432 +				<div class="meter"><progress max="100" value="$pct">${pct}%</progress><span>${pct}%</span></div>
   1.433  
   1.434 -<table class="webstat"><thead>
   1.435 -<tr><th>        </th><th>Total  </th><th>Cooked  </th><th>Unbuilt  </th><th>Blocked  </th><th>Broken  </th></tr>
   1.436 -</thead><tbody>
   1.437 -<tr><td>Receipts</td><td>$rtotal</td><td>$rcooked</td><td>$runbuilt</td><td>$rblocked</td><td>$rbroken</td></tr>
   1.438 -<tr><td>Packages</td><td>$ptotal</td><td>$pcooked</td><td>$punbuilt</td><td>$pblocked</td><td>$pbroken</td></tr>
   1.439 -</tbody></table>
   1.440 -EOT
   1.441 +				<table class="webstat">
   1.442 +					<thead>
   1.443 +						<tr>
   1.444 +							<th>        </th>
   1.445 +							<th>Total  </th>
   1.446 +							<th>Cooked  </th>
   1.447 +							<th>Unbuilt  </th>
   1.448 +							<th>Blocked  </th>
   1.449 +							<th>Broken  </th>
   1.450 +						</tr>
   1.451 +					</thead>
   1.452 +					<tbody>
   1.453 +						<tr>
   1.454 +							<td>Receipts</td>
   1.455 +							<td>$rtotal</td>
   1.456 +							<td>$rcooked</td>
   1.457 +							<td>$runbuilt</td>
   1.458 +							<td>$rblocked</td>
   1.459 +							<td>$rbroken</td>
   1.460 +						</tr>
   1.461 +						<tr>
   1.462 +							<td>Packages</td>
   1.463 +							<td>$ptotal</td>
   1.464 +							<td>$pcooked</td>
   1.465 +							<td>$punbuilt</td>
   1.466 +							<td>$pblocked</td>
   1.467 +							<td>$pbroken</td>
   1.468 +						</tr>
   1.469 +					</tbody>
   1.470 +				</table>
   1.471 +			EOT
   1.472  			if [ -z "$nojs" ]; then echo "<script>getPart('$1')</script>"; fi
   1.473  			;;
   1.474  		activity)
   1.475 @@ -977,8 +1148,18 @@
   1.476  				s|\[ Failed|<span class="r c10">Failed|;
   1.477  				s|\[ -Failed|<span class="r c10"><del>Failed</del>|;
   1.478  				s| \]|</span>|;
   1.479 -				s|%2B|\+|g' | \
   1.480 -				section $activity 12 "Activity|More activity"
   1.481 +				s|%2B|\+|g' \
   1.482 +			| while read line; do
   1.483 +				case "$line" in
   1.484 +					*data-badges=*)
   1.485 +						badges="$(echo "$line" | sed "s|.*data-badges='\([^']*\)'.*|\1|")"
   1.486 +						echo "$line" | sed "s|</a>|</a> $(show_badges "$badges")|"
   1.487 +						;;
   1.488 +					*)
   1.489 +						echo "$line"
   1.490 +						;;
   1.491 +				esac
   1.492 +			done | section $activity 12 "Activity|More activity" \
   1.493  			;;
   1.494  		cooknotes)
   1.495  			[ -s "$cooknotes" ] && tac $cooknotes | head -n12 | \
   1.496 @@ -1070,11 +1251,26 @@
   1.497  			esac
   1.498  			echo '<section id="content2">'
   1.499  			echo "<h2>DB: $list $nb</h2>"
   1.500 +
   1.501  			tac $CACHE/$list | sed 's|cooker.cgi?pkg=||; s|%2B|+|g;
   1.502  				s|\[ Done|<span class="r c20">Done|;
   1.503  				s|\[ Failed|<span class="r c10">Failed|;
   1.504  				s|\[ -Failed|<span class="r c10"><del>Failed</del>|;
   1.505 -				s| \]|</span>|' | mktable $list
   1.506 +				s| \]|</span>|;
   1.507 +				s|%2B|\+|g' \
   1.508 +			| while read line; do
   1.509 +				case "$line" in
   1.510 +					*data-badges=*)
   1.511 +						badges="$(echo "$line" | sed "s|.*data-badges='\([^']*\)'.*|\1|")"
   1.512 +						echo "$line" | sed "s|</a>|</a> $(show_badges "$badges")|"
   1.513 +						;;
   1.514 +					*)
   1.515 +						echo "$line"
   1.516 +						;;
   1.517 +				esac
   1.518 +			done \
   1.519 +			| mktable $list
   1.520 +
   1.521  			echo '</section>'
   1.522  		done
   1.523  
   1.524 @@ -1118,64 +1314,84 @@
   1.525  				fi
   1.526  				;;
   1.527  			toolchain)
   1.528 -				cat <<EOT
   1.529 -<div id="content2">
   1.530 -<section>
   1.531 -<h2>SliTaz GNU/Linux toolchain</h2>
   1.532 +				cat <<-EOT
   1.533 +					<div id="content2">
   1.534 +					<section>
   1.535 +					<h2>SliTaz GNU/Linux toolchain</h2>
   1.536  
   1.537 -<table>
   1.538 -<tr><td>Build date</td>		<td colspan="2">$(sed -n '/^Cook date/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td></tr>
   1.539 -<tr><td>Build duration</td>	<td colspan="2">$(sed -n '/^Cook time/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td></tr>
   1.540 -<tr><td>Architecture</td>	<td colspan="2">$ARCH</td></tr>
   1.541 -<tr><td>Host system</td>	<td colspan="2">$BUILD_SYSTEM</td></tr>
   1.542 -<tr><td>Target system</td>	<td colspan="2">$HOST_SYSTEM</td></tr>
   1.543 -<tr><th>Package</th><th>Version</th><th>Description</th></tr>
   1.544 -$(toolchain_version slitaz-toolchain)
   1.545 -$(toolchain_version binutils)
   1.546 -$(toolchain_version linux-api-headers)
   1.547 -$(toolchain_version gcc)
   1.548 -$(toolchain_version glibc)
   1.549 -</table>
   1.550 +					<table>
   1.551 +						<tr>
   1.552 +							<td>Build date</td>
   1.553 +							<td colspan="2">$(sed -n '/^Cook date/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td>
   1.554 +						</tr>
   1.555 +						<tr>
   1.556 +							<td>Build duration</td>
   1.557 +							<td colspan="2">$(sed -n '/^Cook time/s|[^:]*: \(.*\)|\1|p' $LOGS/slitaz-toolchain.log)</td>
   1.558 +						</tr>
   1.559 +						<tr>
   1.560 +							<td>Architecture</td>
   1.561 +							<td colspan="2">$ARCH</td>
   1.562 +						</tr>
   1.563 +						<tr>
   1.564 +							<td>Host system</td>
   1.565 +							<td colspan="2">$BUILD_SYSTEM</td>
   1.566 +						</tr>
   1.567 +						<tr>
   1.568 +							<td>Target system</td>
   1.569 +							<td colspan="2">$HOST_SYSTEM</td>
   1.570 +						</tr>
   1.571 +						<tr>
   1.572 +							<th>Package</th>
   1.573 +							<th>Version</th>
   1.574 +							<th>Description</th>
   1.575 +						</tr>
   1.576 +						$(toolchain_version slitaz-toolchain)
   1.577 +						$(toolchain_version binutils)
   1.578 +						$(toolchain_version linux-api-headers)
   1.579 +						$(toolchain_version gcc)
   1.580 +						$(toolchain_version glibc)
   1.581 +					</table>
   1.582  
   1.583 -<p>Toolchain documentation: <a target="_blank" rel="noopener noreferrer"
   1.584 -href="http://doc.slitaz.org/en:cookbook:toolchain">http://doc.slitaz.org/en:cookbook:toolchain</a>
   1.585 -</p>
   1.586 +					<p>Toolchain documentation: <a target="_blank" rel="noopener noreferrer"
   1.587 +					href="http://doc.slitaz.org/en:cookbook:toolchain">http://doc.slitaz.org/en:cookbook:toolchain</a>
   1.588 +					</p>
   1.589  
   1.590 -</section>
   1.591 -</div>
   1.592 -EOT
   1.593 +					</section>
   1.594 +					</div>
   1.595 +				EOT
   1.596  				;;
   1.597  			maintainer*)
   1.598  				maintainer=$(GET maintainer); maintainer=${maintainer/maintainer/}
   1.599  				regexp=$(GET regexp); regexp=${regexp/regexp/}
   1.600  				[ -n "$regexp" ] && maintainer=''
   1.601 -				cat <<EOT
   1.602 -<section>
   1.603 -	<h2>For maintainers</h2>
   1.604 -	<p>Check packages version either for specified maintainer or using regular expression:</p>
   1.605 -	<form>
   1.606 -		<select name="maintainer">
   1.607 -			<option value=''>--- select maintainer ---
   1.608 -EOT
   1.609 +				cat <<-EOT
   1.610 +					<section>
   1.611 +						<h2>For maintainers</h2>
   1.612 +						<p>Here you can <a href="%/">explore the badges</a>.</p>
   1.613 +						<p>Or see some <a href="?maintainer&amp;stats">repository statistics</a>.</p>
   1.614 +						<p>Or check packages version either for specified maintainer or using regular expression:</p>
   1.615 +						<form>
   1.616 +							<select name="maintainer">
   1.617 +								<option value=''>--- select maintainer ---
   1.618 +				EOT
   1.619  				cut -d$'\t' -f1 $maintdb | sort -u \
   1.620  				| awk -vm=$maintainer '{
   1.621  					selected=$0==m?"selected":""
   1.622  					printf("<option %s value=\"%s\">%s\n", selected, $0, $0)
   1.623  				}'
   1.624 -				cat <<EOT
   1.625 -
   1.626 -		</select>
   1.627 -		or
   1.628 -		<input type="text" name="regexp" value="$regexp"/>
   1.629 -		<button type="submit">Go</button>
   1.630 -	</form>
   1.631 -EOT
   1.632 +				cat <<-EOT
   1.633 +							</select>
   1.634 +							or
   1.635 +							<input type="text" name="regexp" value="$regexp"/>
   1.636 +							<button type="submit">Go</button>
   1.637 +						</form>
   1.638 +				EOT
   1.639  				if [ -n "$maintainer" -o -n "$regexp" ]; then
   1.640  					tmp_status=$(mktemp)
   1.641 -					cat <<EOT
   1.642 -	<table class="maint">
   1.643 -		<thead><tr><th>Package</th><th>Version</th><th>Repology</th></tr></thead>
   1.644 -EOT
   1.645 +					cat <<-EOT
   1.646 +						<table class="maint">
   1.647 +						<thead><tr><th>Package</th><th>Version</th><th>Repology</th></tr></thead>
   1.648 +					EOT
   1.649  					{
   1.650  						if [ -n "$maintainer" ]; then
   1.651  							awk -vm=$maintainer '{if ($1 == m) print $2}' $maintdb
   1.652 @@ -1206,13 +1422,13 @@
   1.653  							repo_info1="<a class='icon $icon' href='https://repology.org/metapackage/$REPOLOGY' target='_blank'"
   1.654  							repo_info2="rel='noopener noreferrer' title='latest packaged version(s)'>${repo_ver// /, }</a>"
   1.655  						fi
   1.656 -						cat <<EOT
   1.657 -		<tr>
   1.658 -			<td><img src="$base/s/$pkg"> <a href="$pkg">$pkg</a></td>
   1.659 -			<td>${ver:-$VERSION}</td>
   1.660 -			<td>$repo_info1 $repo_info2</td>
   1.661 -		</tr>
   1.662 -EOT
   1.663 +						cat <<-EOT
   1.664 +							<tr>
   1.665 +								<td><img src="$base/s/$pkg" alt="$pkg"> <a href="$pkg">$pkg</a></td>
   1.666 +								<td>${ver:-$VERSION}</td>
   1.667 +								<td>$repo_info1 $repo_info2</td>
   1.668 +							</tr>
   1.669 +						EOT
   1.670  					done
   1.671  
   1.672  					pkg_total=$(   wc -l      < $tmp_status)
   1.673 @@ -1228,19 +1444,19 @@
   1.674  					[ "$pkg_outdated" -eq 0 ] && pkg_outdated=''
   1.675  					[ "$pkg_unknown"  -eq 0 ] && pkg_unknown=''
   1.676  
   1.677 -					cat <<EOT
   1.678 -	</table>
   1.679 +					cat <<-EOT
   1.680 +						</table>
   1.681  
   1.682 -	<div class="meter" style="width:100%;text-align:center"><div
   1.683 -	style="display:inline-block;background-color:#090;width:$pct_actual%">$pkg_actual</div><div
   1.684 -	style="display:inline-block;background-color:#f90;width:$pct_outdated%">$pkg_outdated</div><div
   1.685 -	style="display:inline-block;background-color:#ccc;width:$pct_unknown%">$pkg_unknown</div></div>
   1.686 -EOT
   1.687 +						<div class="meter" style="width:100%;text-align:center"><div
   1.688 +						style="display:inline-block;background-color:#090;width:$pct_actual%">$pkg_actual</div><div
   1.689 +						style="display:inline-block;background-color:#f90;width:$pct_outdated%">$pkg_outdated</div><div
   1.690 +						style="display:inline-block;background-color:#ccc;width:$pct_unknown%">$pkg_unknown</div></div>
   1.691 +					EOT
   1.692  					rm $tmp_status
   1.693  				fi
   1.694 -				cat <<EOT
   1.695 -</section>
   1.696 -EOT
   1.697 +				cat <<-EOT
   1.698 +					</section>
   1.699 +				EOT
   1.700  				;;
   1.701  		esac
   1.702  		page_footer
   1.703 @@ -1258,29 +1474,29 @@
   1.704  	# Main page with summary. Count only packages included in ARCH,
   1.705  	# use 'cooker arch-db' to manually create arch.$ARCH files.
   1.706  
   1.707 -	cat <<EOT
   1.708 -<div id="content2">
   1.709 +	cat <<-EOT
   1.710 +		<div id="content2">
   1.711  
   1.712 -<section>
   1.713 -<form method="get" action="" class="search r">
   1.714 -	<input type="hidden" name="search" value="pkg"/>
   1.715 -	<button type="submit" title="Search">Search</button>
   1.716 -	<input type="search" name="q" placeholder="Package" list="packages" autocorrect="off" autocapitalize="off"/>
   1.717 -</form>
   1.718 -EOT
   1.719 +		<section>
   1.720 +		<form method="get" action="" class="search r">
   1.721 +			<input type="hidden" name="search" value="pkg"/>
   1.722 +			<button type="submit" title="Search">Search</button>
   1.723 +			<input type="search" name="q" placeholder="Package" list="packages" autocorrect="off" autocapitalize="off"/>
   1.724 +		</form>
   1.725 +	EOT
   1.726  
   1.727  	unset nojs
   1.728  	part summary
   1.729  	part webstat
   1.730  
   1.731 -	cat <<EOT
   1.732 -<p>
   1.733 -	Service logs:
   1.734 -	<a href="?cookorder.log">cookorder</a> ·
   1.735 -	<a href="?commits.log">commits</a> ·
   1.736 -	<a href="?pkgdb.log">pkgdb</a>
   1.737 -</p>
   1.738 -EOT
   1.739 +	cat <<-EOT
   1.740 +		<p>
   1.741 +			Service logs:
   1.742 +			<a href="?cookorder.log">cookorder</a> ·
   1.743 +			<a href="?commits.log">commits</a> ·
   1.744 +			<a href="?pkgdb.log">pkgdb</a>
   1.745 +		</p>
   1.746 +	EOT
   1.747  
   1.748  	if [ -e "$CACHE/cooker-request" -a ! -s $command ]; then
   1.749  		if [ "$activity" -nt "$CACHE/cooker-request" ]; then
   1.750 @@ -1290,10 +1506,11 @@
   1.751  		fi
   1.752  	fi
   1.753  
   1.754 -	cat <<EOT
   1.755 -<a class="button icon maintainers" href="?maintainer">For maintainers</a>
   1.756 -</section>
   1.757 -EOT
   1.758 +	cat <<-EOT
   1.759 +		<a class="button icon maintainers" href="?maintainer">For maintainers</a>
   1.760 +		<a class="button icon tag" href="~/">Tags</a>
   1.761 +		</section>
   1.762 +	EOT
   1.763  
   1.764  	part activity
   1.765  	part cooknotes
   1.766 @@ -1312,30 +1529,91 @@
   1.767  
   1.768  # show tag
   1.769  
   1.770 -if [ "$pkg" == '~' -a -n "$cmd" ]; then
   1.771 -	tag="$cmd"
   1.772 +if [ "$pkg" == '~' ]; then
   1.773  	page_header
   1.774 -	cat <<EOT
   1.775 -<div id="content2">
   1.776 -<section>
   1.777 -<h2>Tag “$tag”</h2>
   1.778 +	echo '<div id="content2"><section>'
   1.779  
   1.780 -<table>
   1.781 -	<thead>
   1.782 -		<tr><th>Name</th><th>Description</th><th>Category</th></tr>
   1.783 -	</thead>
   1.784 -	<tbody>
   1.785 -EOT
   1.786 -	sort $PKGS/packages.info \
   1.787 -	| awk -F$'\t' -vtag=" $tag " -vbase="$base" '{
   1.788 -		if (index(" " $6 " ", tag)) {
   1.789 -			url = base "/" $1 "/";
   1.790 -			gsub("+", "%2B", url);
   1.791 -			printf("<tr><td><img src=\"%s/s/%s\"> ", base, $1);
   1.792 -			printf("<a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\n", url, $1, $4, $3);
   1.793 -		}
   1.794 -	}'
   1.795 -	echo '</tbody></table></section></div>'
   1.796 +	if [ -n "$cmd" ]; then
   1.797 +		tag="$cmd"
   1.798 +		cat <<-EOT
   1.799 +			<h2>Tag “$tag”</h2>
   1.800 +
   1.801 +			<table>
   1.802 +				<thead><tr><th>Name</th><th>Description</th><th>Category</th></tr></thead>
   1.803 +				<tbody>
   1.804 +		EOT
   1.805 +		sort $PKGS/packages-$ARCH.info \
   1.806 +		| awk -F$'\t' -vtag=" $tag " -vbase="$base/" '{
   1.807 +			if (index(" " $6 " ", tag)) {
   1.808 +				url = base $1 "/";
   1.809 +				gsub("+", "%2B", url);
   1.810 +				printf("<tr><td><img src=\"%ss/%s\" alt=\"%s\"> ", base, $1, $1);
   1.811 +				printf("<a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\n", url, $1, $4, $3);
   1.812 +			}
   1.813 +		}'
   1.814 +		echo '</tbody></table>'
   1.815 +	else
   1.816 +		# Fast and nice tag cloud
   1.817 +		echo '<h2>Tag cloud</h2><p class="tags">'
   1.818 +		# Some magic in tag sizes :-) It's because of non-linear distribution
   1.819 +		# of tags. Currently 1x198 (each of 198 tags marks one package);
   1.820 +		# 2x79 (each of 79 other tags marks two packages); 3x28 (and so on);
   1.821 +		# 4x23; 5x14; 6x5; 7x9; 8x11; 9x4; 10x3; 11x5; 12x6; 13x3; 14x1; 15x1;
   1.822 +		# 16x2; 18x1; 20x3; 22x3; 23, 24, 27, 33, 39, 42, 45, 57, 59, 65, 90x1.
   1.823 +		awk -F$'\t' -vbase="$base/~/" '
   1.824 +			{
   1.825 +				split($6, tags, " ");
   1.826 +				for (i in tags) { tag[tags[i]]++; if (tag[tags[i]] > max) max = tag[tags[i]]; }
   1.827 +			}
   1.828 +		END {
   1.829 +				for (i in tag) {
   1.830 +					j = tag[i];
   1.831 +					size = (j == 1) ? 0 : (j == 2) ? 1 : (j < 5) ? 2 : (j < 9) ? 3 : (j < 18) ? 4 : 5;
   1.832 +					printf("<a href=\"%s\" class=\"tag%s\">%s<sup>%s</sup></a>\n", base i, size, i, tag[i]);
   1.833 +				}
   1.834 +			}
   1.835 +		' $PKGS/packages-$ARCH.info | sort -f # sort alphabetically case insensitive
   1.836 +	fi
   1.837 +	echo '</p></section></div>'
   1.838 +	page_footer
   1.839 +	exit 0
   1.840 +fi
   1.841 +
   1.842 +
   1.843 +# show badges
   1.844 +
   1.845 +if [ "$pkg" == '%' ]; then
   1.846 +	page_header
   1.847 +	echo '<div id="content2">'
   1.848 +
   1.849 +	if [ -n "$cmd" ]; then
   1.850 +		badge="$cmd"
   1.851 +		cat <<-EOT
   1.852 +			<section>
   1.853 +				<h2 class="badge $badge"> Badge “$badge”</h2>
   1.854 +
   1.855 +				<table>
   1.856 +					<thead><tr><th>Name</th><th>Description</th><th>Category</th></tr></thead>
   1.857 +					<tbody>
   1.858 +		EOT
   1.859 +		ls $WOK \
   1.860 +		| while read pkg; do
   1.861 +			[ -e $WOK/$pkg/.badges ] || continue
   1.862 +			grep -q "^${badge}$" $WOK/$pkg/.badges &&
   1.863 +			awk -F$'\t' -vpkg="$pkg" -vbase="$base/" '{
   1.864 +				if ($1 == pkg) {
   1.865 +					url = base $1 "/";
   1.866 +					gsub("+", "%2B", url);
   1.867 +					printf("<tr><td><img src=\"%ss/%s\" alt=\"%s\"> ", base, $1, $1);
   1.868 +					printf("<a href=\"%s\">%s</a></td><td>%s</td><td>%s</td></tr>\n", url, $1, $4, $3);
   1.869 +				}
   1.870 +			}' $PKGS/packages-$ARCH.info
   1.871 +		done
   1.872 +		echo '</tbody></table></section>'
   1.873 +	else
   1.874 +		layout='list' show_badges bdbroken broken any noany libtool nolibtool own ownover perm permover symlink ss fadd frem fdup old orphan patch win
   1.875 +	fi
   1.876 +	echo '</div>'
   1.877  	page_footer
   1.878  	exit 0
   1.879  fi
   1.880 @@ -1396,17 +1674,23 @@
   1.881  		summary "$log"
   1.882  
   1.883  
   1.884 +		# Show Cooker badges
   1.885 +		if [ -s $wok/$pkg/.badges ]; then
   1.886 +			layout='table' show_badges $(cat $wok/$pkg/.badges)
   1.887 +		fi
   1.888 +
   1.889 +
   1.890  		# Repology badge
   1.891 -		[ "$REPOLOGY" == '-' ] || cat <<EOT
   1.892 -<section>
   1.893 -	<h3>Repology</h3>
   1.894 -	<a href="https://repology.org/metapackage/${REPOLOGY:-$pkg}" target='_blank'
   1.895 -	rel='noopener noreferrer' title="latest packaged version(s) by Repology">
   1.896 -	<img src="https://repology.org/badge/latest-versions/${REPOLOGY:-$pkg}.svg" alt="latest packaged version(s)">
   1.897 -	<img src="https://repology.org/badge/tiny-repos/${REPOLOGY:-$pkg}.svg" alt="Packaging status">
   1.898 -	</a>
   1.899 -</section>
   1.900 -EOT
   1.901 +		[ "$REPOLOGY" == '-' ] || cat <<-EOT
   1.902 +			<section>
   1.903 +				<h3>Repology</h3>
   1.904 +				<a href="https://repology.org/metapackage/${REPOLOGY:-$pkg}" target='_blank'
   1.905 +				rel='noopener noreferrer' title="latest packaged version(s) by Repology">
   1.906 +				<img src="https://repology.org/badge/latest-versions/${REPOLOGY:-$pkg}.svg" alt="latest packaged version(s)">
   1.907 +				<img src="https://repology.org/badge/tiny-repos/${REPOLOGY:-$pkg}.svg" alt="Packaging status">
   1.908 +				</a>
   1.909 +			</section>
   1.910 +			EOT
   1.911  
   1.912  
   1.913  		# Show tag list
   1.914 @@ -1463,23 +1747,23 @@
   1.915  			done
   1.916  		} | sort -u > $inf/c
   1.917  
   1.918 -		cat <<EOT
   1.919 -<section>
   1.920 -	<h3>Related packages</h3>
   1.921 -	<table class="third">
   1.922 -		<thead>
   1.923 -			<tr>
   1.924 -				<th>Build dependencies</th>
   1.925 -				<th>Runtime dependencies</th>
   1.926 -				<th>Required by</th>
   1.927 -			</tr>
   1.928 -		</thead>
   1.929 -		<tbody>
   1.930 -EOT
   1.931 +		cat <<-EOT
   1.932 +			<section>
   1.933 +				<h3>Related packages</h3>
   1.934 +				<table class="third">
   1.935 +					<thead>
   1.936 +						<tr>
   1.937 +							<th>Build dependencies</th>
   1.938 +							<th>Runtime dependencies</th>
   1.939 +							<th>Required by</th>
   1.940 +						</tr>
   1.941 +					</thead>
   1.942 +					<tbody>
   1.943 +		EOT
   1.944  
   1.945  		awk -vinf="$inf" -vbase="$base" '
   1.946  			function linki(i) {
   1.947 -				if (i) return sprintf("<img src=\"%s/s/%s\"> <a href=\"%s/%s\">%s</a>", base, i, base, i, i);
   1.948 +				if (i) return sprintf("<img src=\"%s/s/%s\" alt=\"%s\"> <a href=\"%s/%s\">%s</a>", base, i, i, base, i, i);
   1.949  			}
   1.950  			BEGIN{
   1.951  				do {
   1.952 @@ -1490,11 +1774,11 @@
   1.953  					printf("<tr><td>%s </td><td>%s </td><td>%s </td></tr>", linki(a), linki(b), linki(c));
   1.954  				} while ( a b c )
   1.955  			}'
   1.956 -		cat <<EOT
   1.957 -		</tbody>
   1.958 -	</table>
   1.959 -</section>
   1.960 -EOT
   1.961 +		cat <<-EOT
   1.962 +					</tbody>
   1.963 +				</table>
   1.964 +			</section>
   1.965 +		EOT
   1.966  		# Clean
   1.967  		rm -r $inf
   1.968  
   1.969 @@ -1539,6 +1823,7 @@
   1.970  			case $file in
   1.971  				*.desktop|*.theme)   class="ini" ;;
   1.972  				*.patch|*.diff|*.u)  class="diff" ;;
   1.973 +				*/patches/series)    class="bash";;
   1.974  				*.sh)                class="bash" ;;
   1.975  				*.conf*|*.ini)
   1.976  					class="bash"
   1.977 @@ -1572,7 +1857,7 @@
   1.978  			# Display image
   1.979  			case $file in
   1.980  				*.png|*.svg|*.jpg|*.jpeg|*.ico)
   1.981 -					echo "<img src='$base/$pkg/browse/stuff/$arg' style='display: block; max-width: 100%; margin: auto'/>"
   1.982 +					echo "<img src='$base/$pkg/browse/stuff/$arg' style='display: block; max-width: 100%; margin: auto' alt=''/>"
   1.983  					;;
   1.984  			esac
   1.985  
   1.986 @@ -1672,17 +1957,17 @@
   1.987  						esac
   1.988  						echo -e '\t<ul>'
   1.989  						echo "$pkgsofset" | sed 'p' | xargs printf "\t\t<li><a href='#%s'>%s</a></li>\n"
   1.990 -						cat <<EOT
   1.991 -		<li id='li-repeats$set' style='display:none'>
   1.992 -			<a href='#repeats$set'>repeatedly packaged files</a></li>
   1.993 -		<li id='li-empty$set' style='display:none'>
   1.994 -			<a href='#empty$set'>unpackaged empty folders</a></li>
   1.995 -		<li id='li-outoftree$set' style='display:none'>
   1.996 -			<a href='#outoftree$set'>out-of-tree files</a></li>
   1.997 -		<li id='li-orphans$set' style='display:none'>
   1.998 -			<a href='#orphans$set'>unpackaged files</a>
   1.999 -			<span id='orphansTypes$set'></span></li>
  1.1000 -EOT
  1.1001 +						cat <<-EOT
  1.1002 +							<li id='li-repeats$set' style='display:none'>
  1.1003 +								<a href='#repeats$set'>repeatedly packaged files</a></li>
  1.1004 +							<li id='li-empty$set' style='display:none'>
  1.1005 +								<a href='#empty$set'>unpackaged empty folders</a></li>
  1.1006 +							<li id='li-outoftree$set' style='display:none'>
  1.1007 +								<a href='#outoftree$set'>out-of-tree files</a></li>
  1.1008 +							<li id='li-orphans$set' style='display:none'>
  1.1009 +								<a href='#orphans$set'>unpackaged files</a>
  1.1010 +								<span id='orphansTypes$set'></span></li>
  1.1011 +						EOT
  1.1012  						echo -e '\t</ul>'
  1.1013  						[ -n "$splitsets" ] && echo "</li>"
  1.1014  						;;
  1.1015 @@ -1697,7 +1982,7 @@
  1.1016  						for p in $pkgsofset; do
  1.1017  							namever="$(awk -F$'\t' -vp="$p" '{
  1.1018  								if ($1==p) {printf("%s-%s\n", $1, $2); exit}
  1.1019 -								}' $PKGS/packages.info)"
  1.1020 +								}' $PKGS/packages-$ARCH.info)"
  1.1021  							if [ -d "$wok/$p/taz/$p-$ver" ]; then
  1.1022  								indir=$p
  1.1023  							elif [ -d "$wok/$main/taz/$p-$ver" ]; then
  1.1024 @@ -1739,10 +2024,12 @@
  1.1025  						repeats=$(mktemp)
  1.1026  						sort $packaged | uniq -d > $repeats
  1.1027  						if [ -s "$repeats" ]; then
  1.1028 -							echo
  1.1029 -							echo "<script>document.getElementById('li-repeats$set').style.display = 'list-item'</script>"
  1.1030 -							echo "<section id='repeats$set'>"
  1.1031 -							echo "	<h3>Repeatedly packaged files$set_description:</h3>"
  1.1032 +							cat <<-EOT
  1.1033 +
  1.1034 +								<script>document.getElementById('li-repeats$set').style.display = 'list-item'</script>
  1.1035 +								<section id='repeats$set'>
  1.1036 +									<h3>Repeatedly packaged files$set_description:</h3>
  1.1037 +							EOT
  1.1038  							cd $install
  1.1039  
  1.1040  							IFS=$'\n'
  1.1041 @@ -1753,8 +2040,10 @@
  1.1042  								| syntax_highlighter files \
  1.1043  								| sed 's|>\./|>/|'
  1.1044  							done < $repeats
  1.1045 -							echo '</pre>'
  1.1046 -							echo '</section>'
  1.1047 +							cat <<-EOT
  1.1048 +								</pre>
  1.1049 +								</section>
  1.1050 +							EOT
  1.1051  							unset IFS
  1.1052  						fi
  1.1053  						rm $repeats
  1.1054 @@ -1790,15 +2079,19 @@
  1.1055  						done > $emptydirs
  1.1056  						unset IFS
  1.1057  						if [ -s "$emptydirs" ]; then
  1.1058 -							echo
  1.1059 -							echo "<script>document.getElementById('li-empty$set').style.display = 'list-item'</script>"
  1.1060 -							echo "<section id='empty$set'>"
  1.1061 -							echo "	<h3>Unpackaged empty folders$set_description:</h3>"
  1.1062 +							cat <<-EOT
  1.1063 +
  1.1064 +								<script>document.getElementById('li-empty$set').style.display = 'list-item'</script>
  1.1065 +								<section id='empty$set'>
  1.1066 +									<h3>Unpackaged empty folders$set_description:</h3>
  1.1067 +							EOT
  1.1068  							echo -n '	<pre class="files">'
  1.1069  							echo -en '<span class="underline">permissions·lnk·user    ·group   ·     size·date &amp; time ·name\n</span>'
  1.1070  							cat $emptydirs
  1.1071 -							echo '</pre>'
  1.1072 -							echo '</section>'
  1.1073 +							cat <<-EOT
  1.1074 +								</pre>
  1.1075 +								</section>
  1.1076 +							EOT
  1.1077  						fi
  1.1078  						rm $emptydirs
  1.1079  						# ------------------------------------------------------
  1.1080 @@ -1892,7 +2185,9 @@
  1.1081  							/\.h$/ || /\.a$/ || /\.pc$/ || /\/bin\/.*-config$/ ||
  1.1082  								/\/Makefile.*$/ { tag("dev", 3); next }
  1.1083  							/\/share\/help\// || /\/share\/appdata\// ||
  1.1084 -							/\/share\/metainfo\// { tag("gnm", 6); next }
  1.1085 +							/\/share\/metainfo\// || /\/share\/application-registry\// ||
  1.1086 +							/\/share\/mime-info\// || /\/share\/gnome\/help\// || /\/share\/omf\// {
  1.1087 +								tag("gnm", 6); next }
  1.1088  							{ tag("???", 1) }
  1.1089  							' "$orphans" > $table
  1.1090  
  1.1091 @@ -2042,7 +2337,7 @@
  1.1092  		# disable next `sed` for the 'like2016' theme
  1.1093  		theme=$(COOKIE theme); theme=${theme:-default}; [ "$theme" != 'like2016' ] && theme=''
  1.1094  		cat $logfile | syntax_highlighter log | \
  1.1095 -		sed -e "/(pkg\/local$theme):/ s|: \([^<]*\)|<img src='$base/i/$blog/\1'> \1|" | \
  1.1096 +		sed -e "/(pkg\/local$theme):/ s|: \([^<]*\)|<img src='$base/i/$blog/\1' alt=''> \1|" | \
  1.1097  		awk '
  1.1098  		BEGIN { print "<pre class=\"log\">"; }
  1.1099  		      { printf("<span id=\"l%d\">%s</span><a href=\"#l%d\"></a>\n", NR, $0, NR); }
  1.1100 @@ -2138,14 +2433,14 @@
  1.1101  								wok/*) page="${arg#wok/}"; page="$base/$pkg/browse/${page#*/}";;
  1.1102  								*)     page="$base/$pkg/browse/install/usr/share/$cmd/$arg";;
  1.1103  							esac
  1.1104 -							cat <<EOT
  1.1105 -<object id="idoc" data="$page" width="100%" height="100%" type="application/pdf" style="min-height: 600px">
  1.1106 -	$(show_note w "Missing PDF plugin.<br/>Get the file <a href="$page">$(basename "$page")</a>.")
  1.1107 -</object>
  1.1108 -EOT
  1.1109 +							cat <<-EOT
  1.1110 +								<object id="idoc" data="$page" width="100%" height="100%" type="application/pdf" style="min-height: 600px">
  1.1111 +									$(show_note w "Missing PDF plugin.<br/>Get the file <a href="$page">$(basename "$page")</a>.")
  1.1112 +								</object>
  1.1113 +							EOT
  1.1114  							;;
  1.1115  						*.md|*.markdown)
  1.1116 -							echo '<section>'
  1.1117 +							echo '<section class="markdown">'
  1.1118  							$md2html "$tmp" | sed 's|class="|class="language-|g'
  1.1119  							echo '</section>'
  1.1120  							;;
  1.1121 @@ -2204,7 +2499,7 @@
  1.1122  
  1.1123  		if [ -n "$TARBALL" -a -s "$SRC/$TARBALL" ]; then
  1.1124  			files_header
  1.1125 -			echo "<tr><td><a href='$base/src/$TARBALL'>$TARBALL</a></td>"
  1.1126 +			echo "<tr><td><a href='$base/src/$TARBALL' class='icon tarball'>$TARBALL</a></td>"
  1.1127  			ls -lh "$SRC/$TARBALL" | awk '{printf("<td>%sB</td>", $5)}'
  1.1128  			echo "<td>Sources for building the package “$pkg”</td></tr>"
  1.1129  			show=1
  1.1130 @@ -2214,19 +2509,25 @@
  1.1131  			[ "$show" -eq 1 ] || files_header
  1.1132  
  1.1133  			common_version=$VERSION
  1.1134 -			for i in $(all_names); do
  1.1135 +			for i in $(all_names | tr ' ' '\n' | sort); do
  1.1136  				[ -e "$wok/$pkg/taz/$i-$common_version$EXTRAVERSION/receipt" ] || continue
  1.1137  				. $wok/$pkg/taz/$i-$common_version$EXTRAVERSION/receipt
  1.1138  
  1.1139 -				for filename in "$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" "$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg"; do
  1.1140 -					[ -f "$PKGS/$filename" ] &&
  1.1141 -						cat <<EOT
  1.1142 -<tr>
  1.1143 -<td><a href="$base/get/$filename">$filename</a></td>
  1.1144 -<td>$(ls -lh ./packages/$filename | awk '{printf("%sB", $5)}')</td>
  1.1145 -<td>$SHORT_DESC</td>
  1.1146 -</tr>
  1.1147 -EOT
  1.1148 +				for filename in "$PACKAGE-$VERSION$EXTRAVERSION.tazpkg" "$PACKAGE-$VERSION$EXTRAVERSION-$ARCH.tazpkg" "$PACKAGE-$VERSION$EXTRAVERSION-any.tazpkg"; do
  1.1149 +					[ -f "$PKGS/$filename" ] || continue
  1.1150 +
  1.1151 +					case $filename in
  1.1152 +						*-x86_64.tazpkg) class='pkg64';;
  1.1153 +						*-any.tazpkg)    class='pkgany';;
  1.1154 +						*)               class='pkg32';;
  1.1155 +					esac
  1.1156 +					cat <<-EOT
  1.1157 +						<tr>
  1.1158 +							<td><a href="$base/get/$filename" class='icon $class'>$filename</a></td>
  1.1159 +							<td>$(ls -lh ./packages/$filename | awk '{printf("%sB", $5)}')</td>
  1.1160 +							<td>$SHORT_DESC</td>
  1.1161 +						</tr>
  1.1162 +					EOT
  1.1163  				done
  1.1164  			done
  1.1165  			show=1