fbe6142fe946965f7d6fc8552c86946b71f4cc16
[plewww.git] / plekit / php / columns.php
1 <?php
2
3 require_once 'tophat_api.php';
4
5 drupal_set_html_head('
6 <script type="text/javascript" src="/plekit/table/columns.js"></script>
7 ');
8
9 class PlekitColumns {
10
11 var $column_configuration = "";
12 var $reference_node = "";
13 var $first_time = false;
14
15 var $all_headers = array();
16 var $this_table_headers = array();
17 var $visible_headers = array();
18
19 var $fix_columns = array();
20 var $tag_columns = array();
21 var $extra_columns = array();
22
23 var $comon_live_data = "";
24 var $tophat_live_data = "";
25 var $live_data = array();
26
27 var $table_ids;
28
29 var $HopCount = array();
30
31   function PlekitColumns ($column_configuration, $fix_columns, $tag_columns, $extra_columns=NULL, $this_table_headers=NULL) {
32
33         if ($column_configuration != NULL) {
34         $this->fix_columns = $fix_columns;
35         $this->tag_columns = $tag_columns;
36         $this->extra_columns = $extra_columns;
37
38         //print("<p>FIX<p>");
39         //print_r($this->fix_columns);
40         //print("<p>TAG<p>");
41         //print_r($this->tag_columns);
42         //print("<p>EXTRA<p>");
43         //print_r($this->extra_columns);
44
45         $this->prepare_headers();
46         $this->parse_configuration($column_configuration);
47
48         $this->visible_headers = $this->get_visible();
49         }
50
51         //print("<p>VISIBLE<p>");
52         //print_r($this->visible_headers);
53
54 }
55
56
57
58 /*
59
60 INFO
61
62 */
63
64 function prepare_headers() {
65
66 foreach ($this->fix_columns as $column) {
67 $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, 'source'=>'myplc');
68 }
69
70 $tmp_headers = array();
71 foreach ($this->tag_columns as $column) {
72
73 if ($column['headerId'] != "")
74         $headerId = $column['headerId'];
75 else
76         $headerId = $column['header'];
77
78 //$this->all_headers[$headerId]=array('header'=>$headerId,'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'],'visible'=>false);
79 $tmp_headers[$headerId]=array('header'=>$headerId,'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'],'visible'=>false, 'source'=>'myplc');
80 }
81
82 if ($this->extra_columns)
83 foreach ($this->extra_columns as $column) {
84 //$this->all_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'], 'fetched'=>$column['fetched'],'visible'=>false);
85 $tmp_headers[$column['header']]=array('header'=>$column['header'],'type'=>$column['type'],'tagname'=>$column['tagname'],'title'=>$column['title'], 'description'=>$column['title'], 'label'=>$column['header'], 'fetched'=>$column['fetched'], 'visible'=>false, 'source'=>$column['source']);
86
87 usort ($tmp_headers, create_function('$col1,$col2','return strcmp($col1["label"],$col2["label"]);'));
88 }
89
90 foreach ($tmp_headers as $t) 
91 $this->all_headers[$t['header']] = $t;
92
93 //$this->all_headers = array_merge($this->all_headers, $tmp_headers);
94
95 //print($this->print_headers());
96
97 return $this->all_headers;
98
99 }
100
101
102 function get_headers() {
103
104 return $this->all_headers;
105
106 }
107
108 function get_selected_period($label) {
109
110 if ($this->all_headers[$label."w"]['visible'])
111         return "w";
112 else if ($this->all_headers[$label."m"]['visible'])
113         return "m";
114 else if ($this->all_headers[$label."y"]['visible'])
115         return "y";
116 else if ($this->all_headers[$label]['visible'])
117         return "";
118         
119 return "";
120 }
121
122 function node_tags() {
123
124         $fetched_tags = array('node_id','hostname');    
125
126         foreach ($this->all_headers as $h)
127         {
128                 if ($h['visible'] == true && $h['tagname'] != "" && !$h['fetched'] && $h['source']=="myplc")
129                         $fetched_tags[] = $h['tagname'];
130         }
131
132         return $fetched_tags;
133 }
134
135 function print_headers() {
136
137         $headers = "";  
138
139         foreach ($this->all_headers as $l => $h)
140         {
141                 $headers.="<br>[".$l."]=".$h['header'].":".$h['label'].":".$h['tagname'].":".$h['visible'];
142         }
143         return $headers;
144 }
145
146 function get_visible() {
147
148         $visibleHeaders = array();      
149
150         foreach ($this->all_headers as $h)
151         {
152                 if ($h['visible'] == true)
153                         $visibleHeaders[] = $h['header'];
154         }
155         return $visibleHeaders;
156 }
157
158 function headerIsVisible($header_name) {
159
160 $headersToShow = $this->visible_headers;
161
162 if (in_array($header_name, $headersToShow))
163         return true;
164
165 if ($this->inTypeC($header_name."w"))
166         return (in_array($header_name."w", $headersToShow) || in_array($header_name."m", $headersToShow) || in_array($header_name."y", $headersToShow));
167 }
168
169
170
171
172 /*
173
174 CONFIGURATION
175
176 */
177
178
179 function parse_configuration($column_configuration) {
180
181         $this->column_configuration = $column_configuration;
182         //$this->default_configuration = $default_configuration;
183
184         //print($this->print_headers());
185
186         $columns_conf = explode("|", $column_configuration);
187
188
189         foreach ($columns_conf as $c)
190         {
191                 $conf = explode(":",$c);
192
193                 if ($conf[0] == "default")
194                         continue;
195
196                 if (!$this->all_headers[$conf[0]])
197                         continue;
198
199                 $this->all_headers[$conf[0]]['visible']=true;
200
201                 if ($this->all_headers[$conf[0]]['source'] == "comon")
202                         $this->comon_live_data.=",".$this->all_headers[$conf[0]]['tagname'];
203
204                 if ($this->all_headers[$conf[0]]['source'] == "tophat")
205                 {
206                         $this->reference_node = $conf[1];
207                         print ("ref node in configuration = ".$conf[1]);
208                         $this->reference_node = "planetlab-europe-07.ipv6.lip6.fr";
209                         $this->all_headers[$conf[0]]['refnode']=$this->reference_node;
210                         //$threshold = explode(",",$conf[1]);
211                         //$this->all_headers[$conf[0]]['threshold']=$threshold;
212                 }
213
214                 //print("<p>-".$conf[0]."-should be visible now - ".$this->all_headers[$conf[0]]['visible']);
215                 //print_r($this->all_headers[$conf[0]]);
216
217 /*
218                 if ($conf[1] == "f")
219                         continue;
220
221                 else if ($this->inTypeC($conf[0]))
222                 {
223                         $this->all_headers[$conf[0]]['duration']= substr($conf[0], strlen($conf[0])-1, strlen($conf[0]));
224                         $threshold = explode(",",$conf[1]);
225                         $this->all_headers[$conf[0]]['threshold']=$threshold;
226                 }
227                 else if ($this->inTypeA($conf[0]))
228                 {
229                         $exclude_list = explode(",",$conf[1]);
230                         $this->all_headers[$conf[0]]['exclude_list']=$exclude_list;
231                 }
232                 else
233                 {
234                         $threshold = explode(",",$conf[1]);
235                         $this->all_headers[$conf[0]]['threshold']=$threshold;
236                 }
237 */
238         }
239
240 }
241
242
243                 
244
245
246 /*
247
248 CELLS
249
250 */
251
252 function convert_data($value, $data_type) {
253
254         if ($value == "" || $value == null || $value == "n/a" || $value == "None")
255                 return "n/a";
256
257         if ($data_type == "string")
258                 return $value;
259
260         if ($data_type == "date") 
261                 return date("Y-m-d", $value);
262
263         if ($data_type == "uptime") 
264                 return (int)((int) $value / 86400);
265         
266         return ((int) ($value * 10))/10;
267
268 }
269
270 function getHopCount($ref_node, $planetlab_nodes) {
271
272         $tophat_auth = array( 'AuthMethod' => 'password', 'Username' => 'guest', 'AuthString' => 'guest');
273         $tophat_api = new TopHatAPI($tophat_auth);
274
275         $traceroute = $tophat_api->Get('traceroute', 'latest', array('src_hostname' => $ref_node, 'dst_hostname' => $planetlab_nodes), array('dst_hostname', 'hop_count') );
276
277         $hopcount = array();
278
279         if ($traceroute) foreach ($traceroute as $t)
280                 $hopcount[$t['dst_hostname']]=$t['hop_count'];
281
282         return $hopcount;
283 }
284
285 function comon_query_nodes($requested_data) {
286         //$base_url = 'http://comon.cs.princeton.edu/status/tabulator.cgi?forma=nameonly&';
287         $base_url = "http://comon.cs.princeton.edu/status/tabulator.cgi?table=table_nodeviewshort&format=formatcsv&dumpcols='name";
288
289         $url = $base_url.$requested_data."'";
290
291         //print ("retriecing comon data for url ".$url);
292
293         $sPattern = '\', \'';
294         $sReplace = '|';
295
296         if( false == ($str=file_get_contents($url)))
297                 return '';
298
299         $result=preg_replace( $sPattern, $sReplace, $str );
300         $sPattern = '/\s+/';
301         $sReplace = ';';
302         $result=preg_replace( $sPattern, $sReplace, $result );
303
304         $comon_data = explode(";", $result);
305         $cl = array();
306         $comon_values = array();
307
308         foreach ($comon_data as $cd) {
309                 $cc = explode("|", $cd);
310                 if ($cc[0] == "name") {
311                         $cl = $cc;
312                 }
313                 $comon_values[$cc[0]] = array();
314                 $cindex=1;
315                 foreach ($cl as $cltag) {
316                         if ($cltag != "name")
317                                 $comon_values[$cc[0]][$cltag] = $cc[$cindex++];
318                 }
319         }
320
321         return $comon_values;
322 }
323
324
325 //Depending on the columns selected more data might need to be fetched from
326 //external sources
327
328 function fetch_live_data($all_nodes) {
329
330         //print("<p>fetching live data<p>");
331
332 //comon data
333         if ($this->comon_live_data != "") {
334         
335                 //print ("live data to be fetched =".$this->comon_live_data);
336                 $this->live_data = $this->comon_query_nodes($this->comon_live_data);
337                 //print_r($this->live_data);
338         }
339
340
341 //TopHat pairwise data
342         //if ($this->tophat_live_data != "")
343         if ($this->reference_node != "")
344         {
345                 $dd = array();
346
347                 if ($all_nodes) foreach ($all_nodes as $n)
348                         $dd[] = $n['hostname'];
349
350                 print("Calling tophat api for reference node = ".$this->reference_node);
351                 $st = time() + microtime();
352                 $HopCount = $this->getHopCount($this->reference_node, $dd);
353                 printf(" (%.2f ms)<br/>", (time() + microtime()-$st)*100);
354                 print_r($HopCount);
355         }
356 }
357
358
359 function excludeItems($value, $exclude_list, $hh) {
360
361         if ($value == "")
362                 $value = "n/a";
363
364         if ($exclude_list)
365         if (in_array($value, $exclude_list))
366                 return array($value, array('name'=>$hh, 'display'=>'table-cell'));
367         else
368                 return array($value, array('name'=>$hh, 'display'=>'table-cell'));
369
370         return array($value, array('name'=>$hh, 'display'=>'table-cell'));
371 }
372
373
374 function checkThreshold($value, $threshold, $hh) {
375
376         if ($value == "")
377                 return array("n/a", array('name'=>$hh, 'display'=>'table-cell'));
378
379         if ($threshold)
380         if ((float) $value >= (float) $threshold[0] && (float) $value <= (float) $threshold[1])
381                 return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
382         else
383                 return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
384
385         return array(round($value,1), array('name'=>$hh, 'display'=>'table-cell'));
386 }
387
388
389 function cells($table, $node) {
390
391 foreach ($this->all_headers as $h)
392 {
393 if (!$h['fixed']) { 
394
395 if ($h['visible'] != "")
396 {
397
398 /*
399 if ($this->inTypeC($h['header']))
400 {
401         $tagname = $h['tagname'];
402         $value = $node[$tagname];
403         $v = $this->checkThreshold($value, $h['threshold'], $h['header']);
404         $table->cell($v[0],$v[1]);
405 }
406 else if ($this->inTypeB($h['header']))
407 {
408         $value = $node[$h['tagname']];
409         $v = $this->checkThreshold($value, $h['threshold'], $h['header']);
410         $table->cell($v[0],$v[1]);
411 }
412 else if ($this->inTypeD($h['header']))
413 {
414         $value = $this->HopCount[$node['hostname']];
415         $v = $this->excludeItems($value, $h['threshold'], $h['header']);
416         $table->cell($v[0],$v[1]);
417 }
418 else if ($this->inTypeA($h['header']))
419 {
420         $value = $node[$h['tagname']];
421         $v = $this->excludeItems($value, $h['exclude_list'], $h['header']);
422         $table->cell($v[0],$v[1]);
423 }
424 */
425 if ($h['type'] == "date")
426 {
427         $value = $this->convert_data($node[$h['tagname']], $h['type']);
428         $table->cell($value,array('name'=>$h['header'], 'display'=>'table-cell'));
429 }
430 else if ($h['source'] == "comon")
431 {
432         //print("<br>Searching for ".$h['tagname']."at ".$node);
433         $value = $this->convert_data($this->live_data[$node['hostname']][$h['tagname']], $h['tagname']);
434
435         $table->cell($value,array('name'=>$h['header'], 'display'=>'table-cell'));
436 }
437 else
438 {
439         //$value = $node[$h['tagname']];
440         $value = $this->convert_data($node[$h['tagname']], $h['type']);
441         $table->cell($value,array('name'=>$h['header'], 'display'=>'table-cell'));
442 }
443 }
444 else 
445         if ($node[$h['tagname']])
446         {
447                 $value = $this->convert_data($node[$h['tagname']], $h['type']);
448                 $table->cell($value, array('name'=>$h['header'], 'display'=>'none'));
449         }
450         else
451                 if ($node[$h['fetched']])
452                         $table->cell("n/a", array('name'=>$h['header'], 'display'=>'none'));
453                 else
454                         $table->cell("??", array('name'=>$h['header'], 'display'=>'none'));
455 }
456 }
457
458 }
459
460
461 /*
462
463 HTML
464
465 */
466
467
468 function javascript_init() {
469
470 print("<input type='hidden' id='selected_reference_node' value='".$this->reference_node."' />");
471
472 print("<script type='text/javascript'>");
473 print("highlightOption('AU');");
474 print("overrideTitles();");
475 print("</script>");
476
477 }
478
479 function quickselect_html() {
480
481 //return '<p>This link uses the onclick event handler.<br><a href="#" onclick="setVisible(\'quicklist\');return false" target="_self">Open popup</a></p>';
482
483
484 $quickselection = "<select id='quicklist' onChange=changeSelectStatus(this.value)><option value='0'>Short column descriptions and quick add/remove</option>";
485 //$quickselection = "<select id='quicklist'><option value='0'>Short column descriptions and quick add/remove</option>";
486 $prev_label="";
487 $optionclass = "out";
488 foreach ($this->all_headers as $h)
489 {
490         if ($h['header'] == "hostname" || $h['header'] == "ID")
491                 continue;
492
493         if ($h['fixed'])
494                 $disabled = "disabled=true";
495         else
496                 $disabled = "";
497
498         if ($this->headerIsVisible($h['label']))
499         {
500                 $optionclass = "in";
501                 //$selected = "selected=selected";
502         }
503         else
504         {
505                 $optionclass = "out";
506                 //$selected = "";
507         }
508
509         if ($prev_label == $h['label'])
510                 continue;
511
512         $prev_label = $h['label'];
513
514
515 //$quickselection.="<option onclick=\"debugfilter('here2');removeSelectHandler(this);\" id='option'".$h['label']." class='".$optionclass."' value='".$h['label']."'><b>".$h['label']."</b>:&nbsp;".$h['title']."</option>";
516 $quickselection.="<option id='option'".$h['label']." class='".$optionclass."' value='".$h['label']."'><b>".$h['label']."</b>:&nbsp;".$h['title']."</option>";
517 }
518
519
520 $quickselection.="</select>";
521
522 return $quickselection;
523
524 }
525
526
527 function configuration_panel_html($showDescription) {
528
529 if ($showDescription)
530         $table_width = 700;
531 else
532         $table_width = 350;
533
534 print("<table align=center cellpadding=10 width=".$table_width.">");
535 print("<tr><th>Add/remove columns</th>");
536
537 if ($showDescription)
538         print("<th>Column description and configuration</th>");
539
540 print("</tr><tr><td valign=top width=300>");
541
542         print('<div id="scrolldiv" style="border : solid 2px grey; padding:4px; width:300px; height:180px; overflow:auto;">');
543 print ("<table>");
544         $prev_label="";
545         $optionclass = "out";
546         foreach ($this->all_headers as $h)
547         {
548                 if ($h['header'] == "hostname" || $h['header'] == "ID")
549                         continue;
550
551                 if ($h['fixed'])
552                         $disabled = "disabled=true";
553                 else
554                         $disabled = "";
555
556                 if ($this->headerIsVisible($h['label']))
557                 {
558                         $selected = "checked=true";
559                         $fetch = "true";
560                         //print("header ".$h['label']." checked!");
561                 }
562                 else
563                 {
564                         $selected = "";
565                         if ($h['fetched'])
566                                 $fetch = "true";
567                         else
568                                 $fetch = "false";
569                 }
570
571                 print("<input type='hidden' id='tagname".$h['header']."' value='".$h['tagname']."'></input>");
572
573                 if ($prev_label == $h['label'])
574                         continue;
575
576                 $prev_label = $h['label'];
577                 $period = $this->get_selected_period($h['label']);
578
579 //<input type='hidden' id='fdesc".$h['label']."' value='".$h['description']."'></input>
580                 print ("<tr><td>
581 <input type='hidden' id='fetched".$h['label']."' value=',".$period.",".$fetch."'></input>
582 <input type='hidden' id='period".$h['label']."' value='".$period."'></input>
583 <input type='hidden' id='type".$h['label']."' value='".$h['type']."'></input>
584 <input type='hidden' id='source".$h['label']."' value='".$h['source']."'></input>
585                 <div id='".$h['label']."' name='columnlist' class='".$optionclass."' onclick='highlightOption(this.id)'>
586 <table width=280 id='table".$h['label']."'><tr>
587 <td bgcolor=#CAE8EA align=center width=30><b><span style='color:#3399CC'>".$h['label']."</span></b></td> 
588 <td align=left>&nbsp;<span style='height:10px' id ='htitle".$h['label']."'>".$h['title']."</span>&nbsp;</td>
589 <td align=right width=20>&nbsp;<span style='height:10px' id ='loading".$h['label']."'></span>&nbsp;</td>
590 <td align=right width=20><input id='check".$h['label']."' name='".$h['tagname']."' type='checkbox' ".$selected." ".$disabled." autocomplete='off' value='".$h['label']."' onclick='changeCheckStatus(this.id)'></input></td>
591 </tr></table></div></td></tr>");
592         }
593
594         print("</table> </div></td>");
595
596 if ($showDescription)
597 {
598         print("<td valign=top width=400>");
599         print("<div class='myslice' id='selectdescr'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div></td>");
600 }
601
602 print("</tr>");
603 //print("<tr><td align=center>");
604 //print("<input type='button' value='Reset' onclick=resetCols('previousConf') />");
605 //print("<input type='button' value='Default' onclick=saveConfiguration('defaultConf') />");
606 //print("<input type='button' value='Reset table' onclick=\"resetConfiguration()\" />");
607 //print("</td>");
608 //print("&nbsp;<input type='button' value='Save configuration' onclick=saveConfiguration('column_configuration') />");
609 //print("&nbsp;<input type='button' id='fetchbutton' onclick='fetchData()' value='Fetch data' disabled=true /> </td>");
610
611 if ($showDescription)
612         print("<td></td>");
613
614 print(" </tr> </table>");
615 }
616
617
618
619 function column_filter () {
620
621 echo <<< EOF
622
623 Highlight <select onChange="filterByType(this.value)">
624 <option value="none">None</option>
625 <option value="capabilities">Capabilities</option>
626 <option value="statistics">Statistics</option>
627 <option value="network">Network</option>
628 <option value="pairwise">Pairwise</option>
629 <option value="other">Other</option>
630 </select>
631 <p>
632
633 EOF;
634 }
635
636   function column_html ($colHeader, $colName, $colId, $fulldesc, $visible) {
637
638         if ($visible) 
639                 $display = 'display:table-cell';
640         else 
641                 $display = 'color:red;display:none';
642
643     return "
644         <th class='sample plekit_table' name='confheader".$colHeader."' id='testid' style='".$display."'>
645         <div id=\"".$colId."\" onclick=\"showDescription('".$colHeader."')\" onmouseover=\"showDescription('".$colHeader."')\">$colHeader</div>
646         </th>
647         ";
648   }
649
650   function column_fix_html ($colHeader, $colName, $colId) {
651
652         $display = 'display:table-cell';
653
654         $res="<th name='confheader".$colHeader."' class='fix plekit_table' style='$display'>";
655                 $res.= "<div id='$colId' onmouseover=\"showDescription('".$colHeader."')\">$colHeader</div></th>";
656
657         return $res;
658   }
659
660
661 function graph_html($colHeader) {
662
663         return "<p><img src='/planetlab/slices/graph.png' width='20' align='BOTTOM'><input type='checkbox' id='graph".$colHeader."'></input> Show details on mouse over";
664
665         }
666
667 function threshold_html($colHeader) {
668
669         $updatecall = "updateColumnThreshold('".$colHeader."',window.document.getElementById('min".$colHeader."').value,window.document.getElementById('max".$colHeader."').value);";
670
671         $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.">&nbsp;</input>"; 
672
673         return $bublle;
674 }
675
676
677 /*
678
679 UTILS
680
681 */
682
683 //simple strings
684 function inTypeA($header_name) {
685         $typeA = array('ST','SN','RES','OS','NRR','NTP','NSR','NSF','NDS','NTH','NEC','LRN','LCY','LPR','LCN','LAT','LON','IP','ASN','AST');
686         return in_array($header_name, $typeA);
687 }
688
689 //integers
690 function inTypeB($header_name) {
691         $typeB = array('BW','DS','MS','CC','CR','AS','DU','CN');
692         return in_array($header_name, $typeB);
693 }
694
695 //statistical values
696 function inTypeC($header_name) {
697         $typeC = array('Rw','Rm','Ry','Lw','Lm','Ly','Sw','Sm','Sy','CFw','CFm','CFy','BUw','BUm','BUy','MUw','MUm','MUy','SSHw','SSHm','SSHy');
698         return in_array($header_name, $typeC);
699 }
700
701 //tophat
702 function inTypeD($header_name) {
703         $typeD = array('HC');
704         return in_array($header_name, $typeD);
705 }
706
707
708 function removeDuration($header)
709 {
710         if ($this->inTypeC($header))
711                 return substr($header, 0, strlen($header)-1);
712         else
713                 return $header;
714 }
715
716 }
717
718 ?>
719
720