Salome HOME
'sat log' : add --clean option
[tools/sat.git] / commands / log.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3
4 import os
5 import shutil
6 import re
7 import gettext
8
9 # Compatibility python 2/3 for input function
10 # input stays input for python 3 and input = raw_input for python 2
11 try: 
12     input = raw_input
13 except NameError: 
14     pass
15
16 import src
17
18 # Define all possible option for log command :  sat log <options>
19 parser = src.options.Options()
20 parser.add_option('t', 'terminal', 'boolean', 'terminal', "Terminal log.")
21 parser.add_option('l', 'last', 'boolean', 'last', "Show the log of the last launched command.")
22 parser.add_option('f', 'full', 'boolean', 'full', "Show the logs of ALL launched commands.")
23 parser.add_option('c', 'clean', 'int', 'clean', "Erase the n most ancient log files.")
24
25 def getLastLogFile(logDir, notShownCommands):
26     '''Used in case of last option. Get the last log command file path.
27     
28     :param logDir str: The directory where to search the log files
29     :param notShownCommands list: the list of commands to ignore
30     :return: the path to the last log file
31     :rtype: str
32     '''
33     last = (_, 0)
34     for fileName in os.listdir(logDir):
35         # YYYYMMDD_HHMMSS_namecmd.xml
36         sExpr = src.logger.logCommandFileExpression
37         oExpr = re.compile(sExpr)
38         if oExpr.search(fileName):
39             # get date and hour and format it
40             date_hour_cmd = fileName.split('_')
41             datehour = date_hour_cmd[0] + date_hour_cmd[1]
42             cmd = date_hour_cmd[2][:-len('.xml')]
43             if cmd in notShownCommands:
44                 continue
45             if int(datehour) > last[1]:
46                 last = (fileName, int(datehour))
47     return os.path.join(logDir, last[0])
48
49 def print_log_command_in_terminal(filePath, logger):
50     '''Print the contain of filePath. It contains a command log in xml format.
51     
52     :param filePath: The command xml file from which extract the commands context and traces
53     :param logger Logger: the logging instance to use in order to print.  
54     '''
55     logger.write(_("Reading ") + src.printcolors.printcHeader(filePath) + "\n", 5)
56     # Instantiate the readXmlFile class that reads xml files
57     xmlRead = src.xmlManager.readXmlFile(filePath)
58     # Get the attributes containing the context (user, OS, time, etc..)
59     dAttrText = xmlRead.get_attrib('Site')
60     # format dAttrText and print the context
61     lAttrText = []
62     for attrib in dAttrText:
63         lAttrText.append((attrib, dAttrText[attrib]))
64     logger.write("\n", 1)
65     src.print_info(logger, lAttrText)
66     # Get the traces
67     command_traces = xmlRead.get_node_text('Log')
68     # Print it if there is any
69     if command_traces:
70         logger.write(src.printcolors.printcHeader(_("Here are the command traces :\n")), 1)
71         logger.write(command_traces, 1)
72         logger.write("\n", 1)
73
74 def ask_value(nb):
75     '''Ask for an int n. 0<n<nb
76     
77     :param nb int: The maximum value of the value to be returned by the user.
78     :return: the value entered by the user. Return -1 if it is not as expected
79     :rtype: int
80     '''
81     try:
82         # ask for a value
83         rep = input(_("Which one (enter or 0 to quit)? "))
84         # Verify it is on the right range
85         if len(rep) == 0:
86             x = 0
87         else:
88             x = int(rep)
89             if x > nb:
90                 x = -1
91     except:
92         x = -1
93     
94     return x
95
96 def description():
97     '''method that is called when salomeTools is called with --help option.
98     
99     :return: The text to display for the log command description.
100     :rtype: str
101     '''
102     return _("Gives access to the logs produced by the salomeTools commands.")    
103
104 def run(args, runner, logger):
105     '''method that is called when salomeTools is called with log parameter.
106     '''
107     # Parse the options
108     (options, args) = parser.parse_args(args)
109
110     # get the log directory. If there is an application, it is in cfg.APPLICATION.out_dir, else in user directory
111     logDir = runner.cfg.SITE.log.logDir
112
113     # If the clean options is invoked, do nothing but deleting the concerned files.
114     if options.clean:
115         nbClean = options.clean
116         # get the list of files to remove
117         lLogs = src.logger.listLogFile(logDir, src.logger.logCommandFileExpression)
118         nbLogFiles = len(lLogs)
119         # Delete all if the invoked number is bigger than the number of log files
120         if nbClean > nbLogFiles:
121             nbClean = nbLogFiles
122         # Get the list to delete and do the removing
123         lLogsToDelete = sorted(lLogs)[:nbClean]
124         for filePath, _, _, _, _, _ in lLogsToDelete:
125             logger.write(src.printcolors.printcWarning("Removing ") + filePath + "\n", 5)
126             os.remove(filePath)
127         
128         logger.write(src.printcolors.printcSuccess("OK\n"))
129         logger.write("%i files deleted.\n" % nbClean)
130         return 0 
131
132     # determine the commands to show in the hat log
133     notShownCommands = runner.cfg.INTERNAL.log.notShownCommands
134     if options.full:
135         notShownCommands = []
136
137     # If the user asks for a terminal display
138     if options.terminal:
139         # Parse the log directory in order to find all the files corresponding to the commands
140         lLogs = src.logger.listLogFile(logDir, src.logger.logCommandFileExpression)
141         lLogsFiltered = []
142         for filePath, _, date, _, hour, cmd in lLogs:
143             showLog, cmdAppli = src.logger.showcommandLog(filePath, cmd, runner.cfg.VARS.application, notShownCommands)
144             if showLog:
145                 lLogsFiltered.append((filePath, date, hour, cmd, cmdAppli))
146             
147         lLogsFiltered = sorted(lLogsFiltered)
148         nb_logs = len(lLogsFiltered)
149         index = 0
150         # loop on all files and print it with date, time and command name 
151         for _, date, hour, cmd, cmdAppli in lLogsFiltered:          
152             num = src.printcolors.printcLabel("%2d" % (nb_logs - index))
153             logger.write("%s: %13s %s %s %s\n" % (num, cmd, date, hour, cmdAppli), 1, False)
154             index += 1
155         
156         # ask the user what for what command he wants to be displayed
157         x = -1
158         while (x < 0):
159             x = ask_value(nb_logs)
160             if x > 0:
161                 index = len(lLogsFiltered) - int(x)
162                 # Show the log corresponding to the selected command call
163                 print_log_command_in_terminal(lLogsFiltered[index][0], logger)                
164                 x = 0
165         
166         return 0
167                     
168     
169     # Find the stylesheets Directory and files
170     xslDir = os.path.join(runner.cfg.VARS.srcDir, 'xsl')
171     xslCommand = os.path.join(xslDir, "command.xsl")
172     xslHat = os.path.join(xslDir, "hat.xsl")
173     imgLogo = os.path.join(xslDir, "LOGO-SAT.png")
174     
175     # copy the stylesheets in the log directory
176     shutil.copy2(xslCommand, logDir)
177     shutil.copy2(xslHat, logDir)
178     shutil.copy2(imgLogo, logDir)
179
180     # If the last option is invoked, just, show the last log file
181     if options.last:
182         lastLogFilePath = getLastLogFile(logDir, notShownCommands)
183         # open the log xml file in the user editor
184         src.system.show_in_editor(runner.cfg.USER.browser, lastLogFilePath, logger)
185         return 0
186
187     # Create or update the hat xml that gives access to all the commands log files
188     xmlHatFilePath = os.path.join(logDir, 'hat.xml')
189     src.logger.update_hat_xml(runner.cfg.SITE.log.logDir, application = runner.cfg.VARS.application, notShownCommands = notShownCommands)
190     
191     # open the hat xml in the user editor
192     src.system.show_in_editor(runner.cfg.USER.browser, xmlHatFilePath, logger)
193     return 0