Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/logviewer.py
diff options
context:
space:
mode:
authorEduardo Silva <edsiper@gmail.com>2007-10-24 20:01:58 (GMT)
committer Eduardo Silva <edsiper@gmail.com>2007-10-24 20:01:58 (GMT)
commit46911776689384062cbf841cdac350fe0ec57e2c (patch)
treebae46a2e63712539f0197d08af8dc1db0657d0cb /logviewer.py
parent18633778a191b9c0894da76c16fadbc91d34ecc0 (diff)
Logviewer
Diffstat (limited to 'logviewer.py')
-rw-r--r--logviewer.py248
1 files changed, 248 insertions, 0 deletions
diff --git a/logviewer.py b/logviewer.py
new file mode 100644
index 0000000..ead92bc
--- /dev/null
+++ b/logviewer.py
@@ -0,0 +1,248 @@
+#!/usr/bin/env python
+
+# Copyright (C) 2006-2007, Eduardo Silva <edsiper@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import logging
+from gettext import gettext as _
+
+import gtk
+import dbus
+import pygtk
+import gobject
+import pango
+import gnomevfs
+
+from sugar.activity import activity
+from sugar import env
+
+class MultiLogView(gtk.VBox):
+ def __init__(self, path, extra_files):
+ self._logs_path = path
+ self._active_log = None
+ self._extra_files = extra_files
+
+ # Creating Main treeview with Actitivities list
+ self._tv_menu = gtk.TreeView()
+ self._tv_menu.connect('cursor-changed', self._load_log)
+ self._tv_menu.set_rules_hint(True)
+
+ # Set width
+ box_width = gtk.gdk.screen_width() * 80 / 100
+ self._tv_menu.set_size_request(box_width*25/100, 0)
+
+ self._store_menu = gtk.TreeStore(str)
+ self._tv_menu.set_model(self._store_menu)
+
+ self._add_column(self._tv_menu, 'Sugar logs', 0)
+ self._logs = {}
+
+ # Activities menu
+ self.hbox = gtk.HBox(False, 3)
+ self.hbox.pack_start(self._tv_menu, True, True, 0)
+
+ # Activity log, set width
+ self._view = LogView()
+ self._view.set_size_request(box_width*75/100, 0)
+
+ self.hbox.pack_start(self._view, True, True, 0)
+ self.hbox.show_all()
+ self._configure_watcher()
+ self._create_log_view()
+
+
+ def _configure_watcher(self):
+ # Setting where gnomeVFS will be watching
+ gnomevfs.monitor_add('file://' + self._logs_path,
+ gnomevfs.MONITOR_DIRECTORY,
+ self._log_file_changed_cb)
+
+ for f in self._extra_files:
+ gnomevfs.monitor_add('file://' + f,
+ gnomevfs.MONITOR_FILE,
+ self._log_file_changed_cb)
+
+ def _log_file_changed_cb(self, monitor_uri, info_uri, event):
+ path = info_uri.split('file://')[-1]
+ filename = self._get_filename_from_path(path)
+
+ if event == gnomevfs.MONITOR_EVENT_CHANGED:
+ self._logs[filename].update()
+ elif event == gnomevfs.MONITOR_EVENT_DELETED:
+ self._delete_log_file_view(filename)
+ elif event == gnomevfs.MONITOR_EVENT_CREATED:
+ self._add_log_file(path)
+
+ # Load the log information in View (textview)
+ def _load_log(self, treeview):
+ treeselection = treeview.get_selection()
+ treestore, iter = treeselection.get_selected()
+
+ # Get current selection
+ act_log = self._store_menu.get_value(iter, 0)
+
+ # Set buffer and scroll down
+ self._view.textview.set_buffer(self._logs[act_log])
+ self._view.textview.scroll_to_mark(self._logs[act_log].get_insert(), 0)
+ self._active_log = act_log
+
+ def _create_log_view(self):
+ # Searching log files
+ for logfile in os.listdir(self._logs_path):
+ full_log_path = os.path.join(self._logs_path, logfile)
+ self._add_log_file(full_log_path)
+
+ for ext in self._extra_files:
+ self._add_log_file(ext)
+
+ return True
+
+ def _delete_log_file_view(self, logkey):
+ self._store_menu.remove(self._logs[logkey].iter)
+ del self._logs[logkey]
+
+ def _get_filename_from_path(self, path):
+ return path.split('/')[-1]
+
+ def _add_log_file(self, path):
+ if os.path.isdir(path):
+ return False
+
+ if not os.path.exists(path):
+ print "ERROR: %s don't exists"
+ return False
+
+ logfile = self._get_filename_from_path(path)
+
+ if not self._logs.has_key(logfile):
+ iter = self._add_log_row(logfile)
+ model = LogBuffer(path, iter)
+ self._logs[logfile] = model
+
+ self._logs[logfile].update()
+ written = self._logs[logfile]._written
+
+ # Load the first iter
+ if self._active_log == None:
+ self._active_log = logfile
+ iter = self._tv_menu.get_model().get_iter_root()
+ self._tv_menu.get_selection().select_iter(iter)
+ self._load_log(self._tv_menu)
+
+ if written > 0 and self._active_log == logfile:
+ self._view.textview.scroll_to_mark(self._logs[logfile].get_insert(), 0)
+
+
+ def _add_log_row(self, name):
+ return self._insert_row(self._store_menu, None, name)
+
+ # Add a new column to the main treeview, (code from Memphis)
+ def _add_column(self, treeview, column_name, index):
+ cell = gtk.CellRendererText()
+ col_tv = gtk.TreeViewColumn(column_name, cell, text=index)
+ col_tv.set_resizable(True)
+ col_tv.set_property('clickable', True)
+
+ treeview.append_column(col_tv)
+
+ # Set the last column index added
+ self.last_col_index = index
+
+ # Insert a Row in our TreeView
+ def _insert_row(self, store, parent, name):
+ iter = store.insert_before(parent, None)
+ index = 0
+ store.set_value(iter, index , name)
+
+ return iter
+
+class LogBuffer(gtk.TextBuffer):
+ def __init__(self, logfile, iter=None):
+ gtk.TextBuffer.__init__(self)
+
+ self._logfile = logfile
+ self._pos = 0
+ self.iter = iter
+ self.update()
+
+ def update(self):
+ try:
+ f = open(self._logfile, 'r')
+ init_pos = self._pos
+
+ f.seek(self._pos)
+ self.insert(self.get_end_iter(), f.read())
+ self._pos = f.tell()
+ f.close()
+
+ self._written = (self._pos - init_pos)
+ except:
+ self.insert(self.get_end_iter(), "Console error: can't open the file\n")
+ self._written = 0
+
+class LogView(gtk.ScrolledWindow):
+ def __init__(self):
+ gtk.ScrolledWindow.__init__(self)
+
+ self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ self.textview = gtk.TextView()
+ self.textview.set_wrap_mode(gtk.WRAP_WORD)
+
+ font = pango.FontDescription('Sans 8')
+ font.set_weight(pango.WEIGHT_LIGHT)
+ self.textview.modify_font(font)
+
+ # Set background color
+ bgcolor = gtk.gdk.color_parse("#FFFFFF")
+ self.textview.modify_base(gtk.STATE_NORMAL, bgcolor)
+
+ self.textview.set_editable(False)
+
+ self.add(self.textview)
+ self.textview.show()
+
+
+class LogViewer(activity.Activity):
+ def __init__(self, handle):
+ activity.Activity.__init__(self, handle)
+ logging.debug('Starting the Log Viewer activity')
+ self.set_title(_('Log Viewer Activity'))
+
+ # Main path to watch: ~/.sugar/someuser/logs...
+ main_path = os.path.join(env.get_profile_path(), 'logs')
+
+ # extra files to watch in logviewer
+ ext_files = []
+ ext_files.append("/var/log/Xorg.0.log")
+ ext_files.append("/var/log/syslog")
+ ext_files.append("/var/log/messages")
+
+ viewer = MultiLogView(main_path, ext_files)
+ self.set_canvas(viewer.hbox)
+
+ # TOOLBAR
+ toolbox = activity.ActivityToolbox(self)
+ toolbox.show()
+
+ self.set_toolbox(toolbox)
+ self.show_all()
+
+ # Dirty hide()
+ toolbar = toolbox.get_activity_toolbar()
+ toolbar.share.hide()
+ toolbar.keep.hide()