new-life-introductory-band/website/s3-dir-listing.html
2017-02-17 15:30:02 -06:00

252 lines
6.4 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
<title>Directory Listing</title>
<style type=text/css>
body { font-family: Cantarell, sans; }
#loading { text-align: center; }
.hidden {
display: none;
transition: 0.5s;
}
a {
color: black;
text-decoration: none;
}
a:hover { color: orange; }
#navigation {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 2rem;
border-bottom: solid thin darkgray;
}
#navigation, th { font-family: 'Roboto Condensed', sans; }
footer {
color: #999;
text-align: center;
margin-top: 2rem;
}
#content h1 { font-size: 2.4rem; }
#content h2 { font-size: 2rem; }
#content h3 { font-size: 1.5rem; }
#content h4 { font-size: 1.35rem; }
#content h5 {
font-size: 1.35rem;
font-weight: normal;
text-decoration: underline;
}
#content h6 {
font-size: 1rem;
font-weight: normal;
font-variant: small-caps;
}
/* xsmall */
@media screen and (max-width: 320px) {
html { font-size: 10px; }
#content h1 { font-size: 2rem; }
#content h2 { font-size: 1.67rem; }
table tr th:nth-child(2), table tr th:nth-child(3),
table tr td:nth-child(2), table tr td:nth-child(3) { display: none; }
}
/* small */
@media screen and (min-width: 321px) and (max-width: 640px) {
html { font-size: 12px; }
#content h1 { font-size: 2rem; }
#content h2 { font-size: 1.67rem; }
table tr th:nth-child(3), table tr td:nth-child(3) { display: none; }
}
/* medium */
@media screen and (min-width: 641px) and (max-width: 1200px) {
html { font-size: 16px; }
}
/* large */
@media screen and (min-width: 1201px) {
html { font-size: 1.1vw; }
body {
margin: 2vw auto;
width: 70vw;
}
}
</style>
</head>
<body>
<div id=loading><img src=/img/gears.svg /></div>
<div id=navigation class=hidden></div>
<div id=listing class=hidden>
<table class='row-border compact hover'>
<thead>
<tr>
<th class=dt-left>Name</th>
<th class=dt-left>Size</th>
<th class=dt-left>Last Modified</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<link href="http://fonts.googleapis.com/css?family=Roboto+Condensed|Cantarell" rel="stylesheet" type="text/css">
<link type=text/css rel=stylesheet href="https://cdn.datatables.net/1.10.13/css/jquery.dataTables.min.css"/>
<script type=application/javascript src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type=application/javascript src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
<script type=application/javascript src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
<script type=application/javascript>
var s3BucketUrl = 'http://newlifeintroband.jdbernard.com.s3-us-west-2.amazonaws.com';
window.onload = function() {
loadBucketListing()
.then(function(listingInfo) { return render(listingInfo); })
.then(function(listingInfo) {
$('#loading').addClass('hidden');
$('#listing, #navigation').removeClass('hidden');
var title = listingInfo.prefix.split('/');
if (title.length > 1) {
document.title = title[title.length - 2] + " Directory Listing";
}
});
};
function loadBucketListing(prevInfo) {
return $.get(makeS3Url())
.then(function(data) {
var info = getInfoFromS3Data($(data));
if (prevInfo) {
info.directories = prevInfo.directories.concat(info.directories);
info.files = prevInfo.files.concat(info.files);
}
if (info.nextMarker) return loadBucketListing(info);
else return info;
});
}
function makeS3Url(marker) {
var s3Url = s3BucketUrl + '?delimiter=/&prefix=' + location.pathname.substr(1);
if (marker) s3Url += '&marker=' + marker;
return s3Url;
}
function getInfoFromS3Data(xml) {
var prefix = $(xml.find('Prefix')[0]).text();
var files = $.map(xml.find('Contents'), function(item) {
item = $(item);
var key = item.find('Key').text();
return {
Key: key,
Name: key.substr(prefix.length),
LastModified: moment(item.find('LastModified').text()).format('lll'),
Size: bytesToHumanReadable(item.find('Size').text()),
Type: 'file'
}
});
var directories = $.map(xml.find('CommonPrefixes'), function(item) {
item = $(item);
var key = item.find('Prefix').text();
return {
Key: key,
Name: key.substr(prefix.length),
LastModified: '',
Size: '',
Type: 'directory'
}
});
if ($(xml.find('IsTruncated')[0]).text() == 'true') {
var nextMarker = $(xml.find('NextMarker')[0]).text();
} else {
var nextMarker = null;
}
return {
files: files,
directories: directories,
prefix: prefix,
nextMarker: nextMarker ? encodeURIComponent(nextMarker) : null
}
}
function bytesToHumanReadable(sizeInBytes) {
var i = -1;
var units = [' kB', ' MB', ' GB'];
do {
sizeInBytes = sizeInBytes / 1024;
i++;
} while (sizeInBytes > 1024);
return Math.max(sizeInBytes, 0.1).toFixed(1) + units[i];
}
function render(dirInfo) {
var navParts = [];
var pathItems = dirInfo.prefix.split('/').reverse();
var backPath = "../";
pathItems.forEach(function(p) {
if (!p) return;
navParts.unshift("<a href='" + backPath + p + "'>" + p + "</a>");
backPath += "../"; });
navParts.unshift("<a href='/'>New Life Intro. Band</a>");
$("#navigation").html(navParts.join(' > '));
dirInfo.directories.forEach(function(d) {
$("#listing tbody").append(renderRow(d)); });
dirInfo.files.forEach(function(f) {
$("#listing tbody").append(renderRow(f)); });
$("#listing table").DataTable({
autoWidth: false,
paging: false,
info: false
});
return dirInfo;
}
function renderRow(item) {
if (item.Name == 'index.html' || item.Name.trim() == '') return "";
var row = "<tr>";
if (item.Type == 'directory' || item.Name.endsWith('.html')) {
row += "<td><a href='" + item.Name + "'>" + item.Name + "</a></td>"; }
else {
row += "<td><a href='" + s3BucketUrl + "/" + encodeURIComponent(item.Key) + "'>" +
item.Name + "</a></td>"; }
return row +
"<td>" + item.Size + "</td>" +
"<td>" + item.LastModified + "</td>" +
"</tr>";
}
</script>
<footer>Banged together in a day by <a href=https://github.com/jdbernard>Jonathan Bernard</a>.</footer>
</body>
</html>