123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License 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.
- */
- (function() {
- "use strict";
- // The chunk size of tailing the files, i.e., how many bytes will be shown
- // in the preview.
- var TAIL_CHUNK_SIZE = 32768;
- //This stores the current directory which is being browsed
- var current_directory = "";
- function show_err_msg(msg) {
- $('#alert-panel-body').html(msg);
- $('#alert-panel').show();
- }
- $(window).bind('hashchange', function () {
- $('#alert-panel').hide();
- var dir = decodeURIComponent(window.location.hash.slice(1));
- if(dir == "") {
- dir = "/";
- }
- if(current_directory != dir) {
- browse_directory(dir);
- }
- });
- function network_error_handler(url) {
- return function (jqxhr, text, err) {
- switch(jqxhr.status) {
- case 401:
- var msg = '<p>Authentication failed when trying to open ' + url + ': Unauthorized.</p>';
- break;
- case 403:
- if(jqxhr.responseJSON !== undefined && jqxhr.responseJSON.RemoteException !== undefined) {
- var msg = '<p>' + jqxhr.responseJSON.RemoteException.message + "</p>";
- break;
- }
- var msg = '<p>Permission denied when trying to open ' + url + ': ' + err + '</p>';
- break;
- case 404:
- var msg = '<p>Path does not exist on HDFS or WebHDFS is disabled. Please check your path or enable WebHDFS</p>';
- break;
- default:
- var msg = '<p>Failed to retrieve data from ' + url + ': ' + err + '</p>';
- }
- show_err_msg(msg);
- };
- }
- function append_path(prefix, s) {
- var l = prefix.length;
- var p = l > 0 && prefix[l - 1] == '/' ? prefix.substring(0, l - 1) : prefix;
- return p + '/' + s;
- }
- function get_response(data, type) {
- return data[type] !== undefined ? data[type] : null;
- }
- function get_response_err_msg(data) {
- return data.RemoteException !== undefined ? data.RemoteException.message : "";
- }
- function delete_path(inode_name, absolute_file_path) {
- $('#delete-modal-title').text("Delete - " + inode_name);
- $('#delete-prompt').text("Are you sure you want to delete " + inode_name
- + " ?");
- $('#delete-button').click(function() {
- // DELETE /webhdfs/v1/<path>?op=DELETE&recursive=<true|false>
- var url = '/webhdfs/v1' + encode_path(absolute_file_path) +
- '?op=DELETE' + '&recursive=true';
- $.ajax(url,
- { type: 'DELETE'
- }).done(function(data) {
- browse_directory(current_directory);
- }).fail(network_error_handler(url)
- ).always(function() {
- $('#delete-modal').modal('hide');
- $('#delete-button').button('reset');
- });
- })
- $('#delete-modal').modal();
- }
- /* This method loads the checkboxes on the permission info modal. It accepts
- * the octal permissions, eg. '644' or '755' and infers the checkboxes that
- * should be true and false
- */
- function view_perm_details(e, filename, abs_path, perms) {
- $('.explorer-perm-links').popover('destroy');
- e.popover({html: true, content: $('#explorer-popover-perm-info').html(), trigger: 'focus'})
- .on('shown.bs.popover', function(e) {
- var popover = $(this), parent = popover.parent();
- //Convert octal to binary permissions
- var bin_perms = parseInt(perms, 8).toString(2);
- bin_perms = bin_perms.length == 9 ? "0" + bin_perms : bin_perms;
- parent.find('#explorer-perm-cancel').on('click', function() { popover.popover('destroy'); });
- parent.find('#explorer-set-perm-button').off().click(function() { set_permissions(abs_path); });
- parent.find('input[type=checkbox]').each(function(idx, element) {
- var e = $(element);
- e.prop('checked', bin_perms.charAt(9 - e.attr('data-bit')) == '1');
- });
- })
- .popover('show');
- }
- // Use WebHDFS to set permissions on an absolute path
- function set_permissions(abs_path) {
- var p = 0;
- $.each($('.popover .explorer-popover-perm-body input:checked'), function(idx, e) {
- p |= 1 << (+$(e).attr('data-bit'));
- });
- var permission_mask = p.toString(8);
- // PUT /webhdfs/v1/<path>?op=SETPERMISSION&permission=<permission>
- var url = '/webhdfs/v1' + encode_path(abs_path) +
- '?op=SETPERMISSION' + '&permission=' + permission_mask;
- $.ajax(url, { type: 'PUT'
- }).done(function(data) {
- browse_directory(current_directory);
- }).fail(network_error_handler(url))
- .always(function() {
- $('.explorer-perm-links').popover('destroy');
- });
- }
- function encode_path(abs_path) {
- abs_path = encodeURIComponent(abs_path);
- var re = /%2F/g;
- return abs_path.replace(re, '/');
- }
- function view_file_details(path, abs_path) {
- function show_block_info(blocks) {
- var menus = $('#file-info-blockinfo-list');
- menus.empty();
- menus.data("blocks", blocks);
- menus.change(function() {
- var d = $(this).data('blocks')[$(this).val()];
- if (d === undefined) {
- return;
- }
- dust.render('block-info', d, function(err, out) {
- $('#file-info-blockinfo-body').html(out);
- });
- });
- for (var i = 0; i < blocks.length; ++i) {
- var item = $('<option value="' + i + '">Block ' + i + '</option>');
- menus.append(item);
- }
- menus.change();
- }
- abs_path = encode_path(abs_path);
- var url = '/webhdfs/v1' + abs_path + '?op=GET_BLOCK_LOCATIONS';
- $.ajax({url: url, dataType: 'text'}).done(function(data_text) {
- var data = JSONParseBigNum(data_text);
- var d = get_response(data, "LocatedBlocks");
- if (d === null) {
- show_err_msg(get_response_err_msg(data));
- return;
- }
- $('#file-info-tail').hide();
- $('#file-info-title').text("File information - " + path);
- var download_url = '/webhdfs/v1' + abs_path + '?op=OPEN';
- $('#file-info-download').attr('href', download_url);
- var processPreview = function(url) {
- url += "&noredirect=true";
- $.ajax({
- type: 'GET',
- url: url,
- processData: false,
- crossDomain: true
- }).done(function(data) {
- url = data.Location;
- $.ajax({
- type: 'GET',
- url: url,
- processData: false,
- crossDomain: true
- }).always(function(data) {
- $('#file-info-preview-body').val(data.responseText);
- $('#file-info-tail').show();
- }).fail(function(jqXHR, textStatus, errorThrown) {
- show_err_msg("Couldn't preview the file. " + errorThrown);
- });
- }).fail(function(jqXHR, textStatus, errorThrown) {
- show_err_msg("Couldn't find datanode to read file from. " + errorThrown);
- });
- }
- $('#file-info-preview-tail').click(function() {
- var offset = d.fileLength - TAIL_CHUNK_SIZE;
- var url = offset > 0 ? download_url + '&offset=' + offset : download_url;
- processPreview(url);
- });
- $('#file-info-preview-head').click(function() {
- var url = d.fileLength > TAIL_CHUNK_SIZE ? download_url + '&length=' + TAIL_CHUNK_SIZE : download_url;
- processPreview(url);
- });
- if (d.fileLength > 0) {
- show_block_info(d.locatedBlocks);
- $('#file-info-blockinfo-panel').show();
- } else {
- $('#file-info-blockinfo-panel').hide();
- }
- $('#file-info').modal();
- }).fail(network_error_handler(url));
- }
- /**Use X-editable to make fields editable with a nice UI.
- * elementType is the class of element(s) you want to make editable
- * op is the WebHDFS operation that will be triggered
- * parameter is (currently the 1) parameter which will be passed along with
- * the value entered by the user
- */
- function makeEditable(elementType, op, parameter) {
- $(elementType).each(function(index, value) {
- $(this).editable({
- url: function(params) {
- var inode_name = $(this).closest('tr').attr('inode-path');
- var absolute_file_path = append_path(current_directory, inode_name);
- var url = '/webhdfs/v1' + encode_path(absolute_file_path) + '?op=' +
- op + '&' + parameter + '=' + encodeURIComponent(params.value);
- return $.ajax(url, { type: 'PUT', })
- .fail(network_error_handler(url))
- .done(function() {
- browse_directory(current_directory);
- });
- },
- error: function(response, newValue) {return "";}
- });
- });
- }
- function func_size_render(data, type, row, meta) {
- if(type == 'display') {
- return dust.filters.fmt_bytes(data);
- }
- else return data;
- }
- // Change the format of date-time depending on how old the
- // the timestamp is. If older than 6 months, no need to be
- // show exact time.
- function func_time_render(data, type, row, meta) {
- if(type == 'display') {
- var cutoff = moment().subtract(6, 'months').unix() * 1000;
- if(data < cutoff) {
- return moment(Number(data)).format('MMM DD YYYY');
- } else {
- return moment(Number(data)).format('MMM DD HH:mm');
- }
- }
- return data;
- }
- function browse_directory(dir) {
- var HELPERS = {
- 'helper_date_tostring' : function (chunk, ctx, bodies, params) {
- var value = dust.helpers.tap(params.value, chunk, ctx);
- return chunk.write('' + moment(Number(value)).format('ddd MMM DD HH:mm:ss ZZ YYYY'));
- }
- };
- var url = '/webhdfs/v1' + encode_path(dir) + '?op=LISTSTATUS';
- $.get(url, function(data) {
- var d = get_response(data, "FileStatuses");
- if (d === null) {
- show_err_msg(get_response_err_msg(data));
- return;
- }
- current_directory = dir;
- $('#directory').val(dir);
- window.location.hash = dir;
- var base = dust.makeBase(HELPERS);
- dust.render('explorer', base.push(d), function(err, out) {
- $('#panel').html(out);
- $('.explorer-browse-links').click(function() {
- var type = $(this).attr('inode-type');
- var path = $(this).closest('tr').attr('inode-path');
- var abs_path = append_path(current_directory, path);
- if (type == 'DIRECTORY') {
- browse_directory(abs_path);
- } else {
- view_file_details(path, abs_path);
- }
- });
- //Set the handler for changing permissions
- $('.explorer-perm-links').click(function() {
- var filename = $(this).closest('tr').attr('inode-path');
- var abs_path = append_path(current_directory, filename);
- var perms = $(this).closest('tr').attr('data-permission');
- view_perm_details($(this), filename, abs_path, perms);
- });
- makeEditable('.explorer-owner-links', 'SETOWNER', 'owner');
- makeEditable('.explorer-group-links', 'SETOWNER', 'group');
- makeEditable('.explorer-replication-links', 'SETREPLICATION', 'replication');
- $('.explorer-entry .glyphicon-trash').click(function() {
- var inode_name = $(this).closest('tr').attr('inode-path');
- var absolute_file_path = append_path(current_directory, inode_name);
- delete_path(inode_name, absolute_file_path);
- });
- $('#file-selector-all').click(function() {
- $('.file_selector').prop('checked', $('#file-selector-all')[0].checked );
- });
- //This needs to be last because it repaints the table
- $('#table-explorer').dataTable( {
- 'lengthMenu': [ [25, 50, 100, -1], [25, 50, 100, "All"] ],
- 'columns': [
- { 'orderable' : false }, //select
- {'searchable': false }, //Permissions
- null, //Owner
- null, //Group
- { 'searchable': false, 'render': func_size_render}, //Size
- { 'searchable': false, 'render': func_time_render}, //Last Modified
- { 'searchable': false }, //Replication
- null, //Block Size
- null, //Name
- { 'orderable' : false } //Trash
- ],
- "deferRender": true
- });
- });
- }).fail(network_error_handler(url));
- }
- function init() {
- dust.loadSource(dust.compile($('#tmpl-explorer').html(), 'explorer'));
- dust.loadSource(dust.compile($('#tmpl-block-info').html(), 'block-info'));
- var b = function() { browse_directory($('#directory').val()); };
- $('#btn-nav-directory').click(b);
- //Also navigate to the directory when a user presses enter.
- $('#directory').on('keyup', function (e) {
- if (e.which == 13) {
- browse_directory($('#directory').val());
- }
- });
- var dir = window.location.hash.slice(1);
- if(dir == "") {
- window.location.hash = "/";
- } else {
- browse_directory(dir);
- }
- }
- $('#btn-create-directory').on('show.bs.modal', function(event) {
- $('#new_directory_pwd').text(current_directory);
- });
- $('#btn-create-directory-send').click(function () {
- $(this).prop('disabled', true);
- $(this).button('complete');
- var url = '/webhdfs/v1' + encode_path(append_path(current_directory,
- $('#new_directory').val())) + '?op=MKDIRS';
- $.ajax(url, { type: 'PUT' }
- ).done(function(data) {
- browse_directory(current_directory);
- }).fail(network_error_handler(url)
- ).always(function() {
- $('#btn-create-directory').modal('hide');
- $('#btn-create-directory-send').button('reset');
- });
- })
- $('#modal-upload-file-button').click(function() {
- $(this).prop('disabled', true);
- $(this).button('complete');
- var files = []
- var numCompleted = 0
- for(var i = 0; i < $('#modal-upload-file-input').prop('files').length; i++) {
- (function() {
- var file = $('#modal-upload-file-input').prop('files')[i];
- var url = '/webhdfs/v1' + current_directory;
- url = encode_path(append_path(url, file.name));
- url += '?op=CREATE&noredirect=true';
- files.push( { file: file } )
- files[i].request = $.ajax({
- type: 'PUT',
- url: url,
- processData: false,
- crossDomain: true
- });
- })()
- }
- for(var f in files) {
- (function() {
- var file = files[f];
- file.request.done(function(data) {
- var url = data['Location'];
- $.ajax({
- type: 'PUT',
- url: url,
- data: file.file,
- processData: false,
- crossDomain: true
- }).always(function(data) {
- numCompleted++;
- if(numCompleted == files.length) {
- reset_upload_button();
- browse_directory(current_directory);
- }
- }).fail(function(jqXHR, textStatus, errorThrown) {
- numCompleted++;
- reset_upload_button();
- show_err_msg("Couldn't upload the file " + file.file.name + ". "+ errorThrown);
- });
- }).fail(function(jqXHR, textStatus, errorThrown) {
- numCompleted++;
- reset_upload_button();
- show_err_msg("Couldn't find datanode to write file. " + errorThrown);
- });
- })();
- }
- });
- //Reset the upload button
- function reset_upload_button() {
- $('#modal-upload-file').modal('hide');
- $('#modal-upload-file-button').button('reset');
- }
- //Store the list of files which have been checked into session storage
- function store_selected_files(current_directory) {
- sessionStorage.setItem("source_directory", current_directory);
- var selected_files = $("input:checked.file_selector");
- var selected_file_names = new Array();
- selected_files.each(function(index) {
- selected_file_names[index] = $(this).closest('tr').attr('inode-path');
- })
- sessionStorage.setItem("selected_file_names", JSON.stringify(selected_file_names));
- alert("Cut " + selected_file_names.length + " files/directories");
- }
- //Retrieve the list of files from session storage and rename them to the current
- //directory
- function paste_selected_files() {
- var files = JSON.parse(sessionStorage.getItem("selected_file_names"));
- var source_directory = sessionStorage.getItem("source_directory");
- $.each(files, function(index, value) {
- var url = "/webhdfs/v1"
- + encode_path(append_path(source_directory, value))
- + '?op=RENAME&destination='
- + encode_path(append_path(current_directory, value));
- $.ajax({
- type: 'PUT',
- url: url
- }).done(function(data) {
- if(index == files.length - 1) {
- browse_directory(current_directory);
- }
- }).fail(function(jqXHR, textStatus, errorThrown) {
- show_err_msg("Couldn't move file " + value + ". " + errorThrown);
- });
- })
- }
- $('#explorer-cut').click(function() {
- store_selected_files(current_directory);
- });
- $('#explorer-paste').click(function() {
- paste_selected_files();
- });
- init();
- })();
|