| <div id="listing"></div> |
| <!-- add jquery - if you already have it just ignore this line --> |
| <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> |
| |
| <!-- the JS variables for the listing --> |
| <script type="text/javascript"> |
| // this is https://github.com/rgrp/s3-bucket-listing |
| var S3BL_IGNORE_PATH = true; |
| var BUCKET_URL = 'https://couchdb-ci.s3-eu-west-1.amazonaws.com'; |
| var S3B_ROOT_DIR = 'release-candidate/' |
| if (typeof S3BL_IGNORE_PATH == 'undefined' || S3BL_IGNORE_PATH!=true) { |
| var S3BL_IGNORE_PATH = false; |
| } |
| |
| if (typeof BUCKET_URL == 'undefined') { |
| var BUCKET_URL = location.protocol + '//' + location.hostname; |
| } |
| |
| if (typeof BUCKET_NAME != 'undefined') { |
| // if bucket_url does not start with bucket_name, |
| // assume path-style url |
| if (!~BUCKET_URL.indexOf(location.protocol + '//' + BUCKET_NAME)) { |
| BUCKET_URL += '/' + BUCKET_NAME; |
| } |
| } |
| |
| if (typeof S3B_ROOT_DIR == 'undefined') { |
| var S3B_ROOT_DIR = ''; |
| } |
| |
| jQuery(function($) { |
| getS3Data(); |
| }); |
| |
| function getS3Data(marker, html) { |
| var s3_rest_url = createS3QueryUrl(marker); |
| // set loading notice |
| $('#listing').html('<img src="//assets.okfn.org/images/icons/ajaxload-circle.gif" />'); |
| $.get(s3_rest_url) |
| .done(function(data) { |
| // clear loading notice |
| $('#listing').html(''); |
| var xml = $(data); |
| var info = getInfoFromS3Data(xml); |
| html = typeof html !== 'undefined' ? html + prepareTable(info) : prepareTable(info); |
| if (info.nextMarker != "null") { |
| getS3Data(info.nextMarker, html); |
| } else { |
| document.getElementById('listing').innerHTML = '<pre>' + html + '</pre>'; |
| } |
| }) |
| .fail(function(error) { |
| console.error(error); |
| $('#listing').html('<strong>Error: ' + error + '</strong>'); |
| }); |
| } |
| |
| function createS3QueryUrl(marker) { |
| var s3_rest_url = BUCKET_URL; |
| s3_rest_url += '?delimiter=/'; |
| |
| // |
| // Handling paths and prefixes: |
| // |
| // 1. S3BL_IGNORE_PATH = false |
| // Uses the pathname |
| // {bucket}/{path} => prefix = {path} |
| // |
| // 2. S3BL_IGNORE_PATH = true |
| // Uses ?prefix={prefix} |
| // |
| // Why both? Because we want classic directory style listing in normal |
| // buckets but also allow deploying to non-buckets |
| // |
| |
| var rx = '.*[?&]prefix=' + S3B_ROOT_DIR + '([^&]+)(&.*)?$'; |
| var prefix = ''; |
| if (S3BL_IGNORE_PATH==false) { |
| var prefix = location.pathname.replace(/^\//, S3B_ROOT_DIR); |
| } |
| var match = location.search.match(rx); |
| if (match) { |
| prefix = S3B_ROOT_DIR + match[1]; |
| } else { |
| if (S3BL_IGNORE_PATH) { |
| var prefix = S3B_ROOT_DIR; |
| } |
| } |
| if (prefix) { |
| // make sure we end in / |
| var prefix = prefix.replace(/\/$/, '') + '/'; |
| s3_rest_url += '&prefix=' + prefix; |
| } |
| if (marker) { |
| s3_rest_url += '&marker=' + marker; |
| } |
| return s3_rest_url; |
| } |
| |
| function getInfoFromS3Data(xml) { |
| var files = $.map(xml.find('Contents'), function(item) { |
| item = $(item); |
| return { |
| Key: item.find('Key').text(), |
| LastModified: item.find('LastModified').text(), |
| Size: item.find('Size').text(), |
| Type: 'file' |
| } |
| }); |
| var directories = $.map(xml.find('CommonPrefixes'), function(item) { |
| item = $(item); |
| return { |
| Key: item.find('Prefix').text(), |
| LastModified: '', |
| Size: '0', |
| 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: $(xml.find('Prefix')[0]).text(), |
| nextMarker: encodeURIComponent(nextMarker) |
| } |
| } |
| |
| // info is object like: |
| // { |
| // files: .. |
| // directories: .. |
| // prefix: ... |
| // } |
| function prepareTable(info) { |
| var files = info.files.concat(info.directories) |
| , prefix = info.prefix |
| ; |
| |
| files = files.sort(function(a, b) { |
| if(a.LastModified == b.LastModified) { |
| return 0; |
| } |
| return a.LastModified < b.LastModified ? 1 : -1; |
| }); |
| var cols = [ 45, 30, 15 ]; |
| var content = []; |
| content.push(padRight('Last Modified', cols[1]) + ' ' + padRight('Size', cols[2]) + 'Key \n'); |
| content.push(new Array(cols[0] + cols[1] + cols[2] + 4).join('-') + '\n'); |
| |
| // add the ../ at the start of the directory listing |
| if (prefix) { |
| var up = prefix.replace(/\/$/, '').split('/').slice(0, -1).concat('').join('/'), // one directory up |
| item = { |
| Key: up, |
| LastModified: '', |
| Size: '', |
| keyText: '../', |
| href: S3BL_IGNORE_PATH ? '?prefix=' + up : '../' |
| }, |
| row = renderRow(item, cols); |
| // content.push(row + '\n'); |
| } |
| |
| jQuery.each(files, function(idx, item) { |
| if (item.Key == 'release-candidate/' || item.Key == 'release-candidate/index.html') { |
| return; |
| } |
| // strip off the prefix |
| item.keyText = item.Key.substring(prefix.length); |
| if (item.Type === 'directory') { |
| if (S3BL_IGNORE_PATH) { |
| item.href = location.protocol + '//' + location.hostname + location.pathname + '?prefix=' + item.Key; |
| } else { |
| item.href = item.keyText; |
| } |
| } else { |
| item.href = BUCKET_URL + '/' + encodeURIComponent(item.Key); |
| item.href = item.href.replace(/%2F/g, '/'); |
| } |
| var row = renderRow(item, cols); |
| content.push(row + '\n'); |
| }); |
| |
| return content.join(''); |
| } |
| |
| function renderRow(item, cols) { |
| var row = ''; |
| row += padRight(item.LastModified, cols[1]) + ' '; |
| row += padRight(item.Size, cols[2]); |
| row += '<a href="' + item.href + '">' + item.keyText + '</a>'; |
| return row; |
| } |
| |
| function padRight(padString, length) { |
| var str = padString.slice(0, length-3); |
| if (padString.length > str.length) { |
| str += '...'; |
| } |
| while (str.length < length) { |
| str = str + ' '; |
| } |
| return str; |
| } |
| </script> |