Philipp Hörist pushed to branch master at gajim / gajim
Commits:
f4f7f1d1 by Andrey Gursky at 2019-07-22T02:03:27Z
Fix typo
Closes #9766
- - - - -
23d0bfcf by Andrey Gursky at 2019-07-22T02:55:30Z
Make exception message more informative
- - - - -
3 changed files:
- gajim/common/modules/base.py
- gajim/common/modules/message.py
- gajim/session.py
Changes:
=====================================
gajim/common/modules/base.py
=====================================
@@ -50,7 +50,7 @@ class BaseModule:
def __getattr__(self, key):
if key not in self._nbxmpp_methods:
- raise AttributeError
+ raise AttributeError("attribute '%s' is neither part of object '%s' nor declared in '_nbxmpp_methods'" % (key, self.__class__.__name__))
if not app.account_is_connected(self._account):
self._log.warning('Account not connected, cant use %s', key)
return
=====================================
gajim/common/modules/message.py
=====================================
@@ -294,7 +294,7 @@ class Message(BaseModule):
message_id=event.message_id)
if muc_caps_cache.has_mam(event.room_jid):
- finished = self._con.get_module('MAM').is_catchup_finished(
+ finished = self._con.get_module('MAM').is_catch_up_finished(
event.room_jid)
if not finished:
return
=====================================
gajim/session.py
=====================================
@@ -140,7 +140,7 @@ class ChatControlSession:
message_id=obj.message_id)
jid = self.conn.get_own_jid().getStripped()
- if self.conn.get_module('MAM').is_catchup_finished(jid):
+ if self.conn.get_module('MAM').is_catch_up_finished(jid):
app.logger.set_archive_infos(jid,
last_mam_id=obj.stanza_id,
last_muc_timestamp=obj.timestamp)
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/623960beb212af053b5ffa7967010e4ad…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/623960beb212af053b5ffa7967010e4ad…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
623960be by Philipp Hörist at 2019-07-21T21:13:27Z
StartChat: Only show GroupchatInfo when not already joined
When we are already in a group chat just show the GroupChatControl
instead of GroupchatInfo
- - - - -
2 changed files:
- gajim/gtk/start_chat.py
- gajim/gui_interface.py
Changes:
=====================================
gajim/gtk/start_chat.py
=====================================
@@ -259,7 +259,14 @@ class StartChatDialog(Gtk.ApplicationWindow):
self._show_error_page(_('You can not join a group chat '
'unless you are connected.'))
return
+
+ self.ready_to_destroy = True
+ if app.interface.show_groupchat(row.account, row.jid):
+ return
+
+ self.ready_to_destroy = False
self._disco_muc(row.account, row.jid)
+
else:
app.interface.new_chat_from_jid(row.account, row.jid)
self.ready_to_destroy = True
=====================================
gajim/gui_interface.py
=====================================
@@ -1553,6 +1553,19 @@ class Interface:
### Methods for opening new messages controls
################################################################################
+ def show_groupchat(self, account, room_jid):
+ minimized_control = self.minimized_controls[account].get(room_jid)
+ if minimized_control is not None:
+ self.roster.on_groupchat_maximized(None, room_jid, account)
+ return True
+
+ if self.msg_win_mgr.has_window(room_jid, account):
+ gc_ctrl = self.msg_win_mgr.get_gc_control(room_jid, account)
+ # FIXME: Access message window directly
+ gc_ctrl.parent_win.set_active_tab(gc_ctrl)
+ return True
+ return False
+
def join_gc_room(self, account, room_jid, nick, password, minimize=False,
is_continued=False, config=None):
"""
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/623960beb212af053b5ffa7967010e4ad4…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/623960beb212af053b5ffa7967010e4ad4…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
d6178669 by Philipp Hörist at 2019-07-21T14:30:14Z
MUC: Use SyncThreshold for MUC history
Before SyncThreshold was only used for MAM history. Now its also used
for MUC history.
- - - - -
e97a6317 by Philipp Hörist at 2019-07-21T17:38:15Z
XMLConsole: Add jabber:client namespace to templates
Without the namespace all child elements get a undeclared namespace
- - - - -
dc282f22 by Philipp Hörist at 2019-07-21T18:02:05Z
Refactor save_archive_id
Move the code out of the MAM module as we need it also for
MUC history now
- - - - -
9 changed files:
- gajim/common/config.py
- gajim/common/logger.py
- gajim/common/modules/mam.py
- gajim/common/modules/message.py
- gajim/common/modules/muc.py
- gajim/common/structs.py
- gajim/groupchat_control.py
- gajim/gtk/xml_console.py
- gajim/session.py
Changes:
=====================================
gajim/common/config.py
=====================================
@@ -170,8 +170,6 @@ class Config:
'change_roster_title': [opt_bool, True, _('If enabled, Gajim will add * and [n] in contact list window title.')],
'restore_lines': [opt_int, 10, _('Number of messages from chat history to be restored when a chat tab/window is reopened.')],
'restore_timeout': [opt_int, -1, _('How far back in time (minutes) chat history is restored. -1 means no limit.')],
- 'muc_restore_lines': [opt_int, 100, _('How many lines to request from server when entering a group chat. -1 means no limit.')],
- 'muc_restore_timeout': [opt_int, -1, _('Minutes of backlog to request when entering a group chat. -1 means no limit.')],
'muc_autorejoin_timeout': [opt_int, 1, _('How many seconds to wait before trying to automatically rejoin a group chat you were disconnected from. Set to 0 to disable automatic rejoining.')],
'muc_autorejoin_on_kick': [opt_bool, False, _('Should automatic rejoin be activated when you were kicked from a group chat?')],
'send_on_ctrl_enter': [opt_bool, False, _('Send message on Ctrl+Enter and make a new line with Enter.')],
@@ -429,8 +427,6 @@ class Config:
}, {}),
'rooms': ({
'speller_language': [opt_str, '', _('Language used for spell checking.')],
- 'muc_restore_lines': [opt_int, -2, _('How many lines to request from server when entering a group chat. -1 means no limit, -2 means global value.')],
- 'muc_restore_timeout': [opt_int, -2, _('Minutes of backlog to request when entering a group chat. -1 means no limit, -2 means global value.')],
'notify_on_all_messages': [opt_bool, False, _('If enabled, a notification is created for every message in this group chat.')],
'print_status': [opt_bool, False, _('Show a status message for all status changes (away, dnd, etc.) of users in a group chat.')],
'print_join_left': [opt_bool, False, _('Show a status message for every join or leave in a group chat.')],
=====================================
gajim/common/logger.py
=====================================
@@ -103,10 +103,7 @@ CACHE_SQL_STATEMENT = '''
hash_method TEXT,
hash TEXT,
data TEXT,
- last_seen INTEGER);
- CREATE TABLE rooms_last_message_time(
- jid_id INTEGER PRIMARY KEY UNIQUE,
- time INTEGER
+ last_seen INTEGER
);
CREATE TABLE roster_entry(
account_jid_id INTEGER,
@@ -962,45 +959,6 @@ class Logger:
return self._con.execute(
sql, tuple(jids) + (start, end)).fetchone()
- def get_room_last_message_time(self, account, jid):
- """
- Get the timestamp of the last message we received in a room.
-
- :param account: The account
-
- :param jid: The jid for which we request the last timestamp
-
- returns a timestamp or None
- """
- sql = '''
- SELECT time FROM rooms_last_message_time
- NATURAL JOIN jids WHERE jid = ?
- '''
-
- row = self._con.execute(sql, (jid,)).fetchone()
- if not row:
- return self.get_last_date_that_has_logs(account, jid)
- return row.time
-
- def set_room_last_message_time(self, jid, timestamp):
- """
- Set the timestamp of the last message we received in a room.
-
- :param jid: The jid
-
- :param timestamp: The timestamp in epoch
-
- """
-
- jid_id = self.get_jid_id(jid, type_=JIDConstant.ROOM_TYPE)
- sql = '''REPLACE INTO rooms_last_message_time
- VALUES (:jid_id, COALESCE(
- (SELECT time FROM rooms_last_message_time
- WHERE jid_id = :jid_id AND time >= :time), :time))'''
-
- self._con.execute(sql, {"jid_id": jid_id, "time": timestamp})
- self._timeout_commit()
-
def save_transport_type(self, jid, type_):
"""
Save the type of the transport in DB
@@ -1497,6 +1455,10 @@ class Logger:
kwargs.get('sync_threshold', None)
))
else:
+ for key, value in list(kwargs.items()):
+ if value is None:
+ del kwargs[key]
+
args = ' = ?, '.join(kwargs.keys()) + ' = ?'
sql = '''UPDATE last_archive_message SET {}
WHERE jid_id = ?'''.format(args)
=====================================
gajim/common/modules/mam.py
=====================================
@@ -73,6 +73,9 @@ class MAM(BaseModule):
self._mam_query_ids.clear()
self._catch_up_finished.clear()
+ def is_catch_up_finished(self, jid):
+ return jid in self._catch_up_finished
+
def _from_valid_archive(self, _stanza, properties):
if properties.type.is_groupchat:
expected_archive = properties.jid
@@ -531,20 +534,6 @@ class MAM(BaseModule):
query.setAttr('queryid', query_id)
return iq
- def save_archive_id(self, jid, stanza_id, timestamp):
- if jid is None:
- jid = self._con.get_own_jid().getStripped()
- if jid not in self._catch_up_finished:
- return
- self._log.info('Save: %s: %s, %s', jid, stanza_id, timestamp)
- if stanza_id is None:
- # mam:1
- app.logger.set_archive_infos(jid, last_muc_timestamp=timestamp)
- else:
- # mam:2
- app.logger.set_archive_infos(
- jid, last_mam_id=stanza_id, last_muc_timestamp=timestamp)
-
def request_mam_preferences(self):
self._log.info('Request MAM preferences')
iq = nbxmpp.Iq('get', self.archiving_namespace)
=====================================
gajim/common/modules/message.py
=====================================
@@ -26,6 +26,7 @@ from gajim.common.i18n import _
from gajim.common.nec import NetworkIncomingEvent
from gajim.common.nec import NetworkEvent
from gajim.common.helpers import AdditionalDataDict
+from gajim.common.caps_cache import muc_caps_cache
from gajim.common.const import KindConstant
from gajim.common.modules.base import BaseModule
from gajim.common.modules.util import get_eme_message
@@ -251,7 +252,6 @@ class Message(BaseModule):
event.nickname = event.resource
event.xhtml_msgtxt = event.xhtml
event.nick = event.resource or ''
-
app.nec.push_incoming_event(NetworkEvent('gc-message-received',
**vars(event)))
# TODO: Some plugins modify msgtxt in the GUI event
@@ -292,9 +292,16 @@ class Message(BaseModule):
additional_data=event.additional_data,
stanza_id=event.stanza_id,
message_id=event.message_id)
- app.logger.set_room_last_message_time(event.room_jid, event.timestamp)
- self._con.get_module('MAM').save_archive_id(
- event.room_jid, event.stanza_id, event.timestamp)
+
+ if muc_caps_cache.has_mam(event.room_jid):
+ finished = self._con.get_module('MAM').is_catchup_finished(
+ event.room_jid)
+ if not finished:
+ return
+
+ app.logger.set_archive_infos(event.room_jid,
+ last_mam_id=event.stanza_id,
+ last_muc_timestamp=event.timestamp)
def _check_for_mam_compliance(self, room_jid, stanza_id):
namespace = caps_cache.muc_caps_cache.get_mam_namespace(room_jid)
=====================================
gajim/common/modules/muc.py
=====================================
@@ -17,6 +17,8 @@
import time
import logging
+from datetime import datetime
+from datetime import timedelta
from functools import partial
import nbxmpp
@@ -30,9 +32,11 @@ from gajim.common import app
from gajim.common import helpers
from gajim.common.const import KindConstant
from gajim.common.const import MUCJoinedState
+from gajim.common.const import SyncThreshold
from gajim.common.structs import MUCData
from gajim.common.helpers import AdditionalDataDict
from gajim.common.helpers import get_default_muc_config
+from gajim.common.helpers import get_sync_threshold
from gajim.common import idle
from gajim.common.caps_cache import muc_caps_cache
from gajim.common.nec import NetworkEvent
@@ -130,11 +134,11 @@ class MUC(BaseModule):
def get_mucs_with_state(self, states):
return [muc for muc in self._muc_data.values() if muc.state in states]
- def join(self, room_jid, nick, password, rejoin=False, config=None):
+ def join(self, room_jid, nick, password, config=None):
if not app.account_is_connected(self._account):
return
- muc_data = MUCData(room_jid, nick, password, rejoin, config)
+ muc_data = MUCData(room_jid, nick, password, config)
self._muc_data[room_jid] = muc_data
self._con.get_module('Discovery').disco_muc(
@@ -149,7 +153,7 @@ class MUC(BaseModule):
status=self._con.status)
muc_x = presence.setTag(nbxmpp.NS_MUC + ' x')
- self._add_history_query(muc_x, str(muc_data.jid), muc_data.rejoin)
+ self._add_history_query(muc_x, str(muc_data.jid))
if muc_data.password is not None:
muc_x.setTagData('password', muc_data.password)
@@ -281,37 +285,27 @@ class MUC(BaseModule):
show=show,
status=self._con.status)
- def _add_history_query(self, muc_x, room_jid, rejoin):
- last_date = app.logger.get_room_last_message_time(
- self._account, room_jid)
- if not last_date:
- last_date = 0
-
+ def _add_history_query(self, muc_x, room_jid):
if muc_caps_cache.has_mam(room_jid):
# The room is MAM capable dont get MUC History
muc_x.setTag('history', {'maxchars': '0'})
else:
# Request MUC History (not MAM)
- tags = {}
- timeout = app.config.get_per('rooms', room_jid,
- 'muc_restore_timeout')
- if timeout is None or timeout == -2:
- timeout = app.config.get('muc_restore_timeout')
- if last_date == 0 and timeout >= 0:
- last_date = time.time() - timeout * 60
- elif not rejoin and timeout >= 0:
- last_date = max(last_date, time.time() - timeout * 60)
- last_date = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(
- last_date))
- tags['since'] = last_date
-
- nb = app.config.get_per('rooms', room_jid, 'muc_restore_lines')
- if nb is None or nb == -2:
- nb = app.config.get('muc_restore_lines')
- if nb >= 0:
- tags['maxstanzas'] = nb
- if tags:
- muc_x.setTag('history', tags)
+ archive = app.logger.get_archive_infos(room_jid)
+ threshold = get_sync_threshold(room_jid, archive)
+
+ since_epoch = 0
+ if archive is not None and archive.last_muc_timestamp is not None:
+ since_epoch = float(archive.last_muc_timestamp)
+
+ since_date = datetime.utcfromtimestamp(since_epoch)
+ if threshold != SyncThreshold.NO_THRESHOLD:
+ threshold_date = datetime.utcnow() - timedelta(days=threshold)
+ since_date = max(threshold_date, since_date)
+
+ date_string = since_date.strftime('%Y-%m-%dT%H:%M:%SZ')
+ muc_x.setTag('history', {'since': date_string})
+ self._log.info('Threshold for %s: %s', room_jid, threshold)
def _on_muc_presence(self, _con, _stanza, properties):
muc_data = self._get_muc_data(properties.muc_jid)
=====================================
gajim/common/structs.py
=====================================
@@ -26,11 +26,10 @@ CapsIdentity = namedtuple('CapsIdentity', 'category type name lang')
class MUCData:
- def __init__(self, room_jid, nick, password, rejoin, config=None):
+ def __init__(self, room_jid, nick, password, config=None):
self._room_jid = JID(room_jid)
self._nick = nick
self._password = password
- self._rejoin = rejoin
self._config = config
self._state = MUCJoinedState.NOT_JOINED
@@ -64,14 +63,6 @@ class MUCData:
def state(self, value):
self._state = value
- @property
- def rejoin(self):
- return self._rejoin
-
- @rejoin.setter
- def rejoin(self, value):
- self._rejoin = value
-
@property
def config(self):
return self._config
=====================================
gajim/groupchat_control.py
=====================================
@@ -511,10 +511,6 @@ class GroupchatControl(ChatControlBase):
vcard_support and
contact.affiliation.is_owner)
- # Sync Threshold
- has_mam = muc_caps_cache.has_mam(self.room_jid)
- self._get_action('choose-sync-').set_enabled(has_mam)
-
# Print join/left
join_default = app.config.get('print_join_left_default')
value = app.config.get_per('rooms', self.contact.jid,
@@ -1414,8 +1410,7 @@ class GroupchatControl(ChatControlBase):
if obj.conn.name != self.account:
return
password = app.gc_passwords.get(self.room_jid, '')
- obj.conn.get_module('MUC').join(self.room_jid, self.nick, password,
- rejoin=True)
+ obj.conn.get_module('MUC').join(self.room_jid, self.nick, password)
def _nec_decrypted_message_received(self, obj):
if obj.conn.name != self.account:
@@ -1552,7 +1547,7 @@ class GroupchatControl(ChatControlBase):
return False
password = app.gc_passwords.get(self.room_jid, '')
app.connections[self.account].get_module('MUC').join(
- self.room_jid, self.nick, password, rejoin=True)
+ self.room_jid, self.nick, password)
return True
def draw_roster(self):
=====================================
gajim/gtk/xml_console.py
=====================================
@@ -34,9 +34,6 @@ from gajim.gtk.const import SettingKind
from gajim.gtk.const import SettingType
-UNDECLARED = 'http://www.gajim.org/xmlns/undeclared'
-
-
class XMLConsoleWindow(Gtk.ApplicationWindow):
def __init__(self, account):
Gtk.ApplicationWindow.__init__(self)
@@ -141,19 +138,19 @@ class XMLConsoleWindow(Gtk.ApplicationWindow):
input_text = None
if text == 'Presence':
input_text = (
- '<presence>\n'
+ '<presence xmlns="jabber:client">\n'
'<show></show>\n'
'<status></status>\n'
'<priority></priority>\n'
'</presence>')
elif text == 'Message':
input_text = (
- '<message to="" type="">\n'
+ '<message to="" type="" xmlns="jabber:client">\n'
'<body></body>\n'
'</message>')
elif text == 'Iq':
input_text = (
- '<iq to="" type="">\n'
+ '<iq to="" type="" xmlns="jabber:client">\n'
'<query xmlns=""></query>\n'
'</iq>')
@@ -176,8 +173,6 @@ class XMLConsoleWindow(Gtk.ApplicationWindow):
if stanza:
try:
node = nbxmpp.Protocol(node=stanza)
- if node.getNamespace() == UNDECLARED:
- node.setNamespace(nbxmpp.NS_CLIENT)
except Exception as error:
ErrorDialog(_('Invalid Node'), str(error))
return
=====================================
gajim/session.py
=====================================
@@ -139,8 +139,11 @@ class ChatControlSession:
stanza_id=obj.unique_id,
message_id=obj.message_id)
- self.conn.get_module('MAM').save_archive_id(
- None, obj.stanza_id, obj.timestamp)
+ jid = self.conn.get_own_jid().getStripped()
+ if self.conn.get_module('MAM').is_catchup_finished(jid):
+ app.logger.set_archive_infos(jid,
+ last_mam_id=obj.stanza_id,
+ last_muc_timestamp=obj.timestamp)
if obj.muc_pm and not obj.gc_control:
# This is a carbon of a PM from a MUC we are not currently
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/f6ce10eb4d0c0c69ffa18258d1fe9ad07…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/compare/f6ce10eb4d0c0c69ffa18258d1fe9ad07…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
f6ce10eb by Philipp Hörist at 2019-07-20T21:58:17Z
AdHoc: Prevent request with invalid JID
resource can also be an empty string
- - - - -
1 changed file:
- gajim/roster_window.py
Changes:
=====================================
gajim/roster_window.py
=====================================
@@ -3537,7 +3537,7 @@ class RosterWindow:
callback
"""
jid = contact.jid
- if resource is not None:
+ if resource:
jid = jid + '/' + resource
AdHocCommand(account, jid)
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/f6ce10eb4d0c0c69ffa18258d1fe9ad073…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/f6ce10eb4d0c0c69ffa18258d1fe9ad073…
You're receiving this email because of your account on dev.gajim.org.
Philipp Hörist pushed to branch master at gajim / gajim
Commits:
2c82decc by Philipp Hörist at 2019-07-17T22:05:24Z
Remove unused import
- - - - -
1 changed file:
- gajim/groupchat_control.py
Changes:
=====================================
gajim/groupchat_control.py
=====================================
@@ -74,7 +74,6 @@ from gajim.common.connection_handlers_events import GcMessageOutgoingEvent
from gajim.gtk.dialogs import DialogButton
from gajim.gtk.dialogs import NewConfirmationCheckDialog
from gajim.gtk.dialogs import ErrorDialog
-from gajim.gtk.dialogs import InputTextDialog
from gajim.gtk.dialogs import DestroyMucDialog
from gajim.gtk.dialogs import InputDialog
from gajim.gtk.single_message import SingleMessageWindow
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/2c82deccf7186b062da930e85a7bd53e1e…
--
View it on GitLab: https://dev.gajim.org/gajim/gajim/commit/2c82deccf7186b062da930e85a7bd53e1e…
You're receiving this email because of your account on dev.gajim.org.