From 97dc7215dff8bad1ae9c7875f986a2e95cf2a286 Mon Sep 17 00:00:00 2001 From: Dimitur Kirov Date: Mon, 10 Apr 2006 22:08:02 +0000 Subject: [PATCH] keep reference to unread messages untill they are printed in tv --- src/chat_control.py | 8 +++++-- src/common/check_paths.py | 20 +++++++++++++++++ src/common/connection_handlers.py | 2 +- src/common/logger.py | 37 +++++++++++++++++++++++++++---- src/gajim.py | 2 +- src/roster_window.py | 6 +++-- 6 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/chat_control.py b/src/chat_control.py index b4aaa3a7d..6b1b47d45 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -1403,6 +1403,8 @@ class ChatControl(ChatControlBase): if control and control.type_id == message_control.TYPE_GC: is_pm = True events_to_keep = [] + # list of message ids which should be marked as read + message_ids = [] for event in l: typ = event[0] if typ != 'chat': @@ -1416,13 +1418,15 @@ class ChatControl(ChatControlBase): kind = 'print_queue' self.print_conversation(data[0], kind, tim = data[3], encrypted = data[4], subject = data[1]) - + if len(data) > 6 and isinstance(data[6], int): + message_ids.append(data[6]) # remove from gc nb_unread if it's pm or from roster if is_pm: control.nb_unread -= 1 else: gajim.interface.roster.nb_unread -= 1 - + if message_ids: + gajim.logger.set_read_messages(message_ids) if is_pm: control.parent_win.show_title() else: diff --git a/src/common/check_paths.py b/src/common/check_paths.py index 78cb3c583..45e8815b8 100644 --- a/src/common/check_paths.py +++ b/src/common/check_paths.py @@ -35,6 +35,20 @@ Q_ = i18n.Q_ from pysqlite2 import dbapi2 as sqlite # DO NOT MOVE ABOVE OF import gajim +def assert_um_exists(): + ''' create table unread_messages if there is no such table ''' + con = sqlite.connect(logger.LOG_DB_PATH) + os.chmod(logger.LOG_DB_PATH, 0600) # rw only for us + cur = con.cursor() + cur.executescript( + ''' + CREATE TABLE IF NOT EXISTS unread_messages ( + message_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE + ); + ''' + ) + con.commit() + def create_log_db(): print _('creating logs database') con = sqlite.connect(logger.LOG_DB_PATH) @@ -56,6 +70,10 @@ def create_log_db(): type INTEGER ); + CREATE TABLE unread_messages( + message_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE + ); + CREATE TABLE logs( log_line_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE, jid_id INTEGER, @@ -105,6 +123,8 @@ def check_and_possibly_create_paths(): print _('%s is directory but should be file') % LOG_DB_PATH print _('Gajim will now exit') sys.exit() + else: + assert_um_exists() else: # dot_gajim doesn't exist if dot_gajim: # is '' on win9x so avoid that diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index 579a10392..946d5be9d 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -1288,7 +1288,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco) return if msg.getTag('body') and self.name not in no_log_for and jid not in\ no_log_for and msgtxt: - gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim, + msg_id = gajim.logger.write('chat_msg_recv', frm, msgtxt, tim = tim, subject = subject) self.dispatch('MSG', (frm, msgtxt, tim, encrypted, mtype, subject, chatstate, msg_id, composing_jep)) diff --git a/src/common/logger.py b/src/common/logger.py index 6bbeddb22..85932cb95 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -194,10 +194,35 @@ class Logger: return kind_col, show_col - def commit_to_db(self, values): + def commit_to_db(self, values, write_unread = False): #print 'saving', values sql = 'INSERT INTO logs (jid_id, contact_name, time, kind, show, message, subject) VALUES (?, ?, ?, ?, ?, ?, ?)' self.cur.execute(sql, values) + message_id = None + try: + self.con.commit() + if write_unread: + message_id = self.cur.lastrowid + except sqlite.OperationalError, e: + print >> sys.stderr, str(e) + if message_id: + self.insert_unread_events(message_id) + return message_id + + def insert_unread_events(self, message_id): + ''' add unread message with id: message_id''' + sql = 'INSERT INTO unread_messages VALUES (%d)' % message_id + self.cur.execute(sql) + try: + self.con.commit() + except sqlite.OperationalError, e: + print >> sys.stderr, str(e) + + def set_read_messages(self, message_ids): + ''' mark all messages with ids in message_ids as read''' + ids = ','.join([str(i) for i in message_ids]) + sql = 'DELETE FROM unread_messages WHERE message_id IN (%s)' % ids + self.cur.execute(sql) try: self.con.commit() except sqlite.OperationalError, e: @@ -233,7 +258,9 @@ class Logger: kind_col, show_col = self.convert_human_values_to_db_api_values(kind, show) - + + write_unread = False + # now we may have need to do extra care for some values in columns if kind == 'status': # we store (not None) time, jid, show, msg # status for roster items @@ -260,14 +287,16 @@ class Logger: contact_name_col = nick else: jid_id = self.get_jid_id(jid) + if kind == 'chat_msg_recv': + write_unread = True if show_col == 'UNKNOWN': # unknown show, do not log return values = (jid_id, contact_name_col, time_col, kind_col, show_col, message_col, subject_col) - self.commit_to_db(values) - + return self.commit_to_db(values, write_unread) + def get_last_conversation_lines(self, jid, restore_how_many_rows, pending_how_many, timeout): '''accepts how many rows to restore and when to time them out (in minutes) diff --git a/src/gajim.py b/src/gajim.py index 12062b9d7..d0dfbf198 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -618,7 +618,7 @@ class Interface: # array: (jid, msg, time, encrypted, msg_type, subject) self.roster.on_message(jid, message, array[2], account, array[3], - msg_type, array[5], resource) + msg_type, array[5], resource, msg_id) if self.remote_ctrl: self.remote_ctrl.raise_signal('NewMessage', (account, array)) diff --git a/src/roster_window.py b/src/roster_window.py index d7cb21d86..bd87a7728 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -2097,7 +2097,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid) mw.new_tab(gc_control) def on_message(self, jid, msg, tim, account, encrypted = False, - msg_type = '', subject = None, resource = ''): + msg_type = '', subject = None, resource = '', msg_id = None): '''when we receive a message''' contact = None # if chat window will be for specific resource @@ -2167,6 +2167,8 @@ _('If "%s" accepts this request you will know his or her status.') % jid) typ = 'status' ctrl.print_conversation(msg, typ, tim = tim, encrypted = encrypted, subject = subject) + if msg_id: + gajim.logger.set_read_messages([msg_id]) return # We save it in a queue @@ -2176,7 +2178,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid) if msg_type == 'normal': kind = 'normal' qs[fjid].append((kind, (msg, subject, msg_type, tim, encrypted, - resource))) + resource, msg_id))) self.nb_unread += 1 if popup: if not ctrl: