emesene forum
July 31, 2010, 01:18:23 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: CACHE KEY ERRORS? NICK NOT SAVED? UPGRADE TO 1.6.2 FIRST!

REPORT ANY ISSUE HERE - PLEASE CHECK IF THE PROBLEM HAS ALREADY BEEN REPORTED FIRST -- THANKS
 
  Home   Forum   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Improved logger plugin  (Read 396 times)
darkblood
Jr. Member
**

l33tness: 0
Offline Offline

Posts: 6


View Profile Email
« on: February 24, 2010, 07:44:15 PM »

Hi,

I improved a bit the Logger plugin which is a base plugin of emesene. I added a search functionality.

I hope you like it. Wink
Logged
hit^
Hero Member
*****

l33tness: 1
Offline Offline

Posts: 370


svn up´d


View Profile
« Reply #1 on: February 25, 2010, 12:10:42 AM »

That's really awesome and everything seems to work. But can you maybe make something like jumping to the matching conversation from the results?
Logged

"We are changing the world, one commit at a time."
C10uD
ololol
Administrator
Hero Member
*****

l33tness: -9990
Offline Offline

Posts: 2308



View Profile Email
« Reply #2 on: February 25, 2010, 01:29:42 AM »

thanks for your contribution! however, i've seen the diff against our latest code and seems some of it is removed (some "new" cando code, in example) can you confirm this?
Code:
=== modified file 'plugins_base/Logger.py'
--- plugins_base/Logger.py 2010-01-13 14:34:17 +0000
+++ plugins_base/Logger.py 2010-02-25 09:09:25 +0000
@@ -4,20 +4,20 @@
 
 #   This file is part of emesene.
 #
-#    Emesene 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.
-#
-#    Emesene 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 emesene; if not, write to the Free Software
-#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
-#    USA
+#   Emesene 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.
+#
+#   Emesene 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 emesene; if not, write to the Free Software
+#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
+#   USA
 
 import os
 import gtk
@@ -290,24 +290,14 @@
 
     def get_conversation_ids(self, account):
         '''return the ids of the conversations where the contact was present'''
-        #in the inner query i select all convs ids where the contact is present
-        #in the outer query i select only convs where there is at
-        #least one message! --cando
 
-        query = '''select co.id,co.started
-        from conversation co,conversation_event coe,event ev
-        where co.id = coe.id_conversation
-        and coe.id_event = ev.id and ev.name = 'message'
-        and co.id in ( select distinct c.id
+        query = '''select distinct c.id, c.started
         from conversation c, event e, conversation_event ce, user u
         where c.id = ce.id_conversation and
         e.id = ce.id_event and
         ce.id_user = u.id and
-        u.account = "%s")
-        group by co.id
-        having count(*) >= 1
-        order by co.started
-        '''
+        u.account = "%s"
+        order by c.started'''
 
         return self.query(query % (account,))
 
@@ -350,7 +340,7 @@
 class MainClass(Plugin.Plugin):
     '''Main plugin class'''
 
-    description = _('Log all events and conversations in a database')
+    description = _('Log all events to a file')
     authors = {'Mariano Guerra' :
         'luismarianoguerra at gmail dot com'}
     website = 'http://emesene.org'
@@ -360,7 +350,7 @@
         '''Contructor'''
         Plugin.Plugin.__init__(self, controller, msn, 1000)
 
-        self.description = _('Log all events and conversations in a database')
+        self.description = _('Log all events to a file')
         self.authors = {'Mariano Guerra' :
             'luismarianoguerra at gmail dot com'}
         self.website = 'http://emesene.org'
@@ -408,7 +398,7 @@
             self._cb_sb_action_message_sent
         self.signals['switchboard::custom-emoticon-received'] = \
             self._cb_sb_custom_emoticon_received
-        self.signals['switchboard::user-join'] = self._cb_sb_user_join
+
         # functions to be called on mainloop idleness
         self.queued = []
         self.queuedtag = 0
@@ -672,6 +662,7 @@
 
         textview = gtk.TextView()
         self.textBuffer = textview.get_buffer()
+        self.textBuffer.create_tag('highlight', background = 'yellow')
 
         scroll = gtk.ScrolledWindow()
         scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
@@ -683,7 +674,7 @@
         self.textview.set_editable(False)
         self.textview.set_cursor_visible(False)
 
-        scroll.add_with_viewport(self.textview)
+        scroll.add(self.textview)
 
         hbox = gtk.HBox(False, 5)
         saveButton = gtk.Button(stock=gtk.STOCK_SAVE)
@@ -694,10 +685,48 @@
 
         closeButton = gtk.Button(stock=gtk.STOCK_CLOSE)
         closeButton.connect("clicked", lambda w: self.window.hide())
+       
+        ############ Search TreeView ###################
+        self.search_active = False
+       
+        self.searchStore = gtk.ListStore(str, str, str, str)
+        self.searchTree = gtk.TreeView(self.searchStore)
+        self.searchTree.connect("row-activated", self.set_cursor)
+        self.searchTree.set_rules_hint(True)
+        cell = gtk.CellRendererText()
+       
+        nameCol = gtk.TreeViewColumn(_("Date"), cell, text=0)
+        dateCol = gtk.TreeViewColumn(_("Time"), cell, text=1)
+        timeCol = gtk.TreeViewColumn(_("Name"), cell, text=2)
+        msgCol = gtk.TreeViewColumn(_("Message"), cell, text=3)
+       
+        nameCol.set_resizable(True)
+        dateCol.set_resizable(True)
+        timeCol.set_resizable(True)       
+        msgCol.set_resizable(True)
+       
+        self.searchTree.append_column(nameCol)
+        self.searchTree.append_column(dateCol)
+        self.searchTree.append_column(timeCol)
+        self.searchTree.append_column(msgCol)
+       
+        self.searchSw = gtk.ScrolledWindow()
+        self.searchSw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+        self.searchSw.add(self.searchTree)
+        self.searchSw.set_size_request(100, 100)
+       
+        ##################################################
+       
+        #search box
+        searchLabel = gtk.Label(_("Search:"))
+        self.searchBox = gtk.Entry()
+        self.searchBox.connect("key-press-event", self.enter_pressed)
 
         hbox.pack_end(saveButton, False, False)
         hbox.pack_end(refreshButton, False, False)
         hbox.pack_end(closeButton, False, False)
+        hbox.pack_end(self.searchBox, False, False)
+        hbox.pack_end(searchLabel, False, False)
 
         textRenderer = gtk.CellRendererText()
         column = gtk.TreeViewColumn(_("Date"), textRenderer, markup=0)
@@ -713,7 +742,6 @@
         datesScroll.add_with_viewport(self.datesTree)
         datesScroll.set_size_request(150, -1)
 
-
         hPaned = gtk.HPaned()
         hPaned.pack1(datesScroll)
         hPaned.pack2(scroll)
@@ -721,6 +749,7 @@
         vbox = gtk.VBox(spacing=5)
         vbox.pack_start(hPaned)
         vbox.pack_start(hbox, False, False)
+        vbox.pack_start(self.searchSw)
         vbox.pack_start(gtk.Statusbar(), False, False)
 
         self.datesStamps = {}
@@ -730,6 +759,66 @@
         else:
             self.window.add(vbox)
             self.window.show_all()
+           
+        self.searchSw.hide_all()
+
+    def set_cursor(self, treeview, path, col):
+        (model, iter) = self.searchTree.get_selection().get_selected()
+        dateSearch = self.searchStore.get_value(iter, 0)
+        timeSearch = self.searchStore.get_value(iter, 1)
+       
+        #Search in the datesTree
+        self.datesTree.set_cursor_on_cell(0)
+        (model, iter) = self.datesTree.get_selection().get_selected()
+        while iter:
+            date = self.datesListstore.get_value(iter, 0)
+           
+            if date == dateSearch:
+                self.datesTree.set_cursor_on_cell(model.get_path(iter))
+                break
+           
+            iter = model.iter_next(iter)
+           
+        self.scroll_to_result(timeSearch)
+           
+    def scroll_to_result(self, timee):
+        start_iter = self.textBuffer.get_start_iter()
+        result = start_iter.forward_search(timee, gtk.TEXT_SEARCH_VISIBLE_ONLY,
+                None)
+               
+        if result is not None:
+            match_start_iter, match_end_iter = result
+            match_start_iter.backward_char() #include '(' or other character before time
+            match_end_iter.forward_line() #highlight all message not just time
+           
+            self.textBuffer.apply_tag_by_name('highlight', match_start_iter,
+                    match_end_iter)
+                   
+            match_start_mark = self.textBuffer.create_mark('match_start',
+                    match_start_iter, True)
+                   
+            self.textview.scroll_to_mark(match_start_mark, 0, True)
+
+    def enter_pressed(self, button, event):
+        print event.keyval
+        if len(self.searchBox.get_text()) == 0:
+            self.searchSw.hide_all()
+        elif event.keyval == 65293 or event.keyval == 65421: #If enter key is pressed
+            self.searchStore.clear()
+            text = self.searchBox.get_text()
+            self.searchSw.show_all()
+            self.datesTree.set_cursor_on_cell(0)
+            (model, iter) = self.datesTree.get_selection().get_selected()
+            self.search_active = True
+            while iter:
+                self.searchIter = iter
+                self.searchText = text
+                self.datesTree.set_cursor_on_cell(model.get_path(iter))
+                iter = model.iter_next(iter)
+               
+            self.search_active = False
+               
+            self.textview.get_buffer().set_text("")
 
     def fill_dates_tree(self, mail):
         '''fill the treeview with the logs dates'''
@@ -755,6 +844,7 @@
             #self.datesStamps[ctime] =  id_conversation
 
         return self.datesStamps
+               
 
     def on_dates_cursor_change(self, *args):
         try:
@@ -762,52 +852,50 @@
                 self.datesTree.get_selection().get_selected()[1], 0)[0]
         except (TypeError, AttributeError):
             return
-       
-        string1 = (_('Conversation opened'))
-        string2 = (_('Conversation closed'))
+
+
         ids_conversation = self.datesStamps[selected]
         nick_cache = {}
         self.textview.get_buffer().set_text("")
-        for id_conversation in ids_conversation:         
-            listMessages = self.logger.get_conversation(id_conversation, 10000)
-            if (len(listMessages)!= 0):
-                self.textview.display_html('<body><span style=\"font-weight: bold;\"><b>*** '+string1+' ***</b>'
-                                            '</span></body>')
-                for (stamp, mail, message) in listMessages:
+        for id_conversation in ids_conversation:
+            for (stamp, mail, message) in \
+                 self.logger.get_conversation(id_conversation, 10000):
 
-                    if mail in nick_cache:
-                        if nick_cache[mail]['next'] is not None and \
-                            nick_cache[mail]['next'] <= stamp:
-                            nick = self.logger.get_user_nick(mail, stamp)
-                            next = self.logger.get_next_nick_stamp(mail, stamp)
-                            nick_cache[mail] = {'nick': nick, 'next' : next}
-                        else:
-                            nick = nick_cache[mail]['nick']
-                    else:
+                if mail in nick_cache:
+                    if nick_cache[mail]['next'] is not None and \
+                        nick_cache[mail]['next'] <= stamp:
                         nick = self.logger.get_user_nick(mail, stamp)
                         next = self.logger.get_next_nick_stamp(mail, stamp)
                         nick_cache[mail] = {'nick': nick, 'next' : next}
-
-                    date = time.ctime(float(stamp)).split()[3]
-                    (_format, encoding, text) = message.split('\r\n', 2)
-                    style = parse_format(_format)
-                    nick = self.controller.unifiedParser.getParser(nick).get()
-                    text = self.controller.unifiedParser.getParser(text).get()
-                    text = text.replace("\r\n", "\n").replace("\n", "<br />")
-
-                    try:
-                        self.textview.display_html('<body>(%s) <b>%s: </b>'
-                            '<span style="%s">%s</span></body>' % (date, nick, style, text))
-                    except:
-                        # hide messages that we can't display
-                        pass
-                self.textview.display_html('<body><span style=\"font-weight: bold;\"><b>*** '+string2+' ***</b>'
-                                            '</span></body>')
-                self.textview.display_html('<br/>')
-
-            else:
-                pass
-
+                    else:
+                        nick = nick_cache[mail]['nick']
+                else:
+                    nick = self.logger.get_user_nick(mail, stamp)
+                    next = self.logger.get_next_nick_stamp(mail, stamp)
+                    nick_cache[mail] = {'nick': nick, 'next' : next}
+
+                timee = time.ctime(float(stamp)).split()[3]
+                (_format, encoding, text) = message.split('\r\n', 2)
+                style = parse_format(_format)
+                nick = self.controller.unifiedParser.getParser(nick).get()
+                text = self.controller.unifiedParser.getParser(text).get()
+                text = text.replace("\r\n", "\n").replace("\n", "<br />")
+               
+                if self.search_active:   
+                    date = self.datesListstore.get_value(self.searchIter, 0)
+                    if text.find(self.searchText) != -1:
+                        self.searchStore.append([date, timee, nick, text])
+
+                try:
+                    self.textview.display_html('<body>(%s) <b>%s: </b>'
+                        '<span style="%s">%s</span></body>' % (timee, nick, style, text))
+                except:
+                    # hide messages that we can't display
+                    pass
+            self.textview.display_html('<br/>')
+
+        #print self.textBuffer.get_text(self.textBuffer.get_start_iter(),
+         #self.textBuffer.get_end_iter())
 
     def on_save_logs(self, button):
 
Logged
darkblood
Jr. Member
**

l33tness: 0
Offline Offline

Posts: 6


View Profile Email
« Reply #3 on: February 25, 2010, 04:09:59 AM »

That's really awesome and everything seems to work. But can you maybe make something like jumping to the matching conversation from the results?

Thanks. Yes, i think. Tongue

thanks for your contribution! however, i've seen the diff against our latest code and seems some of it is removed (some "new" cando code, in example) can you confirm this?

I based myself on Logger.py from the source avaiable on the site. So i guess it's not the latest, I'm sorry, i should have used the latest version. I hope  it doesn't conflict with the code i've written, i'll check that later on today.

One question, is the latest versions of emesene on sourceforge or launchpad?

Thanks.
Logged
C10uD
ololol
Administrator
Hero Member
*****

l33tness: -9990
Offline Offline

Posts: 2308



View Profile Email
« Reply #4 on: February 25, 2010, 05:47:38 AM »

launchpad mirrors sourceforge, so they've some hours of difference, nothing more

if you please rebase your patch on the latest code, it could be better so we wouldn't lose any improvement it's been made meanwhile Smiley
Logged
darkblood
Jr. Member
**

l33tness: 0
Offline Offline

Posts: 6


View Profile Email
« Reply #5 on: February 25, 2010, 07:37:15 AM »

Hi again,

I ported to the most recent Logger, i didn't need to do any additional change. which is good. Tongue
Let me know if something is wrong.

Bye.
Logged
Pages: [1]
  Print  
 
Jump to:  

TinyPortal v.1.0.6 beta 2 © Bloc
Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!