diff --git a/src/chat_control.py b/src/chat_control.py index 0739adf0d..0726ffe21 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -1623,14 +1623,9 @@ class ChatControl(ChatControlBase): pending_how_many += len(gajim.events.get_events(self.account, self.contact.get_full_jid(), ['chat', 'pm'])) - 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 repair it or ' - 'remove it (all history will be lost).') % logger.LOG_DB_PATH) - rows = [] + rows = gajim.logger.get_last_conversation_lines(jid, restore_how_many, + pending_how_many, timeout, self.account) + local_old_kind = None self.conv_textview.just_cleared = True for row in rows: # row[0] time, row[1] has kind, row[2] the message, row[3] subject, row[4] additional_data diff --git a/src/common/connection.py b/src/common/connection.py index d5c709350..c1caf10bd 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -529,20 +529,10 @@ class CommonConnection: kind = 'chat_msg_sent' else: kind = 'single_msg_sent' - try: - gajim.logger.write( - kind, obj.jid, message, subject=obj.subject, - additional_data=obj.additional_data) - except exceptions.PysqliteOperationalError as error: - self.dispatch('DB_ERROR', (_('Disk Write Error'), str(error))) - except exceptions.DatabaseMalformed: - pritext = _('Database Error') - sectext = _('The database file (%s) cannot be read. Try' - ' to repair it (see ' - 'https://dev.gajim.org/gajim/gajim/wikis/help/DatabaseBackup)' - ' or remove it (all history will be lost).') % \ - common.logger.LOG_DB_PATH - self.dispatch('DB_ERROR', (pritext, sectext)) + + gajim.logger.write( + kind, obj.jid, message, subject=obj.subject, + additional_data=obj.additional_data) def ack_subscribed(self, jid): """ diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py index b5cfea5de..132770759 100644 --- a/src/common/connection_handlers.py +++ b/src/common/connection_handlers.py @@ -1069,17 +1069,7 @@ class ConnectionHandlersBase: if gajim.config.get('log_contact_status_changes') and \ gajim.config.should_log(self.name, obj.jid): - try: - gajim.logger.write('status', obj.jid, obj.status, obj.show) - except exceptions.PysqliteOperationalError as e: - self.dispatch('DB_ERROR', (_('Disk Write Error'), str(e))) - except exceptions.DatabaseMalformed: - pritext = _('Database Error') - sectext = _('The database file (%s) cannot be read. Try to ' - 'repair it (see http://trac.gajim.org/wiki/DatabaseBackup) ' - 'or remove it (all history will be lost).') % LOG_DB_PATH - self.dispatch('DB_ERROR', (pritext, sectext)) - our_jid = gajim.get_jid_from_account(self.name) + gajim.logger.write('status', obj.jid, obj.status, obj.show) def _nec_gc_presence_received(self, obj): if obj.conn.name != self.name: @@ -1244,18 +1234,8 @@ class ConnectionHandlersBase: subject = msg.getSubject() if session.is_loggable(): - try: - gajim.logger.write('error', frm, error_msg, tim=tim, - subject=subject) - except exceptions.PysqliteOperationalError as e: - self.dispatch('DB_ERROR', (_('Disk Write Error'), str(e))) - except exceptions.DatabaseMalformed: - pritext = _('Database Error') - sectext = _('The database file (%s) cannot be read. Try to ' - 'repair it (see http://trac.gajim.org/wiki/DatabaseBackup) ' - 'or remove it (all history will be lost).') % \ - common.logger.LOG_DB_PATH - self.dispatch('DB_ERROR', (pritext, sectext)) + gajim.logger.write('error', frm, error_msg, tim=tim, + subject=subject) gajim.nec.push_incoming_event(MessageErrorEvent(None, conn=self, fjid=frm, error_code=msg.getErrorCode(), error_msg=error_msg, msg=msgtxt, time_=tim, session=session, stanza=msg)) diff --git a/src/common/connection_handlers_events.py b/src/common/connection_handlers_events.py index 82f28e665..e8482b6f2 100644 --- a/src/common/connection_handlers_events.py +++ b/src/common/connection_handlers_events.py @@ -946,18 +946,7 @@ class GcPresenceReceivedEvent(nec.NetworkIncomingEvent, HelperEvent): if jid: # we know real jid, save it in db st += ' (%s)' % jid - try: - gajim.logger.write('gcstatus', self.fjid, st, self.show) - except exceptions.PysqliteOperationalError as e: - self.conn.dispatch('DB_ERROR', (_('Disk Write Error'), str(e))) - except exceptions.DatabaseMalformed: - pritext = _('Database Error') - sectext = _('The database file (%s) cannot be read. ' - 'Try to repair it (see ' - 'http://trac.gajim.org/wiki/DatabaseBackup) or ' - 'remove it (all history will be lost).') % \ - LOG_DB_PATH - self.conn.dispatch('DB_ERROR', (pritext, sectext)) + gajim.logger.write('gcstatus', self.fjid, st, self.show) if self.avatar_sha == '': # contact has no avatar puny_nick = helpers.sanitize_filename(self.nick) diff --git a/src/common/exceptions.py b/src/common/exceptions.py index 958d996dc..79c418b56 100644 --- a/src/common/exceptions.py +++ b/src/common/exceptions.py @@ -38,11 +38,15 @@ class DatabaseMalformed(Exception): The databas can't be read """ - def __init__(self): + def __init__(self, path=''): Exception.__init__(self) + self.path = path def __str__(self): - return _('Database cannot be read.') + return _('The database file (%s) cannot be read. ' + 'Try to repair it (see ' + 'https://dev.gajim.org/gajim/gajim/wikis/help/DatabaseBackup)' + ' or remove it (all history will be lost).') % self.path class ServiceNotAvailable(Exception): """ diff --git a/src/common/logger.py b/src/common/logger.py index 0d0d46bd9..b9221e8ba 100644 --- a/src/common/logger.py +++ b/src/common/logger.py @@ -121,6 +121,9 @@ class Logger: gajim.ged.register_event_handler('gc-message-received', ged.POSTCORE, self._nec_gc_message_received) + def dispatch(self, event, error): + gajim.ged.raise_event(event, None, str(error)) + def close_db(self): if self.con: self.con.close() @@ -191,7 +194,7 @@ class Logger: # list of tuples: [('aaa@bbb',), ('cc@dd',)] rows = self.cur.fetchall() except sqlite.DatabaseError: - raise exceptions.DatabaseMalformed + raise exceptions.DatabaseMalformed(LOG_DB_PATH) self.jids_already_in = [] for row in rows: # row[0] is first item of row (the only result here, the jid) @@ -416,7 +419,7 @@ class Logger: except sqlite.OperationalError as e: raise exceptions.PysqliteOperationalError(str(e)) except sqlite.DatabaseError: - raise exceptions.DatabaseMalformed + raise exceptions.DatabaseMalformed(LOG_DB_PATH) message_id = None if write_unread: try: @@ -531,58 +534,53 @@ class Logger: 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 - try: + try: + # 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 jid_id = self.get_jid_id(jid) - except exceptions.PysqliteOperationalError as e: - raise exceptions.PysqliteOperationalError(str(e)) - if show is None: # show is None (xmpp), but we say that 'online' - show_col = ShowConstant.ONLINE + if show is None: # show is None (xmpp), but we say that 'online' + show_col = ShowConstant.ONLINE - elif kind == 'gcstatus': - # status in ROOM (for pm status see status) - if show is None: # show is None (xmpp), but we say that 'online' - show_col = ShowConstant.ONLINE - jid, nick = jid.split('/', 1) - try: - # re-get jid_id for the new jid - jid_id = self.get_jid_id(jid, 'ROOM') - except exceptions.PysqliteOperationalError as e: - raise exceptions.PysqliteOperationalError(str(e)) - contact_name_col = nick - - elif kind == 'gc_msg': - if jid.find('/') != -1: # if it has a / + elif kind == 'gcstatus': + # status in ROOM (for pm status see status) + if show is None: # show is None (xmpp), but we say that 'online' + show_col = ShowConstant.ONLINE jid, nick = jid.split('/', 1) - else: - # it's server message f.e. error message - # when user tries to ban someone but he's not allowed to - nick = None - try: + # re-get jid_id for the new jid jid_id = self.get_jid_id(jid, 'ROOM') - except exceptions.PysqliteOperationalError as e: - raise exceptions.PysqliteOperationalError(str(e)) - contact_name_col = nick - else: - try: + contact_name_col = nick + + elif kind == 'gc_msg': + if jid.find('/') != -1: # if it has a / + jid, nick = jid.split('/', 1) + else: + # it's server message f.e. error message + # when user tries to ban someone but he's not allowed to + nick = None + + # re-get jid_id for the new jid + jid_id = self.get_jid_id(jid, 'ROOM') + + contact_name_col = nick + else: jid_id = self.get_jid_id(jid) - except exceptions.PysqliteOperationalError as e: - raise exceptions.PysqliteOperationalError(str(e)) - if kind == 'chat_msg_recv': - if not self.jid_is_from_pm(jid) and not mam_query: - # Save in unread table only if it's not a pm - write_unread = True + if kind == 'chat_msg_recv': + if not self.jid_is_from_pm(jid) and not mam_query: + # Save in unread table only if it's not a pm + write_unread = True - if show_col == 'UNKNOWN': # unknown show, do not log - return + 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, additional_data_col) - return self.commit_to_db(values, write_unread) + values = (jid_id, contact_name_col, time_col, kind_col, show_col, + message_col, subject_col, additional_data_col) + return self.commit_to_db(values, write_unread) + + except (exceptions.DatabaseMalformed, + exceptions.PysqliteOperationalError) as error: + self.dispatch('DB_ERROR', error) def get_last_conversation_lines(self, jid, restore_how_many_rows, pending_how_many, timeout, account): @@ -621,7 +619,9 @@ class Logger: parsed_entry = entry[:4] + (additional_data, ) + entry[5:] messages.append(parsed_entry) except sqlite.DatabaseError: - raise exceptions.DatabaseMalformed + self.dispatch('DB_ERROR', + exceptions.DatabaseMalformed(LOG_DB_PATH)) + return [] messages.reverse() return messages @@ -1186,19 +1186,8 @@ class Logger: # if not obj.nick, it means message comes from room itself # usually it hold description and can be send at each connection # so don't store it in logs - try: - self.write('gc_msg', obj.fjid, obj.msgtxt, tim=obj.timestamp, additional_data=obj.additional_data) - # store in memory time of last message logged. - # this will also be saved in rooms_last_message_time table - # when we quit this muc - obj.conn.last_history_time[obj.jid] = tim_f - - except exceptions.PysqliteOperationalError as e: - obj.conn.dispatch('DB_ERROR', (_('Disk Write Error'), str(e))) - except exceptions.DatabaseMalformed: - pritext = _('Database Error') - sectext = _('The database file (%s) cannot be read. Try to ' - 'repair it (see http://trac.gajim.org/wiki/DatabaseBackup) ' - 'or remove it (all history will be lost).') % \ - LOG_DB_PATH - obj.conn.dispatch('DB_ERROR', (pritext, sectext)) + self.write('gc_msg', obj.fjid, obj.msgtxt, tim=obj.timestamp, additional_data=obj.additional_data) + # store in memory time of last message logged. + # this will also be saved in rooms_last_message_time table + # when we quit this muc + obj.conn.last_history_time[obj.jid] = tim_f diff --git a/src/gajim.py b/src/gajim.py index f06af138a..b5849e92b 100644 --- a/src/gajim.py +++ b/src/gajim.py @@ -142,17 +142,14 @@ class GajimApplication(Gtk.Application): gajim.logger = logger.Logger() caps_cache.initialize(gajim.logger) check_paths.check_and_possibly_create_paths() - except exceptions.DatabaseMalformed: + except exceptions.DatabaseMalformed as error: dlg = Gtk.MessageDialog( None, Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, _('Database Error')) - dlg.format_secondary_text( - _('The database file (%s) cannot be read. Try to repair it ' - '(see http://trac.gajim.org/wiki/DatabaseBackup) or remove it ' - '(all history will be lost).') % gajim.gajimpaths['LOG_DB']) + dlg.format_secondary_text(str(error)) dlg.run() dlg.destroy() sys.exit() diff --git a/src/gui_interface.py b/src/gui_interface.py index 3226674c4..e5d2f9bce 100644 --- a/src/gui_interface.py +++ b/src/gui_interface.py @@ -109,11 +109,11 @@ class Interface: ### Methods handling events from connection ################################################################################ - def handle_event_db_error(self, unused, data): - #('DB_ERROR', account, (title_text, section_text)) + def handle_event_db_error(self, unused, error): + #('DB_ERROR', account, error) if self.db_error_dialog: return - self.db_error_dialog = dialogs.ErrorDialog(data[0], data[1]) + self.db_error_dialog = dialogs.ErrorDialog(_('Database Error'), error) def destroyed(win): self.db_error_dialog = None self.db_error_dialog.connect('destroy', destroyed) diff --git a/src/session.py b/src/session.py index ec5d3dd47..fcc1aee80 100644 --- a/src/session.py +++ b/src/session.py @@ -95,26 +95,12 @@ class ChatControlSession(stanza_session.EncryptedStanzaSession): log_type += end if self.is_loggable() and obj.msgtxt: - try: - if obj.xhtml and gajim.config.get('log_xhtml_messages'): - msg_to_log = obj.xhtml - else: - msg_to_log = obj.msgtxt - obj.msg_log_id = gajim.logger.write(log_type, obj.fjid, - msg_to_log, tim=obj.timestamp, subject=obj.subject, additional_data=obj.additional_data) - except exceptions.PysqliteOperationalError as e: - gajim.nec.push_incoming_event(InformationEvent(None, - conn=self.conn, level='error', pri_txt=_('Disk Write Error'), - sec_txt=str(e))) - except exceptions.DatabaseMalformed: - pritext = _('Database Error') - sectext = _('The database file (%s) cannot be read. Try to ' - 'repair it (see http://trac.gajim.org/wiki/DatabaseBackup) ' - 'or remove it (all history will be lost).') % \ - gajim.logger.LOG_DB_PATH - gajim.nec.push_incoming_event(InformationEvent(None, - conn=self.conn, level='error', pri_txt=pritext, - sec_txt=sectext)) + if obj.xhtml and gajim.config.get('log_xhtml_messages'): + msg_to_log = obj.xhtml + else: + msg_to_log = obj.msgtxt + obj.msg_log_id = gajim.logger.write(log_type, obj.fjid, + msg_to_log, tim=obj.timestamp, subject=obj.subject, additional_data=obj.additional_data) treat_as = gajim.config.get('treat_incoming_messages') if treat_as: