Add a configurable threshold for MAM in MUC
This commit is contained in:
parent
7ece7dbaff
commit
d35a9f6a10
|
@ -293,6 +293,9 @@ class Config:
|
||||||
'pgp_encoding': [opt_str, '', _('Sets the encoding used by python-gnupg'), True],
|
'pgp_encoding': [opt_str, '', _('Sets the encoding used by python-gnupg'), True],
|
||||||
'remote_commands': [opt_bool, False, _('If true, Gajim will execute XEP-0146 Commands.')],
|
'remote_commands': [opt_bool, False, _('If true, Gajim will execute XEP-0146 Commands.')],
|
||||||
'dark_theme': [opt_int, 2, _('2: System, 1: Enabled, 0: Disabled')],
|
'dark_theme': [opt_int, 2, _('2: System, 1: Enabled, 0: Disabled')],
|
||||||
|
'threshold_options': [opt_str, '1, 2, 4, 10, 0', _('Options in days which can be chosen in the sync threshold menu'), True],
|
||||||
|
'public_room_sync_threshold': [opt_int, 1, _('Maximum history in days we request from a public room archive. 0: As much as possible')],
|
||||||
|
'private_room_sync_threshold': [opt_int, 0, _('Maximum history in days we request from a private room archive. 0: As much as possible')],
|
||||||
}, {}) # type: Tuple[Dict[str, List[Any]], Dict[Any, Any]]
|
}, {}) # type: Tuple[Dict[str, List[Any]], Dict[Any, Any]]
|
||||||
|
|
||||||
__options_per_key = {
|
__options_per_key = {
|
||||||
|
|
|
@ -186,6 +186,13 @@ class Chatstate(IntEnum):
|
||||||
return self.name.lower()
|
return self.name.lower()
|
||||||
|
|
||||||
|
|
||||||
|
class SyncThreshold(IntEnum):
|
||||||
|
NO_THRESHOLD = 0
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.value)
|
||||||
|
|
||||||
|
|
||||||
ACTIVITIES = {
|
ACTIVITIES = {
|
||||||
'doing_chores': {
|
'doing_chores': {
|
||||||
'category': _('Doing Chores'),
|
'category': _('Doing Chores'),
|
||||||
|
|
|
@ -51,6 +51,7 @@ from gajim.common import configpaths
|
||||||
from gajim.common.i18n import Q_
|
from gajim.common.i18n import Q_
|
||||||
from gajim.common.i18n import _
|
from gajim.common.i18n import _
|
||||||
from gajim.common.i18n import ngettext
|
from gajim.common.i18n import ngettext
|
||||||
|
from gajim.common.caps_cache import muc_caps_cache
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import precis_i18n.codec # pylint: disable=unused-import
|
import precis_i18n.codec # pylint: disable=unused-import
|
||||||
|
@ -1481,3 +1482,13 @@ def call_counter(func):
|
||||||
self._connect_machine_calls += 1
|
self._connect_machine_calls += 1
|
||||||
return func(self, restart=False)
|
return func(self, restart=False)
|
||||||
return helper
|
return helper
|
||||||
|
|
||||||
|
def get_sync_threshold(jid, archive_info):
|
||||||
|
if archive_info is None or archive_info.sync_threshold is None:
|
||||||
|
if muc_caps_cache.supports(jid, 'muc#roomconfig_membersonly'):
|
||||||
|
threshold = app.config.get('private_room_sync_threshold')
|
||||||
|
else:
|
||||||
|
threshold = app.config.get('public_room_sync_threshold')
|
||||||
|
app.logger.set_archive_infos(jid, sync_threshold=threshold)
|
||||||
|
return threshold
|
||||||
|
return archive_info.sync_threshold
|
||||||
|
|
|
@ -78,11 +78,12 @@ LOGS_SQL_STATEMENT = '''
|
||||||
jid_id INTEGER PRIMARY KEY UNIQUE,
|
jid_id INTEGER PRIMARY KEY UNIQUE,
|
||||||
last_mam_id TEXT,
|
last_mam_id TEXT,
|
||||||
oldest_mam_timestamp TEXT,
|
oldest_mam_timestamp TEXT,
|
||||||
last_muc_timestamp TEXT
|
last_muc_timestamp TEXT,
|
||||||
|
sync_threshold INTEGER
|
||||||
);
|
);
|
||||||
CREATE INDEX idx_logs_jid_id_time ON logs (jid_id, time DESC);
|
CREATE INDEX idx_logs_jid_id_time ON logs (jid_id, time DESC);
|
||||||
CREATE INDEX idx_logs_stanza_id ON logs (stanza_id);
|
CREATE INDEX idx_logs_stanza_id ON logs (stanza_id);
|
||||||
PRAGMA user_version=1;
|
PRAGMA user_version=2;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
CACHE_SQL_STATEMENT = '''
|
CACHE_SQL_STATEMENT = '''
|
||||||
|
@ -219,7 +220,11 @@ class Logger:
|
||||||
self._execute_multiple(con, statements)
|
self._execute_multiple(con, statements)
|
||||||
|
|
||||||
if self._get_user_version(con) < 2:
|
if self._get_user_version(con) < 2:
|
||||||
pass
|
statements = [
|
||||||
|
'ALTER TABLE last_archive_message ADD COLUMN "sync_threshold" INTEGER',
|
||||||
|
'PRAGMA user_version=2'
|
||||||
|
]
|
||||||
|
self._execute_multiple(con, statements)
|
||||||
|
|
||||||
def _migrate_cache(self, con):
|
def _migrate_cache(self, con):
|
||||||
if self._get_user_version(con) == 0:
|
if self._get_user_version(con) == 0:
|
||||||
|
@ -1394,20 +1399,20 @@ class Logger:
|
||||||
self._con.execute(sql, (sha, account_jid_id, jid_id))
|
self._con.execute(sql, (sha, account_jid_id, jid_id))
|
||||||
self._timeout_commit()
|
self._timeout_commit()
|
||||||
|
|
||||||
def get_archive_timestamp(self, jid, type_=None):
|
def get_archive_infos(self, jid):
|
||||||
"""
|
"""
|
||||||
Get the last archive id/timestamp for a jid
|
Get the archive infos
|
||||||
|
|
||||||
:param jid: The jid that belongs to the avatar
|
:param jid: The jid that belongs to the avatar
|
||||||
|
|
||||||
"""
|
"""
|
||||||
jid_id = self.get_jid_id(jid, type_=type_)
|
jid_id = self.get_jid_id(jid, type_=JIDConstant.ROOM_TYPE)
|
||||||
sql = '''SELECT * FROM last_archive_message WHERE jid_id = ?'''
|
sql = '''SELECT * FROM last_archive_message WHERE jid_id = ?'''
|
||||||
return self._con.execute(sql, (jid_id,)).fetchone()
|
return self._con.execute(sql, (jid_id,)).fetchone()
|
||||||
|
|
||||||
def set_archive_timestamp(self, jid, **kwargs):
|
def set_archive_infos(self, jid, **kwargs):
|
||||||
"""
|
"""
|
||||||
Set the last archive id/timestamp
|
Set archive infos
|
||||||
|
|
||||||
:param jid: The jid that belongs to the avatar
|
:param jid: The jid that belongs to the avatar
|
||||||
|
|
||||||
|
@ -1419,20 +1424,28 @@ class Logger:
|
||||||
:param last_muc_timestamp: The timestamp of the last message we
|
:param last_muc_timestamp: The timestamp of the last message we
|
||||||
received in a MUC
|
received in a MUC
|
||||||
|
|
||||||
|
:param sync_threshold: The max days that we request from a
|
||||||
|
MUC archive
|
||||||
|
|
||||||
"""
|
"""
|
||||||
jid_id = self.get_jid_id(jid)
|
jid_id = self.get_jid_id(jid)
|
||||||
exists = self.get_archive_timestamp(jid)
|
exists = self.get_archive_infos(jid)
|
||||||
if not exists:
|
if not exists:
|
||||||
sql = '''INSERT INTO last_archive_message VALUES (?, ?, ?, ?)'''
|
sql = '''INSERT INTO last_archive_message
|
||||||
|
(jid_id, last_mam_id, oldest_mam_timestamp,
|
||||||
|
last_muc_timestamp, sync_threshold)
|
||||||
|
VALUES (?, ?, ?, ?, ?)'''
|
||||||
self._con.execute(sql, (
|
self._con.execute(sql, (
|
||||||
jid_id,
|
jid_id,
|
||||||
kwargs.get('last_mam_id', None),
|
kwargs.get('last_mam_id', None),
|
||||||
kwargs.get('oldest_mam_timestamp', None),
|
kwargs.get('oldest_mam_timestamp', None),
|
||||||
kwargs.get('last_muc_timestamp', None)))
|
kwargs.get('last_muc_timestamp', None),
|
||||||
|
kwargs.get('sync_threshold', None)
|
||||||
|
))
|
||||||
else:
|
else:
|
||||||
args = ' = ?, '.join(kwargs.keys()) + ' = ?'
|
args = ' = ?, '.join(kwargs.keys()) + ' = ?'
|
||||||
sql = '''UPDATE last_archive_message SET {}
|
sql = '''UPDATE last_archive_message SET {}
|
||||||
WHERE jid_id = ?'''.format(args)
|
WHERE jid_id = ?'''.format(args)
|
||||||
self._con.execute(sql, tuple(kwargs.values()) + (jid_id,))
|
self._con.execute(sql, tuple(kwargs.values()) + (jid_id,))
|
||||||
log.info('Save archive timestamps: %s', kwargs)
|
log.info('Save archive infos: %s', kwargs)
|
||||||
self._timeout_commit()
|
self._timeout_commit()
|
||||||
|
|
|
@ -15,14 +15,18 @@
|
||||||
# XEP-0313: Message Archive Management
|
# XEP-0313: Message Archive Management
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
import nbxmpp
|
import nbxmpp
|
||||||
|
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common.nec import NetworkIncomingEvent
|
from gajim.common.nec import NetworkIncomingEvent
|
||||||
from gajim.common.const import ArchiveState, JIDConstant, KindConstant
|
from gajim.common.const import ArchiveState
|
||||||
|
from gajim.common.const import KindConstant
|
||||||
|
from gajim.common.const import SyncThreshold
|
||||||
from gajim.common.caps_cache import muc_caps_cache
|
from gajim.common.caps_cache import muc_caps_cache
|
||||||
|
from gajim.common.helpers import get_sync_threshold
|
||||||
from gajim.common.modules.misc import parse_delay
|
from gajim.common.modules.misc import parse_delay
|
||||||
from gajim.common.modules.misc import parse_oob
|
from gajim.common.modules.misc import parse_oob
|
||||||
from gajim.common.modules.misc import parse_correction
|
from gajim.common.modules.misc import parse_correction
|
||||||
|
@ -352,7 +356,7 @@ class MAM:
|
||||||
log.warning('MAM request for %s already running', own_jid)
|
log.warning('MAM request for %s already running', own_jid)
|
||||||
return
|
return
|
||||||
|
|
||||||
archive = app.logger.get_archive_timestamp(own_jid)
|
archive = app.logger.get_archive_infos(own_jid)
|
||||||
|
|
||||||
# Migration of last_mam_id from config to DB
|
# Migration of last_mam_id from config to DB
|
||||||
if archive is not None:
|
if archive is not None:
|
||||||
|
@ -379,16 +383,12 @@ class MAM:
|
||||||
self._send_archive_query(query, query_id, start_date)
|
self._send_archive_query(query, query_id, start_date)
|
||||||
|
|
||||||
def request_archive_on_muc_join(self, jid):
|
def request_archive_on_muc_join(self, jid):
|
||||||
archive = app.logger.get_archive_timestamp(
|
archive = app.logger.get_archive_infos(jid)
|
||||||
jid, type_=JIDConstant.ROOM_TYPE)
|
threshold = get_sync_threshold(jid, archive)
|
||||||
|
log.info('Threshold for %s: %s', jid, threshold)
|
||||||
query_id = self._get_query_id(jid)
|
query_id = self._get_query_id(jid)
|
||||||
start_date = None
|
start_date = None
|
||||||
if archive is not None:
|
if archive is None or archive.last_mam_id is None:
|
||||||
log.info('Request from archive %s after %s:',
|
|
||||||
jid, archive.last_mam_id)
|
|
||||||
query = self._get_archive_query(
|
|
||||||
query_id, jid=jid, after=archive.last_mam_id)
|
|
||||||
else:
|
|
||||||
# First Start, we dont request history
|
# First Start, we dont request history
|
||||||
# Depending on what a MUC saves, there could be thousands
|
# Depending on what a MUC saves, there could be thousands
|
||||||
# of Messages even in just one day.
|
# of Messages even in just one day.
|
||||||
|
@ -397,6 +397,37 @@ class MAM:
|
||||||
query = self._get_archive_query(
|
query = self._get_archive_query(
|
||||||
query_id, jid=jid, start=start_date)
|
query_id, jid=jid, start=start_date)
|
||||||
|
|
||||||
|
elif threshold == SyncThreshold.NO_THRESHOLD:
|
||||||
|
# Not our first join and no threshold set
|
||||||
|
log.info('Request from archive: %s, after mam-id %s',
|
||||||
|
jid, archive.last_mam_id)
|
||||||
|
query = self._get_archive_query(
|
||||||
|
query_id, jid=jid, after=archive.last_mam_id)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Not our first join, check how much time elapsed since our
|
||||||
|
# last join and check against threshold
|
||||||
|
last_timestamp = archive.last_muc_timestamp
|
||||||
|
if last_timestamp is None:
|
||||||
|
log.info('No last muc timestamp found ( mam:1? )')
|
||||||
|
last_timestamp = 0
|
||||||
|
|
||||||
|
last = datetime.utcfromtimestamp(float(last_timestamp))
|
||||||
|
if datetime.utcnow() - last > timedelta(days=threshold):
|
||||||
|
# To much time has elapsed since last join, apply threshold
|
||||||
|
start_date = datetime.utcnow() - timedelta(days=threshold)
|
||||||
|
log.info('Too much time elapsed since last join, '
|
||||||
|
'request from: %s, threshold: %s',
|
||||||
|
start_date, threshold)
|
||||||
|
query = self._get_archive_query(
|
||||||
|
query_id, jid=jid, start=start_date)
|
||||||
|
else:
|
||||||
|
# Request from last mam-id
|
||||||
|
log.info('Request from archive %s after %s:',
|
||||||
|
jid, archive.last_mam_id)
|
||||||
|
query = self._get_archive_query(
|
||||||
|
query_id, jid=jid, after=archive.last_mam_id)
|
||||||
|
|
||||||
if jid in self._catch_up_finished:
|
if jid in self._catch_up_finished:
|
||||||
self._catch_up_finished.remove(jid)
|
self._catch_up_finished.remove(jid)
|
||||||
self._send_archive_query(query, query_id, start_date, groupchat=True)
|
self._send_archive_query(query, query_id, start_date, groupchat=True)
|
||||||
|
@ -424,20 +455,22 @@ class MAM:
|
||||||
return
|
return
|
||||||
|
|
||||||
complete = fin.getAttr('complete')
|
complete = fin.getAttr('complete')
|
||||||
app.logger.set_archive_timestamp(
|
|
||||||
jid, last_mam_id=last, last_muc_timestamp=None)
|
|
||||||
if complete != 'true':
|
if complete != 'true':
|
||||||
|
app.logger.set_archive_infos(jid, last_mam_id=last)
|
||||||
self._mam_query_ids.pop(jid)
|
self._mam_query_ids.pop(jid)
|
||||||
query_id = self._get_query_id(jid)
|
query_id = self._get_query_id(jid)
|
||||||
query = self._get_archive_query(query_id, jid=jid, after=last)
|
query = self._get_archive_query(query_id, jid=jid, after=last)
|
||||||
self._send_archive_query(query, query_id, groupchat=groupchat)
|
self._send_archive_query(query, query_id, groupchat=groupchat)
|
||||||
else:
|
else:
|
||||||
self._mam_query_ids.pop(jid)
|
self._mam_query_ids.pop(jid)
|
||||||
if start_date is not None:
|
app.logger.set_archive_infos(
|
||||||
app.logger.set_archive_timestamp(
|
jid, last_mam_id=last, last_muc_timestamp=time.time())
|
||||||
jid,
|
if start_date is not None and not groupchat:
|
||||||
last_mam_id=last,
|
# Record the earliest timestamp we request from
|
||||||
oldest_mam_timestamp=start_date.timestamp())
|
# the account archive. For the account archive we only
|
||||||
|
# set start_date at the very first request.
|
||||||
|
app.logger.set_archive_infos(
|
||||||
|
jid, oldest_mam_timestamp=start_date.timestamp())
|
||||||
|
|
||||||
self._catch_up_finished.append(jid)
|
self._catch_up_finished.append(jid)
|
||||||
log.info('End of MAM query, last mam id: %s', last)
|
log.info('End of MAM query, last mam id: %s', last)
|
||||||
|
@ -481,7 +514,7 @@ class MAM:
|
||||||
if last is None:
|
if last is None:
|
||||||
app.nec.push_incoming_event(ArchivingIntervalFinished(
|
app.nec.push_incoming_event(ArchivingIntervalFinished(
|
||||||
None, query_id=query_id))
|
None, query_id=query_id))
|
||||||
app.logger.set_archive_timestamp(
|
app.logger.set_archive_infos(
|
||||||
jid, oldest_mam_timestamp=timestamp)
|
jid, oldest_mam_timestamp=timestamp)
|
||||||
log.info('End of MAM request, no items retrieved')
|
log.info('End of MAM request, no items retrieved')
|
||||||
return
|
return
|
||||||
|
@ -491,7 +524,7 @@ class MAM:
|
||||||
self.request_archive_interval(start_date, end_date, last, query_id)
|
self.request_archive_interval(start_date, end_date, last, query_id)
|
||||||
else:
|
else:
|
||||||
log.info('Request finished')
|
log.info('Request finished')
|
||||||
app.logger.set_archive_timestamp(
|
app.logger.set_archive_infos(
|
||||||
jid, oldest_mam_timestamp=timestamp)
|
jid, oldest_mam_timestamp=timestamp)
|
||||||
app.nec.push_incoming_event(ArchivingIntervalFinished(
|
app.nec.push_incoming_event(ArchivingIntervalFinished(
|
||||||
None, query_id=query_id))
|
None, query_id=query_id))
|
||||||
|
@ -536,14 +569,17 @@ class MAM:
|
||||||
return iq
|
return iq
|
||||||
|
|
||||||
def save_archive_id(self, jid, stanza_id, timestamp):
|
def save_archive_id(self, jid, stanza_id, timestamp):
|
||||||
if stanza_id is None:
|
|
||||||
return
|
|
||||||
if jid is None:
|
if jid is None:
|
||||||
jid = self._con.get_own_jid().getStripped()
|
jid = self._con.get_own_jid().getStripped()
|
||||||
if jid not in self._catch_up_finished:
|
if jid not in self._catch_up_finished:
|
||||||
return
|
return
|
||||||
log.info('Save: %s: %s, %s', jid, stanza_id, timestamp)
|
log.info('Save: %s: %s, %s', jid, stanza_id, timestamp)
|
||||||
app.logger.set_archive_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)
|
jid, last_mam_id=stanza_id, last_muc_timestamp=timestamp)
|
||||||
|
|
||||||
def request_mam_preferences(self):
|
def request_mam_preferences(self):
|
||||||
|
|
|
@ -60,6 +60,7 @@ from gajim.common import i18n
|
||||||
from gajim.common import contacts
|
from gajim.common import contacts
|
||||||
from gajim.common.const import StyleAttr
|
from gajim.common.const import StyleAttr
|
||||||
from gajim.common.const import Chatstate
|
from gajim.common.const import Chatstate
|
||||||
|
|
||||||
from gajim.chat_control import ChatControl
|
from gajim.chat_control import ChatControl
|
||||||
from gajim.chat_control_base import ChatControlBase
|
from gajim.chat_control_base import ChatControlBase
|
||||||
|
|
||||||
|
@ -575,6 +576,17 @@ class GroupchatControl(ChatControlBase):
|
||||||
act.connect('change-state', self._on_notify_on_all_messages)
|
act.connect('change-state', self._on_notify_on_all_messages)
|
||||||
self.parent_win.window.add_action(act)
|
self.parent_win.window.add_action(act)
|
||||||
|
|
||||||
|
archive_info = app.logger.get_archive_infos(self.contact.jid)
|
||||||
|
threshold = helpers.get_sync_threshold(self.contact.jid,
|
||||||
|
archive_info)
|
||||||
|
|
||||||
|
inital = GLib.Variant.new_string(str(threshold))
|
||||||
|
act = Gio.SimpleAction.new_stateful(
|
||||||
|
'choose-sync-' + self.control_id,
|
||||||
|
inital.get_type(), inital)
|
||||||
|
act.connect('change-state', self._on_sync_threshold)
|
||||||
|
self.parent_win.window.add_action(act)
|
||||||
|
|
||||||
def update_actions(self):
|
def update_actions(self):
|
||||||
if self.parent_win is None:
|
if self.parent_win is None:
|
||||||
return
|
return
|
||||||
|
@ -638,6 +650,25 @@ class GroupchatControl(ChatControlBase):
|
||||||
win.lookup_action('upload-avatar-' + self.control_id).set_enabled(
|
win.lookup_action('upload-avatar-' + self.control_id).set_enabled(
|
||||||
self.is_connected and vcard_support and contact.affiliation == 'owner')
|
self.is_connected and vcard_support and contact.affiliation == 'owner')
|
||||||
|
|
||||||
|
# Sync Threshold
|
||||||
|
has_mam = muc_caps_cache.has_mam(self.room_jid)
|
||||||
|
win.lookup_action('choose-sync-' + self.control_id).set_enabled(has_mam)
|
||||||
|
|
||||||
|
def _on_room_created(self):
|
||||||
|
if self.parent_win is None:
|
||||||
|
return
|
||||||
|
win = self.parent_win.window
|
||||||
|
self.update_actions()
|
||||||
|
|
||||||
|
# After the room has been created, reevaluate threshold
|
||||||
|
if muc_caps_cache.has_mam(self.contact.jid):
|
||||||
|
archive_info = app.logger.get_archive_infos(self.contact.jid)
|
||||||
|
threshold = helpers.get_sync_threshold(self.contact.jid,
|
||||||
|
archive_info)
|
||||||
|
win.change_action_state('choose-sync-%s' % self.control_id,
|
||||||
|
GLib.Variant('s', str(threshold)))
|
||||||
|
|
||||||
|
|
||||||
def _connect_window_state_change(self, parent_win):
|
def _connect_window_state_change(self, parent_win):
|
||||||
if self._state_change_handler_id is None:
|
if self._state_change_handler_id is None:
|
||||||
id_ = parent_win.window.connect('notify::is-maximized',
|
id_ = parent_win.window.connect('notify::is-maximized',
|
||||||
|
@ -755,6 +786,11 @@ class GroupchatControl(ChatControlBase):
|
||||||
app.config.set_per('rooms', self.contact.jid,
|
app.config.set_per('rooms', self.contact.jid,
|
||||||
'notify_on_all_messages', param.get_boolean())
|
'notify_on_all_messages', param.get_boolean())
|
||||||
|
|
||||||
|
def _on_sync_threshold(self, action, param):
|
||||||
|
threshold = param.get_string()
|
||||||
|
action.set_state(param)
|
||||||
|
app.logger.set_archive_infos(self.contact.jid, sync_threshold=threshold)
|
||||||
|
|
||||||
def _on_execute_command(self, action, param):
|
def _on_execute_command(self, action, param):
|
||||||
"""
|
"""
|
||||||
Execute AdHoc commands on the current room
|
Execute AdHoc commands on the current room
|
||||||
|
@ -1838,7 +1874,7 @@ class GroupchatControl(ChatControlBase):
|
||||||
self.print_conversation(_('Room logging is enabled'))
|
self.print_conversation(_('Room logging is enabled'))
|
||||||
if '201' in obj.status_code:
|
if '201' in obj.status_code:
|
||||||
app.connections[self.account].get_module('Discovery').disco_muc(
|
app.connections[self.account].get_module('Discovery').disco_muc(
|
||||||
self.room_jid, self.update_actions, update=True)
|
self.room_jid, self._on_room_created, update=True)
|
||||||
self.print_conversation(_('A new room has been created'))
|
self.print_conversation(_('A new room has been created'))
|
||||||
if '210' in obj.status_code:
|
if '210' in obj.status_code:
|
||||||
self.print_conversation(\
|
self.print_conversation(\
|
||||||
|
|
|
@ -53,7 +53,7 @@ class HistorySyncAssistant(Gtk.Assistant):
|
||||||
own_jid = self.con.get_own_jid().getStripped()
|
own_jid = self.con.get_own_jid().getStripped()
|
||||||
|
|
||||||
mam_start = ArchiveState.NEVER
|
mam_start = ArchiveState.NEVER
|
||||||
archive = app.logger.get_archive_timestamp(own_jid)
|
archive = app.logger.get_archive_infos(own_jid)
|
||||||
if archive is not None and archive.oldest_mam_timestamp is not None:
|
if archive is not None and archive.oldest_mam_timestamp is not None:
|
||||||
mam_start = int(float(archive.oldest_mam_timestamp))
|
mam_start = int(float(archive.oldest_mam_timestamp))
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ from gajim import message_control
|
||||||
from gajim.gtkgui_helpers import get_action
|
from gajim.gtkgui_helpers import get_action
|
||||||
from gajim.common import app
|
from gajim.common import app
|
||||||
from gajim.common import helpers
|
from gajim.common import helpers
|
||||||
|
from gajim.common.i18n import ngettext
|
||||||
|
|
||||||
|
|
||||||
def build_resources_submenu(contacts, account, action, room_jid=None,
|
def build_resources_submenu(contacts, account, action, room_jid=None,
|
||||||
|
@ -635,6 +636,7 @@ def get_groupchat_menu(control_id):
|
||||||
('win.upload-avatar-', _('Upload Avatar…')),
|
('win.upload-avatar-', _('Upload Avatar…')),
|
||||||
('win.destroy-', _('Destroy Room')),
|
('win.destroy-', _('Destroy Room')),
|
||||||
]),
|
]),
|
||||||
|
(_('Sync Threshold'), []),
|
||||||
('win.change-nick-', _('Change Nick')),
|
('win.change-nick-', _('Change Nick')),
|
||||||
('win.bookmark-', _('Bookmark Room')),
|
('win.bookmark-', _('Bookmark Room')),
|
||||||
('win.request-voice-', _('Request Voice')),
|
('win.request-voice-', _('Request Voice')),
|
||||||
|
@ -656,11 +658,28 @@ def get_groupchat_menu(control_id):
|
||||||
menu.append(label, action_name + control_id)
|
menu.append(label, action_name + control_id)
|
||||||
else:
|
else:
|
||||||
label, sub_menu = item
|
label, sub_menu = item
|
||||||
|
if not sub_menu:
|
||||||
|
# Sync threshold menu
|
||||||
|
submenu = build_sync_menu()
|
||||||
|
else:
|
||||||
# This is a submenu
|
# This is a submenu
|
||||||
submenu = build_menu(sub_menu)
|
submenu = build_menu(sub_menu)
|
||||||
menu.append_submenu(label, submenu)
|
menu.append_submenu(label, submenu)
|
||||||
return menu
|
return menu
|
||||||
|
|
||||||
|
def build_sync_menu():
|
||||||
|
menu = Gio.Menu()
|
||||||
|
days = app.config.get('threshold_options').split(',')
|
||||||
|
days = [int(day) for day in days]
|
||||||
|
action_name = 'win.choose-sync-%s::' % control_id
|
||||||
|
for day in days:
|
||||||
|
if day == 0:
|
||||||
|
label = _('No threshold')
|
||||||
|
else:
|
||||||
|
label = ngettext('%i day', '%i days', day, day, day)
|
||||||
|
menu.append(label, '%s%s' % (action_name, day))
|
||||||
|
return menu
|
||||||
|
|
||||||
return build_menu(groupchat_menu)
|
return build_menu(groupchat_menu)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue