#leases_buttons { padding: 0px 10px 10px 10px; }
#leases_clear { position: relative; left: 30%;}
#leases_submit { position: relative; left: 60%; }
-
+
+
+/*panos: some additional styles for the column configuration */
+
+div#toggle-container-my-slice-nodes-configuration {
+ background: #f8f8f8;
+}
+
+div.out{background-color:white; color:black}
+div.in{background-color:#CAE8EA; color:#4f6b72}
+div.selected{background-color:gray; color:black}
+div.invisible{display:none}
+
+.myslice {
+ font: 11px Arial, Helvetica, sans-serif;
+ color: gray;
+}
+
+.myslice .title {
+ font: 11px;
+ font-weight: bold;
+}
+
+.myslice .desc {
+ font: 11px;
+ font-style: italic;
+}
+
+.myslice .subtitle{
+ color: #bb9c61;
+}
+
--- /dev/null
+<?php
+
+ // $Id: plc_functions.php 15734 2009-11-13 10:52:31Z thierry $
+
+ // utility function for displaying extra columns based on tags and categories
+ // expected type is e.g. 'node'
+
+class VisibleTags {
+ var $api;
+ var $type;
+
+ function VisibleTags ($api,$type) {
+ $this->api=$api;
+ $this->type=$type;
+ $this->columns=NULL;
+ }
+
+ // returns an ordered set of columns - compute only once
+ function columns () {
+ # if cached
+ if ($this->columns != NULL)
+ return $this->columns;
+
+ // scan tag types to find relevant additional columns
+ $tag_types = $this->api->GetTagTypes(array('category'=>"$type*/ui*"));
+
+ $columns = array();
+ foreach ($tag_types as $tag_type) {
+ $tagname=$tag_type['tagname'];
+ $column=array();
+ $column['tagname']=$tagname;
+ // defaults
+ $column['header']=$tagname;
+ $column['rank']=$tagname;
+ $column['type']='string';
+ $column['description']=$tag_type['description'];
+ // split category and parse any setting
+ $category_tokens=explode('/',$tag_type['category']);
+ foreach ($category_tokens as $token) {
+ $assign=explode('=',$token);
+ if (count($assign)==2)
+ $column[$assign[0]]=$assign[1];
+ }
+ $columns []= $column;
+ }
+
+ // sort upon 'rank'
+ usort ($columns, create_function('$col1,$col2','return strcmp($col1["header"],$col2["header"]);'));
+
+ # cache for next time
+ $this->columns=$columns;
+// plc_debug('columns',$columns);
+ return $columns;
+ }
+
+ // extract tagname
+ function column_names () {
+ return array_map(create_function('$tt','return $tt["tagname"];'),$this->columns());
+ }
+
+ // to add with array_merge to the headers part of the Plekit Table
+ function headers () {
+ $headers=array();
+ $columns=$this->columns();
+ foreach ($columns as $column)
+ //panos: needed a few more fields in the header array
+ $headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['description']);
+ /*
+ if ($column['header'] == $column['tagname'])
+ $headers[$column['header']]=$column['type'];
+ else
+ $headers[$column['header']]=array('type'=>$column['type'],'title'=>$column['description']);
+ */
+ return $headers;
+ }
+
+ // to add with array_merge to the notes part of the Plekit Table
+ function notes () {
+ $notes=array();
+ $columns=$this->columns();
+ foreach ($columns as $column)
+ if ($column['header'] != $column['tagname'])
+ $notes []= strtoupper($column['header']) . ' = ' . $column['description'];
+ return $notes;
+ }
+
+}
+?>
--- /dev/null
+<?php
+
+// $Id$
+
+// Require login
+require_once 'plc_login.php';
+
+// Get session and API handles
+require_once 'plc_session.php';
+global $plc, $api;
+
+// Print header
+require_once 'plc_drupal.php';
+include 'plc_header.php';
+
+// Common functions
+require_once 'plc_functions.php';
+require_once 'plc_peers.php';
+require_once 'plc_objects.php';
+require_once 'plc_visibletags2.php';
+require_once 'linetabs.php';
+require_once 'table2.php';
+require_once 'details.php';
+require_once 'toggle.php';
+require_once 'form.php';
+require_once 'columns.php';
+
+// keep css separate for now
+drupal_set_html_head('
+<link href="/planetlab/css/my_slice.css" rel="stylesheet" type="text/css" />
+');
+
+// -------------------- admins potentially need to get full list of users
+ini_set('memory_limit','32M');
+
+// --------------------
+// recognized URL arguments
+$slice_id=intval($_GET['id']);
+if ( ! $slice_id ) { plc_error('Malformed URL - id not set'); return; }
+
+////////////////////
+// Get all columns as we focus on only one entry
+$slices= $api->GetSlices( array($slice_id));
+
+if (empty($slices)) {
+ drupal_set_message ("Slice " . $slice_id . " not found");
+ return;
+ }
+
+$slice=$slices[0];
+
+// pull all node info to vars
+$name= $slice['name'];
+$expires = date( "d/m/Y", $slice['expires'] );
+$site_id= $slice['site_id'];
+
+$person_ids=$slice['person_ids'];
+
+// get peers
+$peer_id= $slice['peer_id'];
+$peers=new Peers ($api);
+$local_peer = ! $peer_id;
+
+// gets site info
+$sites= $api->GetSites( array( $site_id ) );
+$site=$sites[0];
+$site_name= $site['name'];
+$max_slices = $site['max_slices'];
+
+//////////////////////////////////////// building blocks for the renew area
+// Constants
+global $DAY; $DAY = 24*60*60;
+global $WEEK; $WEEK = 7 * $DAY;
+global $MAX_WEEKS; $MAX_WEEKS= 8; // weeks from today
+global $GRACE_DAYS; $GRACE_DAYS=10; // days for renewal promoted on top
+global $NOW; $NOW=mktime();
+
+////////////////////////////////////////////////////////////
+// make the renew area on top and open if the expiration time is less than 10 days from now
+function renew_needed ($slice) {
+ global $DAY, $NOW, $GRACE_DAYS;
+ $current_exp=$slice['expires'];
+
+ $time_left = $current_exp - $NOW;
+ $visible = $time_left/$DAY <= $GRACE_DAYS;
+ return $visible;
+}
+
+function renew_area ($slice,$site,$visible) {
+ global $DAY, $WEEK, $MAX_WEEKS, $GRACE_DAYS, $NOW;
+
+ $current_exp=$slice['expires'];
+ $current_text = gmstrftime("%A %b-%d-%y %T %Z", $current_exp);
+ $max_exp= $NOW + ($MAX_WEEKS * $WEEK); // seconds since epoch
+ $max_text = gmstrftime("%A %b-%d-%y %T %Z", $max_exp);
+
+ // xxx some extra code needed to enable this area only if the slice description is OK:
+ // description and url must be non void
+ $toggle=
+ new PlekitToggle('renew',"Expires $current_text - Renew this slice",
+ array("bubble"=>
+ "Enter this zone if you wish to renew your slice",
+ 'visible'=>$visible));
+ $toggle->start();
+
+ // xxx message could take roles into account
+ if ($site['max_slices']<=0) {
+ $message= <<< EOF
+<p class='my-slice-renewal'>Slice creation and renewal have been temporarily disabled for your
+<site. This may have occurred because your site's nodes have been down
+or unreachable for several weeks, and multiple attempts to contact
+your site's PI(s) and Technical Contact(s) have all failed. If so,
+contact your site's PI(s) and Technical Contact(s) and ask them to
+bring up your site's nodes. Please visit your <a
+href='/db/sites/index.php?id=$site_id'>site details</a> page to find
+out more about your site's nodes, and how to contact your site's PI(s)
+and Technical Contact(s).</p>
+EOF;
+ echo $message;
+
+ } else {
+ // xxx this is a rough cut and paste from the former UI
+ // showing a datepicker view could be considered as well with some extra work
+ // calculate possible extension lengths
+ $selectors = array();
+ foreach ( array ( 1 => "One more week",
+ 2 => "Two more weeks",
+ 3 => "Three more weeks",
+ 4 => "One more month" ) as $weeks => $text ) {
+ $candidate_exp = $current_exp + $weeks*$WEEK;
+ if ( $candidate_exp < $max_exp) {
+ $selectors []= array('display'=>"$text (" . gmstrftime("%A %b-%d-%y %T %Z", $candidate_exp) . ")",
+ 'value'=>$candidate_exp);
+ $max_renewal_weeks=$weeks;
+ $max_renewal_date= gmstrftime("%A %b-%d-%y %T %Z", $candidate_exp);
+ }
+ }
+
+ if ( empty( $selectors ) ) {
+ print <<< EOF
+<div class='my-slice-renewal'>
+Slices annot be renewed more than $MAX_WEEKS weeks from now, i.e. not beyond $max_text.
+For this reason, the current slice cannot be renewed any further into the future, try again closer to expiration date.
+</div>
+EOF;
+ } else {
+ print <<< EOF
+<div class='my-slice-renewal'>
+<p>You must provide a short description as well as a link to a project website before renewing it.
+Do <span class='bold'>not</span> provide bogus information; if a complaint is lodged against your slice
+and PlanetLab Operations is unable to determine what the normal behavior of your slice is,
+your slice may be deleted to resolve the complaint.</p>
+<p><span class='bold'>NOTE:</span>
+Slices cannot be renewed beyond another $max_renewal_weeks week(s) ($max_renewal_date).
+</p>
+</div>
+EOF;
+
+ $form = new PlekitForm (l_actions(),
+ array('action'=>'renew-slice',
+ 'slice_id'=>$slice['slice_id']));
+ $form->start();
+ print $form->label_html('expires','Duration');
+ print $form->select_html('expires',$selectors,array('label'=>'Pick one'));
+ print $form->submit_html('renew-button','Renew');
+ $form->end();
+ }
+ }
+
+ $toggle->end();
+}
+
+////////////////////////////////////////////////////////////
+
+$am_in_slice = in_array(plc_my_person_id(),$person_ids);
+
+if ($am_in_slice) {
+ drupal_set_title("My slice " . $name);
+ } else {
+ drupal_set_title("Slice " . $name);
+}
+
+$privileges = ( $local_peer && (plc_is_admin() || plc_is_pi() || $am_in_slice));
+$tags_privileges = $privileges || plc_is_admin();
+
+$tabs=array();
+$tabs [] = tab_nodes_slice($slice_id);
+$tabs [] = tab_site($site_id);
+
+// are these the right privileges for deletion ?
+if ($privileges) {
+ $tabs ['Delete']= array('url'=>l_actions(),
+ 'method'=>'post',
+ 'values'=>array('action'=>'delete-slice','slice_id'=>$slice_id),
+ 'bubble'=>"Delete slice $name",
+ 'confirm'=>"Are you sure to delete slice $name");
+
+ $tabs["Events"]=array_merge(tablook_event(),
+ array('url'=>l_event("Slice","slice",$slice_id),
+ 'bubble'=>"Events for slice $name"));
+ $tabs["Comon"]=array_merge(tablook_comon(),
+ array('url'=>l_comon("slice_id",$slice_id),
+ 'bubble'=>"Comon page about slice $name"));
+}
+
+plekit_linetabs($tabs);
+
+////////////////////////////////////////
+$peers->block_start($peer_id);
+
+//////////////////////////////////////// renewal area
+// (1) close to expiration : show on top and open
+
+if ($local_peer ) {
+ $renew_visible = renew_needed ($slice);
+ if ($renew_visible) renew_area ($slice,$site,true);
+ }
+
+
+//////////////////// details
+// default for opening the details section or not ?
+if ($local_peer) {
+ $default_show_details = true;
+ } else {
+ $default_show_details = ! $renew_visible;
+ }
+
+$toggle =
+ new PlekitToggle ('my-slice-details',"Details",
+ array('bubble'=>
+ 'Display and modify details for that slice',
+ 'visible'=>get_arg('show_details',$default_show_details)));
+$toggle->start();
+
+$details=new PlekitDetails($privileges);
+$details->form_start(l_actions(),array('action'=>'update-slice',
+ 'slice_id'=>$slice_id,
+ 'name'=>$name));
+
+$details->start();
+if (! $local_peer) {
+ $details->th_td("Peer",$peers->peer_link($peer_id));
+ $details->space();
+ }
+
+
+$details->th_td('Name',$slice['name']);
+$details->th_td('Description',$slice['description'],'description',
+ array('input_type'=>'textarea',
+ 'width'=>50,'height'=>5));
+$details->th_td('URL',$slice['url'],'url',array('width'=>50));
+$details->tr_submit("submit","Update Slice");
+$details->th_td('Expires',$expires);
+$details->th_td('Instantiation',$slice['instantiation']);
+$details->th_td('Site',l_site_obj($site));
+// xxx show the PIs here
+//$details->th_td('PIs',...);
+$details->end();
+
+$details->form_end();
+$toggle->end();
+
+//////////////////// persons
+$person_columns = array('email','person_id','first_name','last_name','roles');
+// get persons in slice
+if (!empty($person_ids))
+ $persons=$api->GetPersons(array('person_id'=>$slice['person_ids']),$person_columns);
+// just propose to add everyone else
+// xxx this is maybe too much for admins as it slows stuff down
+// as regular persons can see only a fraction of the db anyway
+$potential_persons=
+ $api->GetPersons(array('~person_id'=>$slice['person_ids'],
+ 'peer_id'=>NULL,
+ 'enabled'=>true),
+ $person_columns);
+$count=count($persons);
+
+$toggle=
+ new PlekitToggle ('my-slice-persons',"$count users",
+ array('bubble'=>
+ 'Manage accounts attached to this slice',
+ 'visible'=>get_arg('show_persons',false)));
+$toggle->start();
+
+////////// people currently in
+// visible:
+// hide if both current+add are included
+// so user can chose which section is of interest
+// show otherwise
+$toggle_persons = new PlekitToggle ('my-slice-persons-current',
+ "$count people currently in $name",
+ array('visible'=>get_arg('show_persons_current',!$privileges)));
+$toggle_persons->start();
+
+$headers=array();
+$headers['email']='string';
+$headers['first']='string';
+$headers['last']='string';
+$headers['R']='string';
+if ($privileges) $headers[plc_delete_icon()]="none";
+$table=new PlekitTable2('persons',$headers,'0', NULL,
+ array('notes_area'=>false));
+$form=new PlekitForm(l_actions(),array('slice_id'=>$slice['slice_id']));
+$form->start();
+$table->start();
+if ($persons) foreach ($persons as $person) {
+ $table->row_start();
+ $table->cell(l_person_obj($person));
+ $table->cell($person['first_name']);
+ $table->cell($person['last_name']);
+ $table->cell(plc_vertical_table ($person['roles']));
+ if ($privileges) $table->cell ($form->checkbox_html('person_ids[]',$person['person_id']));
+ $table->row_end();
+}
+// actions area
+if ($privileges) {
+
+ // remove persons
+ $table->tfoot_start();
+
+ $table->row_start();
+ $table->cell($form->submit_html ("remove-persons-from-slice","Remove selected"),
+ array('hfill'=>true,'align'=>'right'));
+ $table->row_end();
+ }
+$table->end();
+$toggle_persons->end();
+
+////////// people to add
+if ($privileges) {
+ $count=count($potential_persons);
+ $toggle_persons = new PlekitToggle ('my-slice-persons-add',
+ "$count people may be added to $name",
+ array('visible'=>get_arg('show_persons_add',false)));
+ $toggle_persons->start();
+ if ( ! $potential_persons ) {
+ // xxx improve style
+ echo "<p class='not-relevant'>No person to add</p>";
+ } else {
+ $headers=array();
+ $headers['email']='string';
+ $headers['first']='string';
+ $headers['last']='string';
+ $headers['R']='string';
+ $headers['+']="none";
+ $options = array('notes_area'=>false,
+ 'search_width'=>15,
+ 'pagesize'=>8);
+ // show search for admins only as other people won't get that many names to add
+ if ( ! plc_is_admin() ) $options['search_area']=false;
+
+ $table=new PlekitTable2('add_persons',$headers,'0',NULL,$options);
+ $form=new PlekitForm(l_actions(),array('slice_id'=>$slice['slice_id']));
+ $form->start();
+ $table->start();
+ if ($potential_persons) foreach ($potential_persons as $person) {
+ $table->row_start();
+ $table->cell(l_person_obj($person));
+ $table->cell($person['first_name']);
+ $table->cell($person['last_name']);
+ $table->cell(plc_vertical_table ($person['roles']));
+ $table->cell ($form->checkbox_html('person_ids[]',$person['person_id']));
+ $table->row_end();
+ }
+ // add users
+ $table->tfoot_start();
+ $table->row_start();
+ $table->cell($form->submit_html ("add-persons-in-slice","Add selected"),
+ array('hfill'=>true,'align'=>'right'));
+ $table->row_end();
+ $table->end();
+ $form->end();
+ }
+ $toggle_persons->end();
+}
+$toggle->end();
+
+//////////////////////////////////////////////////////////// Nodes
+// the nodes details to display here
+// (1) we search for the tag types for which 'category' matches 'node*/ui*'
+// all these tags will then be tentatively displayed in this area
+// (2) further information can also be optionally specified in the category:
+// (.) we split the category with '/' and search for assignments of the form var=value
+// (.) header can be set to supersede the column header (default is tagname)
+// (.) rank can be used for ordering the columns (default is tagname)
+// (.) type is passed to the javascript table, for sorting (default is 'string')
+
+// minimal list as a start
+//$node_fixed_columns = array('hostname','node_id','slice_ids_whitelist','boot_state','last_contact');
+// create a VisibleTags object : basically the list of tag columns to show
+//$visibletags = new VisibleTags ($api, 'node');
+//$visiblecolumns = $visibletags->column_names();
+//$node_columns=array_merge($node_fixed_columns,$visiblecolumns);
+
+
+
+/* TEST PlekitColumns */
+
+//prepare fix and configurable columns
+
+$fix_columns = array();
+$fix_columns[]=array('tagname'=>'hostname', 'header'=>'hostname', 'type'=>'string', 'title'=>'The name of the node');
+$fix_columns[]=array('tagname'=>'peer_id', 'header'=>'AU', 'type'=>'string', 'title'=>'Authority');
+$fix_columns[]=array('tagname'=>'run_level', 'header'=>'ST', 'type'=>'string', 'title'=>'Status');
+
+$visibletags = new VisibleTags ($api, 'node');
+$visibletags->columns();
+$tag_columns = $visibletags->headers();
+
+$extra_columns = array();
+$extra_columns[]=array('tagname'=>'site_id', 'header'=>'SN', 'type'=>'string', 'title'=>'Site name', 'description'=>'Site name');
+
+//$configurable_columns = array_merge($tag_columns, $extra_columns);
+//usort ($configurable_columns, create_function('$col1,$col2','return strcmp($col1["header"],$col2["header"]);'));
+
+
+$first_time_configuration = 'false';
+$default_configuration = "hostname:f|ST:f|AU:f|Rw|AST";
+$column_configuration = "";
+
+$DescTags=$api->GetSliceTags (array('slice_id'=>$slice['slice_id']));
+for ($i=0; $i<count($DescTags); $i++ ) {
+ if ($DescTags [$i]['tagname']=='Configuration'){
+ $column_configuration = $DescTags [$i]['value'];
+ break;
+ }
+}
+
+if ($column_configuration == "")
+{
+ $first_time_configuration = 'true';
+ $column_configuration = $default_configuration;
+}
+
+//print("<p>GOT CONFIGURATION: ".$column_configuration);
+
+//$test_configuration = "hostname:f|AU:f|ST:f|Rw|AST";
+//print("<p>Parsing configuration ".$test_configuration);
+
+
+$ConfigureColumns =new PlekitColumns($column_configuration, $fix_columns, $tag_columns, $extra_columns);
+
+$node_requested_data = $ConfigureColumns->node_tags();
+$nodes=$api->GetNodes(array('node_id'=>$slice['node_ids']),$node_requested_data);
+$potential_nodes=$api->GetNodes(array('~node_id'=>$slice['node_ids']),$node_requested_data);
+
+//$nodes = array();
+//$potential_nodes = array();
+
+//print("<p>RESULTS for ".print_r(array('~node_id'=>$slice['node_ids'])));
+//print_r($nodes);
+
+$count=count($nodes);
+
+$toggle=new PlekitToggle ('my-slice-nodes',"$count nodes",
+ array('bubble'=>
+ 'Manage nodes attached to this slice',
+ 'visible'=>get_arg('show_nodes',false)));
+$toggle->start();
+
+
+$toggle_nodes=new PlekitToggle('my-slice-nodes-configuration',
+ "Node table column configuration",
+ array('visible'=>'1'));
+
+$toggle_nodes->start();
+
+
+//usort ($table_headers, create_function('$col1,$col2','return strcmp($col1["header"],$col2["header"]);'));
+
+//print("<p>HEADERS TO SHOW<p>");
+//print_r($headersToShow);
+
+//print("<p>TABLE HEADERS<p>");
+//print_r($table_headers);
+
+print("<div id='debug'></div>");
+print("<input type='hidden' id='slice_id' value='".$slice['slice_id']."' />");
+print("<input type='hidden' size='80' id='column_configuration' value='".$column_configuration."' />");
+print("<input type='hidden' id='previousConf' value='".$column_configuration."'></input>");
+print("<input type='hidden' id='defaultConf' value='".$default_configuration."'></input>");
+//print("<input type='button' id='testFunctions' onclick=\"highlightOption('AU')\" value='test'></input>");
+
+$ConfigureColumns->javascript_vars();
+
+$ConfigureColumns->configuration_panel_html(true);
+
+print("<div align='center' id='loadingDiv'></div>");
+
+$toggle_nodes->end();
+
+
+////////// nodes currently in
+
+$count=count($nodes);
+
+$toggle_nodes=new PlekitToggle('my-slice-nodes-current',
+ "$count nodes currently in $name",
+ array('visible'=>get_arg('show_nodes_current',!$privileges)));
+
+$toggle_nodes->start();
+
+$edit_header = array();
+if ($privileges) $edit_header[plc_delete_icon()]="none";
+
+$table_options = array('search_width'=>15,
+ 'pagesize'=>20);
+//$table=new PlekitTable2('nodes',$headers,'1',$table_options);
+//$table=new PlekitTable2('nodes_pairwise',array_merge($ConfigureColumns->plekit_columns_get_headers(),$edit_header),NULL,$headersToShow, $table_option);
+//$headersToShow = $ConfigureColumns->plekit_columns_visible();
+
+$table=new PlekitTable2('nodes',array_merge($ConfigureColumns->get_headers(),$edit_header),NULL,NULL, $table_option);
+
+$form=new PlekitForm(l_actions(),array('slice_id'=>$slice['slice_id']));
+$form->start();
+$table->start();
+if ($nodes) foreach ($nodes as $node) {
+ $table->row_start();
+
+ $table->cell($node['node_id'], array('display'=>'none'));
+ $table->cell(l_node_obj($node));
+
+ $peers->cell($table,$node['peer_id']);
+ $run_level=$node['run_level'];
+ list($label,$class) = Node::status_label_class_($node);
+ $table->cell ($label,array('name'=>'ST', 'class'=>$class, 'display'=>'table-cell'));
+
+
+$ConfigureColumns->cells($table, $node);
+
+
+
+ if ($privileges) $table->cell ($form->checkbox_html('node_ids[]',$node['node_id']));
+ $table->row_end();
+}
+// actions area
+if ($privileges) {
+
+ // remove nodes
+ $table->tfoot_start();
+
+ $table->row_start();
+ $table->cell($form->submit_html ("remove-nodes-from-slice","Remove selected"),
+ array('hfill'=>true,'align'=>'right'));
+ $table->row_end();
+ }
+$table->end();
+$toggle_nodes->end();
+
+////////// nodes to add
+if ($privileges) {
+ $new_potential_nodes = array();
+ if ($potential_nodes) foreach ($potential_nodes as $node) {
+ $emptywl=empty($node['slice_ids_whitelist']);
+ $inwl = (!emptywl) and in_array($slice['slice_id'],$node['slice_ids_whitelist']);
+ if ($emptywl or $inwl)
+ $new_potential_nodes[]=$node;
+ }
+ $potential_nodes=$new_potential_nodes;
+
+ $count=count($potential_nodes);
+ $toggle_nodes=new PlekitToggle('my-slice-nodes-add',
+ "$count more nodes available",
+ array('visible'=>get_arg('show_nodes_add',false)));
+ $toggle_nodes->start();
+
+ if ( ! $potential_nodes ) {
+ // xxx improve style
+ echo "<p class='not-relevant'>No node to add</p>";
+ } else {
+
+ $edit_header = array();
+ if ($privileges) $edit_header['+']="none";
+
+ //$table=new PlekitTable2('add_nodes',$headers,'1', $table_options);
+ $table=new PlekitTable2('add_nodes',array_merge($ConfigureColumns->get_headers(), $edit_header),NULL,$headersToShow, $table_options);
+ $form=new PlekitForm(l_actions(),
+ array('slice_id'=>$slice['slice_id']));
+ $form->start();
+ $table->start();
+
+ if ($potential_nodes) foreach ($potential_nodes as $node) {
+ $table->row_start();
+
+ $table->cell($node['node_id'], array('display'=>'none'));
+ $table->cell(l_node_obj($node));
+
+ $peers->cell($table,$node['peer_id']);
+ $run_level=$node['run_level'];
+ list($label,$class) = Node::status_label_class_($node);
+ $table->cell ($label,array('name'=>'ST', 'class'=>$class, 'display'=>'table-cell'));
+
+$ConfigureColumns->cells($table, $node);
+
+ $table->cell ($form->checkbox_html('node_ids[]',$node['node_id']));
+ $table->row_end();
+ }
+ // add nodes
+ $table->tfoot_start();
+ $table->row_start();
+ $table->cell($form->submit_html ("add-nodes-in-slice","Add selected"),
+ array('hfill'=>true,'align'=>'right'));
+ $table->row_end();
+ $table->end();
+ $form->end();
+ }
+ $toggle_nodes->end();
+}
+$toggle->end();
+
+//////////////////////////////////////////////////////////// Tags
+//if ( $local_peer ) {
+ $tags=$api->GetSliceTags (array('slice_id'=>$slice_id));
+ function get_tagname ($tag) { return $tag['tagname'];}
+ $tagnames = array_map ("get_tagname",$tags);
+
+ $toggle = new PlekitToggle ('slice-tags',count_english_warning($tags,'tag'),
+ array('bubble'=>'Inspect and set tags on tat slice',
+ 'visible'=>get_arg('show_tags',false)));
+ $toggle->start();
+
+ $headers=array(
+ "Name"=>"string",
+ "Value"=>"string",
+ "Node"=>"string",
+ "NodeGroup"=>"string");
+ if ($tags_privileges) $headers[plc_delete_icon()]="none";
+
+ $table_options=array("notes_area"=>false,"pagesize_area"=>false,"search_width"=>10);
+ $table=new PlekitTable2("slice_tags",$headers,'0',NULL,$table_options);
+ $form=new PlekitForm(l_actions(),
+ array('slice_id'=>$slice['slice_id']));
+ $form->start();
+ $table->start();
+ if ($tags) {
+ foreach ($tags as $tag) {
+ $node_name = "ALL";
+ if ($tag['node_id']) {
+ $nodes = $api->GetNodes(array('node_id'=>$tag['node_id']));
+ if($nodes) {
+ $node = $nodes[0];
+ $node_name = $node['hostname'];
+ }
+ }
+ $nodegroup_name="n/a";
+ if ($tag['nodegroup_id']) {
+ $nodegroup=$api->GetNodeGroups(array('nodegroup_id'=>$tag['nodegroup_id']));
+ if ($nodegroup) {
+ $nodegroup = $nodegroup[0];
+ $nodegroup_name = $nodegroup['groupname'];
+ }
+ }
+ $table->row_start();
+ $table->cell(l_tag_obj($tag));
+ $table->cell($tag['value']);
+ $table->cell($node_name);
+ $table->cell($nodegroup_name);
+ if ($tags_privileges) $table->cell ($form->checkbox_html('slice_tag_ids[]',$tag['slice_tag_id']));
+ $table->row_end();
+ }
+ }
+ if ($tags_privileges) {
+ $table->tfoot_start();
+ $table->row_start();
+ $table->cell($form->submit_html ("delete-slice-tags","Remove selected"),
+ array('hfill'=>true,'align'=>'right'));
+ $table->row_end();
+
+ $table->row_start();
+ function tag_selector ($tag) {
+ return array("display"=>$tag['tagname'],"value"=>$tag['tag_type_id']);
+ }
+ $all_tags= $api->GetTagTypes( array ("category"=>"slice*","-SORT"=>"+tagname"), array("tagname","tag_type_id"));
+ $selector_tag=array_map("tag_selector",$all_tags);
+
+ function node_selector($node) {
+ return array("display"=>$node["hostname"],"value"=>$node['node_id']);
+ }
+ $all_nodes = $api->GetNodes( array ("node_id" => $slice['node_ids']), array("hostname","node_id"));
+ $selector_node=array_map("node_selector",$all_nodes);
+
+ function nodegroup_selector($ng) {
+ return array("display"=>$ng["groupname"],"value"=>$ng['nodegroup_id']);
+ }
+ $all_nodegroups = $api->GetNodeGroups( array("groupname"=>"*"), array("groupname","nodegroup_id"));
+ $selector_nodegroup=array_map("nodegroup_selector",$all_nodegroups);
+
+ $table->cell($form->select_html("tag_type_id",$selector_tag,array('label'=>"Choose Tag")));
+ $table->cell($form->text_html("value","",array('width'=>8)));
+ $table->cell($form->select_html("node_id",$selector_node,array('label'=>"All Nodes")));
+ $table->cell($form->select_html("nodegroup_id",$selector_nodegroup,array('label'=>"No Nodegroup")));
+ $table->cell($form->submit_html("add-slice-tag","Set Tag"),array('columns'=>2,'align'=>'left'));
+ $table->row_end();
+ }
+
+ $table->end();
+ $form->end();
+ $toggle->end();
+//}
+
+
+//////////////////////// renew slice
+if ($local_peer ) {
+ if ( ! $renew_visible) renew_area ($slice,$site,false);
+ }
+
+$peers->block_end($peer_id);
+
+// Print footer
+include 'plc_footer.php';
+
+?>
+
+
+<script type="text/javascript">
+
+var sourceComon = '<a target="source_window" href="http://comon.cs.princeton.edu/">CoMoN</a>';
+var sourceTophat = '<b><a target="source_window" href="http://www.top-hat.info/">TopHat</a></b>';
+var sourceTophatAPI = '<b><a target="source_window" href="http://www.top-hat.info/API/">TopHat API</a></b>';
+var sourceMySlice = '<b><a target="source_window" href="http://myslice.info/">MySlice</a></b>';
+var sourceCymru = '<b><a target="source_window" href="http://www.team-cymru.org/">Team Cymru</a></b>';
+var sourceMyPLC = '<b><a target="source_window" href="http://www.planet-lab.eu/PLCAPI/">MyPLC API</a></b>';
+var sourceManiacs = '<b><a target="source_window" href="http://www.ece.gatech.edu/research/labs/MANIACS/as_taxonomy/">MANIACS</a></b>';
+var sourceMonitor = '<b><a target="source_window" href="http://monitor.planet-lab.org/">Monitor</a></b>';
+var selectReferenceNode ='Select reference node: <select id="reference_node" onChange="updateDefaultConf(this.value)"><option value=planetlab-europe-07.ipv6.lip6.fr>planetlab-europe-07.ipv6.lip6.fr</option></select>';
+var addButton = '<input id="addButton" type="button" value="Add" onclick=addColumnAjax(document.getElementById("list1").value)></input>';
+var deleteButton = '<input id="deleteButton" type="button" value="Delete" onclick=deleteColumn(window.document.getElementById("list1").value)></input>';
+
+var titleAU = 'Authority';
+var detailAU = '<i>The authority of the global PlanetLab federation that the site of the node belongs to.</i>';
+var valuesAU = 'Values: <b>PLC</b> (PlanetLab Central), <b>PLE</b> (PlanetLab Europe)';
+var sourceAU = '<b>Source:</b> '+sourceMyPLC;
+var descAU = '<span class="myslice title">'+titleAU+'</span><p>'+detailAU+'<p>'+valuesAU+'<p>'+sourceAU;
+
+var descHOSTNAME = "test";
+
+
+var titleAS = 'Autonomous system ID';
+var sourceAS = 'Source: '+sourceCymru+' (via '+sourceTophat+')';
+var valuesAS = 'Unit: <b>Integer between 0 and 65535</b>';
+var descAS = '<span class="myslice title">'+titleAS+'</span><p>'+valuesAS+'<p>' + sourceAS;
+
+var titleAST = 'Autonomous system type';
+var sourceAST = 'Source: '+sourceManiacs;
+var valuesAST = 'Values: <b>t1</b> (tier-1), <b>t2</b> (tier-2), <b>edu</b> (university), <b>comp</b> (company), <b>nic</b> (network information center), <b>ix</b> (IXP), <b>n/a</b>';
+var descAST = '<span class="myslice title">'+titleAST+'</span><p>'+valuesAST+'<p>'+sourceAST;
+
+var titleASN = 'Autonomous system name';
+var sourceASN = 'Source: '+sourceTophat;
+var descASN = '<span class="myslice title">'+titleASN+'</span><p>'+sourceASN;
+
+var selectPeriodBU = 'Select period: <select id="selectperiodBU" onChange=updatePeriod("BU")><option value=w>Week</option><option value=m>Month</option><option value=y>Year</option></select>';
+var titleBU = 'Bandwidth utilization ';
+var sourceBU = 'Source: '+sourceComon+' (via '+sourceMySlice+')';
+var valuesBU ='Unit: <b>Kbps</b>';
+var detailBU = '<i>The average Transmited bandwidh (Tx) over the selected period. The period is the most recent for which data is available, with CoMoN data being collected by MySlice daily.</i>'
+var descBU = '<span class="myslice title">'+titleBU+'</span><p>'+detailBU+'<p>'+selectPeriodBU+'<p>'+valuesBU+'<p>'+sourceBU;
+
+var titleBW= 'Bandwidth limit';
+var sourceBW = 'Source: '+sourceComon;
+var valuesBW = 'Unit: <b>Kbps</b>';
+var detailBW = '<i>The bandwidth limit is a cap on the total outbound bandwidth usage of a node. It is set by the site administrator (PI). For more details see <a href="http://www.planet-lab.org/doc/BandwidthLimits">Bandwidth Limits (planet-lab.org)</a></i>';
+var descBW = '<span class="myslice title">'+titleBW+'</span><p>'+detailBW+'<p>'+valuesBW+'<p>'+sourceBW;
+
+var titleCC = 'Number of CPU cores';
+var sourceCC = 'Source: '+sourceComon;
+var valuesCC = 'Current PlanetLab hardware requirements: 4 cores min. <br><i>(Older nodes may have fewer cores)</i>';
+var descCC = '<span class="myslice title">'+titleCC+'</span><p>'+valuesCC+'<p>'+sourceCC;
+
+var titleCN = 'Number of CPUs';
+var sourceCN = 'Source: '+sourceComon;
+var valuesCN = 'Current PlanetLab hardware requirements: <b>1 (if quad core) or 2 (if dual core)</b>';
+var descCN = '<span class="myslice title">'+titleCN+'</span><p>'+valuesCN+'<p>'+sourceCN;
+
+var titleCR = 'CPU clock rate';
+var sourceCR = 'Source: '+sourceComon;
+var valuesCR = 'Unit: <b>GHz</b><p>Current PlanetLab hardware requirements: <b>2.4 GHz</b>';
+var descCR = '<span class="myslice title">'+titleCR+'</span><p>'+valuesCR+'<p>'+sourceCR;
+
+var selectPeriodCF = 'Select period: <select id="selectperiodCF" onChange=updatePeriod("CF")><option value=w>Week</option><option value=m>Month</option><option value=y>Year</option></select>';
+var titleCF = 'Free CPU';
+var sourceCF = 'Source: '+sourceComon+' (via '+sourceMySlice+')';
+var valuesCF = 'Unit: <b>%</b>';
+var detailCF = '<i> The average CPU percentage that could be allocated by a test slice (burb) run periodically by CoMoN </i>';
+var descCF = '<span class="myslice title">'+titleCF+'</span><p>'+detailCF+'<p>'+selectPeriodCF+'<p>'+valuesCF+'<p>'+sourceCF;
+
+var titleDS = 'Disk size';
+var sourceDS = 'Source: '+sourceComon;
+var valuesDS = 'Unit: <b>GB</b><p>Current PlanetLab hardware requirements: <b>500GB</b>';
+var descDS = '<span class="myslice title">'+titleDS+'</span><p>'+valuesDS+'<p>'+sourceDS;
+
+var titleDU = 'Current disk utilization';
+var sourceDU = 'Source: '+sourceComon+' (via '+sourceMySlice+')';
+var valuesDU = 'Unit: <b>GB</b>';
+var detailDU = '<i> The amount of disk space currently consumed (checked daily) </i>';
+var descDU = '<span class="myslice title">'+titleDU+'</span><p>'+detailDU+'<p>'+valuesDU+'<p>'+sourceDU;
+
+var titleHC = 'Hop count from a reference node';
+var sourceHC = 'Source: '+sourceTophat;
+var detailHC = '<i>TopHat conducts traceroutes every five minutes in a full mesh between all PlanetLab nodes. The hop count is the length of the traceroute from the node to the reference node, based upon the most recently reported traceroute</i>.';
+var descHC = '<span class="myslice title">'+titleHC+'</span><p>'+detailHC+'<p>'+selectReferenceNode+'<p>'+sourceHC;
+
+var titleIP = 'IP address';
+var sourceIP = 'Source: '+sourceTophat;
+var descIP = '<span class="myslice title">'+titleIP+'</span><p>'+sourceIP;
+
+var selectPeriodL = 'Select period: <select id="selectperiodL" onChange=updatePeriod("L")><option value=w>Week</option><option value=m>Month</option><option value=y>Year</option></select>';
+var titleL= 'Load ';
+var sourceL = 'Source: '+sourceComon;
+var valuesL = 'Unit: <b>float</b>';
+var detailL = '<i>The average 5-minute Unix load (as reported by the uptime command) over the selected period</i>';
+var descL = '<span class="myslice title">'+titleL+'</span><p>'+detailL+'<p>'+selectPeriodL+'<p>'+valuesL+'<p>'+sourceL;
+
+var titleLON= 'Longitude';
+var sourceLON = 'Source: '+sourceTophat;
+var descLON = '<span class="myslice title">'+titleLON+'</span><p>'+sourceLON;
+
+var titleLAT= 'Latitude';
+var sourceLAT = 'Source: '+sourceTophat;
+var descLAT = '<span class="myslice title">'+titleLAT+'</span><p>'+sourceLAT;
+
+var titleLCN= 'Location (Country)';
+var sourceLCN = 'Source: '+sourceTophat;
+var detailLCN = '<i>Based on the latitude, longitude information</i>';
+var descLCN = '<span class="myslice title">'+titleLCN+'</span><p>'+detailLCN+'<p>'+sourceLCN;
+
+var titleLCT= 'Location (Continent)';
+var sourceLCT = 'Source: '+sourceTophat;
+var detailLCT = '<i>Based on the latitude, longitude information</i>';
+var descLCT = '<span class="myslice title">'+titleLCT+'</span><p>'+detailLCT+'<p>'+sourceLCT;
+
+var titleLCY= 'Location (City)';
+var sourceLCY = 'Source: '+sourceTophat;
+var detailLCY = '<i>Based on the latitude, longitude information</i>';
+var descLCY = '<span class="myslice title">'+titleLCY+'</span><p>'+detailLCY+'<p>'+sourceLCY;
+
+var titleLPR= 'Location precision radius';
+var sourceLPR = 'Source: '+sourceTophat;
+var valuesLPR = 'Unit: <b>float</b>';
+var detailLPR = '<i>The radius of the circle corresponding to the error in precision of the geolocalization</i>';
+var descLPR = '<span class="myslice title">'+titleLPR+'</span><p>'+detailLPR+'<p>'+valuesLPR+'<p>'+sourceLPR;
+
+var titleLRN= 'Location (Region)';
+var sourceLRN = 'Source: '+sourceTophat;
+var detailLRN = '<i>Based on the latitude, longitude information</i>';
+var descLRN = '<span class="myslice title">'+titleLRN+'</span><p>'+detailLRN+'<p>'+sourceLRN;
+
+var titleMS= 'Memory size';
+var sourceMS = 'Source: '+sourceComon;
+var valuesMS = 'Unit: <b>GB</b><p>Current PlanetLab hardware requirements: <b>4GB</b>';
+var descMS = '<span class="myslice title">'+titleMS+'</span><p>'+valuesMS+'<p>'+sourceMS;
+
+var selectPeriodMU = 'Select period: <select id="selectperiodMU" onChange=updatePeriod("MU")><option value=w>Week</option><option value=m>Month</option><option value=y>Year</option></select>';
+var titleMU = 'Memory utilization';
+var sourceMU = 'Source: '+sourceComon;
+var valuesMU = '<p>Unit: <b>%</b>';
+var detailMU = '<i>The average active memory utilization as reported by CoMoN</i>';
+var descMU = '<span class="myslice title">'+titleMU+'</span><p>'+detailMU+'<p>'+selectPeriodMU+'<p>'+valuesMU+'<p>'+sourceMU;
+
+var titleNEC= 'Network information (ETOMIC)';
+var sourceNEC = 'Source: '+sourceTophat;
+var valuesNEC = 'Values: <b>yes/no</b>';
+var detailNEC = '<i>The existence of a colocated ETOMIC box. When an ETOMIC box is present you have the possibility to conduct high-precision measurements through the '+sourceTophatAPI+'</i>';
+var descNEC = '<span class="myslice title">'+titleNEC+'</span><p>'+detailNEC+'<p>'+valuesNEC+'<p>'+sourceNEC;
+
+var titleNTH= 'Network information (TopHat)';
+var sourceNTH = 'Source: '+sourceTophat;
+var valuesNTH = 'Values: <b>yes/no</b>';
+var detailNTH = '<i>The existence of a colocated TopHat agent. When a TopHat agent is present you have the possibility to conduct high-precision measurements through the '+sourceTophatAPI+'</i>';
+var descNTH = '<span class="myslice title">'+titleNTH+'</span><p>'+detailNTH+'<p>'+valuesNTH+'<p>'+sourceNTH;
+
+var titleNDS= 'Network information (DIMES)';
+var sourceNDS = 'Source: '+sourceTophat;
+var valuesNDS = 'Values: <b>yes/no</b>';
+var detailNDS = '<i>The existence of a colocated DIMES agent. When a DIMES agent is present you have the possibility to conduct high-precision measurements through the '+sourceTophatAPI+'</i>';
+var descNDS = '<span class="myslice title">'+titleNDS+'</span><p>'+detailNDS+'<p>'+valuesNDS+'<p>'+sourceNDS;
+
+var titleNSF= 'Network information (spoof)';
+var sourceNSF = 'Source: '+sourceTophat;
+var valuesNSF = '<p>Values: <b>yes/no</b>';
+var detailNSF = '<i> Whether the node can send packets packets using the IP spoof option</i>';
+var descNSF = '<span class="myslice title">'+titleNSF+'</span><p>'+detailNSF+'<p>'+valuesNSF+'<p>'+sourceNSF;
+
+var titleNSR= 'Network information (source route)';
+var sourceNSR = 'Source: '+sourceTophat;
+var valuesNSR = '<p>Values: <b>yes/no</b>';
+var detailNSR = '<i> Whether the node can send packets packets using the IP source route option</i>';
+var descNSR = '<span class="myslice title">'+titleNSR+'</span><p>'+detailNSR+'<p>'+valuesNSR+'<p>'+sourceNSR;
+
+var titleNTP= 'Network information (timestamp)';
+var sourceNTP = 'Source: '+sourceTophat;
+var valuesNTP = '<p>Values: <b>yes/no</b>';
+var detailNTP = '<i> Whether the node can send packets packets using the IP timestamp option</i>';
+var descNTP = '<span class="myslice title">'+titleNTP+'</span><p>'+detailNTP+'<p>'+valuesNTP+'<p>'+sourceNTP;
+
+var titleNRR= 'Network information (record route)';
+var sourceNRR = 'Source: '+sourceTophat;
+var valuesNRR = '<p>Values: <b>yes/no</b>';
+var detailNRR = '<i> Whether the node can send packets packets using the IP record route option</i>';
+var descNRR = '<span class="myslice title">'+titleNRR+'</span><p>'+detailNRR+'<p>'+valuesNRR+'<p>'+sourceNRR;
+
+var titleOS = 'Operating system';
+var sourceOS = 'Source: '+sourceMyPLC;
+var valuesOS = 'Values: <b>Fedora, Cent/OS, other, n/a</b>';
+var descOS = '<span class="myslice title">'+titleOS+'</span><p>'+valuesOS+'<p>'+sourceOS;
+
+var selectPeriodR = 'Select period: <select id="selectperiodR" onChange=updatePeriod("R")><option value=w>Week</option><option value=m>Month</option><option value=y>Year</option></select>';
+var titleR = 'Reliability';
+var sourceR = 'Source: '+sourceComon+' (via '+sourceMySlice+')';
+var detailR = '<i>CoMoN queries nodes every 5 minutes, for 255 queries per day. The average reliability is the percentage of queries over the selected period for which CoMoN reports a value. The period is the most recent for which data is available, with CoMoN data being collected by MySlice daily</i>';
+var valuesR = 'Unit: <b>%</b>';
+var descR = '<span class="myslice title">'+titleR+'</span><p>'+detailR+'<p>'+selectPeriodR+'<p>'+valuesR+'<p>'+sourceR;
+
+var titleRES = 'Reservation capabilities';
+var sourceRES = 'Source: '+sourceMyPLC;
+var valuesRES = 'Values: <b>yes/no</b>';
+var detailRES = '<i> Whether the node can be reserved for a certain duration</i>';
+var descRES = '<span class="myslice title">'+titleRES+'</span><p>'+detailRES+'<p>'+valuesRES+'<p>'+sourceRES;
+
+var selectPeriodS = 'Select period: <select id="selectperiodS" onChange=updatePeriod("S")><option value=w>Week</option><option value=m>Month</option><option value=y>Year</option></select>';
+var titleS = 'Active slices';
+var sourceS = 'Source: '+sourceComon+' (via '+sourceMySlice+')';
+var valuesS = 'Unit: <b>%</b>';
+var detailS = '<i>Average number of active slices over the selected period for which CoMoN reports a value. The period is the most recent for which data is available, with CoMoN data being collected by MySlice daily</i>';
+var descS = '<span class="myslice title">'+titleS+'</span><p>'+detailS+'<p>'+selectPeriodS+'<p>'+valuesS+'<p>'+sourceS;
+
+var titleSN = 'Site name';
+var sourceSN = 'Source: '+sourceMyPLC;
+var descSN = '<span class="myslice title">'+titleSN+'</span><p>'+sourceSN;
+
+var selectPeriodSSH = 'Select period: <select id="selectperiodSSH" onChange=updatePeriod("SSH")><option value=w>Week</option><option value=m>Month</option><option value=y>Year</option></select>';
+var titleSSH = 'Average SSH response delay';
+var valuesSSH = 'Unit: <b>%</b>';
+var detailSSH = '<i>The average response delay of the node to SSH logins over the selected period for which CoMoN reports a value. The period is the most recent for which data is available, with CoMoN data being collected by MySlice daily</i>';
+var sourceSSH ='Source: '+sourceComon+' (via '+sourceMySlice+')';
+var descSSH = '<span class="myslice title">'+titleSSH+'</span><p>'+detailSSH+'<p>'+selectPeriodSSH+'<p>'+valuesSSH+'<p>'+sourceSSH;
+
+var titleST = 'Status';
+var sourceST = 'Source: '+sourceMonitor;
+var valuesST = 'Values: <b>online</b> (up and running), <b>good</b> (up and running recently), <b>offline</b> (unreachable today), <b>down</b> (unreachable nodes for more than 1 day), <b>failboot</b> (safeboot, MyPLC API term for debug)';
+var descST = '<span class="myslice title">'+titleST+'</span><p>'+valuesST+'<p>'+sourceST;
+
+highlightOption("AU");
+overrideTitles();
+
+
+/*
+document.defaultAction = false;
+document.onkeyup = detectEvent;
+
+function detectEvent(e) {
+ var evt = e || window.event;
+ //debugfilter(evt.type);
+ //debugfilter('keyCode is ' + evt.keyCode);
+ //debugfilter('charCode is ' + evt.charCode);
+ //debugfilter(document.getElementById('testfocus').focused);
+ return document.defaultAction;
+}
+*/
+
+
+</script>
--- /dev/null
+<?php
+
+require_once 'tophat_api.php';
+
+drupal_set_html_head('
+<script type="text/javascript" src="/plekit/table/columns.js"></script>
+');
+
+class PlekitColumns {
+
+var $column_configuration = "";
+var $reference_node = "";
+var $first_time = false;
+
+var $all_headers = array();
+var $this_table_headers = array();
+var $visible_headers = array();
+
+var $all_columns = array();
+var $fix_columns = array();
+var $tag_columns = array();
+var $extra_columns = array();
+
+var $table_ids;
+
+var $HopCount = array();
+
+ function PlekitColumns ($column_configuration, $fix_columns, $tag_columns, $extra_columns=NULL, $this_table_headers=NULL) {
+
+ $this->fix_columns = $fix_columns;
+ $this->tag_columns = $tag_columns;
+ $this->extra_columns = $extra_columns;
+
+ //print("<p>FIX<p>");
+ //print_r($this->fix_columns);
+ //print("<p>TAG<p>");
+ //print_r($this->tag_columns);
+ //print("<p>EXTRA<p>");
+ //print_r($this->extra_columns);
+
+ $this->prepare_headers();
+ $this->parse_configuration($column_configuration);
+
+ $this->visible_headers = $this->get_visible();
+
+ //print("<p>VISIBLE<p>");
+ //print_r($this->visible_headers);
+
+ $this->all_columns = array_merge($fix_columns, $tag_columns, $extra_columns);
+}
+
+
+
+/*
+
+INFO
+
+*/
+
+function prepare_headers() {
+
+foreach ($this->fix_columns as $column) {
+$this->all_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'], 'fixed'=>true, 'visible'=>false);
+}
+
+foreach ($this->tag_columns as $column) {
+$this->all_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['tagname'], 'description'=>$column['title'], 'label'=>$this->removeDuration($column['header']),'visible'=>false);
+}
+
+foreach ($this->extra_columns as $column) {
+$this->all_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['tagname'], 'description'=>$column['title'], 'label'=>$this->removeDuration($column['header']),'visible'=>false);
+}
+
+return $this->all_headers;
+
+}
+
+
+function get_headers() {
+
+return $this->all_headers;
+
+}
+
+function node_tags() {
+
+ $fetched_tags = array('node_id');
+
+ foreach ($this->all_headers as $h)
+ {
+ if ($h['visible'] == true)
+ $fetched_tags[] = $h['tagname'];
+ }
+
+ return $fetched_tags;
+}
+
+function print_headers() {
+
+ $headers = "";
+
+ foreach ($this->all_headers as $h)
+ {
+ $headers.="<br>".$h['header'].":".$h['label'].":".$h['tagname'];
+ }
+ return $headers;
+}
+
+function get_visible() {
+
+ $visibleHeaders = array();
+
+ foreach ($this->all_headers as $h)
+ {
+ if ($h['visible'] == true)
+ $visibleHeaders[] = $h['header'];
+ }
+ return $visibleHeaders;
+}
+
+function headerIsVisible($header_name) {
+
+$headersToShow = $this->visible_headers;
+
+
+ if ($this->inTypeC($header_name."w") || $this->inTypeC($header_name."m") || $this->inTypeC($header_name."y"))
+ return (in_array($header_name."w", $headersToShow) || in_array($header_name."m", $headersToShow) || in_array($header_name."y", $headersToShow));
+ else
+ return in_array($header_name, $headersToShow);
+}
+
+
+
+
+/*
+
+CONFIGURATION
+
+*/
+
+
+function parse_configuration($column_configuration) {
+
+ $this->column_configuration = $column_configuration;
+ //$this->default_configuration = $default_configuration;
+
+ $columns_conf = explode("|", $column_configuration);
+ foreach ($columns_conf as $c)
+ {
+ $conf = explode(":",$c);
+
+ $this->all_headers[$conf[0]]['visible']=true;
+ //print("<p>".$conf[0]."should be visible now");
+ //print_r($this->all_headers[$conf[0]]);
+
+ if ($conf[1] == "f")
+ continue;
+
+ else if ($this->inTypeC($conf[0]))
+ {
+ $this->all_headers[$conf[0]]['duration']= substr($conf[0], strlen($conf[0])-1, strlen($conf[0]));
+ $threshold = explode(",",$conf[1]);
+ $this->all_headers[$conf[0]]['threshold']=$threshold;
+ }
+ else if ($this->inTypeD($conf[0]))
+ {
+ $this->reference_node = $conf[1];
+ $this->reference_node = "planetlab-europe-07.ipv6.lip6.fr";
+ $this->all_headers[$conf[0]]['refnode']=$this->reference_node;
+ $threshold = explode(",",$conf[1]);
+ $this->all_headers[$conf[0]]['threshold']=$threshold;
+ }
+ else if ($this->inTypeA($conf[0]))
+ {
+ $exclude_list = explode(",",$conf[1]);
+ $this->all_headers[$conf[0]]['exclude_list']=$exclude_list;
+ }
+ else
+ {
+ $threshold = explode(",",$conf[1]);
+ $this->all_headers[$conf[0]]['threshold']=$threshold;
+ }
+ }
+}
+
+
+
+
+
+/*
+
+CELLS
+
+*/
+
+function getHopCount($ref_node, $planetlab_nodes)
+{
+
+$tophat_auth = array( 'AuthMethod' => 'password', 'Username' => 'guest', 'AuthString' => 'guest');
+$tophat_api = new TopHatAPI($tophat_auth);
+
+$traceroute = $tophat_api->Get('traceroute', 'latest', array('src_hostname' => $ref_node, 'dst_hostname' => $planetlab_nodes), array('dst_hostname', 'hop_count') );
+
+$hopcount = array();
+
+if ($traceroute) foreach ($traceroute as $t)
+$hopcount[$t['dst_hostname']]=$t['hop_count'];
+return $hopcount;
+}
+
+
+//Depending on the columns selected more data might need to be fetched from
+//external sources
+
+function fetch_data($nodes) {
+
+//TopHat pairwise data
+
+ if ($this->reference_node != "")
+ {
+ $dd = array();
+
+ if ($nodes) foreach ($nodes as $n)
+ $dd[] = $n['hostname'];
+
+ if ($potential_nodes) foreach ($potential_nodes as $n)
+ $dd[] = $n['hostname'];
+
+ print("Calling tophat api for reference node = ".$this->reference_node);
+ $st = time() + microtime();
+ $HopCount = $this->getHopCount($this->reference_node, $dd);
+ printf(" (%.2f ms)<br/>", (time() + microtime()-$st)*100);
+ //print_r($HopCount);
+ }
+
+}
+
+
+function excludeItems($value, $exclude_list, $hh) {
+
+ if ($value == "")
+ $value = "n/a";
+
+ if ($exclude_list)
+ if (in_array($value, $exclude_list))
+ return array($value, array('name'=>$hh, 'display'=>'table-cell'));
+ else
+ return array($value, array('name'=>$hh, 'display'=>'table-cell'));
+
+ return array($value, array('name'=>$hh, 'display'=>'table-cell'));
+}
+
+function checkThreshold($value, $threshold, $hh) {
+
+ if ($value == "")
+ return array("n/a", array('name'=>$hh, 'display'=>'table-cell'));
+
+ if ($threshold)
+ if ((float) $value >= (float) $threshold[0] && (float) $value <= (float) $threshold[1])
+ return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
+ else
+ return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
+
+ return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
+}
+
+
+function cells($table, $node) {
+
+
+foreach ($this->all_headers as $h)
+{
+
+if (!$h['fixed'] && $h['visible'])
+{
+if ($this->inTypeC($h['header']))
+{
+ $tagname = $h['tagname'];
+ $value = $node[$tagname];
+ $v = $this->checkThreshold($value, $h['threshold'], $h['header']);
+ $table->cell($v[0],$v[1]);
+}
+else if ($this->inTypeB($h['header']))
+{
+ $value = $node[$h['tagname']];
+ $v = $this->checkThreshold($value, $h['threshold'], $h['header']);
+ $table->cell($v[0],$v[1]);
+}
+else if ($this->inTypeD($h['header']))
+{
+ $value = $this->HopCount[$node['hostname']];
+ $v = $this->excludeItems($value, $h['threshold'], $h['header']);
+ $table->cell($v[0],$v[1]);
+}
+else if ($this->inTypeA($h['header']))
+{
+ $value = $node[$h['tagname']];
+ $v = $this->excludeItems($value, $h['exclude_list'], $h['header']);
+ $table->cell($v[0],$v[1]);
+}
+else
+{
+ $value = $node[$h['tagname']];
+ $table->cell($value,array('name'=>$h['header'], 'display'=>'table-cell'));
+}
+}
+else
+ $table->cell("??", array('name'=>$h['header'], 'display'=>'none'));
+
+}
+
+}
+
+
+/*
+
+HTML
+
+*/
+
+
+function javascript_vars() {
+
+print("<input type='hidden' id='reference_node' value='".$this->reference_node."' />");
+
+$all_columns_string = "";
+foreach ($this->all_headers as $h)
+ $all_columns_string.= $h['header'].",";
+
+print("<script type='text/javascript'>");
+
+print("var column_table = new Array();");
+print ("var column_index=0;");
+print("var column_table2 = new Array();");
+print("var column_headers = new Array();");
+print("var columns_to_fetch = new Array();");
+//document.onkeyup = scrollList('test');
+foreach ($this->all_headers as $h)
+{
+/*
+ print("column_table2[column_index] = new Array();");
+ print("column_table2[column_index]['header'] = ".$h['header'].";");
+ print("column_table2[column_index]['label'] = ".$h['label'].";");
+ if ($h['visible'])
+ {
+ print("column_table2[column_index]['visible'] = true;");
+ print("column_table2[column_index]['fetched'] = true;");
+ }
+ else
+ {
+ print("column_table2[column_index]['visible'] = false;");
+ print("column_table2[column_index]]['fetch'] = false;");
+ }
+ print("column_table2[column_index]['tagname'] = '".$h['tagname']."';");
+ print("column_table2[column_index]['description'] = '".$h['description']."';");
+*/
+
+ print("column_table[\"".$h['header']."\"] = new Array();");
+ if ($h['visible'])
+ {
+ print("column_table['".$h['header']."']['visible'] = true;");
+ print("column_table['".$h['header']."']['fetched'] = true;");
+ }
+ else
+ {
+ print("column_table['".$h['header']."']['visible'] = false;");
+ print("column_table['".$h['header']."']['fetch'] = false;");
+ }
+
+ print("column_table['".$h['header']."']['tagname'] = '".$h['tagname']."';");
+ print("column_table['".$h['header']."']['description'] = '".$h['description']."';");
+}
+
+foreach ($this->all_headers as $h)
+ print("column_headers['".$h['label']."'] = '0';");
+
+print("var all_columns_string = '".substr($all_columns_string,0,strlen($all_columns_string)-1)."';");
+
+//if ($first_time == true)
+ //print("resetConfiguration();");
+//print("debugfilter('vars are OK');");
+
+print("</script>");
+
+}
+
+function configuration_panel_html($showDescription) {
+
+
+if ($showDescription)
+ $table_width = 700;
+else
+ $table_width = 350;
+
+print("<table align=center cellpadding=10 width=".$table_width.">");
+print("<tr><th>Add/delete columns</th>");
+
+if ($showDescription)
+ print("<th>Column description and configuration</th>");
+
+print("</tr><tr><td valign=top width=300>");
+
+ print('<div id="scrolldiv" onFocusOut="debugfilter(this.id);" style="border : solid 2px grey; padding:4px; width:300px; height:180px; overflow:auto;">');
+print ("<table>");
+ $prev_label="";
+ $optionclass = "out";
+ foreach ($this->all_headers as $h)
+ {
+ if ($h['header'] == "hostname")
+ continue;
+
+ if ($h['fixed'])
+ $disabled = "disabled=true";
+ else
+ $disabled = "";
+
+ if ($this->headerIsVisible($h['label']))
+ {
+ $selected = "checked=true";
+ //print("header ".$h['label']." checked!");
+ }
+ else
+ {
+ $selected = "";
+ }
+
+ if ($prev_label == $h['label'])
+ continue;
+
+ $prev_label = $h['label'];
+
+ print ("<tr><td><div id='".$h['label']."' class='".$optionclass."' onkeyup='debugfilter(this.id)' onclick='highlightOption(this.id)'><table width=280 id='table".$h['label']."'><tr><td align=left width=30>".$h['label']."</td><td align=left> <span style='height:10px' id ='htitle".$h['label']."'>".$h['title']."</span> </td><td align=right width=20><input id='check".$h['label']."' type='checkbox' ".$selected." ".$disabled." autocomplete='off' value='".$h['label']."' onclick='changeCheckStatus(this.id)'></input></td></tr></table></div></td></tr>");
+ }
+
+ print("</table> </div></td>");
+
+if ($showDescription)
+{
+ print("<td valign=top width=400>");
+ print("<div class='myslice' id='selectdescr'> </div></td>");
+}
+
+print("</tr><tr><td align=center>");
+//print("<input type='button' value='Reset' onclick=resetCols('previousConf') />");
+//print("<input type='button' value='Default' onclick=saveConfiguration('defaultConf') />");
+print("<input type='button' value='Reset table' onclick=\"resetConfiguration('defaultConf')\" />");
+print(" <input type='button' value='Save configuration' onclick=saveConfiguration('column_configuration') />");
+print(" <input type='button' id='fetchbutton' onclick='fetchData()' value='Fetch data' disabled=true /> </td>");
+
+if ($showDescription)
+ print("<td></td>");
+
+print(" </tr> </table>");
+}
+
+function column_filter () {
+
+echo <<< EOF
+
+Highlight <select onChange="filterByType(this.value)">
+<option value="none">None</option>
+<option value="capabilities">Capabilities</option>
+<option value="statistics">Statistics</option>
+<option value="network">Network</option>
+<option value="pairwise">Pairwise</option>
+<option value="other">Other</option>
+</select>
+<p>
+
+EOF;
+}
+
+ function column_html ($colHeader, $colName, $colId, $fulldesc, $visible) {
+
+ if ($visible)
+ $display = 'display:table-cell';
+ else
+ $display = 'color:red;display:none';
+
+ return "
+ <th class='sample plekit_table' name='confheader".$colHeader."' id='testid' style='".$display."'>
+ <div id=\"".$colId."\" onclick=\"showDescription('".$colHeader."')\" onmouseover=\"showDescription('".$colHeader."')\">$colHeader</div>
+ </th>
+ ";
+ }
+
+ function column_fix_html ($colHeader, $colName, $colId) {
+
+ $display = 'display:table-cell';
+
+ $res="<th name='confheader".$colHeader."' class='fix plekit_table' style='$display'>";
+ $res.= "<div id='$colId' onmouseover=\"showDescription('".$colHeader."')\">$colHeader</div></th>";
+
+ return $res;
+ }
+
+
+function graph_html($colHeader) {
+
+ return "<p><img src='/planetlab/slices/graph.png' width='20' align='BOTTOM'><input type='checkbox' id='graph".$colHeader."'></input> Show details on mouse over";
+
+ }
+
+function threshold_html($colHeader) {
+
+ $updatecall = "updateColumnThreshold('".$colHeader."',window.document.getElementById('min".$colHeader."').value,window.document.getElementById('max".$colHeader."').value);";
+
+ $bubble="<b>Grey-out values between</b> <input type='text' id='min".$colHeader."' size='2' value='5'> (low) and <input type='text' id='max".$colHeader."' size='2' value='90'> (high) <input type='submit' value='Update' onclick=".$updatecall."> </input>";
+
+ return $bublle;
+}
+
+
+/*
+
+UTILS
+
+*/
+
+//simple strings
+function inTypeA($header_name) {
+ $typeA = array('ST','SN','RES','OS','NRR','NTP','NSR','NSF','NDS','NTH','NEC','LRN','LCY','LPR','LCN','LAT','LON','IP','ASN','AST');
+ return in_array($header_name, $typeA);
+}
+
+//integers
+function inTypeB($header_name) {
+ $typeB = array('BW','DS','MS','CC','CR','AS','DU','CN');
+ return in_array($header_name, $typeB);
+}
+
+//statistical values
+function inTypeC($header_name) {
+ $typeC = array('Rw','Rm','Ry','Lw','Lm','Ly','Sw','Sm','Sy','CFw','CFm','CFy','BUw','BUm','BUy','MUw','MUm','MUy','SSHw','SSHm','SSHy');
+ return in_array($header_name, $typeC);
+}
+
+//tophat
+function inTypeD($header_name) {
+ $typeD = array('HC');
+ return in_array($header_name, $typeD);
+}
+
+
+function removeDuration($header)
+{
+ if ($this->inTypeC($header))
+ return substr($header, 0, strlen($header)-1);
+ else
+ return $header;
+}
+
+}
+
+?>
+
+
--- /dev/null
+<?php
+//
+// TopHat API PHP interface
+//
+
+// TODO add tophat_api in the php default path in /etc/plc.d/httpd
+// TODO occurences to PLC
+
+define('TOPHAT_API_HOST', 'www.top-hat.info');
+define('TOPHAT_API_PATH', '/API/');
+define('TOPHAT_API_PORT', 443);
+
+class TopHatAPI
+{
+ var $auth;
+ var $server;
+ var $port;
+ var $path;
+ var $errors;
+ var $trace;
+ var $calls;
+ var $multicall;
+
+ function TopHatAPI($auth = NULL,
+ $server = TOPHAT_API_HOST,
+ $port = TOPHAT_API_PORT,
+ $path = TOPHAT_API_PATH,
+ $cainfo = NULL)
+ {
+ $this->auth = $auth;
+ $this->server = $server;
+ $this->port = $port;
+ $this->path = $path;
+ $this->cainfo = $cainfo;
+ $this->errors = array();
+ $this->trace = array();
+ $this->calls = array();
+ $this->multicall = false;
+ }
+
+ function error_log($error_msg, $backtrace_level = 1)
+ {
+ $backtrace = debug_backtrace();
+ $file = $backtrace[$backtrace_level]['file'];
+ $line = $backtrace[$backtrace_level]['line'];
+
+ $this->errors[] = 'TopHatAPI error: ' . $error_msg . ' in ' . $file . ' on line ' . $line;
+ error_log(end($this->errors));
+ }
+
+ function error()
+ {
+ if (empty($this->trace)) {
+ return NULL;
+ } else {
+ $last_trace = end($this->trace);
+ return implode("\\n", $last_trace['errors']);
+ }
+ }
+
+ function trace()
+ {
+ return $this->trace;
+ }
+
+ function microtime_float()
+ {
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float) $usec + (float) $sec);
+ }
+
+ function call($method, $args = NULL)
+ {
+ if ($this->multicall) {
+ $this->calls[] = array ('methodName' => $method,
+ 'params' => $args);
+ return NULL;
+ } else {
+ return $this->internal_call ($method, $args, 3);
+ }
+ }
+
+ function internal_call($method, $args = NULL, $backtrace_level = 2)
+ {
+ $curl = curl_init();
+
+ // Verify peer certificate if talking over SSL
+ if ($this->port == 443) {
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // XXX 2
+ if (!empty($this->cainfo)) {
+ curl_setopt($curl, CURLOPT_CAINFO, $this->cainfo);
+ } elseif (defined('PLC_API_CA_SSL_CRT')) {
+ curl_setopt($curl, CURLOPT_CAINFO, PLC_API_CA_SSL_CRT);
+ }
+ $url = 'https://';
+ } else {
+ $url = 'http://';
+ }
+
+ // Set the URL for the request
+ $url .= $this->server . ':' . $this->port . '/' . $this->path;
+ curl_setopt($curl, CURLOPT_URL, $url);
+
+ // Marshal the XML-RPC request as a POST variable. <nil/> is an
+ // extension to the XML-RPC spec that is supported in our custom
+ // version of xmlrpc.so via the 'allow_null' output_encoding key.
+ $request = xmlrpc_encode_request($method, $args, array('allow_null' => TRUE));
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
+
+ // Construct the HTTP header
+ $header[] = 'Content-type: text/xml';
+ $header[] = 'Content-length: ' . strlen($request);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
+
+ // Set some miscellaneous options
+ curl_setopt($curl, CURLOPT_TIMEOUT, 180);
+
+ // Get the output of the request
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ $t0 = $this->microtime_float();
+ $output = curl_exec($curl);
+ $t1 = $this->microtime_float();
+
+ if (curl_errno($curl)) {
+ $this->error_log('curl: ' . curl_error($curl), true);
+ $ret = NULL;
+ } else {
+ $ret = xmlrpc_decode($output);
+ if (is_array($ret) && xmlrpc_is_fault($ret)) {
+ $this->error_log('Fault Code ' . $ret['faultCode'] . ': ' .
+ $ret['faultString'], $backtrace_level, true);
+ $ret = NULL;
+ }
+ }
+
+ curl_close($curl);
+
+ $this->trace[] = array('method' => $method,
+ 'args' => $args,
+ 'runtime' => $t1 - $t0,
+ 'return' => $ret,
+ 'errors' => $this->errors);
+ $this->errors = array();
+
+ return $ret;
+ }
+
+ function begin()
+ {
+ if (!empty($this->calls)) {
+ $this->error_log ('Warning: multicall already in progress');
+ }
+
+ $this->multicall = true;
+ }
+
+ function commit()
+ {
+ if (!empty ($this->calls)) {
+ $ret = array();
+ $results = $this->internal_call ('system.multicall', array ($this->calls));
+ foreach ($results as $result) {
+ if (is_array($result)) {
+ if (xmlrpc_is_fault($result)) {
+ $this->error_log('Fault Code ' . $result['faultCode'] . ': ' .
+ $result['faultString'], 1, true);
+ $ret[] = NULL;
+ // Thierry - march 30 2007
+ // using $adm->error() is broken with begin/commit style
+ // this is because error() uses last item in trace and checks for ['errors']
+ // when using begin/commit we do run internal_call BUT internal_call checks for
+ // multicall's result globally, not individual results, so ['errors'] comes empty
+ // I considered hacking internal_call
+ // to *NOT* maintain this->trace at all when invoked with multicall
+ // but it is too complex to get all values right
+ // so let's go for the hacky way, and just record individual errors at the right place
+ $this->trace[count($this->trace)-1]['errors'][] = end($this->errors);
+ } else {
+ $ret[] = $result[0];
+ }
+ } else {
+ $ret[] = $result;
+ }
+ }
+ } else {
+ $ret = NULL;
+ }
+
+ $this->calls = array();
+ $this->multicall = false;
+
+ return $ret;
+ }
+
+ //
+ // TopHatAPI Methods
+ //
+
+ // Gets measurement information.
+ //
+ // Returns the measurement (cf doc).
+
+ function Test($param = NULL)
+ {
+ $args[] = $this->auth;
+ if (func_num_args() > 0) $args[] = $param;
+ return $this->call('Test', $args);
+ }
+
+ function Get($method, $timestamp, $input_filter = NULL, $output_fields = NULL, $callback = NULL)
+ {
+ $args[] = $this->auth;
+ $args[] = $method;
+ $args[] = $timestamp;
+ if (func_num_args() > 2) $args[] = $input_filter;
+ if (func_num_args() > 3) $args[] = $output_fields;
+ if (func_num_args() > 4) $args[] = $callback;
+ return $this->call('Get', $args);
+ }
+
+ // TDMI Methods
+
+ function GetPlatforms($input_filter = NULL, $output_fields = NULL)
+ {
+ $args[] = $this->auth;
+ if (func_num_args() > 0) $args[] = $input_filter;
+ if (func_num_args() > 1) $args[] = $output_fields;
+ return $this->call('GetPlatforms', $args);
+ }
+
+ function GetTraceroutes($input_filter = NULL, $output_fields = NULL)
+ {
+ $args[] = $this->auth;
+ if (func_num_args() > 0) $args[] = $input_filter;
+ if (func_num_args() > 1) $args[] = $output_fields;
+ return $this->call('GetTraceroutes', $args);
+ }
+
+ // Imported PLC Methods
+
+ // Returns a new session key if a user or node authenticated
+ // successfully, faults otherwise.
+
+ function GetSession ()
+ {
+ $args[] = $this->auth;
+ return $this->call('GetSession', $args);
+ }
+
+ // Returns an array of structs containing details about users sessions. If
+ // session_filter is specified and is an array of user identifiers or
+ // session_keys, or a struct of session attributes, only sessions matching the
+ // filter will be returned. If return_fields is specified, only the
+ // specified details will be returned.
+
+ function GetSessions ($session_filter = NULL)
+ {
+ $args[] = $this->auth;
+ if (func_num_args() > 0) $args[] = $session_filter;
+ return $this->call('GetSessions', $args);
+ }
+
+ // Returns an array of structs containing details about users. If
+ // person_filter is specified and is an array of user identifiers or
+ // usernames, or a struct of user attributes, only users matching the
+ // filter will be returned. If return_fields is specified, only the
+ // specified details will be returned.
+ //
+ // Users and techs may only retrieve details about themselves. PIs
+ // may retrieve details about themselves and others at their
+ // sites. Admins and nodes may retrieve details about all accounts.
+
+ function GetPersons ($person_filter = NULL, $return_fields = NULL)
+ {
+ $args[] = $this->auth;
+ if (func_num_args() > 0) $args[] = $person_filter;
+ if (func_num_args() > 1) $args[] = $return_fields;
+ return $this->call('GetPersons', $args);
+ }
+
+ // Returns 1 if the user or node authenticated successfully, faults
+ // otherwise.
+
+ function AuthCheck ()
+ {
+ $args[] = $this->auth;
+ return $this->call('AuthCheck', $args);
+ }
+
+}
+
+?>
--- /dev/null
+
+<?php
+
+// Require login
+require_once 'plc_login.php';
+
+// Get session and API handles
+require_once 'plc_session.php';
+global $plc, $api;
+
+//print header
+require_once 'plc_drupal.php';
+
+// Common functions
+require_once 'plc_functions.php';
+
+$slice_id=intval($_GET["slice_id"]);
+$tagN=$_GET["tagName"];
+
+$slices= $api->GetSlices( array($slice_id));
+
+if (empty($slices)) {
+ drupal_set_message ("Slice " . $slice_id . " not found");
+ return;
+ }
+
+$slice=$slices[0];
+
+$nodetags = array('node_id');
+$extratags = explode("|", $tagN);
+
+$nodes=$api->GetNodes(array('node_id'=>$slice['node_ids']),array_merge($nodetags, $extratags));
+$potential_nodes=$api->GetNodes(array('~node_id'=>$slice['node_ids']),array_merge($nodetags, $extratags));
+
+echo "---attached---";
+if ($nodes) foreach ($nodes as $node) {
+ echo "|".$node['node_id'];
+ foreach ($extratags as $t)
+ echo ":".$node[$t];
+}
+echo "|---potential---";
+if ($potential_nodes) foreach ($potential_nodes as $potential_node) {
+ echo "|".$potential_node['node_id'];
+ foreach ($extratags as $t)
+ echo ":".$potential_node[$t];
+}
+
+?>
+
--- /dev/null
+<?php
+
+// Require login
+require_once 'plc_login.php';
+
+// Get session and API handles
+require_once 'plc_session.php';
+global $plc, $api;
+
+//print header
+require_once 'plc_drupal.php';
+
+// Common functions
+require_once 'plc_functions.php';
+
+$value=$_GET["value"];
+$slice_id=intval($_GET["slice_id"]);
+$tagN=$_GET["tagName"];
+
+$fields= array( "$tagN"=>$value);
+$api->UpdateSlice( $slice_id , $fields );
+
+$myFile = "/var/log/myslice-log";
+$fh = fopen($myFile, 'a') or die("can't open file");
+$stringData = "\n".date('Ymd-H:i')."|".$slice_id.":".$value;
+fwrite($fh, $stringData);
+fclose($fh);
+
+?>
--- /dev/null
+
+/* $Id: table.js 13009 2009-04-10 10:49:28Z baris $ */
+
+var filtered_color = "grey";
+var normal_color = "black";
+
+
+function inTypeA(header_name) {
+ var typeA = ['ST','SN','RES','OS','NRR','NTP','NSR','NSF','NDS','NTH','NEC','LRN','LCY','LPR','LCN','LAT','LON','IP','ASN','AST'];
+ return typeA.indexOf(header_name);
+}
+
+function inTypeB(header_name) {
+ var typeB = ['BW','DS','MS','CC','CR','AS','MU','DU','CN'];
+ return typeB.indexOf(header_name);
+}
+
+function inTypeC(header_name) {
+ var typeC = ['Rw','Rm','Ry','BWw','BWm','BWy','Lw','Lm','Ly','Sw','Sm','Sy','CFw','CFm','CFy','BUw','BUm','BUy','MUw','MUm','MUy','SSHw','SSHm','SSHy'];
+ return typeC.indexOf(header_name);
+}
+
+function inTypeD(header_name) {
+ var typeD = ['HC'];
+ return typeD.indexOf(header_name);
+}
+
+function debugfilter(s) {
+ document.getElementById('debug').innerHTML+=s;
+}
+
+function scrollList(tableid) {
+
+debugfilter("here");
+
+if (event.keyCode == 40)
+ debugfilter("down");
+else if (event.keyCode == 38)
+ debugfilter("up");
+
+}
+
+function highlightOption(divid) {
+
+//debugfilter("highlighting option "+divid);
+
+for (var kk in column_headers) {
+
+if (document.getElementById(kk))
+ document.getElementById(kk).className = 'out';
+}
+
+document.getElementById(divid).className = 'selected';
+
+showDescription(divid);
+
+}
+
+
+function showDescription(h) {
+
+ //debugfilter("showing description "+h);
+
+ if (document.getElementById('selectdescr'))
+ {
+ if (window['desc'+h])
+ document.getElementById('selectdescr').innerHTML = ""+window['desc'+h];
+ else if (column_table[h] && column_table[h]['description'])
+ document.getElementById('selectdescr').innerHTML = column_table[h]['description'];
+ else
+ document.getElementById('selectdescr').innerHTML = "No description provided";
+ }
+}
+
+
+function overrideTitles() {
+
+ //debugfilter("<p>overriding...");
+
+ for (var kk in column_headers) {
+
+ //debugfilter("here "+kk);
+
+ if (document.getElementById(kk) && window['title'+kk])
+ document.getElementById('htitle'+kk).innerHTML = window['title'+kk];
+ }
+
+}
+
+function changeCheckStatus(column) {
+
+
+if (document.getElementById('selectdescr'))
+{
+showDescription(document.getElementById(column).value);
+
+if (document.getElementById(column).checked)
+ addColumn(document.getElementById(column).value);
+else
+ deleteColumn(document.getElementById(column).value);
+}
+
+}
+
+function updatePeriod(h) {
+ deleteColumn2(h, h+'w');
+ deleteColumn2(h, h+'m');
+ deleteColumn2(h, h+'y');
+ addColumn(h);
+}
+
+function filterByType(selectedtype) {
+
+var notselectedyet = true;
+
+for (var kk in column_headers) {
+
+ if (document.getElementById(kk))
+ {
+ if (window['type'+kk] == selectedtype)
+ {
+ document.getElementById(kk).className = 'in';
+ if (notselectedyet)
+ highlightOption(kk);
+ notselectedyet = false;
+ }
+ else
+ document.getElementById(kk).className = 'out';
+ }
+}
+}
+
+
+/*
+
+RESET/SAVE CONFIGURATION
+*/
+
+
+function resetColumns() {
+
+ for (var kk in column_table) {
+
+ if (column_table[kk]['visible'] == true && column_table[kk]['fetch'] == false)
+ deleteColumn(kk);
+ else if (column_table[kk]['visible'] == false && column_table[kk]['fetch'] == true)
+ addColumn(kk);
+ }
+
+}
+
+function resetCols(which_conf) {
+
+ var target_configuration = "|"+document.getElementById(which_conf).value+"|";
+
+ //debugfilter("<p>Target configuration = "+target_configuration);
+
+ for (var kk in column_table) {
+ //debugfilter("in "+kk+" ");
+
+ if (target_configuration.indexOf("|"+kk+"|")>=0)
+ {
+ if (document.getElementById('check'+kk))
+ if (document.getElementById('check'+kk).checked == false)
+ {
+ debugfilter("<p>Adding "+kk);
+ addColumn(kk);
+ }
+ }
+ else
+ {
+ if (document.getElementById('check'+kk))
+ if (document.getElementById('check'+kk).checked == true)
+ {
+ debugfilter("<p>Deleting "+kk);
+ deleteColumn(kk);
+ }
+ }
+ }
+}
+
+function saveConfiguration(which_conf)
+{
+ var slice_id = document.getElementById('slice_id').value;
+
+ var target_configuration = document.getElementById(which_conf).value;
+
+ debugfilter("saving configuration "+target_configuration);
+ updateColumnConfiguration(slice_id, target_configuration);
+}
+
+function updateColumnConfiguration(slice_id, value)
+{
+
+ if (window.XMLHttpRequest)
+ {// code for IE7+, Firefox, Chrome, Opera, Safari
+ xmlhttp=new XMLHttpRequest();
+ }
+ else
+ {// code for IE6, IE5
+ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
+ }
+ xmlhttp.onreadystatechange=function()
+ {
+ if (xmlhttp.readyState==4) // && xmlhttp.status==200)
+ {
+ //value=xmlhttp.responseText;
+ //debugfilter(value);
+ if (document.getElementById('column_configuration'))
+ document.getElementById('column_configuration').value=value;
+ }
+ }
+ xmlhttp.open("GET","/plekit/php/updateConf.php?value="+value+"&slice_id="+slice_id+"&tagName=Configuration",true);
+
+ xmlhttp.send();
+}
+
+
+
+function resetConfiguration(which_conf)
+{
+ var slice_id = document.getElementById('slice_id').value;
+ var target_configuration = document.getElementById(which_conf).value;
+
+ debugfilter("reseting configuration "+target_configuration);
+
+ if (window.XMLHttpRequest)
+ {// code for IE7+, Firefox, Chrome, Opera, Safari
+ xmlhttp=new XMLHttpRequest();
+ }
+ else
+ {// code for IE6, IE5
+ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
+ }
+ xmlhttp.onreadystatechange=function()
+ {
+ if (xmlhttp.readyState==4) // && xmlhttp.status==200)
+ {
+ //value=xmlhttp.responseText;
+ //debugfilter(value);
+ window.location.reload(true);
+ }
+ }
+ xmlhttp.open("GET","/plekit/php/updateConf.php?value="+target_configuration+"&slice_id="+slice_id+"&tagName=Configuration",true);
+
+ xmlhttp.send();
+}
+
+function addColumnToConfiguration(column) {
+
+
+ var old_configuration = document.getElementById('column_configuration').value;
+ var slice_id = document.getElementById('slice_id').value;
+
+ var new_configuration = "";
+
+ if (old_configuration != "")
+ new_configuration = old_configuration += "|"+column;
+ else
+ new_configuration = column;
+
+ //debugfilter("new configuration = "+new_configuration);
+
+ updateColumnConfiguration(slice_id, new_configuration);
+}
+
+
+
+/*
+
+ADD/REMOVE COLUMNS
+
+*/
+
+
+function getHTTPObject()
+{
+ if (typeof XMLHttpRequest != 'undefined')
+ { return new XMLHttpRequest(); }
+
+ try
+ { return new ActiveXObject("Msxml2.XMLHTTP"); }
+ catch (e)
+ {
+ try { return new ActiveXObject("Microsoft.XMLHTTP"); }
+ catch (e) {}
+ }
+ return false;
+}
+
+
+function load_html(column, url) {
+ var req = getHTTPObject();
+ var res;
+ req.open('GET', url, true);
+ req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ req.onreadystatechange =
+ function() {
+ if (req.readyState == 4)
+ { updateColumnData(column, req.responseText); }
+ }
+ req.send(null);
+}
+
+function updateColumnData(column,data) {
+
+
+var headers = column.split("|");
+var data_table = data.split("|");
+
+//debugfilter("<p>headers[0] = "+headers[0]);
+//debugfilter("<p>sample line = "+data_table[2]);
+
+
+ var node_data;
+
+ var table_id1 = 'nodes';
+ var table=$(table_id1);
+ var css='#'+table_id1+'>tbody';
+ var rows = $$(css)[0].rows;
+
+ var data_array1 = new Array();
+
+ //debugfilter("COLUMN "+column+"<p>");
+
+ for (var node_index = 1; node_index < data_table.length; node_index++) {
+ if (data_table[node_index] == '---potential---')
+ break;
+ node_data = data_table[node_index].split(':');
+
+ data_array1[node_data[0]] = new Array();
+
+ for (var h_index=0; h_index < headers.length; h_index++) {
+
+ if (node_data[h_index+1] == "")
+ data_array1[node_data[0]][h_index] = "n/a";
+ else
+ data_array1[node_data[0]][h_index] = node_data[h_index+1];
+ }
+
+ }
+
+ if (rows)
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+
+ for (var column_index=0; column_index < tr.cells.length; column_index++) {
+ //debugfilter("<p>node id = "+tr.cells[0].innerHTML);
+ var found_index = headers.indexOf(tr.cells[column_index].getAttribute('name'));
+ if (found_index != -1)
+ tr.cells[column_index].innerHTML = data_array1[tr.cells[0].innerHTML][found_index];
+ }
+ }
+
+//potential nodes
+if (data_table[node_index] == '---potential---')
+{
+
+ var table_id2 = 'add_nodes';
+ var table2=$(table_id2);
+ var css2='#'+table_id2+'>tbody';
+ var rows2 = $$(css2)[0].rows;
+
+ var data_array2 = new Array();
+
+ //debugfilter("COLUMN "+column+"<p>");
+
+ for (; node_index < data_table.length; node_index++) {
+ if (data_table[node_index] == '')
+ continue;
+ node_data = data_table[node_index].split(':');
+
+ data_array2[node_data[0]] = new Array();
+
+ for (var h_index=0; h_index < headers.length; h_index++) {
+
+ if (node_data[h_index+1] == "")
+ data_array2[node_data[0]][h_index] = "n/a";
+ else
+ data_array2[node_data[0]][h_index] = node_data[h_index+1];
+ }
+ }
+
+ if (rows)
+ for (var row_index = 0; row_index < rows2.length ; row_index++) {
+ var tr=rows2[row_index];
+
+ for (var column_index=0; column_index < tr.cells.length; column_index++) {
+ var found_index = headers.indexOf(tr.cells[column_index].getAttribute('name'));
+ if (found_index != -1)
+ tr.cells[column_index].innerHTML = data_array2[tr.cells[0].innerHTML][found_index];
+ }
+ }
+
+}
+
+ document.getElementById('loadingDiv').innerHTML = ""
+}
+
+
+
+
+
+function addColumnCells(column,header) {
+
+ //debugfilter("adding cells now: "+column+":"+header);
+ column_table[header]['visible']=true;
+
+ var cells = document.getElementsByName(header);
+
+
+ //debugfilter("got cells -"+cells+"- for "+header);
+ for(var j = 0; j < cells.length; j++)
+ cells[j].style.display = "table-cell";
+}
+
+function addColumnSamples(column) {
+
+ var cellsheader = document.getElementsByName("confheader"+column);
+ for(var j = 0; j < cellsheader.length; j++)
+ cellsheader[j].style.display = "table-cell";
+
+}
+
+function addColumnAjax(column) {
+
+ var selectedperiod="";
+
+ if (document.getElementById('selectperiod'+column))
+ selectedperiod = document.getElementById('selectperiod'+column).value;
+
+ var header = column+""+selectedperiod;
+
+ addColumnCells(column, header);
+
+ var t = column_table[header]['tagname'];
+ var slice_id = document.getElementById('slice_id').value;
+ document.getElementById('loadingDiv').innerHTML = "<img src=/plekit/icons/ajax-loader.gif>LOADING ...";
+ var url = "/plekit/php/updateColumn.php?slice_id="+slice_id+"&tagName="+t;
+ load_html(header, url);
+
+ addColumnToConfiguration(header);
+}
+
+
+function addColumn2(column) {
+
+ var selectedperiod="";
+
+ if (document.getElementById('selectperiod'+column))
+ selectedperiod = document.getElementById('selectperiod'+column).value;
+
+ var header = column+""+selectedperiod;
+
+ addColumnCells(column,header);
+
+ addColumnToConfiguration(column);
+
+ checkDataToFetch();
+}
+
+function addColumn(column) {
+
+ var selectedperiod="";
+ var header=column;
+
+ //debugfilter("adding column "+column+" and header "+header);
+
+ if (inTypeC(column)!=-1)
+ {
+ column = column.substring(0,column.length-1);
+ }
+ else if (document.getElementById('selectperiod'+column))
+ {
+ selectedperiod = document.getElementById('selectperiod'+column).value;
+ header = column+""+selectedperiod;
+ }
+
+ //debugfilter("adding "+column+","+header);
+
+ addColumnCells(column, header);
+
+ addColumnToConfiguration(header);
+
+ column_table[header]['visible'] = true;
+
+ checkDataToFetch();
+}
+
+function checkDataToFetch() {
+
+var dataExist = false;
+
+for (var kk in column_table) {
+
+ if (document.getElementById(kk))
+ {
+ if (column_table[kk]['visible'] == true && column_table[kk]['fetch'] == false)
+ {
+ document.getElementById('fetchbutton').disabled = false;
+ document.getElementById('fetchbutton').style.color = 'red';
+ dataExist = true;
+ }
+ }
+}
+
+if (!dataExist)
+{
+ document.getElementById('fetchbutton').disabled = true;
+ document.getElementById('fetchbutton').style.color = 'grey';
+}
+
+}
+
+
+function fetchData() {
+
+var tagnames = "";
+var headers = "";
+
+for (var kk in column_table) {
+
+if (column_table[kk]['visible'] == true && column_table[kk]['fetch'] == false)
+ if (tagnames == "")
+ {
+ tagnames = column_table[kk]['tagname'];
+ headers = kk;
+ }
+ else
+ {
+ tagnames += "|"+column_table[kk]['tagname'];
+ headers += "|"+kk;
+ }
+}
+
+//debugfilter("fetching these columns: "+tagnames+ "("+headers+")");
+
+ var slice_id = document.getElementById('slice_id').value;
+ document.getElementById('loadingDiv').innerHTML = " <img src=/plekit/icons/ajax-loader.gif> Loading data. Please wait ...";
+ var url = "/plekit/php/updateColumn.php?slice_id="+slice_id+"&tagName="+tagnames;
+ load_html(headers, url);
+}
+
+function deleteColumnCells(column, header) {
+
+ column_table[header]['visible']=false;
+
+ var cells = document.getElementsByName(header);
+ for(var j = 0; j < cells.length; j++)
+ cells[j].style.display = "none";
+
+}
+
+function deleteColumnSample() {
+ var cellsheader = document.getElementsByName("confheader"+column);
+ for(var j = 0; j < cellsheader.length; j++)
+ cellsheader[j].style.display = "none";
+
+}
+
+function deleteColumnFromConfiguration(column) {
+
+
+ var old_configuration = document.getElementById('column_configuration').value;
+ var slice_id = document.getElementById('slice_id').value;
+
+ var old_columns = old_configuration.split("|");
+ var new_columns = new Array();
+
+ for (var column_index = 0; column_index < old_columns.length ; column_index++) {
+ var conf = old_columns[column_index].split(':');
+ if (conf[0] != column)
+ new_columns.push(old_columns[column_index]);
+ }
+
+ var new_configuration = new_columns.join("|");
+ updateColumnConfiguration(slice_id, new_configuration);
+
+ checkDataToFetch();
+}
+
+function deleteColumn2(column, header) {
+
+ deleteColumnCells(column,header);
+
+ deleteColumnFromConfiguration(column);
+
+ column_table[header]['visible'] = false;
+ document.getElementById('check'+column).checked = false;
+}
+
+function deleteColumn(column) {
+
+ var selectedperiod="";
+ var header=column;
+
+ if (inTypeC(column)!=-1)
+ {
+ column = column.substring(0,column.length-1);
+ }
+ else if (document.getElementById('selectperiod'+column))
+ {
+ selectedperiod = document.getElementById('selectperiod'+column).value;
+ header = column+""+selectedperiod;
+ }
+
+ //debugfilter("deleting "+column+","+header);
+
+ deleteColumnCells(column,header);
+
+ deleteColumnFromConfiguration(header);
+
+ column_table[header]['visible'] = false;
+
+ //document.getElementById('check'+column).checked = false;
+}
+
+
+
+
+/*
+
+
+HIGHLIGHTING
+
+
+
+function updateColumnThreshold(column, minT, maxT) {
+
+debugfilter("updating threshold for "+column+" with "+minT+" and "+maxT);
+
+var cells = document.getElementsByName(column);
+
+for(var j = 0; j < cells.length; j++)
+{
+var val = parseFloat(cells[j].innerHTML);
+
+if (val >= minT && val <= maxT)
+ cells[j].style.color = filtered_color;
+else
+ cells[j].style.color = normal_color;
+}
+
+var old_configuration = document.getElementById('column_configuration').value;
+var slice_id = document.getElementById('slice_id').value;
+
+var old_columns = old_configuration.split("|");
+var new_columns = new Array();
+
+for (var column_index = 0; column_index < old_columns.length ; column_index++) {
+ var conf = old_columns[column_index].split(':');
+ if (conf[0] != column)
+ new_columns.push(old_columns[column_index]);
+ else
+ new_columns.push(column+":"+minT+","+maxT);
+}
+
+var new_configuration = new_columns.join("|");
+
+updateColumnConfiguration(slice_id, new_configuration);
+
+}
+
+function updateExcludeList(column, excludeList) {
+
+//debugfilter("updating list");
+debugfilter("updating list for "+column+" with "+excludeList);
+
+var cells = document.getElementsByName(column);
+
+for(var j = 1; j < cells.length; j++)
+{
+var val = cells[j].innerHTML;
+
+if (excludeList == val)
+ cells[j].style.color = filtered_color;
+else
+ cells[j].style.color = normal_color;
+}
+
+var old_configuration = document.getElementById('column_configuration').value;
+var slice_id = document.getElementById('slice_id').value;
+
+var old_columns = old_configuration.split("|");
+var new_columns = new Array();
+
+for (var column_index = 0; column_index < old_columns.length ; column_index++) {
+ var conf = old_columns[column_index].split(':');
+ if (conf[0] != column)
+ new_columns.push(old_columns[column_index]);
+ else
+ new_columns.push(column+":"+excludeList);
+}
+
+var new_configuration = new_columns.join("|");
+
+updateColumnConfiguration(slice_id, new_configuration);
+
+}
+
+
+
+/*
+
+ROW FILTERING
+
+
+function plekit_table_showAll (slicetable_id) {
+
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+
+ // scan rows, elaborate 'visible'
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+ var visible=true;
+ plekit_table_row_visible(tr,visible);
+ }
+
+ plekit_table_count_filtered(slicetable_id);
+
+ tablePaginater.init(slicetable_id);
+
+}
+
+function plekit_table_count_filtered (slicetable_id) {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+
+ var no_filtered=0;
+
+ // scan rows, elaborate 'visible'
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+ var filtered = false;
+
+ for (var column_index=0; column_index < tr.cells.length; column_index++)
+ if (tr.cells[column_index].style.color == "red")
+ filtered = true;
+
+ if (filtered)
+ no_filtered++;
+
+ }
+
+ debugfilter(no_filtered+' nodes do not satisfy the requested threshold');
+}
+
+
+function plekit_table_hide_filtered (slicetable_id) {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+
+ var reg = /(^|\s)invisibleRow(\s|$)/;
+
+
+ if (!document.getElementById('filtercheck').checked)
+ {
+ plekit_table_showAll(slicetable_id);
+ return;
+ }
+
+ var hidden=0;
+
+ // scan rows, elaborate 'visible'
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+ var visible=true;
+
+ for (var column_index=0; column_index < tr.cells.length; column_index++) {
+ if (tr.cells[column_index].style.color == filtered_color)
+ visible = false;
+ }
+ if (!visible)
+ hidden++;
+
+ plekit_table_row_visible(tr,visible);
+ }
+
+ //debugfilter('hidden '+hidden+' nodes');
+ debugfilter(hidden+' nodes do not satisfy the requested threshold (hidden)');
+
+ tablePaginater.init(slicetable_id);
+}
+
+
+
+
+function plekit_table_apply_config(slicetable_id, configuration) {
+
+var new_configuration = document.getElementById('new_conf').value;
+var all_columns = new_configuration.split("|");
+
+var min_values = new Array();
+var max_values = new Array();
+
+
+for (var column_index = 0; column_index < all_columns.length ; column_index++) {
+
+ var conf = all_columns[column_index].split(':');
+
+ if (inTypeB(conf[0]) != -1)
+ {
+ var threshold = conf[1].split(',');
+ if (threshold.length == 2)
+ {
+ min_values.push(parseFloat(threshold[0]));
+ max_values.push(parseFloat(threshold[1]));
+ }
+ }
+ else if (inTypeC(conf[0]) == -1)
+ {
+ var threshold = conf[2].split(',');
+ if (threshold.length == 2)
+ {
+ min_values.push(parseInt(threshold[0]));
+ max_values.push(parseInt(threshold[1]));
+ }
+ }
+ else
+ {
+ min_values.push(-1);
+ max_values.push(-1);
+ }
+
+}
+
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+
+
+ var no_filtered=0;
+
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+
+ var tr=rows[row_index];
+
+ var filtered = false;
+
+ for (var column_index = 0; column_index < all_columns.length ; column_index++)
+ if (min_values[column_index]!=-1)
+ {
+ var val = parseFloat(tr.cells[3+column_index].innerHTML);
+
+ if (val >= min_values[column_index] && val <= max_values[column_index])
+ {
+ tr.cells[3+column_index].style.color = filtered_color;
+ filtered = true;
+ }
+ else
+ tr.cells[3+column_index].style.color = normal_color;
+ }
+ else
+ if (tr.cells[3+column_index].style.color == filtered_color)
+ filtered = true;
+
+
+ if (filtered)
+ no_filtered++;
+ }
+
+ debugfilter(no_filtered+' nodes do not satisfy the requested threshold');
+
+ //tablePaginater.init(slicetable_id);
+
+}
+
+
+function reset_select () {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+
+var action = document.getElementById('onlyselected');
+action.checked=false;
+
+ // scan rows, elaborate 'visible'
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+
+ document.getElementById("check"+tr.id).checked=false;
+
+ }
+
+ plekit_table_count_nodes();
+}
+
+}
+
+
+function plekit_table_select_filter () {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+
+ var reg = /(^|\s)invisibleRow(\s|$)/;
+
+ var action = document.getElementById('onlyselected');
+ if (!action.checked)
+ plekit_table_reset_filter();
+
+ // scan rows, elaborate 'visible'
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+ var visible=true;
+
+ if (action.checked)
+ {
+ if(tr.className.search(reg) == -1)
+ if(!document.getElementById("check"+tr.id).checked)
+ visible=false;
+ }
+
+ if(tr.className.search(reg) != -1)
+ visible=false;
+
+ plekit_table_row_visible(tr,visible);
+ }
+
+ tablePaginater.init(slicetable_id);
+ plekit_table_count_nodes();
+}
+
+function plekit_table_select_filter2 () {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+
+ var reg = /(^|\s)invisibleRow(\s|$)/;
+
+ var action = document.getElementById('onlyselected');
+
+ // scan rows, elaborate 'visible'
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+ var visible=true;
+
+ if (action.checked)
+ {
+ if(tr.className.search(reg) == -1)
+ if(!document.getElementById("check"+tr.id).checked)
+ visible=false;
+ }
+
+ if(tr.className.search(reg) != -1)
+ visible=false;
+
+ plekit_table_row_visible(tr,visible);
+ }
+
+ tablePaginater.init(slicetable_id);
+ plekit_table_count_nodes();
+}
+
+function CheckTopNodes(n) {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+ var reg = /(^|\s)invisibleRow(\s|$)/;
+
+ var checked=0;
+
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+
+ if(tr.className.search(reg) == -1) {
+ if (checked<n)
+ {
+ document.getElementById("check"+tr.id).checked=true;
+ checked++;
+ }
+ else
+ {
+ document.getElementById("check"+tr.id).checked=false;
+ };
+ };
+ };
+};
+
+
+function CheckRandomNodes(n) {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+ var reg = /(^|\s)invisibleRow(\s|$)/;
+
+ var r = n/plekit_table_visible_count();
+ var checked=0;
+
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+
+ if(tr.className.search(reg) == -1) {
+ if(Math.random() < r) {
+ document.getElementById("check"+tr.id).checked=true;
+ checked++;
+ };
+ if (checked>=n)
+ break;
+ };
+ };
+};
+
+
+function plekit_table_visible_count() {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+ var reg = /(^|\s)invisibleRow(\s|$)/;
+ var v=0;
+
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+
+ if(tr.className.search(reg) == -1)
+ {
+ v++;
+ }
+ }
+
+ return v;
+}
+
+
+function plekit_table_count_nodes() {
+ var table=$(slicetable_id);
+ var css='#'+slicetable_id+'>tbody';
+ var rows = $$(css)[0].rows;
+ var reg = /(^|\s)invisibleRow(\s|$)/;
+ var n=0;
+ var v=0;
+ var s=0;
+
+ for (var row_index = 0; row_index < rows.length ; row_index++) {
+ var tr=rows[row_index];
+
+ n++;
+ var ch = document.getElementById("check"+tr.id);
+
+ if(tr.className.search(reg) == -1)
+ v++;
+ else
+ {
+ if (ch.checked)
+ ch.checked=false;
+ };
+
+ if (ch.checked)
+ s++;
+
+ };
+
+ var dd = document.getElementById('node_statistics');
+ dd.innerHTML = "Total: "+n+" - Shown: "+v+" - Selected: "+s;
+};
+
+function AutoSelect()
+{
+ var a = document.getElementById('automatic').value;
+ var n = parseInt(document.getElementById('no_nodes').value);
+
+ if (isNaN(n))
+ return;
+
+ if (a == "random")
+ CheckRandomNodes(n);
+ else if (a == "top")
+ CheckTopNodes(n);
+
+ plekit_table_select_filter2();
+ plekit_table_count_nodes();
+}
+
+*/