Added Gantt Activity

This commit is contained in:
Deon George
2011-05-27 18:44:44 +10:00
parent d52b86214c
commit 6f38322009
14 changed files with 473 additions and 315 deletions

View File

@@ -251,9 +251,14 @@ abstract class Controller_lnApp_TemplateDefault extends Controller_Template {
// Remove the extension from the filename
$file = substr($file, 0, -(strlen($ext) + 1));
$f = '';
// If our file is pathed with session, our file is in our session.
if ($fd = Session::instance()->get_once($this->request->param('file'))) {
$this->response->body($fd);
// First try and find media files for the site_id
if ($f = Kohana::find_file(sprintf('media/%s',Config::siteid()), $file, $ext)) {
} elseif ($f = Kohana::find_file(sprintf('media/%s',Config::siteid()), $file, $ext)) {
// Send the file content as the response
$this->response->body(file_get_contents($f));
@@ -269,8 +274,8 @@ abstract class Controller_lnApp_TemplateDefault extends Controller_Template {
// Set the proper headers to allow caching
$this->response->headers('Content-Type',File::mime_by_ext($ext));
$this->response->headers('Content-Length',(string)filesize($f));
$this->response->headers('Last-Modified',date('r', filemtime($f)));
$this->response->headers('Content-Length',(string)$this->response->content_length());
$this->response->headers('Last-Modified',date('r', $f ? filemtime($f) : time()));
}
}
?>

View File

@@ -11,8 +11,6 @@
* @license http://phptsmadmin.sf.net/license.html
*/
class Controller_NODE extends Controller_TemplateDefault {
protected $control = array('Client Nodes'=>'node');
/**
* Default Index for Controller
*/
@@ -47,8 +45,6 @@ $(document).ready(function () {$("#node_name").change(function () {
'title'=>_('TSM Nodes'),
'body'=>$output,
));
$this->template->content = Block::factory();
}
public function action_detail($node_name=NULL) {
@@ -88,8 +84,6 @@ $(document).ready(function () {$("#node_name").change(function () {
'title'=>_('Schedule Information'),
'body'=>$output,
));
$this->template->content = Block::factory();
}
}
?>

View File

@@ -0,0 +1,188 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides information on TSM Server.
*
* @package PTA
* @subpackage Server
* @category Controllers
* @author Deon George
* @copyright (c) 2010 phpTSMadmin Development Team
* @license http://phptsmadmin.sf.net/license.html
*/
class Controller_SERVER extends Controller_TemplateDefault {
/**
* Default Index for Controller
*/
public function action_index() {
}
public function action_gantt() {
$end = strftime('%Y-%m-%d 23:59',time());
$start = strftime('%Y-%m-%d 00:00',time()-86400);
$ao = ORM::factory('SUMMARY')
->where_open()
->where('START_TIME','>=',$start)
->and_where('END_TIME','>=',$end)
->where_close()
->or_where_open()
->where('END_TIME','<=',$end)
->and_where('END_TIME','>=',$start)
->or_where_close();
$graph = new JPGraph_Gantt;
foreach ($ao->find_all() as $a) {
$sort = 10;
$csim = '';
$caption = '';
$wait = 0; // @todo
switch ($a->ACTIVITY) {
case('TAPE MOUNT'):
$summary = sprintf('%s (%s)',$a->ACTIVITY,$a->DRIVE_NAME);
$csim = sprintf('%s (%s)',$a->VOLUME_NAME,$a->LAST_USE);
$sort = 1;
break;
case('STGPOOL BACKUP'):
$summary = sprintf('%s (%s)',$a->ACTIVITY,$a->ENTITY);
$csim = sprintf('%3d MB. %ss Media wait',$a->BYTES/1024/1024,$a->MEDIAW);
$sort = 4;
break;
case('ARCHIVE'):
$summary = sprintf('%s (%s)',$a->ACTIVITY,$a->ENTITY);
$csim = sprintf('%3d MB',$a->BYTES/1024/1024);
$sort = 3;
break;
case('BACKUP'):
$summary = sprintf('%s (%s)',$a->ACTIVITY,$a->ENTITY);
$csim = sprintf('%3d MB',$a->BYTES/1024/1024);
$sort = 2;
break;
case('RESTORE'):
$summary = sprintf('%s (%s)',$a->ACTIVITY,$a->ENTITY);
$csim = sprintf('%3d MB. %ss Media wait',$a->BYTES/1024/1024,$a->MEDIAW);
$sort = 2;
break;
case('RETRIEVE'):
$summary = sprintf('%s (%s)',$a->ACTIVITY,$a->ENTITY);
$csim = sprintf('%3d MB. %ss Media wait',$a->BYTES/1024/1024,$a->MEDIAW);
$sort = 2;
break;
case('FULL_DBBACKUP'):
$summary = $a->ACTIVITY;
$csim = sprintf('%3d MB. %ss Media wait',$a->BYTES/1024/1024,$a->MEDIAW);
break;
case('RECLAMATION'):
$summary = $a->ACTIVITY.' ('.preg_replace('/^(.*)\s+\(.*\)$/','$1',$a->ENTITY).')';
$csim = sprintf('%3d MB. %ss Media wait',$a->BYTES/1024/1024,$a->MEDIAW);
$sort = 4;
break;
case('MIGRATION'):
$summary = $a->ACTIVITY.' ('.$a->ENTITY.')';
$csim = sprintf('%3d MB. %ss Media wait',$a->BYTES/1024/1024,$a->MEDIAW);
$sort = 4;
break;
case('MOVE NODEDATA'):
$summary = $a->ACTIVITY.' ('.$a->ENTITY.')';
$csim = sprintf('%3d MB. %ss Media wait',$a->BYTES/1024/1024,$a->MEDIAW);
$sort = 4;
break;
case('EXPIRATION'):
$summary = 'EXPIRATION PROCESSING';
$caption = sprintf('%ss',$a->AFFECTED);
default:
$summary = $a->ACTIVITY;
}
$graph->add($summary,$a->START_TIME,$a->END_TIME)
->sort($sort)
->progress($wait)
->caption($caption)
->csim($csim);
}
$graph->jpgraph->SetMargin(1,1,1,1);
$graph->jpgraph->SetMarginColor('#FFFFFF');
$graph->jpgraph->SetFrame(FALSE,'#FFFFFF',3);
$graph->jpgraph->SetColor('#F6F6F8');
// We want to display day, hour and minute scales
$graph->jpgraph->ShowHeaders(GANTT_HDAY | GANTT_HHOUR | GANTT_HMIN);
$graph->jpgraph->hgrid->Show();
$graph->jpgraph->hgrid->SetRowFillColor('#AAAACC@0.85');
// Setup hour format
$graph->jpgraph->scale->day->SetFontColor('white');
$graph->jpgraph->scale->day->SetBackgroundColor('blue');
$graph->jpgraph->scale->hour->SetFontColor('white');
$graph->jpgraph->scale->hour->SetBackgroundColor('blue');
$graph->jpgraph->scale->hour->SetIntervall(1);
$graph->jpgraph->scale->hour->SetStyle(HOURSTYLE_H24);
$graph->jpgraph->scale->minute->SetFontColor('white');
$graph->jpgraph->scale->minute->SetBackgroundColor('blue');
$graph->jpgraph->scale->minute->SetIntervall(30);
$url = $graph->draw('gantt');
Block::add(array(
'title'=>_('Server Gantt Activity'),
'body'=>HTML::Image('media/'.$url,array('alt'=>_('Service Gantt Activity'))),
));
}
// @todo Other work in progress
public function xaction_gantt() {
$end = date('Y-m-d H:i');
$start = date('Y-m-d H:i',time()-86400);
$startActivites = array();
$startActivities['811'] = array('start'=>'Expire Inventory');
$startActivities['812'] = array('success'=>'Expire Inventory');
$startActivities['2562'] = array('start'=>'Event Records Delete');
$startActivities['2564'] = array('success'=>'Event Records Delete');
$startActivities['2102'] = array('start'=>'Activity Log Delete');
$startActivities['2102'] = array('success'=>'Activity Log Delete');
$startActivities['2280'] = array('start'=>'DB Backup');
$startActivities['4550'] = array('success'=>'DB Backup');
$startActivities['406'] = array('start'=>'Session');
$startActivities['403'] = array('success'=>'Session');
$ao = ORM::factory('ACTLOG')
->where('DATE_TIME','>=',$start)
->and_where('DATE_TIME','<=',$end)
->and_where('ORIGINATOR','=','SERVER')
->and_where('MSGNO','in',array_keys($startActivities));
$activity = array();
foreach ($ao->find_all() as $a) {
# New Event.
if (isset($startActivities[$a->MSGNO]['start'])) {
$activity[$startActivities[$a->MSGNO]['start']][]['start'] = $a->DATE_TIME;
} elseif (isset($startActivities[$a->MSGNO]['success'])) {
$item = (isset($activity[$startActivities[$a->MSGNO]['success']]) ? count($activity[$startActivities[$a->MSGNO]['success']])-1 : 0);
# Is there a start event.
if (! isset($activity[$startActivities[$a->MSGNO]['success']][$item]['start']))
$activity[$startActivities[$a->MSGNO]['success']][$item]['start'] = $a->DATE_TIME;
$activity[$startActivities[$a->MSGNO]['success']][$item]['end'] = $a->DATE_TIME;
}
}
}
}
?>

View File

@@ -31,6 +31,14 @@ class Controller_Tree extends Controller_lnApp_Tree {
'attr_href'=>URL::Site('/node'),
));
array_push($data,array(
'id'=>'activity',
'name'=>'Server Activity Gantt',
'state'=>'none',
'attr_id'=>'1',
'attr_href'=>URL::Site('/server/gantt'),
));
return parent::action_json($id,$data);
}
}

View File

@@ -0,0 +1,4 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
class JPGraph extends lnApp_JPGraph {}
?>

View File

@@ -0,0 +1,4 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
class JPGraph_Gantt extends lnApp_JPGraph_Gantt {}
?>

View File

@@ -0,0 +1,29 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This is class helps with rendering JPGraph images.
*
* @package lnApp
* @subpackage JPGraph
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
abstract class lnApp_JPGraph {
public function __construct() {
// JPGraph should be installed in a our includes dir
$jpgraph = DOCROOT.'includes/jpgraph/src';
if (! file_exists($jpgraph.'/jpgraph_gantt.php'))
throw new Kohana_Exception('jpgraph_gantt.php must be installed in '.$jpgraph);
if (! function_exists('imagetypes') && ! function_exists('imagecreatefromstring'))
throw new Kohana_Exception('It seems that GD support is not available. Please add GD support to your PHP configuration.');
require_once($jpgraph.'/jpgraph.php');
return $jpgraph;
}
}
?>

View File

@@ -0,0 +1,104 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This is class helps with rendering JPGraph Gantt images.
*
* @package lnApp
* @subpackage JPGraph
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class lnApp_JPGraph_Gantt extends JPGraph {
// Our JPGraph object
public $jpgraph;
private $_count;
private $_items = array();
public function __construct() {
// Run through our parent checks
$jpgraph = parent::__construct();
if (! file_exists($jpgraph.'/jpgraph_gantt.php'))
throw new Kohana_Exception('jpgraph_gantt.php must be installed in '.$jpgraph);
require_once $jpgraph.'/jpgraph_gantt.php';
$this->jpgraph = new GanttGraph(0,0,'auto');
return $this;
}
// Add a new line item to the Gantt Chart
public function add($summary,$start,$end) {
$this->_count = count($this->_items);
$this->_items[$this->_count]['summary'] = $summary;
$this->_items[$this->_count]['start'] = $start;
$this->_items[$this->_count]['end'] = $end;
return $this;
}
public function caption($value) {
$this->_items[$this->_count]['caption'] = $value;
return $this;
}
public function csim($value) {
$this->_items[$this->_count]['csim'] = $value;
return $this;
}
public function progress($value) {
$this->_items[$this->_count]['progress'] = $value;
return $this;
}
public function sort($value) {
$this->_items[$this->_count]['sort'] = $value;
return $this;
}
// This will compile the gantt and output a URL that has the image
public function draw($name) {
// Sort our items by sort criteria.
sort::MAsort($this->_items,'sort,summary',0);
$c = 0;
$ls = '';
foreach ($this->_items as $item) {
// Put a gap between our priority items.
if ($c AND ($lp != $item['sort']))
$c++;
if ($ls != $item['summary'])
$c++;
$lp = $item['sort'];
$ls = $item['summary'];
$activity = new GanttBar($c,$item['summary'],$item['start'],$item['end']);
$activity->progress->Set($item['progress']);
$activity->caption ->Set($item['caption']);
$activity->SetCSIMTarget('#',($item['csim'] ? $item['csim'] : 'NoCSIM'));
$activity->title->SetCSIMTarget('#',($item['csim'] ? $item['csim'] : 'NoCSIM'));
$this->jpgraph->Add($activity);
}
$tmpfile = '/tmp/'.$name.'.png';
$file = 'session/'.$name.'.png';
$this->jpgraph->Stroke($tmpfile);
Session::instance()->set($file,file_get_contents($tmpfile));
unlink($tmpfile);
return $file;
}
}
?>

View File

@@ -0,0 +1,105 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class is used to sort multiple dimension arrays.
*
* @package lnApp
* @subpackage Sort
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
* @uses Style
*/
class lnApp_Sort {
/**
* Sort a multi dimensional array.
*
* @param array Multi demension array passed by reference
* @param string Comma delimited string of sort keys.
* @param boolean Whether to reverse sort.
* @return array Sorted multi demension array.
*/
public static function masort(&$data,$sortby,$rev=0) {
// if the array to sort is null or empty
if (! $data)
return;
static $MASORT_CACHE = array();
if (empty($MASORT_CACHE[$sortby])) {
$code = "\$c=0;\n";
foreach (explode(',',$sortby) as $key) {
$code .= "if (is_object(\$a) || is_object(\$b)) {\n";
$code .= " if (is_array(\$a->$key)) {\n";
$code .= " asort(\$a->$key);\n";
$code .= " \$aa = array_shift(\$a->$key);\n";
$code .= " } else\n";
$code .= " \$aa = \$a->$key;\n";
$code .= " if (is_array(\$b->$key)) {\n";
$code .= " asort(\$b->$key);\n";
$code .= " \$bb = array_shift(\$b->$key);\n";
$code .= " } else\n";
$code .= " \$bb = \$b->$key;\n";
$code .= " if (\$aa != \$bb)";
if ($rev)
$code .= " return (\$aa < \$bb ? 1 : -1);\n";
else
$code .= " return (\$aa > \$bb ? 1 : -1);\n";
$code .= "} else {\n";
$code .= " \$a = array_change_key_case(\$a);\n";
$code .= " \$b = array_change_key_case(\$b);\n";
$key = strtolower($key);
$code .= " if ((! isset(\$a['$key'])) && isset(\$b['$key'])) return 1;\n";
$code .= " if (isset(\$a['$key']) && (! isset(\$b['$key']))) return -1;\n";
$code .= " if ((isset(\$a['$key'])) && (isset(\$b['$key']))) {\n";
$code .= " if (is_array(\$a['$key'])) {\n";
$code .= " asort(\$a['$key']);\n";
$code .= " \$aa = array_shift(\$a['$key']);\n";
$code .= " } else\n";
$code .= " \$aa = \$a['$key'];\n";
$code .= " if (is_array(\$b['$key'])) {\n";
$code .= " asort(\$b['$key']);\n";
$code .= " \$bb = array_shift(\$b['$key']);\n";
$code .= " } else\n";
$code .= " \$bb = \$b['$key'];\n";
$code .= " if (\$aa != \$bb)\n";
$code .= " if (is_numeric(\$aa) && is_numeric(\$bb)) {\n";
if ($rev)
$code .= " return (\$aa < \$bb ? 1 : -1);\n";
else
$code .= " return (\$aa > \$bb ? 1 : -1);\n";
$code .= " } else {\n";
if ($rev)
$code .= " if ( (\$c = strcasecmp(\$bb,\$aa)) != 0 ) return \$c;\n";
else
$code .= " if ( (\$c = strcasecmp(\$aa,\$bb)) != 0 ) return \$c;\n";
$code .= " }\n";
$code .= " }\n";
$code .= "}\n";
}
$code .= 'return $c;';
$MASORT_CACHE[$sortby] = create_function('$a, $b',$code);
}
uasort($data,$MASORT_CACHE[$sortby]);
}
}
?>

View File

@@ -0,0 +1,4 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
class sort extends lnApp_Sort {}
?>