You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sm...@apache.org on 2016/03/11 08:00:25 UTC

[09/21] airavata-php-gateway git commit: Added File Storage Browse Capability. It will be required to run 'composer update' command after this update.

Added File Storage Browse Capability.  It will be required to run 'composer update' command after this update.


Project: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/commit/e873f1e1
Tree: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/tree/e873f1e1
Diff: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/diff/e873f1e1

Branch: refs/heads/master
Commit: e873f1e15c9d8771b0c43e0ddcfc00bfc0aad3ce
Parents: 43466f1
Author: Nipurn Doshi <ni...@gmail.com>
Authored: Tue Mar 8 12:31:55 2016 -0500
Committer: Nipurn Doshi <ni...@gmail.com>
Committed: Tue Mar 8 12:31:55 2016 -0500

----------------------------------------------------------------------
 app/controllers/FilemanagerController.php |  35 ++++
 app/libraries/CommonUtilities.php         |   6 +-
 app/libraries/ExperimentUtilities.php     |   5 +-
 app/libraries/FileManager.php             | 262 +++++++++++++++++++++++++
 app/routes.php                            |  14 +-
 app/views/files/browse.blade.php          |  47 +++++
 public/css/filemanager.css                |  49 +++++
 public/js/filemanager.js                  | 137 +++++++++++++
 8 files changed, 547 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/app/controllers/FilemanagerController.php
----------------------------------------------------------------------
diff --git a/app/controllers/FilemanagerController.php b/app/controllers/FilemanagerController.php
new file mode 100644
index 0000000..a27ceb5
--- /dev/null
+++ b/app/controllers/FilemanagerController.php
@@ -0,0 +1,35 @@
+<?php
+
+class FilemanagerController extends BaseController
+{
+	public function __construct()
+    {
+        $this->beforeFilter('verifylogin');
+        $this->beforeFilter('verifyauthorizeduser');
+        Session::put("nav-active", "storage");
+    }
+
+    public function browse(){
+    	return View::make("files/browse");
+    }
+
+	public function get(){
+		if(Session::has('username') ){
+
+			$path = Input::get('path');
+			/*
+			if( $path == null || (0 !== strpos($path, Session::get('username']))){
+			    header('HTTP/1.0 403 Forbidden');
+			}
+			*/
+			$DATA_ROOT = Config::get("pga_config.airavata")["experiment-data-absolute-path"];
+			$data_path = $DATA_ROOT . "/" . $path;
+			if (!file_exists( $data_path))
+			    echo FileManager::msg(False, "$path does not exist");
+			if (is_dir( $data_path))
+			    echo FileManager::get_content( $DATA_ROOT .  "/", $path);
+			else
+			    echo file_get_contents($data_path);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/app/libraries/CommonUtilities.php
----------------------------------------------------------------------
diff --git a/app/libraries/CommonUtilities.php b/app/libraries/CommonUtilities.php
index 4c55d7b..dc3e7a3 100644
--- a/app/libraries/CommonUtilities.php
+++ b/app/libraries/CommonUtilities.php
@@ -193,7 +193,11 @@ class CommonUtilities
         </li>';
         }
 
-
+        $active = "";
+        if( Session::has("nav-active"))
+            if( Session::get("nav-active") == "storage")
+                $active = "active";
+        echo '<li class="' . $active . '"><a href="' . URL::to("/") . '/files/browse"><span class="glyphicon glyphicon-folder-close"></span> Storage</a></li>';
         echo '</ul>
 
         <ul class="nav navbar-nav navbar-right">';

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/app/libraries/ExperimentUtilities.php
----------------------------------------------------------------------
diff --git a/app/libraries/ExperimentUtilities.php b/app/libraries/ExperimentUtilities.php
index acd6822..1350193 100644
--- a/app/libraries/ExperimentUtilities.php
+++ b/app/libraries/ExperimentUtilities.php
@@ -76,8 +76,7 @@ class ExperimentUtilities
             if ($input->type == DataType::URI && empty($input->metaData)) {
                 $inputArray = explode('/', $input->value);
                 echo '<p><a target="_blank"
-                        href="' . URL::to("/") . '/download/' . $inputArray[ count($inputArray)-2] . '/' . 
-                $inputArray[ count($inputArray)-1] . '">' .
+                        href="' . URL::to("/") . '/download/' . $inputArray[ count($inputArray)-3] . '/' . $inputArray[ count($inputArray)-2] . '/' . $inputArray[ count($inputArray)-1] . '">' .
                     $inputArray[ count($inputArray)-1] . '
                 <span class="glyphicon glyphicon-new-window"></span></a></p>';
             }elseif($input->type == DataType::URI && !empty($input->metaData)
@@ -651,7 +650,7 @@ class ExperimentUtilities
                     $outputPathArray = explode("/", $output->value);
 
                     echo '<p>' . $output->name . ' : ' . '<a target="_blank"
-                            href="' . URL::to("/") . '/download/' . $outputPathArray[ count($outputPathArray)-3] . "/" . $outputPathArray[ count($outputPathArray)-2] . '/' .
+                            href="' . URL::to("/") . '/download/' . $outputPathArray[ count($outputPathArray)-4] . "/" . $outputPathArray[ count($outputPathArray)-3] . "/" . $outputPathArray[ count($outputPathArray)-2] . '/' .
             $outputPathArray[ count($outputPathArray)-1] . '">' .
                         $outputPathArray[sizeof($outputPathArray) - 1] . ' <span class="glyphicon glyphicon-new-window"></span></a></p>';
                 }

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/app/libraries/FileManager.php
----------------------------------------------------------------------
diff --git a/app/libraries/FileManager.php b/app/libraries/FileManager.php
new file mode 100644
index 0000000..f109b62
--- /dev/null
+++ b/app/libraries/FileManager.php
@@ -0,0 +1,262 @@
+<?php
+
+class FileManager {
+    /**
+     * returns a json message ether successful or failure.
+     */
+    public static function msg($status, $msg) {
+        return json_encode(array(
+            'status' => $status,
+            'msg' => $msg
+        ));
+    }
+
+    /**
+     * Takes a given path and prints the content in json format.
+     */
+    public static function get_content($dataRoot, $path) {
+        $path = $dataRoot . $path;
+        $path = rtrim($path, '/');
+
+        // get dir content
+        $files = array();
+        $folders = array();
+        FileManager::list_dir($path, $files, $folders);
+        $files = array_merge($folders, $files);
+
+        // get info
+        foreach ($files as $k => $v) {
+            $i = FileManager::get_file_info($v['path'], array(
+                'name',
+                'size',
+                'date',
+                'fileperms'
+            ));
+
+            if ($v['folder']) {
+                $files[$k] = array (
+                    'name' => $i['name'],
+                    'size' => '---',
+                    'date' => date('Y-m-d H:i:s', $i['date']),
+                    'perm' => FileManager::unix_perm_string($i['fileperms']),
+                    'folder' => True
+                );
+            } else {
+                $files[$k] = array(
+                    'name' => $i['name'],
+                    'size' => FileManager::human_filesize($i['size']),
+                    'date' => date('Y-m-d H:i:s', $i['date']),
+                    'perm' => FileManager::unix_perm_string($i['fileperms']),
+                    'folder' => False
+                );
+            }
+            $files[$k]['link'] = str_replace($dataRoot, '', $v['path']);
+        }
+
+        return json_encode(array('status' => 'ok', 'files' => $files));
+    }
+
+    /**
+     * returns html to build a breadcrumb based upon path.
+     * path should look like this: page/subdir/gfx
+     */
+    public static function breadcrumb($path) {
+        $parts = explode('/', $path);
+        $html = '';
+        $link = '';
+        for ($i = 0; $i < count($parts); $i++) {
+            if ($i != count($parts) - 1) {
+                $link .= $i == 0 ? $parts[$i] : '/'.$parts[$i];
+                $html .= "<li><a href=\"$link\">".$parts[$i].'</a></li>';
+            } else {
+                $html .= '<li class="active">'.$parts[$i].'</li>';
+            }
+        }
+
+        return "<ol class=\"breadcrumb\">$html</ol>";
+    }
+
+    /**
+     * stores files and folders of given directory in the provided arrays.
+     */
+    private static function list_dir($path, &$files, &$folders) {
+        foreach (scandir($path) as $f) {
+            if ($f == '.' || $f == '..') continue;
+
+            $file = array(
+                'name' => $f,
+                'path' => "$path/$f",
+            );
+
+            if (is_dir($file['path'])) {
+                $file['folder'] = true;
+                $folders[] = $file;
+            } else {
+                $file['folder'] = false;
+                $files[] = $file;
+            }
+        }
+    }
+
+    /**
+     * create thumbnail. will return false on failure.
+     */
+    private static function create_thumbnail($picture, $picture_thumb, $w) {
+        // get src image
+        if (pathinfo($picture, PATHINFO_EXTENSION) == "jpg")
+            $source_image = imagecreatefromjpeg($picture);
+        else if (pathinfo($picture, PATHINFO_EXTENSION) == "png")
+            $source_image = imagecreatefrompng($picture);
+        else
+            return false;
+
+        $width = imagesx($source_image);
+        $height = imagesy($source_image);
+
+        // calc height according to given width
+        $h = floor($height * ($w / $width));
+
+        // create virtual
+        $virtual_image = imagecreatetruecolor($w, $h);
+
+        // copy src image
+        imagecopyresized($virtual_image, $source_image, 0, 0, 0, 0, $w, $h, $width, $height);
+
+        // create thumbnail
+        if (pathinfo($picture, PATHINFO_EXTENSION) == 'jpg')
+            imagejpeg($virtual_image, $picture_thumb, 83);
+        elseif (pathinfo($picture, PATHINFO_EXTENSION) == 'png')
+            imagepng($virtual_image, $picture_thumb);
+
+        return true;
+    }
+
+    /**
+     * returns a password hash.
+     */
+    private static function generate_hash($pass, $salt) {
+        return hash('sha256', $pass.$salt);
+    }
+
+    /**
+     * returns a random salt.
+     */
+    private static function generate_salt() {
+        mt_srand(microtime(true) * 100000 + memory_get_usage(true));
+        return uniqid(mt_rand(), true);
+    }
+
+    /**
+     * Takes a file size in bytes and returns a human readable filesize.
+     */
+    private static function human_filesize($bytes, $decimals = 2) {
+        $sz = 'BKMGTP';
+        $factor = floor((strlen($bytes) - 1) / 3);
+        return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
+    }
+
+    /**
+     * Takes an permission value and builds a human readable unix style permission
+     * string.
+     * Taken from php.net.
+     */
+    private static function unix_perm_string($perms) {
+        if (($perms & 0xC000) == 0xC000) {
+            // Socket
+            $info = 's';
+        } elseif (($perms & 0xA000) == 0xA000) {
+            // Symbolic Link
+            $info = 'l';
+        } elseif (($perms & 0x8000) == 0x8000) {
+            // Regular
+            $info = '-';
+        } elseif (($perms & 0x6000) == 0x6000) {
+            // Block special
+            $info = 'b';
+        } elseif (($perms & 0x4000) == 0x4000) {
+            // Directory
+            $info = 'd';
+        } elseif (($perms & 0x2000) == 0x2000) {
+            // Character special
+            $info = 'c';
+        } elseif (($perms & 0x1000) == 0x1000) {
+            // FIFO pipe
+            $info = 'p';
+        } else {
+            // Unknown
+            $info = 'u';
+        }
+
+        // Owner
+        $info .= (($perms & 0x0100) ? 'r' : '-');
+        $info .= (($perms & 0x0080) ? 'w' : '-');
+        $info .= (($perms & 0x0040) ?
+            (($perms & 0x0800) ? 's' : 'x' ) :
+            (($perms & 0x0800) ? 'S' : '-'));
+
+        // Group
+        $info .= (($perms & 0x0020) ? 'r' : '-');
+        $info .= (($perms & 0x0010) ? 'w' : '-');
+        $info .= (($perms & 0x0008) ?
+            (($perms & 0x0400) ? 's' : 'x' ) :
+            (($perms & 0x0400) ? 'S' : '-'));
+
+        // World
+        $info .= (($perms & 0x0004) ? 'r' : '-');
+        $info .= (($perms & 0x0002) ? 'w' : '-');
+        $info .= (($perms & 0x0001) ?
+            (($perms & 0x0200) ? 't' : 'x' ) :
+            (($perms & 0x0200) ? 'T' : '-'));
+
+        return $info;
+    }
+
+    /**
+     * Returns information about a given file.
+     * Taken from code igniter.
+     */
+    private static function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date')) {
+        if (!file_exists($file)) {
+            return FALSE;
+        }
+
+        if (is_string($returned_values)) {
+            $returned_values = explode(',', $returned_values);
+        }
+
+        foreach ($returned_values as $key) {
+            switch ($key) {
+                case 'name':
+                    $fileinfo['name'] = substr(strrchr($file, DIRECTORY_SEPARATOR), 1);
+                    if( $fileinfo['name'] == false)
+                        $fileinfo['name'] = substr(strrchr($file, "/"), 1);
+                    break;
+                case 'server_path':
+                    $fileinfo['server_path'] = $file;
+                    break;
+                case 'size':
+                    $fileinfo['size'] = filesize($file);
+                    break;
+                case 'date':
+                    $fileinfo['date'] = filemtime($file);
+                    break;
+                case 'readable':
+                    $fileinfo['readable'] = is_readable($file);
+                    break;
+                case 'writable':
+                    // There are known problems using is_weritable on IIS.  It may not be reliable - consider fileperms()
+                    $fileinfo['writable'] = is_writable($file);
+                    break;
+                case 'executable':
+                    $fileinfo['executable'] = is_executable($file);
+                    break;
+                case 'fileperms':
+                    $fileinfo['fileperms'] = fileperms($file);
+                    break;
+            }
+        }
+
+        return $fileinfo;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/app/routes.php
----------------------------------------------------------------------
diff --git a/app/routes.php b/app/routes.php
index b419c61..3ba4afa 100755
--- a/app/routes.php
+++ b/app/routes.php
@@ -97,10 +97,12 @@ Route::get("experiment/browse", "ExperimentController@browseView");
 
 Route::post("experiment/browse", "ExperimentController@browseView");
 
-Route::get("download/{exp_data_dir}/{exp_folder}/{exp_file}", function($exp_data_dir, $exp_folder, $exp_file){
-    $downloadLink = Config::get('pga_config.airavata')['experiment-data-absolute-path'] . '/' . Session::get('username')
-        . '/' . $exp_data_dir . "/" . $exp_folder . '/' . $exp_file;
-    return Response::download( $downloadLink);
+Route::get("download/{username}/{exp_data_dir}/{exp_folder}/{exp_file}", function( $username, $exp_data_dir, $exp_folder, $exp_file){
+
+    if( $username == Session::get("username")){
+        $downloadLink = Config::get('pga_config.airavata')['experiment-data-absolute-path'] . '/' . $username . '/' . $exp_data_dir . "/" . $exp_folder . '/' . $exp_file;
+        return Response::download( $downloadLink);
+    }
 });
 
 Route::get("download/{exp_data_dir}/{exp_file}", function($exp_data_dir, $exp_file){
@@ -109,6 +111,10 @@ Route::get("download/{exp_data_dir}/{exp_file}", function($exp_data_dir, $exp_fi
     return Response::download( $downloadLink);
 });
 
+Route::get("files/browse", "FilemanagerController@browse");
+
+Route::get("files/get","FilemanagerController@get");
+
 /*
  * Compute Resources Routes
 */

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/app/views/files/browse.blade.php
----------------------------------------------------------------------
diff --git a/app/views/files/browse.blade.php b/app/views/files/browse.blade.php
new file mode 100644
index 0000000..4b0e7da
--- /dev/null
+++ b/app/views/files/browse.blade.php
@@ -0,0 +1,47 @@
+@extends('layout.basic')
+
+@section('page-header')
+@parent
+{{ HTML::style('css/filemanager.css')}}
+
+@stop
+
+@section('content')
+
+    <div class="container">
+        <div class="center-content">
+            <br><br><br>
+            <div class="well-sm" id="tools">
+                <a class="btn btn-default" id="refresh-button"><i class="icon-refresh"></i> Refresh</a>
+            </div>
+
+            <!-- breadcrumb -->
+            <ol class="breadcrumb" id="breadcrumb"></ol>
+            <!-- file manager view -->
+            <div class="input-group"> <span class="input-group-addon">Filter</span>
+                <input id="filter-text" type="text" class="form-control" placeholder="Search Here...">
+            </div>
+            <br/>
+            <table class="table table-hover table-condensed" id="filemanager"></table>
+
+            <!-- message box -->
+            <div id="msgbox"></div>
+
+        </div>
+    </div>
+
+@stop
+
+@section('scripts')
+@parent
+{{ HTML::script('js/filemanager.js')}}
+
+<script type="text/javascript">
+
+    $(document).ready(function () {
+        var PATH = "{{Session::get('username') }}";
+        browse(PATH);
+    });
+
+</script>
+@stop
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/public/css/filemanager.css
----------------------------------------------------------------------
diff --git a/public/css/filemanager.css b/public/css/filemanager.css
new file mode 100644
index 0000000..19980c4
--- /dev/null
+++ b/public/css/filemanager.css
@@ -0,0 +1,49 @@
+@charset "UTF-8";
+
+/* -------------------------------------------------- MAIN */
+body {
+    background: #fff url(../img/bg.png);
+}
+
+#main > .content {
+    background-color: #fdfdfd;
+    border: solid thin #d4d4d4;
+    padding: 3px 10px;
+}
+
+/* -------------------------------------------------- LOGO */
+#main > .logo img {
+    display: block;
+    margin: 0px auto;
+}
+
+/* -------------------------------------------------- LINKS */
+#main > .links {
+    margin: 30px auto;
+    padding: 5px;
+    text-align: center;
+}
+
+#main > .links img {
+    border: none;
+    filter: alpha(opacity=40);
+    height: 16px;
+    margin: 0px 20px;
+    opacity: 0.4;
+    vertical-align: middle;
+    width: 16px;
+}
+
+#main > .links img:hover {
+    filter: alpha(opacity=100);
+    opacity: 1.0;
+}
+
+
+.icon-folder-close:before {
+    content: url(../img/folder-black-icon.png);
+}
+
+.icon-file:before {
+    content: url(../img/file-black-icon.png);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e873f1e1/public/js/filemanager.js
----------------------------------------------------------------------
diff --git a/public/js/filemanager.js b/public/js/filemanager.js
new file mode 100644
index 0000000..35b99b0
--- /dev/null
+++ b/public/js/filemanager.js
@@ -0,0 +1,137 @@
+var FILES;
+
+// -------------------------------------------------- MESSAGE BOX
+/**
+ * add a message to the message box. context and type can be omitted.
+ */
+function add_msg(msg, context, type) {
+    context = typeof context !== 'undefined' ? context : 'Info';
+    type = typeof type !== 'undefined' ? type : 'alert-info';
+
+    $('div#msgbox').html(
+        $('<div />').addClass('alert').addClass(type).append(
+            '<a class="close" data-dismiss="alert">&times;</a>',
+            '<strong>' + context + ':</strong> ' + msg
+        )
+    );
+}
+
+// -------------------------------------------------- BROWSE
+/**
+ * set breadcrumb according to PATH.
+ */
+function set_breadcrumb() {
+    // add parts
+    var parts = PATH.split('/');
+    var html = '';
+    var link = '';
+    for (var i = 0; i < parts.length; i++) {
+        if (i != parts.length - 1) {
+            link += i == 0 ? parts[i] : '/' + parts[i];
+            html += '<li><a href="' + link + '">' + parts[i] + '</a></li>';
+        } else {
+            html += '<li class="active">' + parts[i] + '</li>';
+        }
+    }
+    $('ol#breadcrumb').html(html);
+
+    // register click event
+    $('ol#breadcrumb a').click(function (e) {
+        e.preventDefault();
+        browse($(e.target).attr('href'));
+    });
+}
+
+/**
+ * do the ajax request for the new path.
+ */
+function browse(path) {
+    $.ajax({
+        url: "../files/get",
+        cache: false,
+        dataType: 'json',
+        data:{ path:path},
+        success: function (result) {
+            if (result.status)
+                show_content(path, result.files);
+            else
+                add_msg(result.msg, 'PHP', 'alert-danger');
+        },
+        error: function (jqXHR, status) {
+            add_msg(status, 'AJAX', 'alert-danger');
+        }
+    });
+}
+
+
+/**
+ * handles click on anchor to a directory
+ * @param e
+ * @param path
+ */
+function dir_click(path){
+    browse(path);
+    return false;
+}
+
+/**
+ * ajax success callback, set path and add content to table.
+ */
+function show_content(path, files) {
+    PATH = path;
+    set_breadcrumb();
+    $('#filter-text').val('');
+    FILES = files;
+    show_table(files);
+}
+
+function show_table(files){
+    $('table#filemanager').empty();
+
+    html = "";
+    for (var i = 0; i < files.length; i++) {
+        var f = files[i];
+        var icon_class, name_link;
+        if (f.folder) {
+            icon_class = 'glyphicon glyphicon-folder-open';
+            name_link = '<a href="#" onclick=dir_click("' + f.link + '")>&nbsp;' + f.name + "</a>";
+        } else {
+            icon_class = 'glyphicon glyphicon-save-file';
+            name_link = '<a href="../download/' + f.link + '">&nbsp;' + f.name + '</a>';
+        }
+
+        html += '<tr>'
+            + '<td><span class="' + icon_class + '"></span> ' + name_link + '</td>'
+            + '<td>' + f.size + '</td>'
+            + '<td>' + f.date + '</td>'
+            + '<td>' + f.perm + '</td>'
+            + '</tr>';
+    }
+    $('table#filemanager').html(html);
+}
+
+$('div#tools a#refresh-button').click(function (e) {
+    browse(PATH);
+    $('#filter-text').val('');
+});
+
+$('div#tools a#clear-msgbox-button').click(function (e) {
+    $('div#msgbox').empty();
+    $('#filter-text').val('');
+});
+
+function file_filter(file){
+    var text = $('#filter-text').val();
+    if(file.link.indexOf(text) !== -1){
+        return true;
+    }
+    return false;
+}
+
+$('#filter-text').on("keypress", function(e) {
+    if (e.keyCode == 13) {
+        var files = FILES.filter(file_filter);
+        show_table(files);
+        return false;
+    }
+});
\ No newline at end of file