Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
<html>
<head>
<!--
Amazon S3 Bucket listing.
Copyright (C) 2008 Francesco Pasqualini
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<!--
Modified by Nolan Lawson! (http://nolanlawson.com). I'm keeping the spirit of the
GPL alive by issuing this with the same license!
-->
<title>Bucket loading...</title>
<link href="//netdna.bootstrapcdn.com/bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<style>
.hide-while-loading {
display:none;
}
.i-expand-collapse {
opacity: 0.3;
}
.i-file-or-folder {
margin-right: 4px;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.1.2/handlebars.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.4.0/moment.min.js"></script>
</head>
<body>
<div class="container">
<h1 id="h1-title">Bucket loading...</h1>
<table class="hide-while-loading table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Date Modified</th>
<th>Size</th>
<th>Type</th>
</tr>
</thead>
<tbody id="tbody-content">
</tbody>
</table>
</div>
<script id="file-or-folder" type="text/x-handlebars-template">
<tr>
{{#if isFolder}}
<td><i class="icon-chevron-down i-expand-collapse" style="margin-left:calc(({{numLevels}} - 1) * 16px)");></i><i class="icon-folder-open i-file-or-folder" style="margin-left:4px;"></i>
{{simpleFilename}}</td>
{{else}}
<td><i class="icon-file i-file-or-folder" style="margin-left:calc(({{numLevels}} * 16px) + 4px);"></i>
<a href="{{url}}">{{simpleFilename}}</a></td>
{{/if}}
<td>{{friendlyLastModified}}</td>
<td>{{friendlySizeName}}</td>
<td>{{type}}</td>
</tr>
</script>
<script>
(function($){
"use strict";
var FOLDER_PATTERN = new RegExp('_\\$folder\\$$');
var TYPE_PATTERN = new RegExp('\\.([^\\.\\s]{1,10})$');
var KB = 1024;
var MB = 1000000;
var GB = 1000000000;
// replace last /index.html to get bucket root
var bucketUrl = document.location.href.replace(/\/[^\/]+$/, '');
var compiledTemplate;
// return e.g. 1.2KB, 1.3MB, 2GB, etc.
function toFriendlySizeName(size){
if (size === 0) {
return '';
} else if (size < KB) {
return size + ' B';
} else if (size < MB) {
return (size / KB).toFixed(0) + ' KB';
} else if (size < GB) {
return (size / MB).toFixed(2) + ' MB';
}
return (size / GB).toFixed(2) + ' GB';
}
// POJO describing a file or a folder
function FileOrFolder(lastModified, etag, size, key){
var self = this;
self.lastModified = lastModified;
self.etag = etag;
self.size = size;
self.key = key;
// init logic
self.isFolder = FOLDER_PATTERN.test(self.key);
self.filename = self.isFolder ? self.key.replace(FOLDER_PATTERN,'') : self.key;
self.url = bucketUrl + '/' + self.key;
self.levels = self.filename.split('/');
self.numLevels = self.levels.length;
self.simpleFilename = self.levels[self.numLevels - 1];
self.friendlySizeName = toFriendlySizeName(parseInt(self.size,10));
var foundTypes = TYPE_PATTERN.exec(self.simpleFilename);
self.type = self.isFolder ? 'Folder ' : (foundTypes ? (foundTypes[1].toUpperCase() + ' file') : 'Unknown');
self.friendlyLastModified = moment(lastModified).format('MMM Do YYYY, hh:mm:ss a');
}
function onAjaxSuccess(xml) {
var listBucketResult = $(xml).find('ListBucketResult');
// set a reasonable title instead of "Bucket loading"
var title = 'Index of bucket "' + listBucketResult.find('Name').text() + '"';
document.title = title;
$('#h1-title').text(title);
var $tbodyContent = $('#tbody-content');
// create the file or folder objects
var filesOrFolders = [];
listBucketResult.find('Contents').each(function(idx, element){
var $element = $(element);
var fileOrFolder = new FileOrFolder(
$element.find('LastModified').text(),
$element.find('ETag').text(),
$element.find('Size').text(),
$element.find('Key').text()
);
filesOrFolders.push(fileOrFolder);
});
// sort
filesOrFolders.sort(function(left, right){
if (left.levels === right.levels) {
return 0;
} else if (left.levels < right.levels) {
return -1;
}
return 1;
});
// fill in the rows
var str = '';
for (var i = 0; i < filesOrFolders.length; i ++) {
str += compiledTemplate(filesOrFolders[i]);
}
$tbodyContent.append(str);
$('.hide-while-loading').show();
}
$.ajax({
url: bucketUrl,
success: onAjaxSuccess
});
// compile while ajax is in progress
compiledTemplate = Handlebars.compile($('#file-or-folder').html());
})(jQuery);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.