<!DOCTYPE html>

<!--
Copyright 2014-2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License").

You may not use this file except in compliance with the License. A copy
of the License is located at

https://aws.amazon.com/apache2.0/

or in the "license" file accompanying this file. This file is distributed
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
either express or implied. See the License for the specific language governing
permissions and limitations under the License.
-->

<html lang="en">

<head>
    <title>Ozone S3 Explorer</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="shortcut icon" href="static/images/ozone.ico">
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <link rel="stylesheet"
          href="https://use.fontawesome.com/releases/v5.2.0/css/all.css">
    <link rel="stylesheet"
          href="https://cdn.datatables.net/plug-ins/f2c75b7247b/integration/bootstrap/3/dataTables.bootstrap.css">
    <style type="text/css">
        #wrapper {
            padding-left: 0;
        }

        #page-wrapper {
            width: 100%;
            padding: 5px 15px;
        }

        #tb-s3objects {
            width: 100% !Important;
        }

        body {
            font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
        }

        td {
            font: 12px "Lucida Grande", Helvetica, Arial, sans-serif;
        }
    </style>
</head>

<!-- DEBUG: Enable this for red outline on all elements -->
<!-- <style media="screen" type="text/css"> * { outline: 1px red solid; } </style> -->

<body>
<div id="page-wrapper">
    <div class="row">
        <div class="col-lg-12">
            <div class="panel panel-primary">

                <!-- Panel including bucket/folder information and controls -->
                <div class="panel-heading clearfix">
                    <!-- Bucket selection and breadcrumbs -->
                    <div class="btn-group pull-left">
                        <div class="pull-left">
                            Ozone S3 Explorer&nbsp;
                        </div>
                        <!-- Bucket breadcrumbs -->
                        <div class="btn pull-right">
                            <ul id="breadcrumb"
                                class="btn breadcrumb pull-right">
                                <li class="active dropdown">
                                    <a href="#">&lt;bucket&gt;</a>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <!-- Folder/Bucket radio group and progress spinner -->
                    <div class="btn-group pull-right">
                        <div class="checkbox pull-left">
                            <label>
                                <input type="checkbox" id="hidefolders">&nbsp;Hide
                                folders?
                            </label>
                            <!-- Folder/Bucket radio group -->
                            <div class="btn-group" data-toggle="buttons">
                                <label class="btn btn-primary active"
                                       title="View all objects in folder">
                                    <i class="fa fa-angle-double-up"></i>
                                    <input type="radio" name="optionsdepth"
                                           value="folder" id="optionfolder"
                                           checked>&nbsp;Folder
                                </label>
                                <label class="btn btn-primary"
                                       title="View all objects in bucket">
                                    <i class="fa fa-angle-double-down"></i>
                                    <input type="radio" name="optionsdepth"
                                           value="bucket" id="optionbucket">&nbsp;Bucket
                                </label>
                            </div>
                        </div>
                        <!-- Dual purpose: progress spinner and refresh button -->
                        <div class="btn-group pull-right" id="refresh">
                            <span id="bucket-loader" style="cursor: pointer;"
                                  class="btn fa fa-refresh fa-2x pull-left"
                                  title="Refresh"></span>
                            <span id="badgecount"
                                  class="badge pull-right">42</span>
                        </div>
                    </div>
                </div>

                <!-- Panel including S3 object table -->
                <div class="panel-body">
                    <table class="table table-bordered table-hover table-striped"
                           id="tb-s3objects">
                        <thead>
                        <tr>
                            <th>Object</th>
                            <th>Folder</th>
                            <th>Last Modified</th>
                            <th>Timestamp</th>
                            <th>Size</th>
                        </tr>
                        </thead>
                        <tbody id="tbody-s3objects"></tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
</body>

</html>

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.207.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.0/moment.min.js"></script>
<script src="https://cdn.datatables.net/1.10.5/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/plug-ins/f2c75b7247b/integration/bootstrap/3/dataTables.bootstrap.js"></script>

<script type="text/javascript">
    var bucket;
    var endpoint = document.location.protocol + '//' + document.location.host
    if (document.location.pathname.length > 0) {
        bucket = document.location.pathname.substring(1);
        endpoint += document.location.pathname;
    } else {
        bucket = document.location.host.split(".")[0];
    }
    var s3exp_config = {
        Region: '',
        Bucket: bucket,
        Prefix: '',
        Delimiter: '/'
    };
    var s3exp_lister = null;
    var s3exp_columns = {
        key: 1,
        folder: 2,
        date: 3,
        size: 4
    };


    // Initialize S3 SDK and the moment library (for time formatting utilities)
    var s3 = new AWS.S3({endpoint: new AWS.Endpoint(endpoint)})
    s3.config.s3BucketEndpoint = true;
    moment().format();

    function bytesToSize(bytes) {
        var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
        if (bytes === 0) return '0 Bytes';
        var ii = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
        return Math.round(bytes / Math.pow(1024, ii), 2) + ' ' + sizes[ii];
    }

    // Custom startsWith function for String prototype
    if (typeof String.prototype.startsWith != 'function') {
        String.prototype.startsWith = function (str) {
            return this.indexOf(str) == 0;
        };
    }

    // Custom endsWith function for String prototype
    if (typeof String.prototype.endsWith != 'function') {
        String.prototype.endsWith = function (str) {
            return this.slice(-str.length) == str;
        };
    }

    function object2hrefvirt(bucket, key) {
        var enckey = key.split('/').map(function (x) {
            return encodeURIComponent(x);
        }).join('/');


        return endpoint + "/" + enckey;

    }

    function object2hrefpath(bucket, key) {
        var enckey = key.split('/').map(function (x) {
            return encodeURIComponent(x);
        }).join('/');


        return endpoint + "/" + enckey;

    }

    function isthisdocument(bucket, key) {
        return key === "index.html";
    }

    function isfolder(path) {
        return path.endsWith('/');
    }

    // Convert cars/vw/golf.png to golf.png
    function fullpath2filename(path) {
        return path.replace(/^.*[\\\/]/, '');
    }

    // Convert cars/vw/golf.png to cars/vw
    function fullpath2pathname(path) {
        return path.substring(0, path.lastIndexOf('/'));
    }

    // Convert cars/vw/ to vw/
    function prefix2folder(prefix) {
        var parts = prefix.split('/');
        return parts[parts.length - 2] + '/';
    }

    // Remove hash from document URL
    function removeHash() {
        history.pushState("", document.title, window.location.pathname + window.location.search);
    }

    // We are going to generate bucket/folder breadcrumbs. The resulting HTML will
    // look something like this:
    //
    // <li>Home</li>
    // <li>Library</li>
    // <li class="active">Samples</li>
    //
    // Note: this code is a little complex right now so it would be good to find
    // a simpler way to create the breadcrumbs.
    function folder2breadcrumbs(data) {
        console.log('Bucket: ' + data.params.Bucket);
        console.log('Prefix: ' + data.params.Prefix);

        if (data.params.Prefix && data.params.Prefix.length > 0) {
            console.log('Set hash: ' + data.params.Prefix);
            window.location.hash = data.params.Prefix;
        } else {
            console.log('Remove hash');
            removeHash();
        }

        // The parts array will contain the bucket name followed by all the
        // segments of the prefix, exploded out as separate strings.
        var parts = [data.params.Bucket];

        if (data.params.Prefix) {
            parts.push.apply(parts,
                data.params.Prefix.endsWith('/') ?
                    data.params.Prefix.slice(0, -1).split('/') :
                    data.params.Prefix.split('/'));
        }

        console.log('Parts: ' + parts + ' (length=' + parts.length + ')');

        // Empty the current breadcrumb list
        $('#breadcrumb li').remove();

        // Now build the new breadcrumb list
        var buildprefix = '';
        $.each(parts, function (ii, part) {
            var ipart;

            // Add the bucket (the bucket is always first)
            if (ii === 0) {
                var a1 = $('<a>').attr('href', '#').text(part);
                ipart = $('<li>').append(a1);
                a1.click(function (e) {
                    e.preventDefault();
                    console.log('Breadcrumb click bucket: ' + data.params.Bucket);
                    s3exp_config = {
                        Bucket: data.params.Bucket,
                        Prefix: '',
                        Delimiter: data.params.Delimiter
                    };
                    (s3exp_lister = s3list(s3exp_config, s3draw)).go();
                });
                // Else add the folders within the bucket
            } else {
                buildprefix += part + '/';

                if (ii == parts.length - 1) {
                    ipart = $('<li>').addClass('active').text(part);
                } else {
                    var a2 = $('<a>').attr('href', '#').append(part);
                    ipart = $('<li>').append(a2);

                    // Closure needed to enclose the saved S3 prefix
                    (function () {
                        var saveprefix = buildprefix;
                        // console.log('Part: ' + part + ' has buildprefix: ' + saveprefix);
                        a2.click(function (e) {
                            e.preventDefault();
                            console.log('Breadcrumb click object prefix: ' + saveprefix);
                            s3exp_config = {
                                Bucket: data.params.Bucket,
                                Prefix: saveprefix,
                                Delimiter: data.params.Delimiter
                            };
                            (s3exp_lister = s3list(s3exp_config, s3draw)).go();
                        });
                    })();
                }
            }
            $('#breadcrumb').append(ipart);
        });
    }

    function s3draw(data, complete) {
        $('li.li-bucket').remove();
        folder2breadcrumbs(data);

        // Add each part of current path (S3 bucket plus folder hierarchy) into the breadcrumbs
        $.each(data.CommonPrefixes, function (i, prefix) {
            $('#tb-s3objects').DataTable().rows.add([{
                Key: prefix.Prefix
            }]);
        });

        // Add S3 objects to DataTable
        $('#tb-s3objects').DataTable().rows.add(data.Contents).draw();
    }

    function s3list(config, completecb) {
        console.log('s3list config: ' + JSON.stringify(config));
        var params = {
            Bucket: config.Bucket,
            Prefix: config.Prefix,
            Delimiter: config.Delimiter
        };
        var scope = {
            Contents: [],
            CommonPrefixes: [],
            params: params,
            stop: false,
            completecb: completecb
        };

        return {
            // This is the callback that the S3 API makes when an S3 listObjectsV2
            // request completes (successfully or in error). Note that a single call
            // to listObjectsV2 may not be enough to get all objects so we need to
            // check if the returned data is truncated and, if so, make additional
            // requests with a 'next marker' until we have all the objects.
            cb: function (err, data) {
                if (err) {
                    console.log('Error: ' + JSON.stringify(err));
                    console.log('Error: ' + err.stack);
                    scope.stop = true;
                    $('#bucket-loader').removeClass('fa-spin');
                    bootbox.alert("Error accessing S3 bucket " + scope.params.Bucket + ". Error: " + err);
                } else {
                    // console.log('Data: ' + JSON.stringify(data));
                    console.log("Options: " + $("input[name='optionsdepth']:checked").val());

                    // Store marker before filtering data
                    if (data.IsTruncated) {
                        if (data.NextContinuationToken) {
                            scope.params.ContinuationToken = data.NextContinuationToken;
                        }
                    }

                    // Filter the folders out of the listed S3 objects
                    // (could probably be done more efficiently)
                    console.log("Filter: remove folders");
                    data.Contents = data.Contents.filter(function (el) {
                        return el.Key !== scope.params.Prefix;
                    });

                    // Accumulate the S3 objects and common prefixes
                    scope.Contents.push.apply(scope.Contents, data.Contents);
                    scope.CommonPrefixes.push.apply(scope.CommonPrefixes, data.CommonPrefixes);

                    // Update badge count to show number of objects read
                    $('#badgecount').text(scope.Contents.length + scope.CommonPrefixes.length);

                    if (scope.stop) {
                        console.log('Bucket ' + scope.params.Bucket + ' stopped');
                    } else if (data.IsTruncated) {
                        console.log('Bucket ' + scope.params.Bucket + ' truncated');
                        s3.makeUnauthenticatedRequest('listObjectsV2', scope.params, scope.cb);
                    } else {
                        console.log('Bucket ' + scope.params.Bucket + ' has ' + scope.Contents.length + ' objects, including ' + scope.CommonPrefixes.length + ' prefixes');
                        delete scope.params.ContinuationToken;
                        if (scope.completecb) {
                            scope.completecb(scope, true);
                        }
                        $('#bucket-loader').removeClass('fa-spin');
                    }
                }
            },

            // Start the spinner, clear the table, make an S3 listObjectsV2 request
            go: function () {
                scope.cb = this.cb;
                $('#bucket-loader').addClass('fa-spin');
                $('#tb-s3objects').DataTable().clear();
                s3.makeUnauthenticatedRequest('listObjectsV2', scope.params, this.cb);
            },

            stop: function () {
                scope.stop = true;
                delete scope.params.ContinuationToken;
                if (scope.completecb) {
                    scope.completecb(scope, false);
                }
                $('#bucket-loader').removeClass('fa-spin');
            }
        };
    }

    function promptForBucketInput() {
        bootbox.prompt("Please enter the S3 bucket name", function (result) {
            if (result !== null) {
                resetDepth();
                s3exp_config = {
                    Bucket: result,
                    Delimiter: '/'
                };
                (s3exp_lister = s3list(s3exp_config, s3draw)).go();
            }
        });
    }

    function resetDepth() {
        $('#tb-s3objects').DataTable().column(1).visible(false);
        $('input[name="optionsdepth"]').val(['folder']);
        $('input[name="optionsdepth"][value="bucket"]').parent().removeClass('active');
        $('input[name="optionsdepth"][value="folder"]').parent().addClass('active');
    }

    $(document).ready(function () {
        console.log('ready');

        // Click handler for refresh button (to invoke manual refresh)
        $('#bucket-loader').click(function (e) {
            if ($('#bucket-loader').hasClass('fa-spin')) {
                // To do: We need to stop the S3 list that's going on
                // bootbox.alert("Stop is not yet supported.");
                s3exp_lister.stop();
            } else {
                delete s3exp_config.ContinuationToken;
                (s3exp_lister = s3list(s3exp_config, s3draw)).go();
            }
        });

        // Click handler for bucket button (to allow user to change bucket)
        $('#bucket-chooser').click(function (e) {
            promptForBucketInput();
        });

        $('#hidefolders').click(function (e) {
            $('#tb-s3objects').DataTable().draw();
        });

        // Folder/Bucket radio button handler
        $("input:radio[name='optionsdepth']").change(function () {
            console.log("Folder/Bucket option change to " + $(this).val());
            console.log("Change options: " + $("input[name='optionsdepth']:checked").val());

            // If user selected deep then we do need to do a full list
            if ($(this).val() == 'bucket') {
                console.log("Switch to bucket");
                var choice = $(this).val();
                $('#tb-s3objects').DataTable().column(1).visible(choice === 'bucket');
                delete s3exp_config.ContinuationToken;
                delete s3exp_config.Prefix;
                s3exp_config.Delimiter = '';
                (s3exp_lister = s3list(s3exp_config, s3draw)).go();
                // Else user selected folder then can do a delimiter list
            } else {
                console.log("Switch to folder");
                $('#tb-s3objects').DataTable().column(1).visible(false);
                delete s3exp_config.ContinuationToken;
                delete s3exp_config.Prefix;
                s3exp_config.Delimiter = '/';
                (s3exp_lister = s3list(s3exp_config, s3draw)).go();
            }
        });

        function renderObject(data, type, full) {
            if (isthisdocument(s3exp_config.Bucket, data)) {
                console.log("is this document: " + data);
                return fullpath2filename(data);
            } else if (isfolder(data)) {
                console.log("is folder: " + data);
                return '<a data-s3="folder" data-prefix="' + data + '" href="' + object2hrefvirt(s3exp_config.Bucket, data) + '">' + prefix2folder(data) + '</a>';
            } else {
                console.log("not folder/this document: " + data);
                return '<a data-s3="object" href="' + object2hrefvirt(s3exp_config.Bucket, data) + '"download="' + fullpath2filename(data) + '">' + fullpath2filename(data) + '</a>';
            }
        }

        function renderFolder(data, type, full) {
            return isfolder(data) ? "" : fullpath2pathname(data);
        }

        // Initial DataTable settings
        $('#tb-s3objects').DataTable({
            iDisplayLength: 50,
            order: [
                [1, 'asc'],
                [0, 'asc']
            ],
            aoColumnDefs: [{
                "aTargets": [0],
                "mData": "Key",
                "mRender": function (data, type, full) {
                    return (type == 'display') ? renderObject(data, type, full) : data;
                },
                "sType": "key"
            }, {
                "aTargets": [1],
                "mData": "Key",
                "mRender": function (data, type, full) {
                    return renderFolder(data, type, full);
                }
            }, {
                "aTargets": [2],
                "mData": "LastModified",
                "mRender": function (data, type, full) {
                    return data ? moment(data).fromNow() : "";
                }
            }, {
                "aTargets": [3],
                "mData": "LastModified",
                "mRender": function (data, type, full) {
                    return data ? moment(data).local().format('YYYY-MM-DD HH:mm:ss') : "";
                }
            }, {
                "aTargets": [4],
                "mData": function (source, type, val) {
                    return source.Size ? ((type == 'display') ? bytesToSize(source.Size) : source.Size) : "";
                }
            },]
        });

        $('#tb-s3objects').DataTable().column(s3exp_columns.key).visible(false);
        console.log("jQuery version=" + $.fn.jquery);

        // Custom sort for the Key column so that folders appear before objects
        $.fn.dataTableExt.oSort['key-asc'] = function (a, b) {
            var x = (isfolder(a) ? "0-" + a : "1-" + a).toLowerCase();
            var y = (isfolder(b) ? "0-" + b : "1-" + b).toLowerCase();
            return ((x < y) ? -1 : ((x > y) ? 1 : 0));
        };

        $.fn.dataTableExt.oSort['key-desc'] = function (a, b) {
            var x = (isfolder(a) ? "1-" + a : "0-" + a).toLowerCase();
            var y = (isfolder(b) ? "1-" + b : "0-" + b).toLowerCase();
            return ((x < y) ? 1 : ((x > y) ? -1 : 0));
        };

        // Allow user to hide folders
        $.fn.dataTableExt.afnFiltering.push(function (oSettings, aData, iDataIndex) {
            console.log("hide folders");
            return $('#hidefolders').is(':checked') ? !isfolder(aData[0]) : true;
        });

        // Delegated event handler for S3 object/folder clicks. This is delegated
        // because the object/folder rows are added dynamically and we do not want
        // to have to assign click handlers to each and every row.
        $('#tb-s3objects').on('click', 'a', function (event) {
            event.preventDefault();
            var target = event.target;
            console.log("target href=" + target.href);
            console.log("target dataset=" + JSON.stringify(target.dataset));

            // If the user has clicked on a folder then navigate into that folder
            if (target.dataset.s3 === "folder") {
                resetDepth();
                delete s3exp_config.ContinuationToken;
                s3exp_config.Prefix = target.dataset.prefix;
                s3exp_config.Delimiter = $("input[name='optionsdepth']:checked").val() == "folder" ? "/" : "";
                (s3exp_lister = s3list(s3exp_config, s3draw)).go();
                // Else user has clicked on an object so download it in new window/tab
            } else {
                window.open(target.href, '_blank');
            }
            return false;
        });

        if (window.location.hash) {
            console.log("Location hash=" + window.location.hash);
            s3exp_config.Prefix = window.location.hash.substring(1);
        }

        // Do initial bucket list
        (s3exp_lister = s3list(s3exp_config, s3draw)).go();
    });
</script>
