source: branches/0.4/web/addons/job_monarch/libtoga.php @ 745

Last change on this file since 745 was 745, checked in by ramonb, 11 years ago
  • Property svn:keywords set to Id
File size: 69.0 KB
RevLine 
[102]1<?php
[225]2/*
3 *
4 * This file is part of Jobmonarch
5 *
[713]6 * Copyright (C) 2006-2013  Ramon Bastiaans
[225]7 *
8 * Jobmonarch is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * Jobmonarch is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21 *
[231]22 * SVN $Id: libtoga.php 745 2013-03-25 16:20:44Z ramonb $
23 *
[225]24 */
25
26
[519]27class HTTPVariables
28{
[721]29    var $clustername, $metricname;
30    var $restvars, $httpvars;
[103]31
[721]32    function HTTPVariables( $httpvars, $getvars )
33    {
34        $this->restvars        = array();
[103]35
[721]36        $this->clustername    = isset( $httpvars["c"] ) ? $httpvars["c"] : $getvars["c"];
37        $this->metricname    = isset( $httpvars["m"] ) ? $httpvars["m"] : $getvars["m"];
[110]38
[721]39        if( count( $httpvars ) > 0 )
40        {
41            foreach( $httpvars as $httpvar => $httpval )
42            {
43                if( $httpval )
44                {
45                    $this->restvars[$httpvar] = $httpval;
46                }
47            }
48        }
[117]49
[721]50        if( count( $getvars ) > 0 )
51        {
52            foreach( $getvars as $getvar => $getval )
53            {
54                if( $getval )
55                {
56                    $this->restvars[$getvar] = $getval;
57                }
58            }
59        }
60    }
[103]61
[721]62    function getClusterName()
63    {
64        return $this->clustername;
65    }
[103]66
[721]67    function getMetricName()
68    {
69        return $this->metricname;
70    }
[110]71
[721]72    function getHttpVar( $var )
73    {
74        if( isset( $this->restvars[$var] ) )
75        {
76            return $this->restvars[$var];
77        }
78        else
79        {
80            return null;
81        }
82    }
[103]83}
84
[721]85$CLUSTER_CONFS    = array();
[337]86
[686]87ini_set("memory_limit","500M");
[652]88set_time_limit(0);
89
[519]90// Monarch's conf
[112]91//
92include_once "./conf.php";
[195]93include_once "./version.php";
[112]94
[117]95global $GANGLIA_PATH;
[206]96global $RRDTOOL;
97global $JOB_ARCHIVE_DIR;
[207]98global $JOB_ARCHIVE_DBASE;
[329]99global $skan_str;
100global $x_first, $y_first;
[337]101global $CLUSTER_CONFS;
[112]102
[117]103$my_dir = getcwd();
[112]104
[117]105// Load Ganglia's PHP
106chdir( $GANGLIA_PATH );
[112]107
[686]108include_once "./eval_conf.php";
[117]109include_once "./functions.php";
110include_once "./ganglia.php";
[145]111include_once "./get_context.php";
[519]112
[145]113$context = 'cluster';
[117]114include_once "./get_ganglia.php";
115
116// Back to our PHP
117chdir( $my_dir );
118
119global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH, $DATA_SOURCE, $HTTP_GET_VARS, $_GET;
120$httpvars = new HTTPVariables( $HTTP_GET_VARS, $_GET );
121
[112]122// Set cluster context so that Ganglia will
123// provide us with the correct metrics array
124//
[126]125global $context, $clustername, $reports;
[129]126
[126]127global $default_metric;
128
[112]129// Ganglia's array of host metrics
130//
[126]131global $metrics, $hosts_up;
[738]132global $start;
[112]133
[246]134global $DATETIME_FORMAT;
135
[519]136function makeDate( $time )
137{
[721]138    global $DATETIME_FORMAT;
139    return strftime( $DATETIME_FORMAT, $time );
[246]140}
141
[514]142
[519]143class TarchDbase
144{
[721]145    var $ip, $dbase, $conn;
[130]146
[721]147    function TarchDbase( $ip = null, $dbase = null )
148    {
149        global $CLUSTER_CONFS, $clustername;
150        global $JOB_ARCHIVE_DBASE;
[207]151
[721]152        // Import cluster specific settings
153        //
154        foreach( $CLUSTER_CONFS as $confcluster => $conffile )
155        {
156            if( strtolower( trim($this->clustername) ) == strtolower(trim($confcluster)) )
157            {
158                include_once $conffile;
159            }
160        }
[454]161
[721]162        $db_fields = explode( '/', $JOB_ARCHIVE_DBASE );
[207]163
[721]164        $this->ip    = $db_fields[0];
165        $this->dbase    = $db_fields[1];
166        $this->conn    = null;
167    }
[130]168
[721]169    function connect()
170    {
171        if( $this->ip == null )
172            $this->conn = pg_connect( "dbname=".$this->dbase );
173        else
174            $this->conn = pg_connect( "host=".$this->ip." dbname=".$this->dbase );
175    }
[138]176
[721]177    function searchDbase( $id = null, $queue = null, $owner = null, $name = null, $start_from_time = null, $start_to_time = null, $end_from_time = null, $end_to_time = null )
178    {
179        global $SEARCH_RESULT_LIMIT;
[248]180
[721]181        if( $id )
182        {
183            $select_query = "SELECT job_id FROM jobs WHERE job_id = '$id' AND job_status = 'F'";
184            $this->resultcount = 1;
185        }
186        else
187        {
188            $query_args = array();
189           
190            if( $queue )
191            {
192                $query_args[] = "job_queue ='$queue'";
193            }
194            if( $owner )
195            {
196                $query_args[] = "job_owner ='$owner'";
197            }
198            if( $name )
199            {
200                $query_args[] = "job_name = '$name'";
201            }
202            if( $start_from_time )
203            {
204                $query_args[] = "job_start_timestamp >= $start_from_time";
205            }
206            if( $start_to_time )
207            {
208                $query_args[] = "job_start_timestamp <= $start_to_time";
209            }
210            if( $end_from_time )
211            {
212                $query_args[] = "job_stop_timestamp >= $end_from_time";
213            }
214            if( $end_to_time )
215            {
216                $query_args[] = "job_stop_timestamp <= $end_to_time";
217            }
[138]218
[721]219            $query = "FROM jobs WHERE job_status = 'F' AND ";
220            $extra_query_args = '';
[138]221
[721]222            foreach( $query_args as $myquery )
223            {
224                if( $extra_query_args == '' )
225                {
226                    $extra_query_args = $myquery;
227                }
228                else
229                {
230                    $extra_query_args .= " AND ".$myquery;
231                }
232            }
233            $query .= $extra_query_args;
[138]234
[721]235            $count_result_idname = "COUNT(job_id)";
236            $select_result_idname = "job_id";
[140]237
[721]238            $count_query = "SELECT " . $count_result_idname . " " . $query;
[248]239
[721]240            $count_result = $this->queryDbase( $count_query );
241            $this->resultcount = (int) $count_result[0]['count'];
[248]242
[721]243            $select_query = "SELECT " . $select_result_idname . " " . $query . " ORDER BY job_id DESC LIMIT " . $SEARCH_RESULT_LIMIT;
244        }
[251]245
[721]246        $ids = $this->queryDbase( $select_query );
[248]247
[721]248        $ret = array();
[140]249
[721]250        foreach( $ids as $crow)
251        {
252            $ret[] = $crow['job_id'];
253        }
[140]254
[721]255        return $ret;
256    }
[138]257
[721]258    function getNodesForJob( $jobid )
259    {
260        $result = $this->queryDbase( "SELECT node_id FROM job_nodes WHERE job_id = '$jobid'" );
[138]261
[721]262        $nodes = array();
[138]263
[721]264        foreach( $result as $result_row ) 
265        {
266            $nodes[] = $this->getNodeArray( $result_row['node_id'] );
267        }
[138]268
[721]269        return $nodes;
270    }
[138]271
[721]272    function getJobsForNode( $nodeid )
273    {
274        $result = $this->queryDbase( "SELECT job_id FROM job_nodes WHERE node_id = '$nodeid'" );
[138]275
[721]276        $jobs = array();
[138]277
[721]278        foreach( $result as $result_row )
279        {
280            $jobs[] = $this->getJobArray( $result_row['job_id'] );
281        }
282        return $jobs;
283    }
[138]284
[721]285    function getJobArray( $id )
286    {
287        $result = $this->queryDbase( "SELECT * FROM jobs WHERE job_id = '$id'" );
[138]288
[721]289        return ( $this->makeArray( $result[0] ) );
290    }
[138]291
[721]292    function getNodeArray( $id )
293    {
294        $result = $this->queryDbase( "SELECT * FROM nodes WHERE node_id = '$id'" );
[138]295
[721]296        return ( $this->makeArray( $result[0] ) );
297    }
[138]298
[721]299    function makeArray( $result_row )
300    {
301        $myar = array();
[138]302
[721]303        foreach( $result_row as $mykey => $myval )
304        {
305            $map_key = explode( '_', $mykey );
[138]306
[721]307            $rmap_key = array_reverse( $map_key );
308            array_pop( $rmap_key );
309            $map_key = array_reverse( $rmap_key );
310           
311            $newkey = implode( '_', $map_key );
312           
313            $myar[$newkey] = $result_row[$mykey];
314        }
[138]315
[721]316        return $myar;
317    }
[138]318
[721]319    function queryDbase( $query )
320    {
321        $result_rows = array();
322   
323        if( !$this->conn )
324        {
325            $this->connect();
326        }
[138]327
[721]328        $result = pg_query( $this->conn, $query );
[138]329
[721]330        while ($row = pg_fetch_assoc($result))
331        {
332            $result_rows[] = $row;
333        }
[138]334
[721]335        return $result_rows;
336    }
[130]337}
338
[519]339class TarchRrdGraph
340{
[721]341    var $rrdbin, $rrdvalues, $clustername, $hostname, $tempdir, $tarchdir, $metrics;
[130]342
[721]343    function TarchRrdGraph( $clustername, $hostname )
344    {
[725]345        global $conf;
[721]346        global $JOB_ARCHIVE_DIR;
[206]347
[725]348        $this->rrdbin        = $conf['rrdtool'];
[721]349        $this->rrdvalues    = array();
350        $this->tarchdir        = $JOB_ARCHIVE_DIR;
351        $this->clustername    = $clustername;
352        $this->hostname        = $hostname;
353    }
[130]354
[721]355    function doCmd( $command )
356    {
357        $pipe = popen( $command . ' 2>&1', 'r' );
[130]358
[721]359        if (!$pipe)
360        {
361            print "pipe failed.";
362            return "";
363        }
[130]364
[721]365        $output = '';
[519]366
[721]367        while(!feof($pipe))
368        {
369            $output .= fread($pipe, 1024);
370        }
[130]371
[721]372        pclose($pipe);
[130]373
[721]374        $output = explode( "\n", $output );
[519]375
[721]376        return $output;
377    }
[130]378
[721]379    function dirList( $dir )
380    {
381        $dirlist = array();
[130]382
[721]383        if ($handle = opendir( $dir ))
384        {
385            while (false !== ($file = readdir($handle)))
386            {
387                if ($file != "." && $file != "..")
388                {
389                    $dirlist[] = $file;
390                }
391            }
392            closedir($handle);
393        }
[130]394
[721]395        return $dirlist;
396    }
[130]397
[721]398    function getTimePeriods( $start, $end )
399    {
400        $times = array();
401        $dirlist = $this->dirList( $this->tarchdir . '/' . $this->clustername . '/' . $this->hostname );
[145]402
[721]403        $first = 0;
404        $last = 9999999999999;
[130]405
[721]406        foreach( $dirlist as $dir )
407        {
408            if( $dir > $first and $dir <= $start )
409            {
410                $first = $dir;
411            }
412            if( $dir < $last and $dir >= $end )
413            {
414                $last = $dir;
415            }
416        }
[130]417
[721]418        foreach( $dirlist as $dir )
419        {
420            if( $dir >= $first and $dir <= $last and !array_key_exists( $dir, $times ) )
421            {
422                $times[] = $dir;
423            }
424        }
[130]425
[721]426        sort( $times );
[130]427
[721]428        return $times;
429    }
[130]430
[721]431    function getRrdDirs( $start, $stop )
432    {
433        $timess = $this->getTimePeriods( $start, $stop );
[145]434
[721]435        $rrd_files = array();
[145]436
[721]437        foreach( $timess as $time )
438        {
439            $rrd_files[] = $this->tarchdir . '/' . $this->clustername . '/' . $this->hostname. '/'.$time;
440        }
[145]441
[721]442        return $rrd_files;
443    }
[145]444
[721]445    function getRrdFiles( $metric, $start, $stop )
446    {
447        $times = $this->getTimePeriods( $start, $stop );
[145]448
[721]449        $rrd_files = array();
[145]450
[721]451        foreach( $times as $time )
452        {
453            $rrd_files[] = $this->tarchdir . '/' . $this->clustername . '/' . $this->hostname . '/' .$time. '/' . $metric. '.rrd';
454        }
[145]455
[721]456        return $rrd_files;
457    }
[130]458}
459
[519]460class DataSource
461{
[721]462    var $data, $ip, $port;
[103]463
[721]464    function DataSource()
465    {
[742]466        global $DATA_SOURCE, $clustername;
[326]467
[721]468        $ds_fields     = explode( ':', $DATA_SOURCE );
[326]469
[721]470        $ds_ip         = $ds_fields[0];
[742]471        $ds_port       = $ds_fields[1];
[326]472
[742]473        $this->ip       = $ds_ip;
[721]474        $this->port     = $ds_port;
[742]475        $this->clustername = $clustername;
[721]476    }
[103]477
[721]478    function getData()
479    {
480        $errstr        = '';
[742]481        $errno         = 0;
482        $timeout       = 3;
[103]483
[721]484        $fp = fsockopen( $this->ip, $this->port, $errno, $errstr, $timeout );
[103]485
[721]486        if( !$fp )
487        {
488            echo 'Unable to connect to '.$this->ip.':'.$this->port;
489            return;
490        }
[103]491
[742]492        if( $this->port == '8652' )
493        {
[745]494            $request = "/" . $this->clustername . "\n";
[742]495            $rc = fputs($fp, $request);
496            if (!$rc)
497            {
498                $error = "Could not sent request to gmetad: $errstr";
499                if ($debug) print "<br/>DEBUG: $error\n";
500                   return FALSE;
501            }
502        }
503
[721]504        stream_set_timeout( $fp, 30 );
[177]505
[721]506        while ( !feof( $fp ) )
507        {
508            $data .= fread( $fp, 16384 );
509        }
[103]510
[721]511        fclose( $fp );
[103]512
[721]513        return $data;
514    }
[103]515}
516
[519]517class DataGatherer
518{
[721]519    var $xmlhandler, $data, $httpvars;
[103]520
[721]521    function DataGatherer( $cluster )
522    {
523        $this->cluster    = $cluster;
524        $this->httpvars = $httpvars;
525    }
[103]526
[721]527    function parseXML( $data )
528    {
[745]529
[721]530        $this->parser         = xml_parser_create();
531        $this->xmlhandler     = new TorqueXMLHandler( $this->cluster );
[326]532
[721]533        xml_set_element_handler( $this->parser, array( &$this->xmlhandler, 'startElement' ), array( &$this->xmlhandler, 'stopElement' ) );
[519]534
[721]535        if ( !xml_parse( $this->parser, $data ) )
536        {
537            $error = sprintf( 'XML error: %s at %d', xml_error_string( xml_get_error_code( $this->parser ) ), xml_get_current_line_number( $this->parser ) );
538        }
539    }
[103]540
[721]541    function printInfo()
542    {
543        $handler = $this->xmlhandler;
544        $handler->printInfo();
545    }
[105]546
[721]547    function getUsingFQDN()
548    {
549        $handler = $this->xmlhandler;
550        return $handler->getUsingFQDN();
551    }
[463]552
[721]553    function getNodes()
554    {
555        $handler = $this->xmlhandler;
556        return $handler->getNodes();
557    }
[106]558
[721]559    function getNode( $node )
560    {
561        $handler = $this->xmlhandler;
562        return $handler->getNode( $node );
563    }
[303]564
[721]565    function getCpus()
566    {
567        $handler = $this->xmlhandler;
568        return $handler->getCpus();
569    }
[124]570
[721]571    function getJobs()
572    {
573        $handler = $this->xmlhandler;
574        return $handler->getJobs();
575    }
[106]576
[721]577    function getJob( $job )
578    {
579        $handler = $this->xmlhandler;
580        return $handler->getJob( $job );
581    }
[303]582
[721]583    function getHeartbeat()
584    {
585        $handler = $this->xmlhandler;
586        return $handler->getHeartbeat();
587    }
[298]588
[721]589    function isJobmonRunning()
590    {
591        $handler = $this->xmlhandler;
592        return $handler->isJobmonRunning();
593    }
[103]594}
595
[519]596class TorqueXMLHandler
597{
[721]598    var $clusters, $heartbeat, $nodes, $jobs, $clustername, $proc_cluster;
[104]599
[721]600    function TorqueXMLHandler( $clustername )
601    {
602        $this->jobs        = array();
603        $this->clusters     = array();
604        $this->nodes         = array();
605        $this->heartbeat     = array();
606        $this->down_nodes    = array();
607        $this->offline_nodes    = array();
608        $this->clustername    = $clustername;
609        $this->fqdn        = 1;
610    }
[103]611
[721]612    function getUsingFQDN()
613    {
614        return $this->fqdn;
615    }
[463]616
[721]617    function getCpus()
618    {
619        $cpus = 0;
[124]620
[721]621        if( isset( $this->jobs ) && count( $this->jobs ) > 0 )
622        {
623            foreach( $this->jobs as $jobid=>$jobattrs )
624            {
625                $nodes    = count( $jobattrs['nodes'] );
626                $ppn    = (int) $jobattrs['ppn'] ? $jobattrs['ppn'] : 1;
627                $mycpus    = $nodes * $ppn;
[124]628
[721]629                $cpus    = $cpus + $mycpus;
630            }
631        }
632    }
[124]633
[721]634    function isJobmonRunning()
635    {
636        if (isset( $this->heartbeat['time'] ))
637        {
638            return 1;
639        }
640        else
641        {
642            return 0;
643        }
644    }
[298]645
[721]646    function makeHostname( $thostname, $tdomain=null )
647    {
648        // Should hostname be FQDN or short w/o domain
649        //
650        $nodes = &$this->nodes;
[514]651
[721]652        $fqdn = 1;
[514]653
[721]654        //$tdomain = explode( '.', $thostname );
655        //
656        // TODO?: extract domain from hostname or something?
[514]657
[721]658        if( $tdomain )
659        {
660            $domain_len    = 0 - strlen( $tdomain );
[514]661
[721]662            // Let's see if Ganglia use's FQDN or short hostnames
663            //
664            foreach( $nodes as $hostname => $nimage )
665            {
666                if( substr( $hostname, $domain_len ) != $tdomain )
667                {
668                    $fqdn    = 0;
669                }
670            }
671        }
672        else
673        {
674            $fqdn    = 0;
675        }
676   
677        if( $tdomain && $fqdn )
678        {
679            if( substr( $thostname, $domain_len ) != $tdomain )
680            {
681                $thostname = $thostname . '.'.$tdomain;
682            } 
683            else
684            {
685                $thostname = $thostname;
686            }
687        }
[514]688
[721]689        return $thostname;
690    }
[514]691
[721]692    function startElement( $parser, $name, $attrs )
693    {
694        $jobs = $this->jobs;
695        $nodes = $this->nodes;
[105]696
[721]697        if( isset( $attrs['TN'] ) )
698        {
699            if ( $attrs['TN'] )
700            {
701                // Ignore dead metrics. Detect and mask failures.
702                if ( $attrs['TN'] > $attrs['TMAX'] * 4 )
703                {
704                    return;
705                }
706            }
707        }
[103]708
[721]709        $jobid = null;
[103]710
[721]711        if( $name == 'CLUSTER' )
712        {
713            $this->proc_cluster = $attrs['NAME'];
714        }
715        else if( $name == 'HOST' and $this->proc_cluster == $this->clustername)
716        {
717            $hostname = $attrs['NAME'];
[459]718
[721]719            $location = $attrs['LOCATION'];
[105]720
[721]721            if( !isset( $nodes[$hostname] ) )
722            {
723                $nodes[$hostname] = new NodeImage( $this->proc_cluster, $hostname );
724            }
725        }
[726]726        else if( $name == 'METRIC' and strstr( $attrs['NAME'], 'zplugin_monarch' ) and $this->proc_cluster == $this->clustername )
[721]727        {
[726]728            if( strstr( $attrs['NAME'], 'zplugin_monarch_heartbeat' ) )
[721]729            {
730                $this->heartbeat['time'] = $attrs['VAL'];
731            }
[726]732            else if( strstr( $attrs['NAME'], 'zplugin_monarch_down' ) )
[721]733            {
734                $fields        = explode( ' ', $attrs['VAL'] );
[104]735
[721]736                $nodes_down    = array();
737                $down_domain    = null;
[514]738
[721]739                foreach( $fields as $f )
740                {
741                    $togavalues    = explode( '=', $f );
[514]742
[721]743                    $toganame    = $togavalues[0];
744                    $togavalue    = $togavalues[1];
[514]745
[721]746                    if( $toganame == 'nodes' )
747                    {
748                        $mynodes = explode( ';', $togavalue );
[514]749
[721]750                        foreach( $mynodes as $node )
751                        {
752                            $nodes_down[] = $node;
753                        }
754                    }
755                    else if( $toganame == 'domain' )
756                    {
757                        $down_domain = $togavalue;
758                    }
759                    else if( $toganame == 'reported' )
760                    {
761                        if( !isset( $this->down_nodes['heartbeat'] ) )
762                        {
763                            $this->down_nodes[$togavalue]    = array( $nodes_down, $down_domain );
764                        }
765                    }
766                }
767            }
[726]768            else if( strstr( $attrs['NAME'], 'zplugin_monarch_offline' ) )
[721]769            {
770                $fields        = explode( ' ', $attrs['VAL'] );
[514]771
[721]772                $nodes_offline    = array();
773                $offline_domain    = null;
[514]774
[721]775                foreach( $fields as $f )
776                {
777                    $togavalues    = explode( '=', $f );
[514]778
[721]779                    $toganame    = $togavalues[0];
780                    $togavalue    = $togavalues[1];
[514]781
[721]782                    if( $toganame == 'nodes' )
783                    {
784                        $mynodes = explode( ';', $togavalue );
[514]785
[721]786                        foreach( $mynodes as $node )
787                        {
788                            $nodes_offline[] = $node;
789                        }
790                    }
791                    else if( $toganame == 'domain' )
792                    {
793                        $offline_domain = $togavalue;
794                    }
795                    else if( $toganame == 'reported' )
796                    {
797                        if( !isset( $this->offline_nodes['heartbeat'] ) )
798                        {
799                            $this->offline_nodes[$togavalue] = array( $nodes_offline, $offline_domain );
800                        }
801                    }
802                }
803            }
[726]804            else if( strstr( $attrs['NAME'], 'zplugin_monarch_job' ) )
[721]805            {
[726]806                sscanf( $attrs['NAME'], 'zplugin_monarch_job_%d_%s$', $monincr, $jobid );
[104]807
[721]808                if( !isset( $jobs[$jobid] ) )
809                {
810                    $jobs[$jobid] = array();
811                }
[104]812
[721]813                $fields = explode( ' ', $attrs['VAL'] );
[104]814
[721]815                foreach( $fields as $f )
816                {
817                    $togavalues = explode( '=', $f );
[104]818
[721]819                    $toganame = $togavalues[0];
820                    $togavalue = $togavalues[1];
[104]821
[721]822                    if( $toganame == 'nodes' )
823                    {
824                        if( $jobs[$jobid]['status'] == 'R' )
825                        {
826                            if( !isset( $jobs[$jobid][$toganame] ) )
827                            {
828                                $jobs[$jobid][$toganame] = array();
829                            }
[104]830
[721]831                            $mynodes = explode( ';', $togavalue );
[103]832
[721]833                            foreach( $mynodes as $node )
834                            {
835                                if( !in_array( $node, $jobs[$jobid][$toganame] ) )
836                                {
[686]837                                    array_push( $jobs[$jobid][$toganame], $node );
[721]838                                }
839                            }
[135]840
[721]841                        }
842                        else if( $jobs[$jobid]['status'] == 'Q' )
843                        {
844                            $jobs[$jobid][$toganame] = $togavalue;
845                        }
846                    }
847                    else
848                    {
849                        $jobs[$jobid][$toganame] = $togavalue;
850                    }
851                }
[111]852
[721]853                if( isset( $jobs[$jobid]['nodes'] ) )
854                {
855                    $nr_nodes = count( $jobs[$jobid]['nodes'] );
856       
857                    if( $jobs[$jobid]['status'] == 'R' )
858                    {
[111]859
[721]860                        if( isset( $jobs[$jobid]['domain'] ) )
861                        {
862                            $domain        = $jobs[$jobid]['domain'];
863                            $domain_len    = 0 - strlen( $domain );
[461]864
[721]865                            // Let's see if Ganglia use's FQDN or short hostnames
866                            //
867                            foreach( $nodes as $hostname => $nimage )
868                            {
869                   
870                                if( substr( $hostname, $domain_len ) != $domain )
871                                {
872                                    $this->fqdn    = 0;
873                                }
874                            }
875                        }
876                        else
877                        {
878                            $this->fqdn    = 0;
879                        }
[459]880
[721]881                        foreach( $jobs[$jobid]['nodes'] as $node )
882                        {
[200]883
[721]884                            // Only add domain name to the hostname if Ganglia is doing that too
885                            //
886                            if( $this->fqdn && isset( $jobs[$jobid]['domain'] ) )
887                            {
888                                if( substr( $node, $domain_len ) != $domain )
889                                {
890                                    $host = $node. '.'.$domain;
891                                } else
892                                {
893                                    $host = $node;
894                                }
895                            }
896                            else
897                            {
898                                $host    = $node;
899                            }
[300]900
[721]901                            if( !isset( $nodes[$host] ) )
902                            {
903                                $my_node = new NodeImage( $this->proc_cluster, $host );
904                            }
905                            else
906                            {
907                                $my_node = $nodes[$host];
908                            }
[111]909
[721]910                            if( !$my_node->hasJob( $jobid ) )
911                            {
912                                if( isset( $jobs[$jobid]['ppn'] ) )
913                                {
914                                    $my_node->addJob( $jobid, ((int) $jobs[$jobid]['ppn']) );
915                                }
916                                else
917                                {
918                                    $my_node->addJob( $jobid, 1 );
919                                }
920                            }
[111]921
[721]922                            $nodes[$host] = $my_node;
923                        }
924                    }
925                }
926            }
927        }
928        $this->jobs    = $jobs;
929        $this->nodes    = $nodes;
930    }
[103]931
[721]932    function stopElement( $parser, $name )
933    {
934        $nodes    = $this->nodes;
[514]935
[721]936        if( $name == "GANGLIA_XML" )
937        {
938            if( sizeof( $this->down_nodes ) > 0 )
939            {
940                foreach( $this->down_nodes as $reported => $dnodes )
941                {
942                    if( $reported == $this->heartbeat['time'] )
943                    {
944                        $domain = $dnodes[1];
[514]945
[721]946                        foreach( $dnodes[0] as $downhost )
947                        {
948                            $downhost = $this->makeHostname( $downhost, $domain );
[518]949
[721]950                            if( isset( $nodes[$downhost] ) )
951                            {
952                                // OMG PHP4 is fking stupid!
953                                // $nodes[$downhost]->setDown( 1 ) won't work here..
954                                //
955                                $mynode = $nodes[$downhost];
956                                $mynode->setDown( 1 );
957                                $nodes[$downhost] = $mynode;
958                            }
959                        }
960                    }
961                }
962            }
[514]963
[721]964            if( sizeof( $this->offline_nodes ) > 0 )
965            {
966                foreach( $this->offline_nodes as $reported => $onodes )
967                {
968                    if( $reported == $this->heartbeat['time'] )
969                    {
970                        $domain = $onodes[1];
[514]971
[721]972                        foreach( $onodes[0] as $offlinehost )
973                        {
974                            $offlinehost = $this->makeHostname( $offlinehost, $domain );
[518]975
[721]976                            if( isset( $nodes[$offlinehost] ) )
977                            {
978                                // OMG PHP4 is fking stupid!
979                                // $nodes[$offlinehost]->setDown( 1 ) won't work here..
980                                //
981                                $mynode = $nodes[$offlinehost];
982                                $mynode->setOffline( 1 );
983                                $nodes[$offlinehost] = $mynode;
984                            }
985                        }
986                    }
987                }
988            }
989        }
[514]990
[721]991        $this->nodes = $nodes;
992    }
[105]993
[721]994    function printInfo()
995    {
996        $jobs = &$this->jobs;
[105]997
[721]998        printf( "---jobs---\n" );
[105]999
[721]1000        foreach( $jobs as $jobid => $job )
1001        {
1002            printf( "job %s\n", $jobid );
[105]1003
[721]1004            if( isset( $job['nodes'] ) )
1005            {
1006                foreach( $job['nodes'] as $node )
1007                {
1008                    $mynode = $this->nodes[$node];
1009                    $hostname = $mynode->getHostname();
1010                    $location = $mynode->getLocation();
[105]1011
[721]1012                    printf( "\t- node %s\tlocation %s\n", $hostname, $location );
1013                }
1014            }
1015        }
[105]1016
[721]1017        printf( "---nodes---\n" );
[105]1018
[721]1019        $nodes = &$this->nodes;
[105]1020
[721]1021        foreach( $nodes as $node )
1022        {
1023            $hostname = $node->getHostname();
1024            $location = $node->getLocation();
1025            $jobs = implode( ' ', $node->getJobs() );
1026            printf( "* node %s\tlocation %s\tjobs %s\n", $hostname, $location, $jobs );
1027        }
1028    }
[106]1029
[721]1030    function getNodes()
1031    {
1032        return $this->nodes;
1033    }
[106]1034
[721]1035    function getNode( $node )
1036    {
1037        $nodes = &$this->nodes;
[303]1038
[721]1039        if( isset( $nodes[$node] ) )
1040        {
1041            return $nodes[$node];
1042        }
1043        else
1044        {
1045            return NULL;
1046        }
1047    }
[303]1048
[721]1049    function getJobs()
1050    {
1051        return $this->jobs;
1052    }
[114]1053
[721]1054    function getJob( $job )
1055    {
1056        $jobs = &$this->jobs;
[303]1057
[721]1058        if( isset( $jobs[$job] ) )
1059        {
1060            return $jobs[$job];
1061        }
1062        else
1063        {
1064            return NULL;
1065        }
1066    }
[303]1067
[721]1068    function getHeartbeat()
1069    {
1070        return $this->heartbeat['time'];
1071    }
[103]1072}
1073
[519]1074class NodeImage
1075{
[721]1076    var $image, $x, $y, $hostname, $jobs, $tasks, $showinfo;
[102]1077
[721]1078    function NodeImage( $cluster, $hostname )
1079    {
1080        global $SMALL_CLUSTERIMAGE_NODEWIDTH;
[305]1081
[721]1082        $this->jobs        = array();
1083        $this->tasks        = 0;
1084        $this->hostname        = $hostname;
1085        $this->clustername    = $cluster;
1086        $this->showinfo        = 1;
1087        $this->size        = $SMALL_CLUSTERIMAGE_NODEWIDTH;
1088        $this->down        = 0;
1089        $this->offline        = 0;
1090    }
[102]1091
[721]1092    function addJob( $jobid, $cpus )
1093    {
1094        $jobs        = &$this->jobs;
1095        $jobs[]        = $jobid;
1096        $this->jobs    = $jobs;
[111]1097
[721]1098        $this->addTask( $cpus );
1099    }
[111]1100
[721]1101    function hasJob( $jobid )
1102    {
1103        $jobfound = 0;
[111]1104
[721]1105        if( count( $this->jobs ) > 0 )
1106        {
1107            foreach( $this->jobs as $job )
1108            {
1109                if( $job == $jobid )
1110                {
1111                    $jobfound = 1;
1112                }
1113            }
1114        }
[111]1115
[721]1116        return $jobfound;
1117    }
[111]1118
[721]1119    function addTask( $cpus )
1120    {
1121        $this->tasks = $this->tasks + $cpus;
1122    }
1123    function setDown( $down )
1124    {
1125        $this->down = $down;
1126    }
1127    function isDown()
1128    {
1129        return $this->down;
1130    }
1131    function setOffline( $offline )
1132    {
1133        $this->offline = $offline;
1134    }
1135    function isOffline()
1136    {
1137        return $this->offline;
1138    }
1139    function setImage( $image )
1140    {
1141        $this->image = $image;
1142    }
1143    function setCoords( $x, $y )
1144    {
1145        $this->x = $x;
1146        $this->y = $y;
1147    }
1148    function getX()
1149    {
1150        return $this->x;
1151    }
1152    function getY()
1153    {
1154        return $this->y;
1155    }
[106]1156
[721]1157    function getImagemapArea()
1158    {
1159        $area_topleft        = $this->x . "," . $this->y;
1160        $area_bottomright    = ($this->x + $this->size) . "," . ($this->y + $this->size);
1161        $area_coords        = $area_topleft . "," . $area_bottomright;
[326]1162
[721]1163        $area_href        = "./?c=" . $this->clustername . "&h=" . $this->hostname;
[326]1164
[721]1165        $area_tooltip        = $this->hostname;
[514]1166
[721]1167        if( $this->down)
1168        {
1169            $area_tooltip        = $area_tooltip . ": DOWN";
1170        }
1171        else if( $this->offline )
1172        {
1173            $area_tooltip        = $area_tooltip . ": OFFLINE";
1174        }
[514]1175
[721]1176        $area_tooltip        = $area_tooltip . ": " . implode( " ", $this->jobs );
[514]1177
[721]1178        $tag_href        = "HREF=\"" . $area_href . "\"";
1179        $tag_coords        = "COORDS=\"" . $area_coords . "\"";
1180        $tag_tooltip1        = "ALT=\"" . $area_tooltip . "\"";
1181        $tag_tooltip2        = "TITLE=\"" . $area_tooltip . "\"";
[326]1182
[721]1183        return ("<AREA SHAPE=\"RECT\" " . $tag_coords . " " . $tag_href . " " . $tag_tooltip1 . " " . $tag_tooltip2 . ">");
1184    }
[326]1185
[721]1186    function colorHex( $color )
1187    {
1188        $my_color = imageColorAllocate( $this->image, hexdec( substr( $color, 0, 2 )), hexdec( substr( $color, 2, 2 )), hexdec( substr( $color, 4, 2 )) );
[102]1189
[721]1190        return $my_color;
1191    }
[102]1192
[721]1193    function setLoad( $load )
1194    {
1195        $this->load = $load;
1196    }
[106]1197
[721]1198    function setHostname( $hostname )
1199    {
1200        $this->hostname = $hostname;
1201    }
[108]1202
[721]1203    function getHostname()
1204    {
1205        return $this->hostname;
1206    }
[122]1207
[721]1208    function getJobs()
1209    {
1210        return $this->jobs;
1211    }
[114]1212
[721]1213    function setShowinfo( $showinfo )
1214    {
1215        $this->showinfo = $showinfo;
1216    }
[122]1217
[721]1218    function drawSmall()
1219    {
1220        global $SMALL_CLUSTERIMAGE_NODEWIDTH;
[305]1221
[721]1222        $this->size    = $SMALL_CLUSTERIMAGE_NODEWIDTH;
[305]1223
[721]1224        $this->draw();
1225    }
[110]1226
[721]1227    function drawBig()
1228    {
1229        global $BIG_CLUSTERIMAGE_NODEWIDTH;
[305]1230
[721]1231        $this->size    = $BIG_CLUSTERIMAGE_NODEWIDTH;
[305]1232
[721]1233        $this->draw();
1234    }
[106]1235
[721]1236    function draw()
1237    {
1238        global $JOB_NODE_MARKING, $NODE_DOWN_MARKING, $NODE_OFFLINE_MARKING;
[102]1239
[721]1240        $black_color = imageColorAllocate( $this->image, 0, 0, 0 );
1241        $size = $this->size;
[107]1242
[721]1243        imageFilledRectangle( $this->image, $this->x, $this->y, $this->x+($size), $this->y+($size), $black_color );
[110]1244
[721]1245        if( $this->showinfo)
1246        {
1247            $this->load = $this->determineLoad();
[111]1248
[721]1249            if( !isset( $this->image ) or !isset( $this->x ) or !isset( $this->y ) )
1250            {
1251                printf( "aborting\n" );
1252                printf( "x %d y %d load %f\n", $this->x, $this->y, $load );
1253                return;
1254            }
[111]1255
[721]1256            // Convert Ganglias Hexadecimal load color to a Decimal one
1257            //
1258            $load = $this->determineLoad();   
1259            $usecolor = $this->colorHex( load_color($load) );
1260            imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-1), $this->y+($size-1), $usecolor );
1261            if( $this->down )
1262            {
1263                imageString( $this->image, 1, $this->x+(($size/2)-1), $this->y+(($size/2)-4), $NODE_DOWN_MARKING, $black_color );
1264            }
1265            else if( $this->offline )
1266            {
1267                imageString( $this->image, 1, $this->x+(($size/2)-1), $this->y+(($size/2)-4), $NODE_OFFLINE_MARKING, $black_color );
1268            }
1269            else if( count( $this->jobs ) > 0 )
1270            {
1271                imageString( $this->image, 1, $this->x+(($size/2)-1), $this->y+(($size/2)-4), $JOB_NODE_MARKING, $black_color );
1272            }
1273        }
1274        else
1275        {
1276            // White
1277            $usecolor = imageColorAllocate( $this->image, 255, 255, 255 );
1278            imageFilledRectangle( $this->image, $this->x+1, $this->y+1, $this->x+($size-1), $this->y+($size-1), $usecolor );
1279        }
1280    }
[102]1281
[742]1282    function determineLoad()
[721]1283    {
1284        global $metrics;
[108]1285
[721]1286        $cpus = $metrics[$this->hostname]['cpu_num']['VAL'];
1287        if (!$cpus)
1288        {
1289            $cpus=1;
1290        }
[519]1291
[721]1292        $load_one    = $metrics[$this->hostname]['load_one']['VAL'];
[742]1293        $load        = ((float) $load_one)/$cpus;
[102]1294
[721]1295        return $load;
1296    }
[106]1297}
1298
[519]1299class ClusterImage
1300{
[721]1301    var $dataget, $image, $clustername;
1302    var $filtername, $filters;
[106]1303
[721]1304    function ClusterImage( $data, $clustername )
1305    {
1306        $this->dataget        = new DataGatherer( $clustername );
1307        $this->data        = $data;
1308        $this->clustername    = $clustername;
1309        $this->filters        = array();
1310        $this->size        = 's';
1311        $this->width        = 0;
1312        $this->height        = 0;
1313        $this->output        = 1;
[743]1314        $this->jobs         = null;
1315        $this->nodes        = null;
[721]1316    }
[106]1317
[721]1318    function getWidth()
1319    {
1320        return $this->width;
1321    }
1322    function getHeight()
1323    {
1324        return $this->height;
1325    }
1326    function setSmall()
1327    {
1328        $this->size    = 's';
1329    }
1330    function setBig()
1331    {
1332        $this->size    = 'b';
1333    }
1334    function setNoimage()
1335    {
1336        $this->output    = 0;
1337    }
[743]1338    function setJobs($jobs )
1339    {
1340        $this->jobs     = &$jobs;
1341    }
1342    function getJobs()
1343    {
1344        if( $this->jobs == null )
1345        {
1346            $mydatag = $this->dataget;
1347            $mydatag->parseXML( $this->data );
1348            $this->jobs = $mydatag->getJobs();
1349        }
1350
1351        return $this->jobs;
1352    }
1353    function getNodes()
1354    {
1355        if( $this->nodes== null )
1356        {
1357            $mydatag = $this->dataget;
1358            $mydatag->parseXML( $this->data );
1359            $this->nodes = $mydatag->getNodes();
1360        }
1361
1362        return $this->nodes;
1363    }
1364    function setNodes($nodes)
1365    {
1366        $this->nodes    = &$nodes;
1367    }
[721]1368    function isSmall()
1369    {
1370        return ($this->size == 's');
1371    }
1372    function isBig()
1373    {
1374        return ($this->size == 'b');
1375    }
1376    function setFilter( $filtername, $filtervalue )
1377    {
1378        $this->filters[$filtername] = $filtervalue;
1379    }
[122]1380
[721]1381    function filterNodes( $jobs, $nodes )
1382    {
1383        $filtered_nodes = array();
[122]1384
[743]1385        //print_r( $nodes );
1386
[721]1387        foreach( $nodes as $node )
1388        {
1389            $hostname = $node->getHostname();
[122]1390
[721]1391            $addhost = 1;
[122]1392
[721]1393            if( count( $this->filters ) > 0 )
1394            {
1395                $mynjobs = $node->getJobs();
[124]1396
[721]1397                if( count( $mynjobs ) > 0 )
1398                {
1399                    foreach( $mynjobs as $myjob )
1400                    {
1401                        foreach( $this->filters as $filtername => $filtervalue )
1402                        {
1403                            if( $filtername!=null && $filtername!='' )
1404                            {
1405                                if( $filtername == 'jobid' && !$node->hasJob( $filtervalue) )
1406                                {
1407                                    $addhost = 0;
1408                                }
1409                                else if( $filtername != 'jobid' )
1410                                {
1411                                    if( $jobs[$myjob][$filtername] != $filtervalue )
1412                                    {
1413                                        $addhost = 0;
1414                                    }
1415                                }
1416                            }
1417                        }
1418                    }
1419                }
1420                else
1421                {
1422                    $addhost = 0;
1423                }
1424            }
[124]1425
[721]1426            if( $addhost )
1427            {
1428                $filtered_nodes[] = $hostname;
1429            }
1430        }
[122]1431
[721]1432        return $filtered_nodes;
1433    }
[122]1434
[721]1435    function draw()
1436    {
1437        global $SMALL_CLUSTERIMAGE_MAXWIDTH, $SMALL_CLUSTERIMAGE_NODEWIDTH;
1438        global $BIG_CLUSTERIMAGE_MAXWIDTH, $BIG_CLUSTERIMAGE_NODEWIDTH;
1439        global $CLUSTER_CONFS, $confcluster, $SHOW_EMPTY_COLUMN, $SHOW_EMPTY_ROW;
[329]1440
[721]1441        global $SORTBY_HOSTNAME, $SORT_ORDER, $skan_str;
1442        global $x_first, $y_first;
[331]1443
[721]1444        foreach( $CLUSTER_CONFS as $confcluster => $conffile )
1445        {
1446            if( strtolower( trim($this->clustername) ) == strtolower(trim($confcluster)) )
1447            {
1448                include_once $conffile;
1449            }
1450        }
[337]1451
[721]1452        if( $this->isSmall() )
1453        {
1454            $max_width    = $SMALL_CLUSTERIMAGE_MAXWIDTH;
1455            $node_width    = $SMALL_CLUSTERIMAGE_NODEWIDTH;
1456        }
1457        else if( $this->isBig() )
1458        {
1459            $max_width    = $BIG_CLUSTERIMAGE_MAXWIDTH;
1460            $node_width    = $BIG_CLUSTERIMAGE_NODEWIDTH;
1461        }
[106]1462
[743]1463        $nodes        = $this->getNodes();
[721]1464        $nodes_hosts    = array_keys( $nodes );
[106]1465
[721]1466        $nodes_nr    = count( $nodes );
[106]1467
[721]1468        $nodes_size    = $nodes_nr*$node_width;
1469        $node_rows    = 0;
[106]1470
[721]1471        if( $nodes_size > $max_width )
1472        {
1473            $nodes_per_row = ( (int) ($max_width/$node_width) );
1474        }
1475        else
1476        {
1477            $nodes_per_row = $nodes_size;
1478            $node_rows = 1;
1479        }
[106]1480
[721]1481        if( $nodes_per_row < $nodes_nr )
1482        {
1483            $node_rows = ( (int) ($nodes_nr/$nodes_per_row) );
1484            $node_rest = fmod( $nodes_nr, $nodes_per_row );
[519]1485
[721]1486            if( $node_rest > 0 )
1487            {
1488                $node_rows++;
1489            }
1490        }
[106]1491
[721]1492        $y_offset    = 0;
1493        $font         = 2;
1494        $fontwidth    = ImageFontWidth( $font );
1495        $fontheight    = ImageFontHeight( $font );
1496        $fontspaceing    = 2;
1497        $y_offset    = $fontheight + (2 * $fontspaceing);
[306]1498
[721]1499        $this->width    = $max_width;
1500        $this->height    = ($y_offset + (($node_rows*$node_width)+1) );
[326]1501
[743]1502        $jobs = $this->getJobs();
[721]1503        $filtered_nodes = $this->filterNodes( $jobs, $nodes );
[122]1504
[721]1505        if( $SORTBY_HOSTNAME != "" )
1506        {
1507                $sorted     = array();
[329]1508
[721]1509            $x_first    = 0;
1510            $y_first    = 0;
[329]1511
[721]1512            $skan_str    = $SORTBY_HOSTNAME;
[329]1513
[721]1514            global $x_present, $y_present;
1515            $x_present    = false;
1516            $y_present    = false;
[339]1517
[721]1518            // Should we scan by X, Y or both
1519            //
1520            if(strpos( $SORTBY_HOSTNAME, "{x}" ) != false )
1521            {
1522                $x_str        = "{x}";
1523                $x_present    = true;
1524            }
1525            else if(strpos( $SORTBY_HOSTNAME, "{X}" ) != false )
1526            {
1527                $x_str        = "{X}";
1528                $x_present    = true;
1529            }
1530            if(strpos( $SORTBY_HOSTNAME, "{y}" ) != false )
1531            {
1532                $y_str        = "{y}";
1533                $y_present    = true;
1534            }
1535            else if(strpos( $SORTBY_HOSTNAME, "{Y}" ) != false )
1536            {
1537                $y_str        = "{Y}";
1538                $y_present    = true;
1539            }
[339]1540
[721]1541            // If we should scan for both X and Y: see which one is first
1542            //
1543            if(( strpos( $SORTBY_HOSTNAME, $x_str ) < strpos( $SORTBY_HOSTNAME, $y_str ) ) && ( $x_present && $y_present ))
1544            {
1545                $x_first    = 1;
1546            }
1547            else if(( strpos( $SORTBY_HOSTNAME, $x_str ) > strpos( $SORTBY_HOSTNAME, $y_str ) ) && ( $x_present && $y_present ))
1548            {
1549                $y_first    = 1;
1550       
1551            }
1552            else if( $x_present )
1553            {
1554                $x_first    = 1;
1555            }
1556            else if( $y_present )
1557            {
1558                $y_first    = 1;
1559            }
[329]1560
[721]1561            // Now replace our {x} and {y} with %d for sscanf parsing
1562            //
1563            if(( $x_first ) && ( $x_present && $y_present ) )
1564            {
1565                $skan_str    = str_replace( $x_str, "%d", $skan_str );
1566                $skan_str    = str_replace( $y_str, "%d", $skan_str );
1567            } 
1568            else if( $x_present)
1569            {
1570                $skan_str    = str_replace( $x_str, "%d", $skan_str );
1571            }
1572            else if( $y_present)
1573            {
1574                $skan_str    = str_replace( $y_str, "%d", $skan_str );
1575            }
[329]1576
[721]1577            $x_min        = null;
1578            $x_max        = null;
1579            $y_min        = null;
1580            $y_max        = null;
[329]1581
[721]1582            $x_columns    = array();
1583            $y_rows        = array();
[522]1584
[721]1585            // Now let's walk through all our nodes and see which one are valid for our scan pattern
1586            //
1587            foreach( $nodes as $hostname => $node )
1588            {
1589                $x    = null;
1590                $y    = null;
[339]1591
[721]1592                if( $x_present && $y_present )
1593                {
1594                    if( $x_first )
1595                    {
1596                        $n = sscanf( $hostname, $skan_str, $x, $y );
1597                    }
1598                    else if( $y_first )
1599                    {
1600                        $n = sscanf( $hostname, $skan_str, $y, $x );
1601                    }
[463]1602
[721]1603                    // Remove nodes that don't match
1604                    //
1605                    if( $n < 2 )
1606                    {
1607                        // This node hostname has no match for: {x} and {y}
1608                        //
1609                        unset( $nodes[$hostname] );
1610                    }
1611                }
1612                else if( $x_present && !$y_present )
1613                {
1614                    $n = sscanf( $hostname, $skan_str, $x );
[463]1615
[721]1616                    // Remove nodes that don't match
1617                    //
1618                    if( $n < 1 )
1619                    {
1620                        // This node hostname has no match for: {x}
1621                        //
1622                        unset( $nodes[$hostname] );
1623                    }
1624                    $y    = 1;
1625                }
1626                else if( $y_present && !$x_present )
1627                {
1628                    $n = sscanf( $hostname, $skan_str, $y );
[463]1629
[721]1630                    // Remove nodes that don't match
1631                    //
1632                    if( $n < 1 )
1633                    {
1634                        // This node hostname has no match for: {y}
1635                        //
1636                        unset( $nodes[$hostname] );
1637                    }
1638                    $x    = 1;
1639                }
[329]1640
[721]1641                // Determine the lowest value of {x} that exists in all node hostnames
1642                //
1643                if( !$x_min && $x != null )
1644                {
1645                    $x_min    = $x;
1646                }
1647                else if( $x < $x_min && $x != null )
1648                {
1649                    $x_min    = $x;
1650                }
[463]1651
[721]1652                // Determine the highest value of {x} that exists in all node hostnames
1653                //
1654                if( !$x_max && $x != null )
1655                {
1656                    $x_max    = $x;
1657                }
1658                else if( $x > $x_max && $x != null )
1659                {
1660                    $x_max    = $x;
1661                }
[463]1662
[721]1663                // Determine the lowest value of {y} that exists in all node hostnames
1664                //
1665                if( !$y_min && $y != null )
1666                {
1667                    $y_min    = $y;
1668                }
1669                else if( $y < $y_min && $y != null )
1670                {
1671                    $y_min    = $y;
1672                }
[463]1673
[721]1674                // Determine the highest value of {y} that exists in all node hostnames
1675                //
1676                if( !$y_max && $y != null )
1677                {
1678                    $y_max    = $y;
1679                }
1680                else if( $y > $y_max && $y != null )
1681                {
1682                    $y_max    = $y;
1683                }
[522]1684
[721]1685                // Store which non-empty columns and rows we found
1686                //
1687                if( !in_array( $x, $x_columns ) )
1688                {
1689                    $x_columns[] = $x;
1690                }
1691                if( !in_array( $y, $y_rows ) )
1692                {
1693                    $y_rows[] = $y;
1694                }
1695            }
[329]1696
[721]1697            // Sort all the nodes (alpha and numerically)
1698            // 1: gb-r1n1, 2: gb-r1n2, 3: gb-r2n1, etc
1699            //
1700            $sorted_nodes    = usort( $nodes, "cmp" );
[329]1701
[721]1702            //print_r( $x_columns ) ;
[522]1703
[721]1704            $cur_node    = 0;
[329]1705
[721]1706            $x_offset    = 0;
1707            $y_offset    = 0;
1708            $font         = 2;
1709            $fontwidth    = ImageFontWidth( $font );
1710            $fontheight    = ImageFontHeight( $font );
1711            $fontspaceing    = 2;
[331]1712
[721]1713            if( $this->isSmall() ) 
1714            {
1715                $y_offset    = $y_offset + (2 * $fontspaceing) + $fontheight;
1716            }
[333]1717
[721]1718            if( $this->isBig() ) 
1719            {
1720                $y_offset    = ($fontheight * (1 + strlen( $x_max) ) ) + ((2 + strlen( $x_max)) * $fontspaceing);
1721                $x_offset    = ($fontwidth * (1 + strlen( $y_max) ) ) + ((2 + strlen( $y_max)) * $fontspaceing);
1722            }
[331]1723
[721]1724            $image_width    = $x_offset + ($node_width * ($x_max-$x_min+2));
[428]1725
[721]1726            if( $this->isSmall() ) 
1727            {
1728                $image_width    = $max_width;
1729            }
1730            else if( $this->isBig() ) 
1731            {
1732                $image_width    = ($image_width < $max_width) ? $image_width : $max_width;
1733            }
1734            $image_height    = $y_offset + ($node_width * ($y_max-$y_min+2));
[330]1735
[721]1736            $this->width    = $image_width;
1737            $this->heigth    = $image_heigth;
[330]1738
[721]1739            $image        = imageCreateTrueColor( $image_width, $image_height );
1740            $colorwhite    = imageColorAllocate( $image, 255, 255, 255 );
[329]1741
[721]1742            imageFill( $image, 0, 0, $colorwhite );
[329]1743
[721]1744            if( $this->isSmall() )
1745            {
1746                // Draw a fancy little header text to explain what it is
1747                //
1748                $colorblue    = imageColorAllocate( $image, 0, 0, 255 );
[333]1749
[721]1750                imageString( $image, $font, 2, 2, "Monarch Joblist - cluster: ".$this->clustername, $colorblue );
1751            }
[333]1752
[721]1753            if( $this->isBig() && ( isset( $SORT_XLABEL ) || isset( $SORT_YLABEL ) ) )
1754            {
1755                $colorblue    = imageColorAllocate( $image, 0, 0, 255 );
[329]1756
[721]1757                if( isset( $SORT_XLABEL ) )
1758                {
1759                    // Print the {x} label: rack
1760                    //
1761                    imageString( $image, $font, $x_offset, $fontspaceing, $SORT_XLABEL, $colorblue );
1762                }
[329]1763
[721]1764                if( isset( $SORT_YLABEL ) )
1765                {
1766                    // Stupid php without imageStringDown function... we'll make one ourself
1767                    //
[463]1768
[721]1769                    // Print the {y} label: node
1770                    //
1771                    imageStringDown( $image, $font, $fontspaceing, $y_offset, $SORT_YLABEL, $colorblue );
1772                }
1773            }
[329]1774
[721]1775            $previous_n    = 0;
1776            $previous_m    = 0;
1777            $x_empty_count    = 0;
1778            $y_empty_count    = 0;
[522]1779
[721]1780            // Let's start assigning x,y coordinates now
1781            //
1782            for( $n = $x_min; $n <= $x_max; $n++ )
1783            {
1784                for( $m = $y_min; $m <= $y_max; $m++ )
1785                {
1786                    if( $x_min > 0 )
1787                    {
1788                        $x    = $x_offset + ( ($n-$x_min) * $node_width ) - ($x_empty_count * $node_width);
1789                    }
1790                    if( $y_min > 0 )
1791                    {
1792                        $y    = $y_offset + ( ($m-$y_min) * $node_width ) - ($y_empty_count * $node_width);
1793                    }
[329]1794
[721]1795                    // Don't show empty rows/columns if option enabled
1796                    //
1797                    if( !in_array( $n, $x_columns ) && !$SHOW_EMPTY_COLUMN )
1798                    {
1799                        // Skip to next iteration: we don't want a empty column
1800                        //
1801                        if( $n > $previous_n )
1802                        {
1803                            $previous_n = $n;
1804                            $x_empty_count++;
1805                        }
1806                        continue;
1807                    }
1808                    if( !in_array( $m, $y_rows ) && !$SHOW_EMPTY_ROW )
[522]1809
[721]1810                    {
1811                        // Skip to next iteration: we don't want a empty column
1812                        //
1813                        if( $m > $previous_m )
1814                        {
1815                            $previous_m = $m;
1816                            $y_empty_count++;
1817                        }
1818                        continue;
1819                    }
[522]1820
[721]1821                    if( $this->isBig() ) 
1822                    {
1823                        // Draw y(node) column number header
1824                        //
1825                        if(( $n == $x_min ) && ( isset($SORT_YLABEL) ) )
1826                        {
1827                            $mfontspacing    = 1;
[463]1828
[721]1829                            $ylabel_x    = $x - ( $fontwidth * strlen( $y_max ) ) - $mfontspacing;
1830                            $ylabel_y    = $y;
[463]1831
[721]1832                            imageString( $image, $font, $ylabel_x, $ylabel_y, strval( $m ), $colorblue );
[463]1833
[721]1834                            $xmin_hit[$n]    = true;
1835                        }
[463]1836
[721]1837                        // Draw x(rack) column number header
1838                        //
1839                        if(( $m == $y_min ) && ( isset($SORT_XLABEL) ) )
1840                        {
1841                            $mfontspacing    = 2;
1842                            $xlabel_y    = $y - ( $fontheight * strlen( $x_max ) );
1843                            $xlabel_x    = $x + $mfontspacing; 
[463]1844
[721]1845                            imageStringDown( $image, $font, $xlabel_x, $xlabel_y, strval( $n ), $colorblue );
1846                        }
1847                    }
[463]1848
[721]1849                    if( isset( $nodes[$cur_node] ) ) 
1850                    {
1851                        $host    = $nodes[$cur_node]->getHostname();
[329]1852
[721]1853                        if( $x_present && $y_present )
1854                        {
1855                            if( $x_first )
1856                            {
1857                                $nn = sscanf( $host, $skan_str, $rx, $ry );
1858                            }
1859                            else if( $y_first )
1860                            {
1861                                $nn = sscanf( $host, $skan_str, $ry, $rx );
1862                            }
1863                            if ( $nn < 2 )
1864                            {
1865                                //printf( "skipping node %s - y present & x present + <2 x,y matchs\n", $host);
1866                                continue;
1867                            }
1868                            if( intval( $rx ) > $n )
1869                            {
1870                                // If x(rack) is higher than current x, skip to next x(rack)
1871                                //
1872                                $m        = $y_max + 1;
[463]1873
[721]1874                                continue;
1875                            }
1876                            if( intval( $ry ) > $m )
1877                            {
1878                                // If y(node) is higher than current y, skip to next y(node)
1879                                //
1880                                continue;
1881                            }
1882                        }
1883                        else if( $x_present )
1884                        {
1885                            $nn = sscanf( $host, $skan_str, $rx );
1886                        }
1887                        else if( $y_present )
1888                        {
1889                            $nn = sscanf( $host, $skan_str, $ry );
1890                        }
[329]1891
[721]1892                        if( !in_array( $host, $filtered_nodes ) )
1893                        {
1894                            // This node has been filtered out: we only want to see certain nodes
1895                            //
1896                            $nodes[$cur_node]->setShowinfo( 0 );
1897                        }
[329]1898
[721]1899                        $nodes[$cur_node]->setCoords( $x, $y );
1900                        $nodes[$cur_node]->setImage( $image );
[329]1901
[721]1902                        if( $this->isSmall() )
1903                        {
1904                            $nodes[$cur_node]->drawSmall();
1905                        }
1906                        else if( $this->isBig() )
1907                        {
1908                            $nodes[$cur_node]->drawBig();
1909                        }
[404]1910
[721]1911                        $cur_node++;
1912                    }
1913                }
1914            }
[329]1915
[721]1916        }
1917        else
1918        {
1919            if( $this->isSmall() )
1920            {
1921                $image        = imageCreateTrueColor( $max_width, ($y_offset + (($node_rows*$node_width)+1) ) );
1922            }
1923            else if( $this->isBig() )
1924            {
1925                $image_width    = ($node_width * $nodes_nr) + 2;
1926                $image_width    = ($image_width < $max_width) ? $image_width : $max_width;
1927                $image        = imageCreateTrueColor( $image_width, ($y_offset + (($node_rows*$node_width)+1) ) );
1928            }
1929            $colorwhite    = imageColorAllocate( $image, 255, 255, 255 );
[329]1930
[721]1931            imageFill( $image, 0, 0, $colorwhite );
[329]1932
[721]1933            if( $this->isSmall() )
1934            {
1935                $colorblue    = imageColorAllocate( $image, 0, 0, 255 );
[329]1936
[721]1937                imageString( $image, $font, 2, 2, "Monarch Joblist - cluster: ".$this->clustername, $colorblue );
1938            }
[329]1939
[721]1940            for( $n = 0; $n < $node_rows; $n++ )
1941            {
1942                for( $m = 0; $m < $nodes_per_row; $m++ )
1943                {
1944                    $x = ($m * $node_width);
1945                    $y = $y_offset + ($n * $node_width);
[107]1946
[721]1947                    $cur_node = ($n * $nodes_per_row) + ($m);
1948                    $host = isset( $nodes_hosts[$cur_node] ) ? $nodes_hosts[$cur_node] : '';
[107]1949
[721]1950                    if( isset( $nodes[$host] ) )
1951                    {
1952                        $nodes[$host]->setCoords( $x, $y );
1953                        $nodes[$host]->setImage( $image );
[122]1954
[721]1955                        if( !in_array( $host, $filtered_nodes ) )
1956                        {
1957                            $nodes[$host]->setShowinfo( 0 );
1958                        }
[122]1959
[721]1960                        if( $this->isSmall() )
1961                        {
1962                            $nodes[$host]->drawSmall();
1963                        }
1964                        else if( $this->isBig() )
1965                        {
1966                            $nodes[$host]->drawBig();
1967                        }
1968                    }
1969                }
1970            }
1971        }
1972   
1973        $this->nodes    = &$nodes;
[326]1974
[721]1975        if ($this->output)
1976        {
1977            header( 'Content-type: image/png' );
1978            imagePNG( $image );
1979            imageDestroy( $image );
1980        }
1981    }
[326]1982
[721]1983    function getImagemapArea()
1984    {
1985        $clusterimage_map    = "";
[326]1986
[721]1987        foreach( $this->nodes as $hostname => $node )
1988        {
1989            $node_map        = $node->getImagemapArea();
1990            $clusterimage_map    .= $node_map;
1991        }
[326]1992
[721]1993        return $clusterimage_map;
1994    }
[102]1995}
1996
[519]1997class EmptyImage
1998{
[721]1999    function draw()
2000    {
2001        $image        = imageCreateTrueColor( 1, 1 );
2002        $colorwhite    = imageColorAllocate( $image, 255, 255, 255 );
2003        imageFill( $image, 0, 0, $colorwhite );                         
[298]2004
[721]2005        header( 'Content-type: image/png' );
2006        imagePNG( $image );
2007        imageDestroy( $image );
2008    }
[298]2009}
2010
[519]2011class HostImage
2012{
[721]2013    var $data_gather, $cluster, $host, $node, $image;
2014    var $headerstrlen;
[303]2015
[721]2016    function HostImage( $data_gather, $cluster, $host )
2017    {
2018        $this->data_gather     = $data_gather;
2019        $this->cluster        = $cluster;
2020        $this->host        = $host;
2021        $this->y_offset        = 0;
2022        $this->font        = 2;
2023        $this->fontspaceing    = 2;
2024        $this->headerstrlen    = array();
[303]2025
[721]2026        $this->fontheight    = ImageFontHeight( $this->font );
2027        $this->fontwidth    = ImageFontWidth( $this->font );
[303]2028
[721]2029        $dg            = &$this->data_gather;
2030        $this->node        = &$dg->getNode( $this->host );
2031        $n            = &$this->node;
2032        $this->njobs        = $n->getJobs();
2033    }
[303]2034
[721]2035    function drawJobs()
2036    {
2037        $dg                     = &$this->data_gather;
2038        $colorblack        = imageColorAllocate( $this->image, 0, 0, 0 );
[303]2039
[721]2040        for( $n = 0; $n < count( $this->njobs ); $n++ )
2041        {
2042            $jobid            = $this->njobs[$n];
2043            $jobinfo        = $dg->getJob( $jobid );
[303]2044
[721]2045            $xoffset        = 5;
2046            imageString( $this->image, $this->font, $xoffset, $this->y_offset, strval( $jobid ), $colorblack );
[303]2047
[721]2048            foreach( $this->headerstrlen as $headername => $headerlen )
2049            {
2050                if( $headername == 'nodes' )
2051                {
2052                    $attrval    = strval( count( $jobinfo['nodes'] ) );
2053                }
2054                else if( $headername == 'cpus' )
2055                {
2056                    if( !isset( $jobinfo['ppn'] ) )
2057                    {
2058                        $jobinfo['ppn'] = 1;
2059                    }
[303]2060
[721]2061                    $attrval    = strval( count( $jobinfo['nodes'] ) * intval( $jobinfo['ppn'] ) );
2062                }
2063                else if( $headername == 'runningtime' )
2064                {
2065                    $attrval    = makeTime( intval( $jobinfo['reported'] ) - intval( $jobinfo['start_timestamp'] ) );
2066                }
2067                else
2068                {
2069                    $attrval    = strval( $jobinfo[$headername] );
2070                }
[303]2071
[721]2072                imageString( $this->image, $this->font, $xoffset, $this->y_offset, $attrval, $colorblack );
2073       
2074                $xoffset    = $xoffset + ($this->fontwidth * ( $headerlen + 1 ) );
2075            }
2076           
2077            $this->newLineOffset();
2078        }
2079    }
[303]2080
[721]2081    function drawHeader()
2082    {
2083        $dg                     = &$this->data_gather;
[303]2084
[721]2085        for( $n = 0; $n < count( $this->njobs ); $n++ )
2086        {
2087            $jobid            = $this->njobs[$n];
2088            $jobinfo        = $dg->getJob( $jobid );
[303]2089
[721]2090            if( !isset( $this->headerstrlen['id'] ) )
2091            {
2092                $this->headerstrlen['id']    = strlen( strval( $jobid ) );
2093            }
2094            else if( strlen( strval( $jobid ) ) > $this->headerstrlen['id'] )
2095            {
2096                $this->headerstrlen['id']    = strlen( strval( $jobid ) );
2097            }
[303]2098
[721]2099            if( !isset( $this->headerstrlen['owner'] ) )
2100            {
2101                $this->headerstrlen['owner']    = strlen( strval( $jobinfo['owner'] ) );
2102            }
2103            else if( strlen( strval( $jobinfo['owner'] ) ) > $this->headerstrlen['owner'] )
2104            {
2105                $this->headerstrlen['owner']    = strlen( strval( $jobinfo['owner'] ) );
2106            }
[303]2107
[721]2108            if( !isset( $this->headerstrlen['queue'] ) )
2109            {
2110                $this->headerstrlen['queue']    = strlen( strval( $jobinfo['queue'] ) );
2111            }
2112            else if( strlen( strval( $jobinfo['queue'] ) ) > $this->headerstrlen['queue'] )
2113            {
2114                $this->headerstrlen['queue']    = strlen( strval( $jobinfo['queue'] ) );
2115            }
[303]2116
[721]2117            if( !isset( $jobinfo['ppn'] ) )
2118            {
2119                $jobinfo['ppn'] = 1;
2120            }
[303]2121
[721]2122            $cpus            = count( $jobinfo['nodes'] ) * intval( $jobinfo['ppn'] );
[303]2123
[721]2124            if( !isset( $this->headerstrlen['cpus'] ) )
2125            {
2126                $this->headerstrlen['cpus']    = strlen( strval( $cpus ) );
2127            }
2128            else if( strlen( strval( $cpus ) ) > $this->headerstrlen['cpus'] )
2129            {
2130                $this->headerstrlen['cpus']    = strlen( strval( $cpus ) );
2131            }
[303]2132
[721]2133            $nodes            = count( $jobinfo['nodes'] );
[303]2134
[721]2135            if( !isset( $this->headerstrlen['nodes'] ) )
2136            {
2137                $this->headerstrlen['nodes']    = strlen( strval( $nodes ) );
2138            }
2139            else if( strlen( strval( $nodes) ) > $this->headerstrlen['nodes'] )
2140            {
2141                $this->headerstrlen['nodes']    = strlen( strval( $nodes ) );
2142            }
[303]2143
[721]2144            $runningtime        = makeTime( intval( $jobinfo[reported] ) - intval( $jobinfo['start_timestamp'] ) );
[303]2145
[721]2146            if( !isset( $this->headerstrlen['runningtime'] ) )
2147            {
2148                $this->headerstrlen['runningtime']    = strlen( strval( $runningtime) );
2149            }
2150            else if( strlen( strval( $runningtime) ) > $this->headerstrlen['runningtime'] )
2151            {
2152                $this->headerstrlen['runningtime']    = strlen( strval( $runningtime) );
2153            }
[303]2154
[721]2155            if( !isset( $this->headerstrlen['name'] ) )
2156            {
2157                $this->headerstrlen['name']    = strlen( strval( $jobinfo['name'] ) );
2158            }
2159            else if( strlen( strval( $jobinfo['name'] ) ) > $this->headerstrlen['name'] )
2160            {
2161                $this->headerstrlen['name']    = strlen( strval( $jobinfo['name'] ) );
2162            }
2163        }
[303]2164
[721]2165        $xoffset    = 5;
[303]2166
[721]2167        foreach( $this->headerstrlen as $headername => $headerlen )
2168        {
2169            $colorgreen    = imageColorAllocate( $this->image, 0, 200, 0 );
[303]2170
[721]2171            if( $headerlen < strlen( $headername ) )
2172            {
2173                $this->headerstrlen[$headername]    = strlen( $headername );
2174            }
[303]2175
[721]2176            imageString( $this->image, $this->font, $xoffset, $this->y_offset, ucfirst( $headername ), $colorgreen );
[303]2177
[721]2178            $xoffset    = $xoffset + ($this->fontwidth * ( $this->headerstrlen[$headername] + 1 ) );
2179        }
2180        $this->newLineOffset();
2181    }
[303]2182
[721]2183    function newLineOffset()
2184    {
2185        $this->y_offset        = $this->y_offset + $this->fontheight + $this->fontspaceing;
2186    }
[303]2187
[721]2188    function draw()
2189    {
2190        $xlen        = 450;
2191        $ylen        = ( count( $this->njobs ) * ( $this->fontheight + $this->fontspaceing ) ) + (3 * $this->fontheight);
[303]2192
[721]2193        $this->image    = imageCreateTrueColor( $xlen, $ylen );
2194        $colorwhite    = imageColorAllocate( $this->image, 255, 255, 255 );
2195        imageFill( $this->image, 0, 0, $colorwhite );                         
[303]2196
[721]2197        $colorblue    = imageColorAllocate( $this->image, 0, 0, 255 );
[303]2198
[721]2199        imageString( $this->image, $this->font, 1, $this->y_offset, "Monarch Joblist - host: ".$this->host, $colorblue );
2200        $this->newLineOffset();
[303]2201
[721]2202        $this->drawHeader();
2203        $this->drawJobs();
[303]2204
[721]2205        header( 'Content-type: image/png' );
2206        imagePNG( $this->image );
2207        imageDestroy( $this->image );
2208    }
[303]2209}
2210
[331]2211function imageStringDown( &$image, $font, $x, $y, &$s, &$col )
2212{
[721]2213    $fw    = imagefontwidth( $font);
2214    $fh    = imagefontheight( $font);
2215   
2216    $fontspacing = 0;
[331]2217
[721]2218    $fx    = $x;
2219    $fy    = $y;
[331]2220
[721]2221    for( $n=0; $n<strlen( $s ); $n++ )
2222    {
2223        $myc    = $s{$n};
[331]2224
[721]2225        imagestring( $image, $font, $fx, $fy, $myc, $col );
[331]2226
[721]2227        $fy    += ($fontspacing + $fh );
2228    }
[331]2229}
2230
[329]2231function array_rem( $val, &$arr )
2232{
[721]2233    // Delete val from arr
2234    //
2235    $i    = array_search( $val, $arr );
[329]2236
[721]2237    if( $i == false ) return false;
[329]2238
[721]2239    $arr    = array_merge( array_slice( $arr, 0, $i ), array_slice( $arr, $i+1, count( $arr ) ) );
[329]2240
[721]2241    return true;
[329]2242}
2243
2244function cmp( $a, $b ) 
2245{
[721]2246    global $SORT_ORDER;
2247    global $skan_str;
2248    global $x_first, $y_first;
2249    global $x_present, $y_present;
[329]2250
[721]2251    $a_node        = $a;
2252    $b_node        = $b;
2253    $a        = $a_node->getHostname();
2254    $b        = $b_node->getHostname();
[329]2255
[721]2256    if( $a == $b ) return 0;
[329]2257
[721]2258    $a_x        = 0;
2259    $b_x        = 0;
2260    $a_y        = 0;
2261    $b_y        = 0;
[339]2262
[721]2263    if( $x_present && $y_present )
2264    {
2265        if( $x_first )
2266        {
2267            $n = sscanf( $a, $skan_str, $a_x, $a_y );
2268            $n = sscanf( $b, $skan_str, $b_x, $b_y );
2269        }
2270        else if( $y_first )
2271        {
2272            $n = sscanf( $a, $skan_str, $a_y, $a_x );
2273            $n = sscanf( $b, $skan_str, $b_y, $b_x );
2274        }
2275    } 
2276    else if( $x_present && !$y_present )
2277    {
2278        $n = sscanf( $a, $skan_str, $a_x );
2279        $n = sscanf( $b, $skan_str, $b_x );
2280    }
2281    else if( $y_present && !$x_present )
2282    {
2283        $n = sscanf( $a, $skan_str, $a_y );
2284        $n = sscanf( $b, $skan_str, $b_y );
2285    }
[329]2286
[721]2287    if ( $SORT_ORDER=="desc" )
2288    {
[329]2289
[721]2290        if( $x_present && $y_present )
2291        {
2292            // 1  = a < b
2293            // -1 = a > b
2294            //
2295            if ($a_x == $b_x)
2296            {
2297                if ($a_y < $b_y)
2298                {
2299                    return 1;
2300                }
2301                else if ($a_y > $b_y)
2302                {
2303                    return -1;
2304                }
2305            }
2306            else if ($a_x < $b_x)
2307            {
2308                return 1;
2309            }
2310            else if ($a_x > $b_x)
2311            {
2312                return -1;
2313            }
2314        } 
2315        else if( $x_present && !$y_present )
2316        {
2317            if ($a_x < $b_x)
2318            {
2319                return 1;
2320            }
2321            else if ($a_x > $b_x)
2322            {
2323                return -1;
2324            }
2325        }
2326        else if( $y_present && !$x_present )
2327        {
2328            if ($a_y < $b_y)
2329            {
2330                return 1;
2331            }
2332            else if ($a_y > $b_y)
2333            {
2334                return -1;
2335            }
2336        }
2337    }
2338    else if ( $SORT_ORDER == "asc" )
2339    {
[329]2340
[721]2341        if( $x_present && $y_present )
2342        {
2343            // 1  = a > b
2344            // -1 = a < b
2345            //
2346            if ($a_x == $b_x)
2347            {
2348                if ($a_y > $b_y)
2349                {
2350                    return 1;
2351                }
2352                else if ($a_y < $b_y)
2353                {
2354                    return -1;
2355                }
2356            }
2357            else if ($a_x > $b_x)
2358            {
2359                return 1;
2360            }
2361            else if ($a_x < $b_x)
2362            {
2363                return -1;
2364            }
2365        }
2366        else if( $x_present && !$y_present )
2367        {
2368            if ($a_x > $b_x)
2369            {
2370                return 1;
2371            }
2372            else if ($a_x < $b_x)
2373            {
2374                return -1;
2375            }
2376        }
2377        else if( $y_present && !$x_present )
2378        {
2379            if ($a_y > $b_y)
2380            {
2381                return 1;
2382            }
2383            else if ($a_y < $b_y)
2384            {
2385                return -1;
2386            }
2387        }
2388    }
[329]2389}
[519]2390function makeTime( $time )
2391{
[303]2392        $days = intval( $time / 86400 );
2393        $time = ($days>0) ? $time % ($days * 86400) : $time;
2394
2395        $date_str = '';
2396        $day_str = '';
2397
[519]2398        if( $days > 0 )
[721]2399        {
2400            if( $days > 1 )
2401            {
2402                $day_str .= $days . ' days';
2403            }
2404            else
2405            {
2406                $day_str .= $days . ' day';
2407            }
[303]2408        }
2409
2410        $hours = intval( $time / 3600 );
2411        $time = $hours ? $time % ($hours * 3600) : $time;
2412
[519]2413        if( $hours > 0 )
[721]2414        {
2415             $date_str .= $hours . ':';
2416             $date_unit = 'hours'; 
[303]2417        }
2418
2419        $minutes = intval( $time / 60 );
2420        $seconds = $minutes ? $time % ($minutes * 60) : $time;
2421
[519]2422        if( $minutes > 0 )
[721]2423        {
2424            if( $minutes >= 10 )
2425            {
2426                $date_str .= $minutes . ':';
2427            }
2428            else
2429            {
2430                $date_str .= '0' . $minutes . ':';
2431            }
[303]2432                $date_unit = (!isset($date_unit)) ? 'minutes' : $date_unit;
[519]2433        }
[721]2434        else
2435        {
2436            if($hours > 0 )
2437            {
2438                $date_str .= '00:';
2439                $date_unit = (!isset($date_unit)) ? 'minutes' : $date_unit;
2440            }
[303]2441        }
2442
2443        $date_unit = (!isset($date_unit)) ? 'seconds' : $date_unit;
2444
[519]2445        if( $seconds > 0 )
[721]2446        {
2447            if( $seconds >= 10 )
2448            {
2449                $date_str .= $seconds . ' ' . $date_unit;
2450            }
2451            else
2452            {
2453                $date_str .= '0' . $seconds . ' ' . $date_unit;
2454            }
[519]2455        }
[721]2456        else if ( $hours > 0 or $minutes > 0 )
2457        {
2458            $date_str .= '00 ' . $date_unit;
2459        }
[303]2460
[519]2461        if( $days > 0)
[721]2462        {
2463            if( $hours > 0 or $minutes > 0 or $seconds > 0 )
2464            {
2465                $date_str = $day_str . ' - ' . $date_str;
2466            }
2467            else
2468            {
2469                $date_str = $day_str;
2470            }
[303]2471        }
2472        return $date_str;
2473}
[102]2474?>
Note: See TracBrowser for help on using the repository browser.