Salome HOME
Produce a global xml status of the command and several particular xml status for...
authorSerge Rehbinder <serge.rehbinder@cea.fr>
Tue, 21 Jun 2016 12:04:34 +0000 (14:04 +0200)
committerSerge Rehbinder <serge.rehbinder@cea.fr>
Tue, 21 Jun 2016 12:04:34 +0000 (14:04 +0200)
commands/jobs.py
src/xmlManager.py
src/xsl/job_report.xsl [deleted file]
src/xsl/jobs_global_report.xsl [new file with mode: 0644]
src/xsl/jobs_table_report.xsl [new file with mode: 0644]
src/xsl/running.gif [new file with mode: 0644]

index 7a7fe6a3c95641906d1f5ad2db413b566977b77c..d63de43164e43dac1e446f57505cb6a4156ae71e 100644 (file)
@@ -23,6 +23,8 @@ import paramiko
 
 import src
 
+STYLESHEET_GLOBAL = "jobs_global_report.xsl"
+STYLESHEET_TABLE = "jobs_table_report.xsl"
 
 parser = src.options.Options()
 
@@ -46,7 +48,13 @@ parser.add_option('p', 'publish', 'boolean', 'publish',
 class Machine(object):
     '''Class to manage a ssh connection on a machine
     '''
-    def __init__(self, name, host, user, port=22, passwd=None, sat_path="salomeTools"):
+    def __init__(self,
+                 name,
+                 host,
+                 user,
+                 port=22,
+                 passwd=None,
+                 sat_path="salomeTools"):
         self.name = name
         self.host = host
         self.port = port
@@ -95,10 +103,10 @@ class Machine(object):
         :rtype: bool
         '''
         if self._connection_successful == None:
-            message = "Warning : trying to ask if the connection to "
-            "(host: %s, port: %s, user: %s) is OK whereas there were"
-            " no connection request" % \
-            (self.host, self.port, self.user)
+            message = _("Warning : trying to ask if the connection to "
+            "(name: %s host: %s, port: %s, user: %s) is OK whereas there were"
+            " no connection request" % 
+                        (self.name, self.host, self.port, self.user))
             logger.write( src.printcolors.printcWarning(message))
         return self._connection_successful
 
@@ -212,7 +220,7 @@ class Machine(object):
 class Job(object):
     '''Class to manage one job
     '''
-    def __init__(self, name, machine, application, distribution,
+    def __init__(self, name, machine, application, distribution, table, 
                  commands, timeout, config, logger, job_file, after=None):
 
         self.name = name
@@ -221,6 +229,7 @@ class Job(object):
         self.timeout = timeout
         self.application = application
         self.distribution = distribution
+        self.table = table
         self.config = config
         self.logger = logger
         # The list of log files to download from the remote machine 
@@ -510,7 +519,7 @@ class Jobs(object):
         # The jobs to be launched today 
         self.ljobs = []
         # The jobs that will not be launched today
-        self.ljobsdef_not_today = []
+        self.ljobs_not_today = []
         self.runner = runner
         self.logger = logger
         # The correlation dictionary between jobs and machines
@@ -524,7 +533,7 @@ class Jobs(object):
         # the list of jobs that are running 
         self._l_jobs_running = [] 
                 
-        self.determine_products_and_machines()
+        self.determine_jobs_and_machines()
     
     def define_job(self, job_def, machine):
         '''Takes a pyconf job definition and a machine (from class machine)
@@ -547,11 +556,15 @@ class Jobs(object):
         distribution = None
         if 'distribution' in job_def:
             distribution = job_def.distribution
+        table = None
+        if 'table' in job_def:
+            table = job_def.table
             
         return Job(name,
                    machine,
                    application,
                    distribution,
+                   table,
                    cmmnds,
                    timeout,
                    self.runner.cfg,
@@ -559,7 +572,7 @@ class Jobs(object):
                    self.job_file,
                    after = after)
     
-    def determine_products_and_machines(self):
+    def determine_jobs_and_machines(self):
         '''Function that reads the pyconf jobs definition and instantiates all
            the machines and jobs to be done today.
 
@@ -570,57 +583,60 @@ class Jobs(object):
         host_list = []
                
         for job_def in self.cfg_jobs.jobs :
-            if today in job_def.when:
-                
-                name_machine = job_def.machine
                 
-                a_machine = None
-                for mach in self.lmachines:
-                    if mach.name == name_machine:
-                        a_machine = mach
-                        break
-                
-                if a_machine == None:
-                    for machine_def in self.cfg_jobs.machines:
-                        if machine_def.name == name_machine:
-                            if 'host' not in machine_def:
-                                host = self.runner.cfg.VARS.hostname
-                            else:
-                                host = machine_def.host
+            if not "machine" in job_def:
+                msg = _('WARNING: The job "%s" do not have the key '
+                       '"machine", this job is ignored.\n\n' % job_def.name)
+                self.logger.write(src.printcolors.printcWarning(msg))
+                continue
+            name_machine = job_def.machine
+            
+            a_machine = None
+            for mach in self.lmachines:
+                if mach.name == name_machine:
+                    a_machine = mach
+                    break
+            
+            if a_machine == None:
+                for machine_def in self.cfg_jobs.machines:
+                    if machine_def.name == name_machine:
+                        if 'host' not in machine_def:
+                            host = self.runner.cfg.VARS.hostname
+                        else:
+                            host = machine_def.host
 
-                            if 'user' not in machine_def:
-                                user = self.runner.cfg.VARS.user
-                            else:
-                                user = machine_def.user
+                        if 'user' not in machine_def:
+                            user = self.runner.cfg.VARS.user
+                        else:
+                            user = machine_def.user
 
-                            if 'port' not in machine_def:
-                                port = 22
-                            else:
-                                port = machine_def.port
-                
-                            if 'password' not in machine_def:
-                                passwd = None
-                            else:
-                                passwd = machine_def.password    
-                                
-                            if 'sat_path' not in machine_def:
-                                sat_path = "salomeTools"
-                            else:
-                                sat_path = machine_def.sat_path
-                            
-                            a_machine = Machine(
-                                                machine_def.name,
-                                                host,
-                                                user,
-                                                port=port,
-                                                passwd=passwd,
-                                                sat_path=sat_path
-                                                )
+                        if 'port' not in machine_def:
+                            port = 22
+                        else:
+                            port = machine_def.port
+            
+                        if 'password' not in machine_def:
+                            passwd = None
+                        else:
+                            passwd = machine_def.password    
                             
-                            if (host, port) not in host_list:
-                                host_list.append((host, port))
-                                             
-                            self.lmachines.append(a_machine)
+                        if 'sat_path' not in machine_def:
+                            sat_path = "salomeTools"
+                        else:
+                            sat_path = machine_def.sat_path
+                        
+                        a_machine = Machine(
+                                            machine_def.name,
+                                            host,
+                                            user,
+                                            port=port,
+                                            passwd=passwd,
+                                            sat_path=sat_path
+                                            )
+                        
+                        self.lmachines.append(a_machine)
+                        if (host, port) not in host_list:
+                            host_list.append((host, port))
                 
                 if a_machine == None:
                     msg = _("WARNING: The job \"%(job_name)s\" requires the "
@@ -629,12 +645,13 @@ class Jobs(object):
                             "The job will not be launched")
                     self.logger.write(src.printcolors.printcWarning(msg))
                                   
-                a_job = self.define_job(job_def, a_machine)
-                self.dic_job_machine[a_job] = a_machine
+            a_job = self.define_job(job_def, a_machine)
+            self.dic_job_machine[a_job] = a_machine
                 
+            if today in job_def.when:    
                 self.ljobs.append(a_job)
             else: # today in job_def.when
-                self.ljobsdef_not_today.append(job_def)
+                self.ljobs_not_today.append(a_job)
                                      
         self.lhosts = host_list
         
@@ -870,7 +887,7 @@ class Jobs(object):
             new_job_finished = self.update_jobs_states_list()
             
             if new_job_start or new_job_finished:
-                self.gui.update_xml_file(self.ljobs)            
+                self.gui.update_xml_files(self.ljobs)            
                 # Display the current status     
                 self.display_status(self.len_columns)
             
@@ -881,7 +898,7 @@ class Jobs(object):
         self.logger.write(tiret_line)                   
         self.logger.write("\n\n")
         
-        self.gui.update_xml_file(self.ljobs)
+        self.gui.update_xml_files(self.ljobs)
         self.gui.last_update()
 
     def write_all_results(self):
@@ -901,141 +918,125 @@ class Gui(object):
     '''Class to manage the the xml data that can be displayed in a browser to
        see the jobs states
     '''
-    
-    """
-    <?xml version='1.0' encoding='utf-8'?>
-    <?xml-stylesheet type='text/xsl' href='job_report.xsl'?>
-    <JobsReport>
-      <infos>
-        <info name="generated" value="2016-06-02 07:06:45"/>
-      </infos>
-      <hosts>
-          <host name=is221553 port=22 distribution=UB12.04/>
-          <host name=is221560 port=22/>
-          <host name=is221553 port=22 distribution=FD20/>
-      </hosts>
-      <applications>
-          <application name=SALOME-7.8.0/>
-          <application name=SALOME-master/>
-          <application name=MED-STANDALONE-master/>
-          <application name=CORPUS/>
-      </applications>
-      
-      <jobs>
-          <job name="7.8.0 FD22">
-                <host>is228809</host>
-                <port>2200</port>
-                <application>SALOME-7.8.0</application>
-                <user>adminuser</user>
-                <timeout>240</timeout>
-                <commands>
-                    export DISPLAY=is221560
-                    scp -p salome@is221560.intra.cea.fr:/export/home/salome/SALOME-7.7.1p1-src.tgz /local/adminuser         
-                    tar xf /local/adminuser/SALOME-7.7.1p1-src.tgz -C /local/adminuser
-                </commands>
-                <state>Not launched</state>
-          </job>
-
-          <job name="master MG05">
-                <host>is221560</host>
-                <port>22</port>
-                <application>SALOME-master</application>
-                <user>salome</user>
-                <timeout>240</timeout>
-                <commands>
-                    export DISPLAY=is221560
-                    scp -p salome@is221560.intra.cea.fr:/export/home/salome/SALOME-7.7.1p1-src.tgz /local/adminuser         
-                    sat prepare SALOME-master
-                    sat compile SALOME-master
-                    sat check SALOME-master
-                    sat launcher SALOME-master
-                    sat test SALOME-master
-                </commands>
-                <state>Running since 23 min</state>
-                <!-- <state>time out</state> -->
-                <!-- <state>OK</state> -->
-                <!-- <state>KO</state> -->
-                <begin>10/05/2016 20h32</begin>
-                <end>10/05/2016 22h59</end>
-          </job>
-
-      </jobs>
-    </JobsReport>
-    
-    """
-    
-    def __init__(self, xml_file_path, l_jobs, l_jobs_not_today, stylesheet):
-        # The path of the xml file
-        self.xml_file_path = xml_file_path
-        # The stylesheet
-        self.stylesheet = stylesheet
-        # Open the file in a writing stream
-        self.xml_file = src.xmlManager.XmlLogFile(xml_file_path, "JobsReport")
+   
+    def __init__(self, xml_dir_path, l_jobs, l_jobs_not_today):
+        # The path of the global xml file
+        self.xml_dir_path = xml_dir_path
+        # Initialize the xml files
+        xml_global_path = os.path.join(self.xml_dir_path, "global_report.xml")
+        self.xml_global_file = src.xmlManager.XmlLogFile(xml_global_path,
+                                                         "JobsReport")
+        # The xml files that corresponds to the tables.
+        # {name_table : xml_object}}
+        self.d_xml_table_files = {}
         # Create the lines and columns
-        self.initialize_array(l_jobs, l_jobs_not_today)
-        # Write the wml file
-        self.update_xml_file(l_jobs)
+        self.initialize_arrays(l_jobs, l_jobs_not_today)
+        # Write the xml file
+        self.update_xml_files(l_jobs)
     
-    def initialize_array(self, l_jobs, l_jobs_not_today):
-        l_dist = []
-        l_applications = []
-        for job in l_jobs:
-            distrib = job.distribution
-            if distrib is not None and distrib not in l_dist:
-                l_dist.append(distrib)
+    def initialize_arrays(self, l_jobs, l_jobs_not_today):
+       
+        # Get the tables to fill and put it in a dictionary
+        # {table_name : xml instance corresponding to the table}
+        for job in l_jobs + l_jobs_not_today:
+            table = job.table
+            if (table is not None and 
+                    table not in self.d_xml_table_files.keys()):
+                xml_table_path = os.path.join(self.xml_dir_path, table + ".xml")
+                self.d_xml_table_files[table] =  src.xmlManager.XmlLogFile(
+                                                            xml_table_path,
+                                                            "JobsReport")
+                self.d_xml_table_files[table].add_simple_node("distributions")
+                self.d_xml_table_files[table].add_simple_node("applications")
+                self.d_xml_table_files[table].add_simple_node("table", text=table)
+                 
+        d_dist = {}
+        d_application = {}
+        for table in self.d_xml_table_files:
+            d_dist[table] = []
+            d_application[table] = []
             
-            application = job.application
-            if application is not None and application not in l_applications:
-                l_applications.append(application)
-        
-        for job_def in l_jobs_not_today:
-            distrib = src.get_cfg_param(job_def, "distribution", "nothing")
-            if distrib is not "nothing" and distrib not in l_dist:
-                l_dist.append(distrib)
+        l_hosts_ports = []
+            
+        for job in l_jobs + l_jobs_not_today:
+            
+            if (job.machine.host, job.machine.port) not in l_hosts_ports:
+                l_hosts_ports.append((job.machine.host, job.machine.port))
                 
-            application = src.get_cfg_param(job_def, "application", "nothing")
-            if application is not "nothing" and application not in l_applications:
-                l_applications.append(application)
-        
-        self.l_dist = l_dist
-        self.l_applications = l_applications
-        
-        # Update the hosts node
-        self.xmldists = self.xml_file.add_simple_node("distributions")
-        for dist_name in self.l_dist:
-            src.xmlManager.add_simple_node(self.xmldists, "dist", attrib={"name" : dist_name})
+            distrib = job.distribution
+            application = job.application
             
-        # Update the applications node
-        self.xmlapplications = self.xml_file.add_simple_node("applications")
-        for application in self.l_applications:
-            src.xmlManager.add_simple_node(self.xmlapplications, "application", attrib={"name" : application})
-        
-        # Initialize the jobs node
-        self.xmljobs = self.xml_file.add_simple_node("jobs")
-        
-        # 
-        self.put_jobs_not_today(l_jobs_not_today)
+            table_job = job.table
+            if table is None:
+                continue
+            for table in self.d_xml_table_files:
+                if table_job == table:
+                    if distrib is not None and distrib not in d_dist[table]:
+                        d_dist[table].append(distrib)
+                        src.xmlManager.add_simple_node(
+                            self.d_xml_table_files[table].xmlroot.find('distributions'),
+                                                   "dist",
+                                                   attrib={"name" : distrib})
+                    
+                if table_job == table:
+                    if application is not None and application not in d_application[table]:
+                        d_application[table].append(application)
+                        src.xmlManager.add_simple_node(self.d_xml_table_files[table].xmlroot.find('applications'),
+                                                   "application",
+                                                   attrib={"name" : application})
+
+        # Initialize the hosts_ports node for the global file
+        self.xmlhosts_ports = self.xml_global_file.add_simple_node("hosts_ports")
+        for host, port in l_hosts_ports:
+            host_port = "%s:%i" % (host, port)
+            src.xmlManager.add_simple_node(self.xmlhosts_ports,
+                                           "host_port",
+                                           attrib={"name" : host_port})
         
-        # Initialize the info node (when generated)
-        self.xmlinfos = self.xml_file.add_simple_node("infos", attrib={"name" : "last update", "JobsCommandStatus" : "running"})
+        # Initialize the jobs node in all files
+        for xml_file in [self.xml_global_file] + self.d_xml_table_files.values():
+            xml_jobs = xml_file.add_simple_node("jobs")      
+            # Get the jobs present in the config file but that will not be launched
+            # today
+            self.put_jobs_not_today(l_jobs_not_today, xml_jobs)
+            
+            xml_file.add_simple_node("infos", attrib={"name" : "last update", "JobsCommandStatus" : "running"})
+
     
-    def put_jobs_not_today(self, l_jobs_not_today):
-        for job_def in l_jobs_not_today:
-            xmlj = src.xmlManager.add_simple_node(self.xmljobs, "job", attrib={"name" : job_def.name})
-            src.xmlManager.add_simple_node(xmlj, "application", src.get_cfg_param(job_def, "application", "nothing"))
-            src.xmlManager.add_simple_node(xmlj, "distribution", src.get_cfg_param(job_def, "distribution", "nothing"))
-            src.xmlManager.add_simple_node(xmlj, "commands", " ; ".join(job_def.commands))
-            src.xmlManager.add_simple_node(xmlj, "state", "Not today")        
-        
-    def update_xml_file(self, l_jobs):      
+    def put_jobs_not_today(self, l_jobs_not_today, xml_node_jobs):
+        for job in l_jobs_not_today:
+            xmlj = src.xmlManager.add_simple_node(xml_node_jobs,
+                                                 "job",
+                                                 attrib={"name" : job.name})
+            src.xmlManager.add_simple_node(xmlj, "application", job.application)
+            src.xmlManager.add_simple_node(xmlj,
+                                           "distribution",
+                                           job.distribution)
+            src.xmlManager.add_simple_node(xmlj, "table", job.table)
+            src.xmlManager.add_simple_node(xmlj,
+                                       "commands", " ; ".join(job.commands))
+            src.xmlManager.add_simple_node(xmlj, "state", "Not today")
+            src.xmlManager.add_simple_node(xmlj, "machine", job.machine.name)
+            src.xmlManager.add_simple_node(xmlj, "host", job.machine.host)
+            src.xmlManager.add_simple_node(xmlj, "port", str(job.machine.port))
+            src.xmlManager.add_simple_node(xmlj, "user", job.machine.user)
+            src.xmlManager.add_simple_node(xmlj, "sat_path",
+                                                        job.machine.sat_path)
+    
+    def update_xml_files(self, l_jobs):
+        for xml_file in [self.xml_global_file] + self.d_xml_table_files.values():
+            self.update_xml_file(l_jobs, xml_file)
+            
+    def update_xml_file(self, l_jobs, xml_file):      
         
+        xml_node_jobs = xml_file.xmlroot.find('jobs')
         # Update the job names and status node
         for job in l_jobs:
             # Find the node corresponding to the job and delete it
             # in order to recreate it
-            for xmljob in self.xmljobs.findall('job'):
+            for xmljob in xml_node_jobs.findall('job'):
                 if xmljob.attrib['name'] == job.name:
-                    self.xmljobs.remove(xmljob)
+                    xml_node_jobs.remove(xmljob)
             
             T0 = str(job._T0)
             if T0 != "-1":
@@ -1047,25 +1048,38 @@ class Gui(object):
                                        time.localtime(job._Tf))
             
             # recreate the job node
-            xmlj = src.xmlManager.add_simple_node(self.xmljobs, "job", attrib={"name" : job.name})
+            xmlj = src.xmlManager.add_simple_node(xml_node_jobs,
+                                                  "job",
+                                                  attrib={"name" : job.name})
+            src.xmlManager.add_simple_node(xmlj, "machine", job.machine.name)
             src.xmlManager.add_simple_node(xmlj, "host", job.machine.host)
             src.xmlManager.add_simple_node(xmlj, "port", str(job.machine.port))
             src.xmlManager.add_simple_node(xmlj, "user", job.machine.user)
-            src.xmlManager.add_simple_node(xmlj, "sat_path", job.machine.sat_path)
+            src.xmlManager.add_simple_node(xmlj, "sat_path",
+                                           job.machine.sat_path)
             src.xmlManager.add_simple_node(xmlj, "application", job.application)
-            src.xmlManager.add_simple_node(xmlj, "distribution", job.distribution)
+            src.xmlManager.add_simple_node(xmlj, "distribution",
+                                           job.distribution)
+            src.xmlManager.add_simple_node(xmlj, "table", job.table)
             src.xmlManager.add_simple_node(xmlj, "timeout", str(job.timeout))
-            src.xmlManager.add_simple_node(xmlj, "commands", " ; ".join(job.commands))
+            src.xmlManager.add_simple_node(xmlj, "commands",
+                                           " ; ".join(job.commands))
             src.xmlManager.add_simple_node(xmlj, "state", job.get_status())
             src.xmlManager.add_simple_node(xmlj, "begin", T0)
             src.xmlManager.add_simple_node(xmlj, "end", Tf)
-            src.xmlManager.add_simple_node(xmlj, "out", src.printcolors.cleancolor(job.out))
-            src.xmlManager.add_simple_node(xmlj, "err", src.printcolors.cleancolor(job.err))
+            src.xmlManager.add_simple_node(xmlj, "out",
+                                           src.printcolors.cleancolor(job.out))
+            src.xmlManager.add_simple_node(xmlj, "err",
+                                           src.printcolors.cleancolor(job.err))
             src.xmlManager.add_simple_node(xmlj, "res", str(job.res_job))
             if len(job.remote_log_files) > 0:
-                src.xmlManager.add_simple_node(xmlj, "remote_log_file_path", job.remote_log_files[0])
+                src.xmlManager.add_simple_node(xmlj,
+                                               "remote_log_file_path",
+                                               job.remote_log_files[0])
             else:
-                src.xmlManager.add_simple_node(xmlj, "remote_log_file_path", "nothing")           
+                src.xmlManager.add_simple_node(xmlj,
+                                               "remote_log_file_path",
+                                               "nothing")           
             
             xmlafter = src.xmlManager.add_simple_node(xmlj, "after", job.after)
             # get the job father
@@ -1077,7 +1091,7 @@ class Gui(object):
                 if job_father is None:
                     msg = _("The job %(father_name)s that is parent of "
                             "%(son_name)s is not in the job list." %
-                             {"father_name" : job.after , "son_name" : job.name})
+                            {"father_name" : job.after , "son_name" : job.name})
                     raise src.SatException(msg)
                 
                 if len(job_father.remote_log_files) > 0:
@@ -1088,21 +1102,26 @@ class Gui(object):
             
         
         # Update the date
-        src.xmlManager.append_node_attrib(self.xmlinfos,
+        xml_node_infos = xml_file.xmlroot.find('infos')
+        src.xmlManager.append_node_attrib(xml_node_infos,
                     attrib={"value" : 
                     datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
                
         # Write the file
-        self.write_xml_file()
+        self.write_xml_files()
     
     def last_update(self, finish_status = "finished"):
-        src.xmlManager.append_node_attrib(self.xmlinfos,
-                    attrib={"JobsCommandStatus" : finish_status})
+        for xml_file in [self.xml_global_file] + self.d_xml_table_files.values():
+            xml_node_infos = xml_file.xmlroot.find('infos')
+            src.xmlManager.append_node_attrib(xml_node_infos,
+                        attrib={"JobsCommandStatus" : finish_status})
         # Write the file
-        self.write_xml_file()
+        self.write_xml_files()
     
-    def write_xml_file(self):
-        self.xml_file.write_tree(self.stylesheet)
+    def write_xml_files(self):
+        self.xml_global_file.write_tree(STYLESHEET_GLOBAL)
+        for xml_file in self.d_xml_table_files.values():
+            xml_file.write_tree(STYLESHEET_TABLE)
         
 ##
 # Describes the command
@@ -1118,7 +1137,8 @@ def run(args, runner, logger):
        
     jobs_cfg_files_dir = runner.cfg.SITE.jobs.config_path
     
-    l_cfg_dir = [jobs_cfg_files_dir, os.path.join(runner.cfg.VARS.datadir, "jobs")]
+    l_cfg_dir = [jobs_cfg_files_dir,
+                 os.path.join(runner.cfg.VARS.datadir, "jobs")]
     
     # Make sure the path to the jobs config files directory exists 
     src.ensure_path_exists(jobs_cfg_files_dir)   
@@ -1178,7 +1198,11 @@ def run(args, runner, logger):
         config_jobs.jobs = l_jb
               
     # Initialization
-    today_jobs = Jobs(runner, logger, options.jobs_cfg, file_jobs_cfg, config_jobs)
+    today_jobs = Jobs(runner,
+                      logger,
+                      options.jobs_cfg,
+                      file_jobs_cfg,
+                      config_jobs)
     # SSH connection to all machines
     today_jobs.ssh_connection_all_machines()
     if options.test_connection:
@@ -1186,7 +1210,9 @@ def run(args, runner, logger):
     
     gui = None
     if options.publish:
-        gui = Gui("/export/home/serioja/LOGS/test.xml", today_jobs.ljobs, today_jobs.ljobsdef_not_today, "job_report.xsl")
+        gui = Gui("/export/home/serioja/LOGS",
+                  today_jobs.ljobs,
+                  today_jobs.ljobs_not_today,)
     
     today_jobs.gui = gui
     
index ee3e425c906118a53545bba8cb369573775660f4..7332cb4956bb413501e4db61c38c1879131042a7 100644 (file)
@@ -45,12 +45,15 @@ class XmlLogFile(object):
         # Initialize the field that contain the xml in memory
         self.xmlroot = etree.Element(rootname, attrib = attrib)
     
-    def write_tree(self, stylesheet=None):
+    def write_tree(self, stylesheet=None, file_path = None):
         '''Write the xml tree in the log file path. Add the stylesheet if asked.
         
         :param stylesheet str: The stylesheet to apply to the xml file
         '''
-        f = open(self.logFile, 'w')
+        log_file_path = self.logFile
+        if file_path:
+            log_file_path = file_path
+        f = open(log_file_path, 'w')
         f.write("<?xml version='1.0' encoding='utf-8'?>\n")
         if stylesheet:
             f.write("<?xml-stylesheet type='text/xsl' href='%s'?>\n" % 
diff --git a/src/xsl/job_report.xsl b/src/xsl/job_report.xsl
deleted file mode 100644 (file)
index 9147912..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-
-<xsl:template match="/">
-<html>
-<head>
-<title>Jobs Report</title>
-<style type="text/css">
-    <!-- styles for commands results -->
-    .OKday        { background-color:#20FF20; }
-    .OKweek       { background-color:#90EE90; font-size: 11px; }
-    .OKmonth      { background-color:#90EE90; font-size: 10px; }
-    .OKold        { background-color:#90EE90; font-size: 9px; }
-
-    .KOday        { background-color:#F20000; }
-    .KOweek       { background-color:#FFC0CB; font-size: 11px; }
-    .KOmonth      { background-color:#FFC0CB; font-size: 10px; }
-    .KOold        { background-color:#FFC0CB; font-size: 9px; }
-
-    .KFday        { background-color:#FFA500; }
-    .KFweek       { background-color:#FAC86D; font-size: 11px; }
-    .KFmonth      { background-color:#FAC86D; font-size: 10px; }
-    .KFold        { background-color:#FAC86D; font-size: 9px; }
-
-    .NAday        { background-color:#BBBBBB; }
-    .NAweek       { background-color:#BFBFBF; font-size: 11px; }
-    .NAmonth      { background-color:#CACACA; font-size: 10px; }
-    .NAold        { background-color:#CFCFCF; font-size: 9px; }
-
-    .label        { font-weight: bold; }
-
-    <!-- styles for links in matrix -->
-    .OK2          { color:#00AA00; }
-    .KO2          { color:#FF0000; }
-    .KF2          { color:#509050; }
-    .NA2          { color:#BBBBBB; }
-    .TO2          { color:GoldenRod; }
-    .RUNNING2     { color:LightSeaGreen; font-weight: bold; }
-    .OK2day       { color:#00AA00; font-weight: bold; }
-    .KO2day       { color:#FF0000; font-weight: bold; }
-    .KF2day       { color:#FF8000; font-weight: bold; }
-    .NA2day       { color:#BBBBBB; font-weight: bold; }
-    .TO2day       { color:GoldenRod; font-weight: bold; }
-
-    .new          { background-color:#FF5500; }
-    .day          { background-color:#F0E25A; font-size: small; }
-    .week         { background-color:#E0E0E0; font-size: small; }
-    .month        { background-color:#C0C0C0; font-size: small; }
-    .old          { background-color:#A0A0A0; font-size: small; }
-    .lnk          { font-size: 12px; }
-    .lnk a        { text-decoration: none; }
-    .note         { text-align : right; font-style: italic; font-size: small; }
-    table.legend  { margin:0px;
-                    padding:5px;
-                    border-collapse:collapse;
-                    empty-cells : show;
-                    border : solid 1px;
-                  }
-    table.summary { width : 100%;
-                    margin:0px;
-                    padding:0px;
-                    border-collapse:collapse;
-                    empty-cells : show;
-                    border : solid 1px;
-                  }
-    td.summary    { border : solid 0px; font-size: medium; }
-    td            { border : solid 1px; }
-    td.small      { border : solid 1px; font-size: small; }
-    th            { font-size: small; border: solid 1px;  }
-    h2            { text-align : center; }
-    h3            { text-align : left; font-size: small; font-weight: normal; }
-    h4            { text-align : left; font-size: small; font-weight: bold; display: inline; }
-    h_err         { text-align : left; font-size: small; font-weight: normal; display: inline;         color: red; }
-    .legend       { text-align : center; } 
-    .def        { font-family: Arial, Verdana, "Times New Roman", Times, serif;}
-   
-</style>
-
-<xsl:if test="//JobsReport/infos/@JobsCommandStatus='running'">
-  <meta http-equiv="refresh" content="1"></meta>
-</xsl:if>
-
-<script language="JavaScript"><![CDATA[
-      function Toggle(id) {
-        collapseall();
-        var element = document.getElementById(id);
-
-         if ( element.style.display == "none" )
-            element.style.display = "block";
-         else 
-            element.style.display = "none";
-      }
-
-      function collapseall() {
-        var x=document.getElementsByTagName("div");
-        for (i=0;i<x.length;i++)
-        {
-            if ( x[i].id != "matrix" )
-                x[i].style.display = "none";
-        }
-      }
-    ]]>
-</script>
-
-</head>
-
-<body class="def">
-    <table width="100%">
-       <tr>
-           <td class="summary">
-               <h2>Jobs Report</h2>
-           </td>
-           <td class="summary" align="right" valign="bottom" width="300">
-               <xsl:for-each select="//JobsReport/infos">
-                 <span class="note"><xsl:value-of select="@name" />: <xsl:value-of select="@value" /></span>
-               </xsl:for-each>
-           </td>
-       </tr>
-    </table>
-       
-    <div id="matrix">
-    <table class="summary">
-      <!-- header -->
-      <tr bgcolor="#9acd32">
-      <th></th>
-      <xsl:for-each select="//JobsReport/applications/application">
-        <xsl:sort select="@name" />
-       <th><xsl:value-of select="@name" /></th>
-      </xsl:for-each>
-      </tr>
-      
-      <!-- for all hosts -->
-      <xsl:for-each select="//JobsReport/distributions/dist">
-        <xsl:sort select="@name" />
-       <xsl:variable name="curr_distname" select="@name" />
-       <tr>
-       <td align="center"><xsl:value-of select="$curr_distname" /></td>
-       <!-- for all jobs -->
-       <xsl:for-each select="//JobsReport/applications/application">
-         <xsl:sort select="@name" />
-         <xsl:variable name="curr_appli" select="@name" />
-         <td align="center" class="small">
-             <!-- get the job for current host and current appli -->
-             <xsl:for-each select="//JobsReport/jobs/job">
-                 <xsl:sort select="@name" />
-                 <xsl:if test="application/.=$curr_appli and distribution/.=$curr_distname">
-                     <xsl:choose>
-                           <xsl:when test="state/.='SSH connection KO' or state/.='Cancelled'">
-                             <a href="#">
-                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
-                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
-                                   <xsl:attribute name="class">KO2day</xsl:attribute>
-                                   <xsl:value-of select="@name"/>
-                             </a>
-                           </xsl:when>
-                           <xsl:when test="contains(state/., 'Not launched')">
-                             <a href="#">
-                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
-                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
-                                   <xsl:attribute name="class">NA2day</xsl:attribute>
-                                   <xsl:value-of select="@name"/>
-                             </a>
-                           </xsl:when>
-                           <xsl:when test="contains(state/., 'running')">
-                             <a href="#">
-                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
-                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
-                                   <xsl:attribute name="class">RUNNING2</xsl:attribute>
-                                   <xsl:value-of select="@name"/>
-                             </a>
-                           </xsl:when>
-                           <xsl:when test="contains(state/., 'Finished')">
-                             <a href="#">
-                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
-                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
-                                   <xsl:attribute name="class">OK2day</xsl:attribute>
-                                   <xsl:value-of select="@name"/>
-                             </a>
-                           </xsl:when>
-                           <xsl:when test="contains(state/., 'Timeout')">
-                             <a href="#">
-                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
-                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
-                                   <xsl:attribute name="class">TO2day</xsl:attribute>
-                                   <xsl:value-of select="@name"/>
-                             </a>
-                           </xsl:when>
-                           <xsl:when test="state/.='Not today'">
-                             <a href="#">
-                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
-                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
-                                   <xsl:attribute name="class">NA2</xsl:attribute>
-                                   <xsl:value-of select="@name"/>
-                             </a>
-                           </xsl:when>
-                     </xsl:choose>
-                     <!--<xsl:value-of select="state/." />-->
-                     <xsl:if test="not(remote_log_file_path/.='nothing') and state/.!='Not today'">
-                            : 
-                           <a>
-                               <xsl:attribute name="title">remote log</xsl:attribute>
-                               <xsl:attribute name="href"><xsl:value-of select="remote_log_file_path/."/></xsl:attribute>
-                               <xsl:if test="res/.='0'">
-                                  <xsl:attribute name="class">OK2day</xsl:attribute>
-                               </xsl:if>
-                               <xsl:if test="res/.='1'">
-                                  <xsl:attribute name="class">KO2day</xsl:attribute>
-                               </xsl:if>
-                               <xsl:value-of select="host/."/>/<xsl:value-of select="port/."/>
-                           </a>
-                     </xsl:if> 
-                     <br/>
-                 </xsl:if> 
-                 
-             </xsl:for-each>
-         </td>
-       </xsl:for-each>
-       </tr>
-      </xsl:for-each>
-    </table>
-    
-    <h3>
-    <xsl:choose>
-       <xsl:when test="//JobsReport/infos/@JobsCommandStatus='running'">
-           Command status : running <img src="running.gif"></img>
-       </xsl:when>
-       
-       <xsl:otherwise>
-           Command status : <xsl:value-of select="//JobsReport/infos/@JobsCommandStatus/."/>
-       </xsl:otherwise>
-    </xsl:choose>
-    </h3>
-    </div>
-
-    
-    <!-- Loop over the jobs in order to find what job was called in the link "onclick". Display information about that job -->
-    <xsl:for-each select="//JobsReport/jobs/job">
-      <xsl:variable name="curr_job_name" select="@name" />
-      <div style="display:none"><xsl:attribute name="id"><xsl:value-of select="@name"/></xsl:attribute>
-         <!-- Display job name -->
-         <h4>Name : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/@name"/>
-         <br/>
-         <xsl:if test="//JobsReport/jobs/job[@name=$curr_job_name]/state!='Not today'">
-                 <!-- Display the job attributes -->
-                 <h4>Hostname/port : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/host"/>/<xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/port"/>
-                 <br/>
-                 <h4>User : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/user"/>
-                 <br/>
-                 <h4>salomeTools path : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/sat_path"/>
-                 <br/>
-                 <h4>After : </h4>
-                 <a href="#">
-                       <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/after"/>')</xsl:attribute>
-                       <xsl:attribute name="title">Click to get job information</xsl:attribute>
-                       <xsl:attribute name="class">OK2</xsl:attribute>
-                       <xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/after"/>
-                 </a>
-                 <br/>
-                 <h4>Timeout : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/timeout"/>
-                 <br/>
-                 <h4>Begin : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/begin"/>
-                 <br/>
-                 <h4>End : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/end"/>
-                 <br/>
-                 <h4>Out : </h4><PRE><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/out"/></PRE>
-                 <br/>
-                 <h4>Err : </h4><h_err><PRE><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/err"/></PRE></h_err>
-          </xsl:if>
-         <h4>Status : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/state"/>
-         <br/>
-         <h4>Commands : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/commands"/>
-         <br/>
-      </div>
-    </xsl:for-each>
-
-</body>
-
-</html>
-</xsl:template>
-</xsl:stylesheet>
\ No newline at end of file
diff --git a/src/xsl/jobs_global_report.xsl b/src/xsl/jobs_global_report.xsl
new file mode 100644 (file)
index 0000000..14364f0
--- /dev/null
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="/">
+<html>
+<head>
+<title>Jobs global report</title>
+<style type="text/css">
+    <!-- styles for commands results -->
+    .OKday        { background-color:#20FF20; }
+    .OKweek       { background-color:#90EE90; font-size: 11px; }
+    .OKmonth      { background-color:#90EE90; font-size: 10px; }
+    .OKold        { background-color:#90EE90; font-size: 9px; }
+
+    .KOday        { background-color:#F20000; }
+    .KOweek       { background-color:#FFC0CB; font-size: 11px; }
+    .KOmonth      { background-color:#FFC0CB; font-size: 10px; }
+    .KOold        { background-color:#FFC0CB; font-size: 9px; }
+
+    .KFday        { background-color:#FFA500; }
+    .KFweek       { background-color:#FAC86D; font-size: 11px; }
+    .KFmonth      { background-color:#FAC86D; font-size: 10px; }
+    .KFold        { background-color:#FAC86D; font-size: 9px; }
+
+    .NAday        { background-color:#BBBBBB; }
+    .NAweek       { background-color:#BFBFBF; font-size: 11px; }
+    .NAmonth      { background-color:#CACACA; font-size: 10px; }
+    .NAold        { background-color:#CFCFCF; font-size: 9px; }
+
+    .label        { font-weight: bold; }
+
+    <!-- styles for links in matrix -->
+    .OK2          { color:#00AA00; }
+    .KO2          { color:#FF0000; }
+    .KF2          { color:#509050; }
+    .NA2          { color:#BBBBBB; }
+    .TO2          { color:GoldenRod; }
+    .RUNNING2     { color:LightSeaGreen; font-weight: bold; }
+    .OK2day       { color:#00AA00; font-weight: bold; }
+    .KO2day       { color:#FF0000; font-weight: bold; }
+    .KF2day       { color:#FF8000; font-weight: bold; }
+    .NA2day       { color:#BBBBBB; font-weight: bold; }
+    .TO2day       { color:GoldenRod; font-weight: bold; }
+
+    .new          { background-color:#FF5500; }
+    .day          { background-color:#F0E25A; font-size: small; }
+    .week         { background-color:#E0E0E0; font-size: small; }
+    .month        { background-color:#C0C0C0; font-size: small; }
+    .old          { background-color:#A0A0A0; font-size: small; }
+    .lnk          { font-size: 12px; }
+    .lnk a        { text-decoration: none; }
+    .note         { text-align : right; font-style: italic; font-size: small; }
+    table.legend  { margin:0px;
+                    padding:5px;
+                    border-collapse:collapse;
+                    empty-cells : show;
+                    border : solid 1px;
+                  }
+    table.summary { width : 100%;
+                    margin:0px;
+                    padding:0px;
+                    border-collapse:collapse;
+                    empty-cells : show;
+                    border : solid 1px;
+                  }
+    td.summary    { border : solid 0px; font-size: medium; }
+    td            { border : solid 1px; }
+    td.small      { border : solid 1px; font-size: small; }
+    th            { font-size: small; border: solid 1px;  }
+    h2            { text-align : center; }
+    h3            { text-align : left; font-size: small; font-weight: normal; }
+    h4            { text-align : left; font-size: small; font-weight: bold; display: inline; }
+    h_err         { text-align : left; font-size: small; font-weight: normal; display: inline;         color: red; }
+    .legend       { text-align : center; } 
+    .def        { font-family: Arial, Verdana, "Times New Roman", Times, serif; background-color:#FFFFCC;}
+   
+</style>
+
+<xsl:if test="//JobsReport/infos/@JobsCommandStatus='running'">
+  <meta http-equiv="refresh" content="1"></meta>
+</xsl:if>
+
+<script language="JavaScript"><![CDATA[
+      function Toggle(id) {
+        collapseall();
+        var element = document.getElementById(id);
+
+         if ( element.style.display == "none" )
+            element.style.display = "block";
+         else 
+            element.style.display = "none";
+      }
+
+      function collapseall() {
+        var x=document.getElementsByTagName("div");
+        for (i=0;i<x.length;i++)
+        {
+            if ( x[i].id != "matrix" )
+                x[i].style.display = "none";
+        }
+      }
+    ]]>
+</script>
+
+</head>
+
+<body class="def">
+    <table width="100%">
+       <tr>
+           <td class="summary">
+               <h2>Jobs global report</h2>
+           </td>
+           <td class="summary" align="right" valign="bottom" width="300">
+               <xsl:for-each select="//JobsReport/infos">
+                 <span class="note"><xsl:value-of select="@name" />: <xsl:value-of select="@value" /></span>
+               </xsl:for-each>
+           </td>
+       </tr>
+    </table>
+       
+    <div id="matrix">
+    <table class="summary">
+     
+    <!-- for all machines -->
+    <xsl:for-each select="//JobsReport/hosts_ports/host_port">
+        <xsl:sort select="@name" />
+        <xsl:variable name="curr_host_port" select="@name" />
+        <tr>
+        <td align="center"><xsl:value-of select="$curr_host_port" /></td>
+          <!-- for all jobs -->
+          
+              <!-- get the jobs for the current machine -->
+              <xsl:for-each select="//JobsReport/jobs/job">
+              <xsl:sort select="@name" />
+              
+              <xsl:if test="concat(host/., ':', port/.)=$curr_host_port">
+                  <td align="center" class="small">
+                  <xsl:choose>
+                    <xsl:when test="state/.='SSH connection KO' or state/.='Cancelled'">
+                      <a href="#">
+                        <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                        <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                        <xsl:attribute name="class">KO2day</xsl:attribute>
+                        <xsl:value-of select="@name"/>
+                      </a>
+                    </xsl:when>
+                    <xsl:when test="contains(state/., 'Not launched')">
+                      <a href="#">
+                        <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                        <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                        <xsl:attribute name="class">NA2day</xsl:attribute>
+                        <xsl:value-of select="@name"/>
+                      </a>
+                    </xsl:when>
+                    <xsl:when test="contains(state/., 'running')">
+                      <a href="#">
+                        <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                        <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                        <xsl:attribute name="class">RUNNING2</xsl:attribute>
+                        <xsl:value-of select="@name"/>
+                      </a>
+                    </xsl:when>
+                    <xsl:when test="contains(state/., 'Finished')">
+                      <a href="#">
+                        <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                        <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                        <xsl:attribute name="class">OK2day</xsl:attribute>
+                        <xsl:value-of select="@name"/>
+                      </a>
+                    </xsl:when>
+                    <xsl:when test="contains(state/., 'Timeout')">
+                      <a href="#">
+                        <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                        <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                        <xsl:attribute name="class">TO2day</xsl:attribute>
+                        <xsl:value-of select="@name"/>
+                      </a>
+                    </xsl:when>
+                    <xsl:when test="state/.='Not today'">
+                      <a href="#">
+                        <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                        <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                        <xsl:attribute name="class">NA2</xsl:attribute>
+                        <xsl:value-of select="@name"/>
+                      </a>
+                    </xsl:when>
+                  </xsl:choose>
+                  <!--<xsl:value-of select="state/." />-->
+                  <xsl:if test="not(remote_log_file_path/.='nothing') and state/.!='Not today'">
+                     : 
+                    <a>
+                    <xsl:attribute name="title">remote log</xsl:attribute>
+                    <xsl:attribute name="href"><xsl:value-of select="remote_log_file_path/."/></xsl:attribute>
+                    <xsl:if test="res/.='0'">
+                       <xsl:attribute name="class">OK2day</xsl:attribute>
+                    </xsl:if>
+                    <xsl:if test="res/.='1'">
+                       <xsl:attribute name="class">KO2day</xsl:attribute>
+                    </xsl:if>
+                    <xsl:value-of select="host/."/>/<xsl:value-of select="port/."/>
+                    </a>
+                  </xsl:if> 
+                  <br/>
+                  </td>
+              </xsl:if> 
+              
+              </xsl:for-each>
+          
+        </tr>
+    </xsl:for-each>
+    </table>
+    
+    <h3>
+    <xsl:choose>
+       <xsl:when test="//JobsReport/infos/@JobsCommandStatus='running'">
+           Command status : running <img src="running.gif"></img>
+       </xsl:when>
+       
+       <xsl:otherwise>
+           Command status : <xsl:value-of select="//JobsReport/infos/@JobsCommandStatus/."/>
+       </xsl:otherwise>
+    </xsl:choose>
+    </h3>
+    </div>
+
+    
+    <!-- Loop over the jobs in order to find what job was called in the link "onclick". Display information about that job -->
+    <xsl:for-each select="//JobsReport/jobs/job">
+      <xsl:variable name="curr_job_name" select="@name" />
+      <div style="display:none"><xsl:attribute name="id"><xsl:value-of select="@name"/></xsl:attribute>
+         <!-- Display job name -->
+         <h4>Name : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/@name"/>
+         <br/>
+         <xsl:if test="//JobsReport/jobs/job[@name=$curr_job_name]/state!='Not today'">
+                 <!-- Display the job attributes -->
+                 <h4>Hostname/port : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/host"/>/<xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/port"/>
+                 <br/>
+                 <h4>User : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/user"/>
+                 <br/>
+                 <h4>salomeTools path : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/sat_path"/>
+                 <br/>
+                 <h4>After : </h4>
+                 <a href="#">
+                       <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/after"/>')</xsl:attribute>
+                       <xsl:attribute name="title">Click to get job information</xsl:attribute>
+                       <xsl:attribute name="class">OK2</xsl:attribute>
+                       <xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/after"/>
+                 </a>
+                 <br/>
+                 <h4>Timeout : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/timeout"/>
+                 <br/>
+                 <h4>Begin : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/begin"/>
+                 <br/>
+                 <h4>End : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/end"/>
+                 <br/>
+                 <h4>Out : </h4><PRE><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/out"/></PRE>
+                 <br/>
+                 <h4>Err : </h4><h_err><PRE><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/err"/></PRE></h_err>
+          </xsl:if>
+         <h4>Status : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/state"/>
+         <br/>
+         <h4>Commands : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/commands"/>
+         <br/>
+      </div>
+    </xsl:for-each>
+
+</body>
+
+</html>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/src/xsl/jobs_table_report.xsl b/src/xsl/jobs_table_report.xsl
new file mode 100644 (file)
index 0000000..7a0a58b
--- /dev/null
@@ -0,0 +1,281 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="/">
+<html>
+<head>
+<title>Jobs <xsl:value-of select="//JobsReport/table/."/> report</title>
+<style type="text/css">
+    <!-- styles for commands results -->
+    .OKday        { background-color:#20FF20; }
+    .OKweek       { background-color:#90EE90; font-size: 11px; }
+    .OKmonth      { background-color:#90EE90; font-size: 10px; }
+    .OKold        { background-color:#90EE90; font-size: 9px; }
+
+    .KOday        { background-color:#F20000; }
+    .KOweek       { background-color:#FFC0CB; font-size: 11px; }
+    .KOmonth      { background-color:#FFC0CB; font-size: 10px; }
+    .KOold        { background-color:#FFC0CB; font-size: 9px; }
+
+    .KFday        { background-color:#FFA500; }
+    .KFweek       { background-color:#FAC86D; font-size: 11px; }
+    .KFmonth      { background-color:#FAC86D; font-size: 10px; }
+    .KFold        { background-color:#FAC86D; font-size: 9px; }
+
+    .NAday        { background-color:#BBBBBB; }
+    .NAweek       { background-color:#BFBFBF; font-size: 11px; }
+    .NAmonth      { background-color:#CACACA; font-size: 10px; }
+    .NAold        { background-color:#CFCFCF; font-size: 9px; }
+
+    .label        { font-weight: bold; }
+
+    <!-- styles for links in matrix -->
+    .OK2          { color:#00AA00; }
+    .KO2          { color:#FF0000; }
+    .KF2          { color:#509050; }
+    .NA2          { color:#BBBBBB; }
+    .TO2          { color:GoldenRod; }
+    .RUNNING2     { color:LightSeaGreen; font-weight: bold; }
+    .OK2day       { color:#00AA00; font-weight: bold; }
+    .KO2day       { color:#FF0000; font-weight: bold; }
+    .KF2day       { color:#FF8000; font-weight: bold; }
+    .NA2day       { color:#BBBBBB; font-weight: bold; }
+    .TO2day       { color:GoldenRod; font-weight: bold; }
+
+    .new          { background-color:#FF5500; }
+    .day          { background-color:#F0E25A; font-size: small; }
+    .week         { background-color:#E0E0E0; font-size: small; }
+    .month        { background-color:#C0C0C0; font-size: small; }
+    .old          { background-color:#A0A0A0; font-size: small; }
+    .lnk          { font-size: 12px; }
+    .lnk a        { text-decoration: none; }
+    .note         { text-align : right; font-style: italic; font-size: small; }
+    table.legend  { margin:0px;
+                    padding:5px;
+                    border-collapse:collapse;
+                    empty-cells : show;
+                    border : solid 1px;
+                  }
+    table.summary { width : 100%;
+                    margin:0px;
+                    padding:0px;
+                    border-collapse:collapse;
+                    empty-cells : show;
+                    border : solid 1px;
+                  }
+    td.summary    { border : solid 0px; font-size: medium; }
+    td            { border : solid 1px; }
+    td.small      { border : solid 1px; font-size: small; }
+    th            { font-size: small; border: solid 1px;  }
+    h2            { text-align : center; }
+    h3            { text-align : left; font-size: small; font-weight: normal; }
+    h4            { text-align : left; font-size: small; font-weight: bold; display: inline; }
+    h_err         { text-align : left; font-size: small; font-weight: normal; display: inline;         color: red; }
+    .legend       { text-align : center; } 
+    .def        { font-family: Arial, Verdana, "Times New Roman", Times, serif;}
+   
+</style>
+
+<xsl:if test="//JobsReport/infos/@JobsCommandStatus='running'">
+  <meta http-equiv="refresh" content="1"></meta>
+</xsl:if>
+
+<script language="JavaScript"><![CDATA[
+      function Toggle(id) {
+        collapseall();
+        var element = document.getElementById(id);
+
+         if ( element.style.display == "none" )
+            element.style.display = "block";
+         else 
+            element.style.display = "none";
+      }
+
+      function collapseall() {
+        var x=document.getElementsByTagName("div");
+        for (i=0;i<x.length;i++)
+        {
+            if ( x[i].id != "matrix" )
+                x[i].style.display = "none";
+        }
+      }
+    ]]>
+</script>
+
+</head>
+
+<body class="def">
+    <table width="100%">
+       <tr>
+           <td class="summary">
+               <h2>Compilation report <xsl:value-of select="//JobsReport/table/."/></h2>
+           </td>
+           <td class="summary" align="right" valign="bottom" width="300">
+               <xsl:for-each select="//JobsReport/infos">
+                 <span class="note"><xsl:value-of select="@name" />: <xsl:value-of select="@value" /></span>
+               </xsl:for-each>
+           </td>
+       </tr>
+    </table>
+       
+    <div id="matrix">
+    <table class="summary">
+      <!-- header -->
+      <tr bgcolor="#9acd32">
+      <th></th>
+      <xsl:for-each select="//JobsReport/applications/application">
+        <xsl:sort select="@name" />
+       <th><xsl:value-of select="@name" /></th>
+      </xsl:for-each>
+      </tr>
+      
+      <!-- for all hosts -->
+      <xsl:for-each select="//JobsReport/distributions/dist">
+        <xsl:sort select="@name" />
+       <xsl:variable name="curr_distname" select="@name" />
+       <tr>
+       <td align="center"><xsl:value-of select="$curr_distname" /></td>
+       <!-- for all jobs -->
+       <xsl:for-each select="//JobsReport/applications/application">
+         <xsl:sort select="@name" />
+         <xsl:variable name="curr_appli" select="@name" />
+         <td align="center" class="small">
+             <!-- get the job for current host and current appli -->
+             <xsl:for-each select="//JobsReport/jobs/job">
+                 <xsl:sort select="@name" />
+                 <xsl:if test="application/.=$curr_appli and distribution/.=$curr_distname and table/.=//JobsReport/table/.">
+                     <xsl:choose>
+                           <xsl:when test="state/.='SSH connection KO' or state/.='Cancelled'">
+                             <a href="#">
+                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                                   <xsl:attribute name="class">KO2day</xsl:attribute>
+                                   <xsl:value-of select="@name"/>
+                             </a>
+                           </xsl:when>
+                           <xsl:when test="contains(state/., 'Not launched')">
+                             <a href="#">
+                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                                   <xsl:attribute name="class">NA2day</xsl:attribute>
+                                   <xsl:value-of select="@name"/>
+                             </a>
+                           </xsl:when>
+                           <xsl:when test="contains(state/., 'running')">
+                             <a href="#">
+                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                                   <xsl:attribute name="class">RUNNING2</xsl:attribute>
+                                   <xsl:value-of select="@name"/>
+                             </a>
+                           </xsl:when>
+                           <xsl:when test="contains(state/., 'Finished')">
+                             <a href="#">
+                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                                   <xsl:attribute name="class">OK2day</xsl:attribute>
+                                   <xsl:value-of select="@name"/>
+                             </a>
+                           </xsl:when>
+                           <xsl:when test="contains(state/., 'Timeout')">
+                             <a href="#">
+                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                                   <xsl:attribute name="class">TO2day</xsl:attribute>
+                                   <xsl:value-of select="@name"/>
+                             </a>
+                           </xsl:when>
+                           <xsl:when test="state/.='Not today'">
+                             <a href="#">
+                                   <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="@name"/>')</xsl:attribute>
+                                   <xsl:attribute name="title"><xsl:value-of select="state/."/></xsl:attribute>
+                                   <xsl:attribute name="class">NA2</xsl:attribute>
+                                   <xsl:value-of select="@name"/>
+                             </a>
+                           </xsl:when>
+                     </xsl:choose>
+                     <!--<xsl:value-of select="state/." />-->
+                     <xsl:if test="not(remote_log_file_path/.='nothing') and state/.!='Not today'">
+                            : 
+                           <a>
+                               <xsl:attribute name="title">remote log</xsl:attribute>
+                               <xsl:attribute name="href"><xsl:value-of select="remote_log_file_path/."/></xsl:attribute>
+                               <xsl:if test="res/.='0'">
+                                  <xsl:attribute name="class">OK2day</xsl:attribute>
+                               </xsl:if>
+                               <xsl:if test="res/.='1'">
+                                  <xsl:attribute name="class">KO2day</xsl:attribute>
+                               </xsl:if>
+                               <xsl:value-of select="host/."/>/<xsl:value-of select="port/."/>
+                           </a>
+                     </xsl:if> 
+                     <br/>
+                 </xsl:if> 
+                 
+             </xsl:for-each>
+         </td>
+       </xsl:for-each>
+       </tr>
+      </xsl:for-each>
+    </table>
+    
+    <h3>
+    <xsl:choose>
+       <xsl:when test="//JobsReport/infos/@JobsCommandStatus='running'">
+           Command status : running <img src="running.gif"></img>
+       </xsl:when>
+       
+       <xsl:otherwise>
+           Command status : <xsl:value-of select="//JobsReport/infos/@JobsCommandStatus/."/>
+       </xsl:otherwise>
+    </xsl:choose>
+    </h3>
+    </div>
+
+    
+    <!-- Loop over the jobs in order to find what job was called in the link "onclick". Display information about that job -->
+    <xsl:for-each select="//JobsReport/jobs/job">
+      <xsl:variable name="curr_job_name" select="@name" />
+      <div style="display:none"><xsl:attribute name="id"><xsl:value-of select="@name"/></xsl:attribute>
+         <!-- Display job name -->
+         <h4>Name : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/@name"/>
+         <br/>
+         <xsl:if test="//JobsReport/jobs/job[@name=$curr_job_name]/state!='Not today'">
+                 <!-- Display the job attributes -->
+                 <h4>Hostname/port : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/host"/>/<xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/port"/>
+                 <br/>
+                 <h4>User : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/user"/>
+                 <br/>
+                 <h4>salomeTools path : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/sat_path"/>
+                 <br/>
+                 <h4>After : </h4>
+                 <a href="#">
+                       <xsl:attribute name="onclick">javascript:Toggle('<xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/after"/>')</xsl:attribute>
+                       <xsl:attribute name="title">Click to get job information</xsl:attribute>
+                       <xsl:attribute name="class">OK2</xsl:attribute>
+                       <xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/after"/>
+                 </a>
+                 <br/>
+                 <h4>Timeout : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/timeout"/>
+                 <br/>
+                 <h4>Begin : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/begin"/>
+                 <br/>
+                 <h4>End : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/end"/>
+                 <br/>
+                 <h4>Out : </h4><PRE><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/out"/></PRE>
+                 <br/>
+                 <h4>Err : </h4><h_err><PRE><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/err"/></PRE></h_err>
+          </xsl:if>
+         <h4>Status : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/state"/>
+         <br/>
+         <h4>Commands : </h4><xsl:value-of select="//JobsReport/jobs/job[@name=$curr_job_name]/commands"/>
+         <br/>
+      </div>
+    </xsl:for-each>
+
+</body>
+
+</html>
+</xsl:template>
+</xsl:stylesheet>
diff --git a/src/xsl/running.gif b/src/xsl/running.gif
new file mode 100644 (file)
index 0000000..3e2ad52
Binary files /dev/null and b/src/xsl/running.gif differ