Subversion Repositories alertlog

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# alertlog.py
# Copyright (C) 2013 Tomás Vírseda <t00m@t00mlabs.net>
#
# alertlog 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 3 of the License, or
# (at your option) any later version.
#
# kb4it-editor 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, see <http://www.gnu.org/licenses/>.

import sys
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf, Gdk

# With Python2
#~ from BeautifulSoup import BeautifulStoneSoup

# With Python3
from bs4 import BeautifulStoneSoup

#FIXME
#UI_FILE = "alertlog.ui" # Development
UI_FILE = "/usr/share/alertlog/ui/alertlog.ui" #Production
HEADERS = ['time', 'org_id', 'comp_id', 'client_id', 'type', \
                'level', 'host_id', 'host_addr', 'module', 'pid']

class GUI:
    def __init__(self):
        self.total = 0
        self.dlog = {}
        self.progress = 0
        self.builder = Gtk.Builder()
        self.builder.add_from_file(UI_FILE)
        self.builder.connect_signals(self)

        self.cfilter = self.builder.get_object('cbtFilter')
        self.tfilter = self.builder.get_object('etyFilter')
        self.filechooser = self.builder.get_object('fcbLog')
        self.window = self.builder.get_object('window')
        self.messages = self.builder.get_object('scwMessages')
        self.text = self.builder.get_object('txvMessage')
        self.__setup_gui()
        self.window.show_all()


    def __setup_gui(self):
        # setup messages model & widgets
        self.store = Gtk.ListStore(str, str, str, str, str, str, \
                                str, str, str, str, str)

        tree = Gtk.TreeView(self.store)
        tree.connect("cursor-changed", self.on_node_changed)
        renderer = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn('Id', renderer, text=0)
        #~ column.set_visible(False)
        tree.append_column(column)
        n = 1
        for field in HEADERS:
            renderer = Gtk.CellRendererText()
            column = Gtk.TreeViewColumn(field, renderer, text=n)
            column.set_sort_column_id(n)
            column.set_expand(True)
            tree.append_column(column)
            n = n + 1

        tree.show_all()
        self.messages.add(tree)

        # setup comboboxtext filter
        for key in HEADERS:
            self.cfilter.append_text(key)
        self.cfilter.append_text('txt')
        self.cfilter.set_active(0)


    def __len__(self):
        return len(self.dlog)


    def file_set(self, filechooser):
        filename = filechooser.get_filename()
        self.analyze(filename)
        self.update()


    def filter_activated (self, data):
        daux = {}
        text = self.tfilter.get_text()
        filter = self.cfilter.get_active_text()
        for node in xrange(len(self.dlog)):
            try:
                if text.upper() in self.dlog[node][filter].upper():
                    daux[node] = self.dlog[node]
            except:
                pass
        self.update(daux, True)


    def filter_changed (self, data):
        # callback not used.
        pass


    def destroy(self, window, event):
        Gtk.main_quit()


    def update(self, daux={}, filter=False):
        self.store.clear()

        if not filter:
            daux = self.dlog.copy()

        nodelist = []
        for node in daux:
            nodelist.append(node)
        nodelist.sort()

        for node in nodelist:
            row = []
            row.append(str(node))
            for key in HEADERS:
                try:
                    if key == 'time':
                        time = daux[node][key]
                        date = time[:10] + ' ' + time[11:23]
                        row.append(date)
                    else:
                        row.append(daux[node][key])
                except:
                    # messages do not have all fields
                    row.append("")
            self.store.append(row)


    def on_node_changed (self, treeview):
        try:
            selection = treeview.get_selection()
            result = selection.get_selected()
            if result:
                model, treeiter = result
                node = model[treeiter][0]
                text = self.dlog[int(node)]['txt']
                buffer = self.text.get_buffer()
                buffer.set_text(text)
                self.text.set_buffer(buffer)
        except: pass


    def analyze(self, filename):
        self.total = 0
        self.progress = 0
        log = open(filename, 'r').read()
        soup = BeautifulStoneSoup(log)
        messages = soup.findAll('msg')
        n = 0
        for node in messages:
            self.dlog[n] = {}
            for key, value in node.attrs:
                if key != 'version':
                    self.dlog[n][key] = value
            self.dlog[n]['txt'] = node.txt.text
            n = n + 1


def main():
    app = GUI()
    Gtk.main()


if __name__ == "__main__":
    sys.exit(main())