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