3 # LADITools - Linux Audio Desktop Integration Tools
4 # ladi-system-log - A log viewer for your Linux Audio Desktop
5 # Copyright (C) 2011-2012 Alessio Treglia <quadrispro@ubuntu.com>
6 # Copyright (C) 2007-2010, Marc-Olivier Barre <marco@marcochapeau.org>
7 # Copyright (C) 2007-2009, Nedko Arnaudov <nedko@arnaudov.name>
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 from subprocess
import Popen
, PIPE
32 from laditools
import _gettext_domain
33 gettext
.install(_gettext_domain
)
35 from laditools
import get_version_string
36 from laditools
import LadiConfiguration
37 from laditools
import LadiApp
39 from gi
.repository
import Gtk
40 from gi
.repository
import GObject
41 from gi
.repository
import Vte
43 from laditools
.gtk
import find_data_file
45 timeout_add
= GObject
.timeout_add
47 # Default configuration
48 max_lines_default
= 100
50 # Output the last <lines> lines
51 def read_last(lfile
, lines
):
52 chunk_size
= lines
* 60
55 pos
= endpos
- chunk_size
61 while pos
>= 0 and backlog_size
<= lines
:
63 s
= lfile
.read(chunk_size
)
64 pos
= pos
- chunk_size
65 backlog_size
+= s
.count("\n")
67 backlog
= backlog
.strip().split("\n")
68 if len(backlog
) > lines
:
69 backlog
= backlog
[-lines
:]
73 class LadiSystemLog(LadiApp
):
75 _appname
= 'ladi-system-log'
76 _appname_long
= _("LADI Log Viewer")
77 _appid
= 'org.linuxaudio.ladi.logviewer'
79 _default_config
= { 'max_lines' : max_lines_default
}
82 LadiApp
.__init
__(self
)
87 'config_name': 'jackdbus_log',
88 'config_default': os
.sep
.join([os
.environ
['HOME'], ".log", "jack", "jackdbus.log"])
92 'config_name': 'ladish_log',
93 'config_default': os
.sep
.join([os
.environ
['HOME'], ".log", "ladish", "ladish.log"])
97 'config_name': 'a2j_log',
98 'config_default': os
.sep
.join([os
.environ
['HOME'], ".log", "a2j", "a2j.log"])
102 # Handle the configuration
103 for log
in self
.log_files
:
104 self
._default
_config
[log
['config_name']] = log
['config_default']
105 self
.global_config
= LadiConfiguration (self
.appname
, self
._default
_config
)
106 self
.param_dict
= self
.global_config
.get_config_section (self
.appname
)
108 self
.connect_signals_quit()
110 for log
in self
.log_files
[:]:
111 log
['logfile_path'] = self
.param_dict
[log
['config_name']]
112 # skip logfiles that dont exist
113 if not os
.access(log
['logfile_path'], os
.R_OK
):
114 self
.log_files
.remove(log
)
115 sys
.stderr
.write( _("Skipping '%s' because it does not exist\n") % log
['logfile_path'])
117 sys
.stderr
.write( _("Watching %s\n") % log
['logfile_path'])
120 max_lines_text
= self
.param_dict
['max_lines']
121 self
.max_lines
= int (max_lines_text
)
123 # Load the glade file
124 uifile
= find_data_file('ladi-system-log.ui')
125 builder
= Gtk
.Builder()
126 builder
.add_from_file(uifile
)
127 sys
.stderr
.write( _("Loading interface from %s\n") % uifile
)
130 # Get the ui ready for action
131 self
.event_dict
= {"on_ladilog_ui_destroy" : self
.quit
,
132 "on_ladilog_ui_delete" : self
.on_delete
,
133 "on_close_button_clicked" : self
.quit
,
134 "on_clear_button_clicked" : self
.on_clear_text
,
135 "on_purge_button_clicked" : self
.on_purge
}
136 builder
.connect_signals(self
.event_dict
)
138 self
.ui
= ui
= builder
.get_object("ladilog_ui")
139 self
.logview_notebook
= builder
.get_object ("ladilog_notebook")
141 # Create our terminal and display it
142 for log
in self
.log_files
:
143 log
['scrolled_window'] = sw
= Gtk
.ScrolledWindow()
144 log
['term'] = term
= Vte
.Terminal
.new ()
145 sw
.set_policy(hscrollbar_policy
=Gtk
.PolicyType
.AUTOMATIC
,
146 vscrollbar_policy
=Gtk
.PolicyType
.ALWAYS
)
149 term
.set_scroll_on_output(True)
150 log
["tab_label"] = Gtk
.Label(label
=log
["name"])
152 self
.logview_notebook
.append_page(log
["scrolled_window"],
155 # Make it do something...
156 for log
in self
.log_files
:
158 log
['log_file'] = open(log
['logfile_path'], "rb")
159 sys
.stderr
.write (_("Opening %s...\n") % log
['logfile_path'])
160 lines
= read_last(log
['log_file'], self
.max_lines
)
162 line
= line
.strip('\r\n') + '\r\n'
163 log
["term"].feed(line
, -1)
165 sys
.stderr
.write( _("You called Popen with invalid arguments... dumbass\n") )
167 sys
.stderr
.write( _("Unexpected error: %s\n") % (sys
.exc_info ()[0]))
171 self
.auto_updater
= timeout_add(250, self
.update
, None)
173 def update(self
, user_data
= None):
174 # Append latest output to the buffer
175 for log
in self
.log_files
:
176 line
= log
['log_file'].readline()
178 log
["term"].feed(line
+ '\r', -1)
179 line
= log
['log_file'].readline()
180 log
['log_file'].seek(log
['log_file'].tell())
183 def on_delete(self
, widget
=None, data
=None):
186 def quit (self
, *args
, **kwargs
):
187 self
.global_config
.set_config_section (self
.appname
, self
.param_dict
)
188 self
.global_config
.save ()
191 def on_clear_text (self
, data
=None):
192 current_view
= self
.logview_notebook
.get_current_page ()
193 self
.log_files
[current_view
]["term"].feed ("\033[2J\033[;f", -1)
195 def on_purge (self
, data
=None):
196 current_view
= self
.logview_notebook
.get_current_page ()
197 # Opens the file in write anew mode thus clearing the file and close it right away
198 open (self
.log_files
[current_view
]['logfile_path'], "w+")
199 self
.log_files
[current_view
]["term"].feed ("\033[2J\033[;f", -1)
205 if __name__
== '__main__':
206 parser
= argparse
.ArgumentParser(description
=_('JACK, ladish and a2jmidid log viewer'),
207 epilog
=_('This program is part of the LADITools suite.'))
208 parser
.add_argument('--version', action
='version', version
="%(prog)s " + get_version_string())
213 LadiSystemLog().run()