Return-Path: X-Original-To: apmail-ambari-commits-archive@www.apache.org Delivered-To: apmail-ambari-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 179A618DF0 for ; Wed, 4 Nov 2015 19:23:47 +0000 (UTC) Received: (qmail 37173 invoked by uid 500); 4 Nov 2015 19:23:40 -0000 Delivered-To: apmail-ambari-commits-archive@ambari.apache.org Received: (qmail 37144 invoked by uid 500); 4 Nov 2015 19:23:40 -0000 Mailing-List: contact commits-help@ambari.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: ambari-dev@ambari.apache.org Delivered-To: mailing list commits@ambari.apache.org Received: (qmail 37135 invoked by uid 99); 4 Nov 2015 19:23:40 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 04 Nov 2015 19:23:40 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 99A91DFCC9; Wed, 4 Nov 2015 19:23:40 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: srimanth@apache.org To: commits@ambari.apache.org Message-Id: <670e0a7fbd6841ba8c541069ac51ac20@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: ambari git commit: AMBARI-Files View: Enable to preview files in WEBHDFS (Pallav Kulshreshtha via srimanth) Date: Wed, 4 Nov 2015 19:23:40 +0000 (UTC) Repository: ambari Updated Branches: refs/heads/branch-2.1 f10ece280 -> 409ea0131 AMBARI-Files View: Enable to preview files in WEBHDFS (Pallav Kulshreshtha via srimanth) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/409ea013 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/409ea013 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/409ea013 Branch: refs/heads/branch-2.1 Commit: 409ea01317a76db8d3ad7c46424dddc1be0040d6 Parents: f10ece2 Author: Srimanth Gunturi Authored: Wed Nov 4 11:23:24 2015 -0800 Committer: Srimanth Gunturi Committed: Wed Nov 4 11:23:24 2015 -0800 ---------------------------------------------------------------------- .../view/filebrowser/FileBrowserService.java | 10 +++ .../view/filebrowser/FilePreviewService.java | 92 ++++++++++++++++++++ .../files/src/main/resources/ui/app/adapter.js | 2 +- .../main/resources/ui/app/controllers/file.js | 13 ++- .../main/resources/ui/app/controllers/files.js | 10 ++- .../ui/app/controllers/previewModal.js | 87 ++++++++++++++++++ .../src/main/resources/ui/app/initialize.js | 3 + .../src/main/resources/ui/app/routes/file.js | 23 ++++- .../ui/app/templates/modal/preview.hbs | 33 +++++++ .../main/resources/ui/app/views/modalPreview.js | 51 +++++++++++ .../files/src/main/resources/ui/bower.json | 3 +- .../files/src/main/resources/ui/package.json | 3 +- 12 files changed, 324 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java index 9224331..fd1c710 100644 --- a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java +++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FileBrowserService.java @@ -68,4 +68,14 @@ public class FileBrowserService { return new HelpService(context); } + + /** + * @see org.apache.ambari.view.filebrowser.FilePreviewService + * @return service + */ + @Path("/preview") + public FilePreviewService preview() { + return new FilePreviewService(context); + } + } http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java new file mode 100644 index 0000000..0c1344d --- /dev/null +++ b/contrib/views/files/src/main/java/org/apache/ambari/view/filebrowser/FilePreviewService.java @@ -0,0 +1,92 @@ +/** + * 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. + */ + +package org.apache.ambari.view.filebrowser; + +import org.apache.ambari.view.ViewContext; +import org.apache.ambari.view.filebrowser.utils.NotFoundFormattedException; +import org.apache.ambari.view.filebrowser.utils.ServiceFormattedException; +import org.apache.ambari.view.utils.hdfs.HdfsApi; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.io.compress.CompressionCodec; +import org.apache.hadoop.io.compress.CompressionCodecFactory; +import org.json.simple.JSONObject; + +import javax.ws.rs.*; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.FileNotFoundException; +import java.io.InputStream; + +/** + * File Preview Service + */ +public class FilePreviewService extends HdfsService{ + + private CompressionCodecFactory compressionCodecFactory; + + public FilePreviewService(ViewContext context) { + super(context); + + Configuration conf = new Configuration(); + conf.set("io.compression.codecs","org.apache.hadoop.io.compress.GzipCodec," + + "org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.SnappyCodec," + + "org.apache.hadoop.io.compress.BZip2Codec"); + + compressionCodecFactory = new CompressionCodecFactory(conf); + } + + @GET + @Path("/file") + @Produces(MediaType.APPLICATION_JSON) + public Response previewFile(@QueryParam("path") String path,@QueryParam("start") int start,@QueryParam("end") int end) { + + try { + HdfsApi api = getApi(context); + FileStatus status = api.getFileStatus(path); + + CompressionCodec codec = compressionCodecFactory.getCodec(status.getPath()); + + // check if we have a compression codec we need to use + InputStream stream = (codec != null) ? codec.createInputStream(api.open(path)) : api.open(path); + + int length = end - start; + byte[] bytes = new byte[length]; + // ((Seekable)stream).seek(start); //seek(start); + stream.skip(start); + int readBytes = stream.read(bytes, 0, length); + boolean isFileEnd = false; + + if (readBytes < length) isFileEnd = true; + + JSONObject response = new JSONObject(); + response.put("data", new String(bytes)); + response.put("readbytes", readBytes); + response.put("isFileEnd", isFileEnd); + + return Response.ok(response).build(); + } catch (WebApplicationException ex) { + throw ex; + } catch (FileNotFoundException ex) { + throw new NotFoundFormattedException(ex.getMessage(), ex); + } catch (Exception ex) { + throw new ServiceFormattedException(ex.getMessage(), ex); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/adapter.js ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/adapter.js b/contrib/views/files/src/main/resources/ui/app/adapter.js index 6ec763b..74cb988 100644 --- a/contrib/views/files/src/main/resources/ui/app/adapter.js +++ b/contrib/views/files/src/main/resources/ui/app/adapter.js @@ -296,7 +296,7 @@ App.ApplicationStore = DS.Store.extend({ option = option || "browse"; if (option == 'browse') { - query = { "path": files.get('firstObject.path'), "download": download }; + query = { "path": (files.get('firstObject.path') || files.get('id')), "download": download }; resolver.resolve(adapter.downloadUrl('browse',query)); return resolver.promise; } http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/controllers/file.js ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/controllers/file.js b/contrib/views/files/src/main/resources/ui/app/controllers/file.js index cf87041..b5054e4 100644 --- a/contrib/views/files/src/main/resources/ui/app/controllers/file.js +++ b/contrib/views/files/src/main/resources/ui/app/controllers/file.js @@ -21,6 +21,13 @@ var App = require('app'); App.FileController = Ember.ObjectController.extend({ needs:['files'], actions:{ + confirmPreview:function (option) { + if (this.get('content.readAccess')) { + this.store.linkFor([this.get('content')],option).then(function (link) { + window.location.href = link; + },Em.run.bind(this,this.sendAlert)); + } + }, download:function (option) { if (this.get('content.readAccess')) { this.store.linkFor([this.get('content')],option).then(function (link) { @@ -28,6 +35,9 @@ App.FileController = Ember.ObjectController.extend({ },Em.run.bind(this,this.sendAlert)); } }, + preview:function (option) { + this.send('showPreviewModal',this.get('content')); + }, showChmod:function () { this.send('showChmodModal',this.get('content')); }, @@ -55,7 +65,8 @@ App.FileController = Ember.ObjectController.extend({ if (this.get('content.isDirectory')) { return this.transitionToRoute('files',{queryParams: {path: this.get('content.id')}}); } else{ - return this.send('download'); + //return this.send('download'); + return this.send('preview'); } }, deleteFile:function (deleteForever) { http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/controllers/files.js ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/controllers/files.js b/contrib/views/files/src/main/resources/ui/app/controllers/files.js index 22cbb7a..7fb55bd 100644 --- a/contrib/views/files/src/main/resources/ui/app/controllers/files.js +++ b/contrib/views/files/src/main/resources/ui/app/controllers/files.js @@ -87,10 +87,12 @@ App.FilesController = Ember.ArrayController.extend({ }, download:function (option) { var files = this.get('selectedFiles').filterBy('readAccess',true); - this.store.linkFor(files,option).then(function (link) { + var content = this.get('content'); + this.store.linkFor(content, option).then(function (link) { window.location.href = link; }); }, + mkdir:function (newDirName) { this.store.mkdir(newDirName) .then(bind(this,this.mkdirSuccessCalback),bind(this,this.throwAlert)); @@ -118,6 +120,12 @@ App.FilesController = Ember.ArrayController.extend({ .chmod(file) .then(null,Em.run.bind(this,this.chmodErrorCallback,file)); }, + confirmPreview:function (file) { + //this.send('download'); + this.store.linkFor(file, "browse").then(function (link) { + window.location.href = link; + }); + }, clearSearchField:function () { this.set('searchString',''); } http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/controllers/previewModal.js ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/controllers/previewModal.js b/contrib/views/files/src/main/resources/ui/app/controllers/previewModal.js new file mode 100644 index 0000000..a2d0c9e --- /dev/null +++ b/contrib/views/files/src/main/resources/ui/app/controllers/previewModal.js @@ -0,0 +1,87 @@ +/** + * 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. + */ + +var App = require('app'); + +App.PreviewModalController = Em.ObjectController.extend({ + needs:['files'], + offset: 3000 , + startIndex:0, + file:Em.computed.alias('content'), + filePageText:'', + pagecontent: Ember.computed('file','startIndex', 'endIndex', function() { + var file = this.get('file'); + var filepath = file.get('path'); + var filePageText = this.get('filePageText'); + + var self = this, + defer = Ember.RSVP.defer(), + startIndex = this.get('startIndex'), + endIndex = this.get('endIndex'); + + var pathName = window.location.pathname; + var pathNameArray = pathName.split("/"); + var ViewVersion = pathNameArray[3]; + var viewName = pathNameArray[4]; + var previewServiceURL = "/api/v1/views/FILES/versions/"+ ViewVersion + "/instances/" + viewName + "/resources/files/preview/file" + '?path=' + filepath + '&start='+ startIndex +'&end='+ endIndex; + + var previousText = $('.preview-content').text(); + + $.ajax({ + url: previewServiceURL, + dataType: "json", + type: 'get', + async: false, + contentType: 'application/json', + success: function( response, textStatus, jQxhr ){ + self.set('filePageText', previousText + response.data); + self.set('isFileEnd',response.isFileEnd); + }, + error: function( jqXhr, textStatus, errorThrown ){ + console.log( "Preview Fail pagecontent : " + errorThrown ); + } + }); + + if(self.get('isFileEnd') == true){ + this.set('showNext', false); + } + return self.get('filePageText'); + }), + endIndex: Ember.computed('startIndex', 'offset', function() { + var startIndex = this.get('startIndex'), + offset = this.get('offset'); + return startIndex + offset; + }), + showPrev : Ember.computed('startIndex', function() { + var startIndex = this.get('startIndex'); + this.set('showNext', true); + return ((startIndex == 0) ? false : true ); + }), + showNext : true, + actions:{ + next: function(){ + console.log('Next'); + this.set('startIndex', this.get('startIndex') + this.get('offset')); + return self.get('filePageText'); + }, + prev: function(){ + console.log('Prev'); + this.set('startIndex', (this.get('startIndex') - this.get('offset')) > 0 ? (this.get('startIndex') - this.get('offset')) : 0); + } + } +}); http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/initialize.js ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/initialize.js b/contrib/views/files/src/main/resources/ui/app/initialize.js index fc6cbc7..7790397 100644 --- a/contrib/views/files/src/main/resources/ui/app/initialize.js +++ b/contrib/views/files/src/main/resources/ui/app/initialize.js @@ -31,6 +31,7 @@ require('templates/index'); require('templates/files'); require('templates/error'); require('templates/modal/chmod'); +require('templates/modal/preview'); require('templates/util/errorRow'); require('templates/util/fileRow'); @@ -56,6 +57,7 @@ require('controllers/file'); require('controllers/error'); require('controllers/filesAlert'); require('controllers/chmodModal'); +require('controllers/previewModal'); ///////////////////////////////// // Components @@ -81,6 +83,7 @@ require('views/file'); require('views/files'); require('views/filesAlert'); require('views/modalChmod'); +require('views/modalPreview'); ///////////////////////////////// // Routes http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/routes/file.js ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/routes/file.js b/contrib/views/files/src/main/resources/ui/app/routes/file.js index ee6a45a..207b57a 100644 --- a/contrib/views/files/src/main/resources/ui/app/routes/file.js +++ b/contrib/views/files/src/main/resources/ui/app/routes/file.js @@ -48,13 +48,16 @@ App.FilesRoute = Em.Route.extend({ }, willTransition:function (argument) { var hasModal = this.router._lookupActiveView('modal.chmod'), - hasAlert = this.router._lookupActiveView('files.alert'); + hasAlert = this.router._lookupActiveView('files.alert'), + hasPreviewModal = this.router._lookupActiveView('modal.preview'); Em.run.next(function(){ if (hasAlert) this.send('removeAlert'); if (hasModal) this.send('removeChmodModal'); + if (hasPreviewModal) this.send('removePreviewModal'); }.bind(this)); }, + showChmodModal:function (content) { this.controllerFor('chmodModal').set('content',content); this.render('modal.chmod',{ @@ -63,12 +66,30 @@ App.FilesRoute = Em.Route.extend({ controller:'chmodModal' }); }, + + showPreviewModal :function (content) { + this.controllerFor('previewModal').set('content',content); + this.controllerFor('previewModal').set('startIndex',0); + + this.render('modal.preview',{ + into:'files', + outlet:'modal', + controller:'previewModal' + }); + }, + removeChmodModal:function () { this.disconnectOutlet({ outlet: 'modal', parentView: 'files' }); }, + removePreviewModal:function () { + this.disconnectOutlet({ + outlet: 'modal', + parentView: 'files' + }); + }, showAlert:function (error) { this.controllerFor('filesAlert').set('content',error); this.render('files.alert',{ http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/templates/modal/preview.hbs ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/templates/modal/preview.hbs b/contrib/views/files/src/main/resources/ui/app/templates/modal/preview.hbs new file mode 100644 index 0000000..d619bd9 --- /dev/null +++ b/contrib/views/files/src/main/resources/ui/app/templates/modal/preview.hbs @@ -0,0 +1,33 @@ +{{! + 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. +}} + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/app/views/modalPreview.js ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/app/views/modalPreview.js b/contrib/views/files/src/main/resources/ui/app/views/modalPreview.js new file mode 100644 index 0000000..927e267 --- /dev/null +++ b/contrib/views/files/src/main/resources/ui/app/views/modalPreview.js @@ -0,0 +1,51 @@ +/** + * 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. + */ + +var App = require('app'); + +App.ModalPreviewView = Em.View.extend({ + actions:{ + confirm:function (file) { + this.get('controller.controllers.files').send('confirmPreview', this.get('controller.file')); + this.$('.preview').modal('hide'); + }, + close:function () { + this.$('.preview').modal('hide'); + } + }, + didInsertElement:function (argument) { + var self = this; + + this.$('.preview').modal(); + + this.$('.preview').on('hidden.bs.modal',function () { + this.get('controller.controllers.files').send('removePreviewModal'); + }.bind(this)); + + this.$('.preview-content').on('scroll', function() { + if($(this).scrollTop() + $(this).innerHeight() >= this.scrollHeight) { + self.get('controller').send('next'); + } + }); + + }, + willClearRender:function () { + this.$('.preview').off('hidden.bs.modal'); + this.$('.preview').modal('hide'); + } +}); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/bower.json ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/bower.json b/contrib/views/files/src/main/resources/ui/bower.json index b7cb52a..c0a4049 100644 --- a/contrib/views/files/src/main/resources/ui/bower.json +++ b/contrib/views/files/src/main/resources/ui/bower.json @@ -12,7 +12,8 @@ "moment": "~2.5.1", "ember-i18n": "~1.6.0", "bootstrap-contextmenu": "~0.2.0", - "font-awesome": "~4.0.3" + "font-awesome": "~4.0.3", + "ivy-codemirror": "~1.0.0" }, "overrides": { "ember-uploader": { http://git-wip-us.apache.org/repos/asf/ambari/blob/409ea013/contrib/views/files/src/main/resources/ui/package.json ---------------------------------------------------------------------- diff --git a/contrib/views/files/src/main/resources/ui/package.json b/contrib/views/files/src/main/resources/ui/package.json index 1fab7e8..f172af8 100644 --- a/contrib/views/files/src/main/resources/ui/package.json +++ b/contrib/views/files/src/main/resources/ui/package.json @@ -30,7 +30,8 @@ "phantomjs": "^1.9.2", "karma": "*", "karma-qunit": "*", - "karma-phantomjs-launcher": "~0.1.2" + "karma-phantomjs-launcher": "~0.1.2", + "ivy-codemirror": "^1.2.0" }, "ignore": [ "**/.*",