diff --git a/src/chat_control.py b/src/chat_control.py index bd74c921283abbade5338f0eecfc555769456555..88f5e244065fa937e488a2d7e28a018e9523cec6 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -37,6 +37,7 @@ import re from common import gajim from common import helpers +from common import exceptions from message_control import MessageControl from conversation_textview import ConversationTextview from message_textview import MessageTextView @@ -2004,8 +2005,13 @@ class ChatControl(ChatControlBase): pending_how_many += len(gajim.events.get_events(self.account, self.contact.get_full_jid(), ['chat', 'pm'])) - rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many, - pending_how_many, timeout, self.account) + try: + rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many, + pending_how_many, timeout, self.account) + except exceptions.DatabaseMalformed: + dialogs.ErrorDialog(_('Database Error'), + _('The database file (%s) cannot be read. Try to repare it or remove it (all history will be lost).') % common.logger.LOG_DB_PATH) + rows = [] local_old_kind = None for row in rows: # row[0] time, row[1] has kind, row[2] the message if not row[2]: # message is empty, we don't print it diff --git a/src/common/exceptions.py b/src/common/exceptions.py index 7b19cddc23e575286ea5652f09e26fa295ac98e4..c8385f6b764363900c5b8dcd894849c4c934b9ff 100644 --- a/src/common/exceptions.py +++ b/src/common/exceptions.py @@ -35,6 +35,14 @@ class PysqliteOperationalError(Exception): def __str__(self): return self.text +class DatabaseMalformed(Exception): + '''The databas can't be read''' + def __init__(self): + Exception.__init__(self) + + def __str__(self): + return _('Database cannot be read.') + class ServiceNotAvailable(Exception): '''This exception is raised when we cannot use Gajim remotely''' def __init__(self): diff --git a/src/common/logger.py b/src/common/logger.py index 3698f2b8c6c27246c58d71407615c58f91a7aa88..f8c8bc9ceb2acbf1f09ea309ecfb787f8ac0a3ad 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -136,8 +136,11 @@ class Logger: self.get_jids_already_in_db() def get_jids_already_in_db(self): - self.cur.execute('SELECT jid FROM jids') - rows = self.cur.fetchall() # list of tupples: [(u'aaa@bbb',), (u'cc@dd',)] + try: + self.cur.execute('SELECT jid FROM jids') + rows = self.cur.fetchall() # list of tupples: [(u'aaa@bbb',), (u'cc@dd',)] + except sqlite.DatabaseError: + raise exceptions.DatabaseMalformed self.jids_already_in = [] for row in rows: # row[0] is first item of row (the only result here, the jid) @@ -443,17 +446,20 @@ class Logger: timed_out = now - (timeout * 60) # before that they are too old # so if we ask last 5 lines and we have 2 pending we get # 3 - 8 (we avoid the last 2 lines but we still return 5 asked) - self.cur.execute(''' - SELECT time, kind, message FROM logs - WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d - ORDER BY time DESC LIMIT %d OFFSET %d - ''' % (where_sql, constants.KIND_SINGLE_MSG_RECV, - constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT, - constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR, - timed_out, restore_how_many_rows, pending_how_many) - ) + try: + self.cur.execute(''' + SELECT time, kind, message FROM logs + WHERE (%s) AND kind IN (%d, %d, %d, %d, %d) AND time > %d + ORDER BY time DESC LIMIT %d OFFSET %d + ''' % (where_sql, constants.KIND_SINGLE_MSG_RECV, + constants.KIND_CHAT_MSG_RECV, constants.KIND_SINGLE_MSG_SENT, + constants.KIND_CHAT_MSG_SENT, constants.KIND_ERROR, + timed_out, restore_how_many_rows, pending_how_many) + ) - results = self.cur.fetchall() + results = self.cur.fetchall() + except sqlite.DatabaseError: + raise exceptions.DatabaseMalformed results.reverse() return results diff --git a/src/gajim.py b/src/gajim.py index b583bb4e5641044d4c94bb268638d43ca3437898..b121afe044fb16e3624a0b4c0561745f8876a286 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -145,57 +145,56 @@ except Warning, msg: sys.exit() warnings.resetwarnings() -import message_control - -from chat_control import ChatControlBase -from atom_window import AtomWindow - -import negotiation - -from common import exceptions -from common.zeroconf import connection_zeroconf -from common import dbus_support -if dbus_support.supported: - import dbus - -if os.name == 'posix': # dl module is Unix Only - try: # rename the process name to gajim - import dl - libc = dl.open('/lib/libc.so.6') - libc.call('prctl', 15, 'gajim\0', 0, 0, 0) - except: - pass - pritext = '' -if gtk.pygtk_version < (2, 8, 0): - pritext = _('Gajim needs PyGTK 2.8 or above') - sectext = _('Gajim needs PyGTK 2.8 or above to run. Quiting...') -elif gtk.gtk_version < (2, 8, 0): - pritext = _('Gajim needs GTK 2.8 or above') - sectext = _('Gajim needs GTK 2.8 or above to run. Quiting...') +from common import exceptions try: - import gtk.glade # check if user has libglade (in pygtk and in gtk) -except ImportError: - pritext = _('GTK+ runtime is missing libglade support') - if os.name == 'nt': - sectext = _('Please remove your current GTK+ runtime and install the latest stable version from %s') % 'http://gladewin32.sourceforge.net' - else: - sectext = _('Please make sure that GTK+ and PyGTK have libglade support in your system.') + from common import gajim +except exceptions.DatabaseMalformed: + pritext = _('Database Error') + sectext = _('The database file (%s) cannot be read. Try to repare it or remove it (all history will be lost).') % common.logger.LOG_DB_PATH +else: + from common import dbus_support + if dbus_support.supported: + import dbus + + if os.name == 'posix': # dl module is Unix Only + try: # rename the process name to gajim + import dl + libc = dl.open('/lib/libc.so.6') + libc.call('prctl', 15, 'gajim\0', 0, 0, 0) + except: + pass -try: - from common import check_paths -except exceptions.PysqliteNotAvailable, e: - pritext = _('Gajim needs PySQLite2 to run') - sectext = str(e) + if gtk.pygtk_version < (2, 8, 0): + pritext = _('Gajim needs PyGTK 2.8 or above') + sectext = _('Gajim needs PyGTK 2.8 or above to run. Quiting...') + elif gtk.gtk_version < (2, 8, 0): + pritext = _('Gajim needs GTK 2.8 or above') + sectext = _('Gajim needs GTK 2.8 or above to run. Quiting...') -if os.name == 'nt': try: - import winsound # windows-only built-in module for playing wav - import win32api # do NOT remove. we req this module - except: - pritext = _('Gajim needs pywin32 to run') - sectext = _('Please make sure that Pywin32 is installed on your system. You can get it at %s') % 'http://sourceforge.net/project/showfiles.php?group_id=78018' + import gtk.glade # check if user has libglade (in pygtk and in gtk) + except ImportError: + pritext = _('GTK+ runtime is missing libglade support') + if os.name == 'nt': + sectext = _('Please remove your current GTK+ runtime and install the latest stable version from %s') % 'http://gladewin32.sourceforge.net' + else: + sectext = _('Please make sure that GTK+ and PyGTK have libglade support in your system.') + + try: + from common import check_paths + except exceptions.PysqliteNotAvailable, e: + pritext = _('Gajim needs PySQLite2 to run') + sectext = str(e) + + if os.name == 'nt': + try: + import winsound # windows-only built-in module for playing wav + import win32api # do NOT remove. we req this module + except: + pritext = _('Gajim needs pywin32 to run') + sectext = _('Please make sure that Pywin32 is installed on your system. You can get it at %s') % 'http://sourceforge.net/project/showfiles.php?group_id=78018' if pritext: dlg = gtk.MessageDialog(None, @@ -230,14 +229,19 @@ import math import gtkgui_helpers import notify +import message_control +import negotiation + +from chat_control import ChatControlBase +from atom_window import AtomWindow import common.sleepy from common.xmpp import idlequeue +from common.zeroconf import connection_zeroconf from common import nslookup from common import proxy65_manager from common import socks5 -from common import gajim from common import helpers from common import optparser from common import dataforms