Improve bulk downloads page

This commit is contained in:
Alex Cabal 2022-07-09 10:28:13 -05:00
parent d659fb9649
commit dbc2fd5fcd
5 changed files with 91 additions and 13 deletions

View file

@ -6,7 +6,7 @@ PHP 7+ is required.
```shell ```shell
# Install Apache, PHP, PHP-FPM, and various other dependencies. # Install Apache, PHP, PHP-FPM, and various other dependencies.
sudo apt install -y git composer php-fpm php-cli php-gd php-xml php-apcu php-mbstring php-intl php-curl php-zip apache2 apache2-utils libfcgi0ldbl task-spooler ipv6calc mariadb-server libaprutil1-dbd-mysql sudo apt install -y git composer php-fpm php-cli php-gd php-xml php-apcu php-mbstring php-intl php-curl php-zip apache2 apache2-utils libfcgi0ldbl task-spooler ipv6calc mariadb-server libaprutil1-dbd-mysql attr
# Create the site root and logs root and clone this repo into it. # Create the site root and logs root and clone this repo into it.
sudo mkdir /standardebooks.org/ sudo mkdir /standardebooks.org/

View file

@ -39,4 +39,30 @@ class Formatter{
public static function ToPlainXmlText(?string $text): string{ public static function ToPlainXmlText(?string $text): string{
return htmlspecialchars(trim($text ?? ''), ENT_QUOTES|ENT_XML1, 'utf-8'); return htmlspecialchars(trim($text ?? ''), ENT_QUOTES|ENT_XML1, 'utf-8');
} }
public static function ToFileSize(?int $bytes): string{
// See https://stackoverflow.com/a/5501447
$output = '';
if($bytes >= 1073741824){
$output = number_format(round($bytes / 1073741824, 1), 1) . 'G';
}
elseif($bytes >= 1048576){
$output = number_format(round($bytes / 1048576, 1), 1) . 'M';
}
elseif($bytes >= 1024){
$output = number_format($bytes / 1024, 2) . 'KB';
}
elseif($bytes > 1){
$output = $bytes . ' bytes';
}
elseif($bytes == 1){
$output = $bytes . ' byte';
}
else{
$output = '0 bytes';
}
return $output;
}
} }

View file

@ -93,5 +93,9 @@ foreach($ebooksByMonth as $month => $ebooks){
$zip->close(); $zip->close();
rename($tempFilename, $filePath); rename($tempFilename, $filePath);
// Set a filesystem attribute for the number of ebooks in the file. This will be used
// to display that number on the downloads page.
exec('attr -q -s ebook-count -V ' . escapeshellarg(sizeof($ebooks)) . ' ' . escapeshellarg($filePath));
} }
} }

View file

@ -679,18 +679,40 @@ ul.message.error li:only-child{
margin-right: auto; margin-right: auto;
} }
ul.download-list i{ ul.download-list thead{
font-style: italic;
}
ul.download-list table thead td{
padding-top: 0;
padding-bottom: 0;
}
ul.download-list table td{
padding: .25rem;
}
ul.download-list table td + td{
text-align: right;
white-space: nowrap;
}
ul.download-list tbody td + td{
color: var(--sub-text); color: var(--sub-text);
} }
main > section.narrow > ul.download-list{
width: auto;
max-width: none;
}
ul.download-list{ ul.download-list{
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
gap: 4rem; gap: 4rem;
list-style: none; list-style: none;
margin-top: 4rem; margin-top: 4rem;
margin-left: auto;
margin-right: auto;
} }
ul.download-list > li{ ul.download-list > li{
@ -706,8 +728,17 @@ ul.download-list > li li:first-of-type{
margin-top: 1rem; margin-top: 1rem;
} }
.bulk-downloads h2{ ul.download-list p.header{
font-size: 1.4rem;
font-family: "League Spartan", Arial, sans-serif;
margin-top: 4rem;
line-height: 1.2;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--header);
margin-top: 0; margin-top: 0;
margin-bottom: 1rem;
text-align: center;
} }
.ebooks nav li.highlighted a:focus, .ebooks nav li.highlighted a:focus,

View file

@ -18,7 +18,13 @@ foreach($files as $file){
$updated = new DateTime('@' . filemtime($file)); $updated = new DateTime('@' . filemtime($file));
$obj->Month = $date->format('F'); $obj->Month = $date->format('F');
$obj->Url = '/patrons-circle/downloads/' . basename($file); $obj->Url = '/patrons-circle/downloads/' . basename($file);
$obj->Size = Formatter::ToFileSize(filesize($file));
$obj->Updated = $updated->format('M i'); $obj->Updated = $updated->format('M i');
// The count of ebooks in each file is stored as a filesystem attribute
$obj->Count = exec('attr -g ebook-count ' . escapeshellarg($file)) ?: null;
if($obj->Count !== null){
$obj->Count = intval($obj->Count);
}
if($updated->format('Y') != gmdate('Y')){ if($updated->format('Y') != gmdate('Y')){
$obj->Updated = $obj->Updated . $updated->format(', Y'); $obj->Updated = $obj->Updated . $updated->format(', Y');
@ -33,10 +39,10 @@ foreach($files as $file){
$years[$year][] = $obj; $years[$year][] = $obj;
} }
?><?= Template::Header(['title' => 'Bulk Ebook Download', 'highlight' => '', 'description' => 'Download zip files containing all of the Standard Ebooks released in a given month.']) ?> ?><?= Template::Header(['title' => 'Bulk Ebook Downloads', 'highlight' => '', 'description' => 'Download zip files containing all of the Standard Ebooks released in a given month.']) ?>
<main> <main>
<section class="narrow bulk-downloads has-hero"> <section class="narrow bulk-downloads has-hero">
<h1>Bulk Ebook Download</h1> <h1>Bulk Ebook Downloads</h1>
<picture> <picture>
<source srcset="/images/the-shop-of-the-bookdealer@2x.avif 2x, /images/the-shop-of-the-bookdealer.avif 1x" type="image/avif"/> <source srcset="/images/the-shop-of-the-bookdealer@2x.avif 2x, /images/the-shop-of-the-bookdealer.avif 1x" type="image/avif"/>
<source srcset="/images/the-shop-of-the-bookdealer@2x.jpg 2x, /images/the-shop-of-the-bookdealer.jpg 1x" type="image/jpg"/> <source srcset="/images/the-shop-of-the-bookdealer@2x.jpg 2x, /images/the-shop-of-the-bookdealer.jpg 1x" type="image/jpg"/>
@ -55,14 +61,25 @@ foreach($files as $file){
<ul class="download-list"> <ul class="download-list">
<? foreach($years as $year => $items){ ?> <? foreach($years as $year => $items){ ?>
<li> <li>
<section> <p class="header"><?= Formatter::ToPlainText($year) ?></p>
<h2><?= Formatter::ToPlainText($year) ?></h2> <table>
<ul> <thead>
<td></td>
<td>Ebooks</td>
<td>Size</td>
<td>Updated</td>
</thead>
<tbody>
<? foreach($items as $item){ ?> <? foreach($items as $item){ ?>
<li><p><a download="" href="<?= Formatter::ToPlainText($item->Url) ?>"><?= Formatter::ToPlainText($item->Month) ?></a> <i>(Updated <?= Formatter::ToPlainText($obj->Updated) ?>)</i></p></li> <tr>
<td><a download="" href="<?= Formatter::ToPlainText($item->Url) ?>"><?= Formatter::ToPlainText($item->Month) ?></a></td>
<td><?= Formatter::ToPlainText(number_format($item->Count)) ?></td>
<td><?= Formatter::ToPlainText($item->Size) ?></td>
<td><?= Formatter::ToPlainText($obj->Updated) ?></td>
</tr>
<? } ?> <? } ?>
</ul> </tbody>
</section> </table>
</li> </li>
<? } ?> <? } ?>
</ul> </ul>