diff --git a/data/gui/archiving_313_preferences_item.ui b/data/gui/archiving_313_preferences_item.ui
new file mode 100644
index 000000000..bda22250a
--- /dev/null
+++ b/data/gui/archiving_313_preferences_item.ui
@@ -0,0 +1,143 @@
+
+
+
+
+
+
+
diff --git a/data/gui/archiving_313_preferences_window.ui b/data/gui/archiving_313_preferences_window.ui
new file mode 100644
index 000000000..c59c442de
--- /dev/null
+++ b/data/gui/archiving_313_preferences_window.ui
@@ -0,0 +1,213 @@
+
+
+
+
+
+ True
+ False
+ gtk-add
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Always
+
+
+ Roster
+
+
+ Never
+
+
+
+
+ True
+ False
+ gtk-remove
+
+
+ False
+ 12
+ center
+ 450
+
+
+
+ True
+ False
+ 5
+ 10
+
+
+ 150
+ True
+ True
+ True
+ True
+ in
+
+
+ True
+ True
+ archive_items_liststore
+
+
+
+
+
+ Jabber ID
+ True
+ True
+ 0
+
+
+
+ 0
+
+
+
+
+
+
+ Preference
+ True
+ True
+ 1
+
+
+
+ 1
+
+
+
+
+
+
+
+
+ 0
+ 1
+ 2
+
+
+
+
+ True
+ False
+ start
+ 5
+ start
+
+
+ True
+ True
+ True
+ add_image
+
+
+
+ False
+ True
+ 0
+ True
+
+
+
+
+ True
+ True
+ True
+ remove_image
+
+
+
+ True
+ True
+ 1
+ True
+
+
+
+
+ 0
+ 2
+
+
+
+
+ True
+ False
+ start
+ 5
+
+
+ True
+ False
+ Default:
+ 0
+
+
+ 0
+ 0
+
+
+
+
+ True
+ False
+ start
+ False
+ default_pref_liststore
+
+
+
+ 0
+
+
+
+
+ 1
+ 0
+
+
+
+
+ 0
+ 0
+
+
+
+
+ gtk-save
+ True
+ True
+ True
+ end
+ True
+ True
+
+
+
+ 1
+ 2
+
+
+
+
+
+
+
+
+
diff --git a/src/common/connection_handlers.py b/src/common/connection_handlers.py
index 42c661829..f679366dd 100644
--- a/src/common/connection_handlers.py
+++ b/src/common/connection_handlers.py
@@ -1465,6 +1465,8 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
gajim.nec.register_incoming_event(ArchivingErrorReceivedEvent)
gajim.nec.register_incoming_event(
ArchivingPreferencesChangedReceivedEvent)
+ gajim.nec.register_incoming_event(
+ Archiving313PreferencesChangedReceivedEvent)
gajim.nec.register_incoming_event(NotificationEvent)
gajim.ged.register_event_handler('http-auth-received', ged.CORE,
@@ -2340,6 +2342,7 @@ ConnectionHandlersBase, ConnectionJingle, ConnectionIBBytestream):
con.RegisterHandler('iq', self._SearchCB, 'result', nbxmpp.NS_SEARCH)
con.RegisterHandler('iq', self._PrivacySetCB, 'set', nbxmpp.NS_PRIVACY)
con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_ARCHIVE)
+ con.RegisterHandler('iq', self._ArchiveCB, ns=nbxmpp.NS_MAM)
con.RegisterHandler('iq', self._PubSubCB, 'result')
con.RegisterHandler('iq', self._PubSubErrorCB, 'error')
con.RegisterHandler('iq', self._JingleCB, 'result')
diff --git a/src/common/connection_handlers_events.py b/src/common/connection_handlers_events.py
index b53efd7f2..00c9eb61e 100644
--- a/src/common/connection_handlers_events.py
+++ b/src/common/connection_handlers_events.py
@@ -1751,9 +1751,8 @@ class ArchivingPreferencesChangedReceivedEvent(nec.NetworkIncomingEvent):
self.conf = {}
self.new_items = {}
self.removed_items = []
- if self.stanza.getTag('pref'):
- pref = self.stanza.getTag('pref')
-
+ pref = self.stanza.getTag('pref', namespace=nbxmpp.NS_ARCHIVE)
+ if pref:
if pref.getTag('auto'):
self.conf['auto'] = pref.getTagAttr('auto', 'save')
@@ -1786,6 +1785,37 @@ class ArchivingPreferencesChangedReceivedEvent(nec.NetworkIncomingEvent):
elif self.stanza.getTag('itemremove'):
for item in pref.getTags('item'):
self.removed_items.append(item.getAttr('jid'))
+ else:
+ return
+ return True
+
+class Archiving313PreferencesChangedReceivedEvent(nec.NetworkIncomingEvent):
+ name = 'archiving-313-preferences-changed-received'
+ base_network_events = ['archiving-received']
+
+ def generate(self):
+ self.conn = self.base_event.conn
+ self.stanza = self.base_event.stanza
+ self.type_ = self.base_event.type_
+ self.items = []
+ self.default = None
+ self.id = self.stanza.getID()
+ self.answer = None
+
+ if self.type_ != 'result':
+ return
+
+ prefs = self.stanza.getTag('prefs', namespace=nbxmpp.NS_MAM)
+ if prefs:
+ self.default = prefs.getAttr('default')
+
+ for item in prefs.getTag('always').getTags('jid'):
+ self.items.append((item.getData(), 'Always'))
+
+ for item in prefs.getTag('never').getTags('jid'):
+ self.items.append((item.getData(), 'Never'))
+ else:
+ return
return True
class AccountCreatedEvent(nec.NetworkIncomingEvent):
diff --git a/src/common/message_archiving.py b/src/common/message_archiving.py
index b0ba359d1..ec95c6830 100644
--- a/src/common/message_archiving.py
+++ b/src/common/message_archiving.py
@@ -41,6 +41,7 @@ class ConnectionArchive313(ConnectionArchive):
ConnectionArchive.__init__(self)
self.archiving_313_supported = False
self.mam_awaiting_disco_result = {}
+ self.iq_answer = []
gajim.ged.register_event_handler('raw-message-received', ged.CORE,
self._nec_raw_message_313_received)
gajim.ged.register_event_handler('agent-info-error-received', ged.CORE,
@@ -49,6 +50,9 @@ class ConnectionArchive313(ConnectionArchive):
self._nec_agent_info)
gajim.ged.register_event_handler('mam-decrypted-message-received',
ged.CORE, self._nec_mam_decrypted_message_received)
+ gajim.ged.register_event_handler(
+ 'archiving-313-preferences-changed-received', ged.CORE,
+ self._nec_archiving_313_preferences_changed_received)
def cleanup(self):
gajim.ged.remove_event_handler('raw-message-received', ged.CORE,
@@ -59,6 +63,13 @@ class ConnectionArchive313(ConnectionArchive):
self._nec_agent_info)
gajim.ged.remove_event_handler('mam-decrypted-message-received',
ged.CORE, self._nec_mam_decrypted_message_received)
+ gajim.ged.remove_event_handler(
+ 'archiving-313-preferences-changed-received', ged.CORE,
+ self._nec_archiving_313_preferences_changed_received)
+
+ def _nec_archiving_313_preferences_changed_received(self, obj):
+ if obj.id in self.iq_answer:
+ obj.answer = True
def _nec_agent_info_error(self, obj):
if obj.jid in self.mam_awaiting_disco_result:
@@ -138,6 +149,32 @@ class ConnectionArchive313(ConnectionArchive):
self.awaiting_answers[queryid_] = (MAM_RESULTS_ARRIVED, )
self.connection.send(iq_)
+ def request_archive_preferences(self):
+ if not gajim.account_is_connected(self.name):
+ return
+ iq = nbxmpp.Iq(typ='get')
+ id_ = self.connection.getAnID()
+ iq.setID(id_)
+ iq.addChild(name='prefs', namespace=nbxmpp.NS_MAM)
+ self.connection.send(iq)
+
+ def set_archive_preferences(self, items, default):
+ if not gajim.account_is_connected(self.name):
+ return
+ iq = nbxmpp.Iq(typ='set')
+ id_ = self.connection.getAnID()
+ self.iq_answer.append(id_)
+ iq.setID(id_)
+ prefs = iq.addChild(name='prefs', namespace=nbxmpp.NS_MAM, attrs={'default': default})
+ always = prefs.addChild(name='always')
+ never = prefs.addChild(name='never')
+ for item in items:
+ jid, preference = item
+ if preference == 'always':
+ always.addChild(name='jid').setData(jid)
+ else:
+ never.addChild(name='jid').setData(jid)
+ self.connection.send(iq)
class ConnectionArchive136(ConnectionArchive):
def __init__(self):
diff --git a/src/dialogs.py b/src/dialogs.py
index 280fe0e9c..a11e5d9cc 100644
--- a/src/dialogs.py
+++ b/src/dialogs.py
@@ -69,6 +69,7 @@ from common import dataforms
from common.exceptions import GajimGeneralException
from common.connection_handlers_events import MessageOutgoingEvent
+
class EditGroupsDialog:
"""
Class for the edit group dialog window
@@ -4107,6 +4108,166 @@ class ArchivingPreferencesWindow:
del gajim.interface.instances[self.account]['archiving_preferences']
+class Archiving313PreferencesWindow:
+
+ default_dict = {'always': 0, 'roster': 1, 'never': 2}
+
+ def __init__(self, account):
+ self.account = account
+ self.idle_id = None
+
+ # Connect to glade
+ self.xml = gtkgui_helpers.get_gtk_builder(
+ 'archiving_313_preferences_window.ui')
+ self.window = self.xml.get_object('archiving_313_pref')
+
+ # Add Widgets
+ for widget in ('archive_items_liststore', 'default_cb'):
+ setattr(self, widget, self.xml.get_object(widget))
+
+ self.window.set_title(_('Archiving Preferences for %s') % self.account)
+
+ gajim.ged.register_event_handler(
+ 'archiving-313-preferences-changed-received', ged.GUI1,
+ self._nec_archiving_313_changed_received)
+ gajim.ged.register_event_handler(
+ 'archiving-error-received', ged.GUI1, self._nec_archiving_error)
+
+ self.default_cb.set_active(0)
+ self.set_widget_state(False)
+ self.window.show_all()
+ self.xml.connect_signals(self)
+
+ self.idle_id = GLib.timeout_add_seconds(3, self._nec_archiving_error)
+ gajim.connections[self.account].request_archive_preferences()
+
+ def set_widget_state(self, state):
+ for widget in ('default_cb', 'save_button', 'add_button',
+ 'remove_button'):
+ self.xml.get_object(widget).set_sensitive(state)
+
+ def _nec_archiving_313_changed_received(self, obj):
+ if obj.conn.name != self.account:
+ return
+ try:
+ GLib.source_remove(self.idle_id)
+ except Exception as e:
+ log.debug(e)
+ self.set_widget_state(True)
+ if obj.answer:
+ def on_ok(dialog):
+ self.window.destroy()
+ dialog = HigDialog(
+ self.window, Gtk.MessageType.INFO, Gtk.ButtonsType.OK,
+ _('Success!'), _('Your Archiving Preferences have been saved!'),
+ on_response_ok=on_ok, on_response_cancel=on_ok)
+ dialog.popup()
+ self.default_cb.set_active(self.default_dict[obj.default])
+ self.archive_items_liststore.clear()
+ for items in obj.items:
+ self.archive_items_liststore.append(items)
+
+ def _nec_archiving_error(self, obj=None):
+ if obj and obj.conn.name != self.account:
+ return
+ try:
+ GLib.source_remove(self.idle_id)
+ except Exception as e:
+ log.debug(e)
+ if not obj:
+ msg = _('We got no response from the Server')
+ else:
+ msg = _('We received an error: {}').format(self.error_msg)
+
+ dialog = HigDialog(
+ self.window, Gtk.MessageType.INFO, Gtk.ButtonsType.OK,
+ _('Error!'), msg)
+ dialog.popup()
+ self.set_widget_state(True)
+ return
+
+ def on_add_item_button_clicked(self, widget):
+ key_name = 'item_archiving_preferences'
+ if key_name in gajim.interface.instances[self.account]:
+ gajim.interface.instances[self.account][key_name].window.present()
+ else:
+ gajim.interface.instances[self.account][key_name] = \
+ ItemArchiving313PreferencesWindow(
+ self.account, self, self.window)
+
+ def on_remove_item_button_clicked(self, widget):
+ archive_view = self.xml.get_object('archive_view')
+ mod, path = archive_view.get_selection().get_selected_rows()
+ if path:
+ iter_ = mod.get_iter(path)
+ self.archive_items_liststore.remove(iter_)
+
+ def on_save_button_clicked(self, widget):
+ self.set_widget_state(False)
+ items = []
+ iter_ = self.default_cb.get_active_iter()
+ default = self.default_cb.get_model().get_value(iter_, 0)
+ for item in self.archive_items_liststore:
+ items.append((item[0].lower(), item[1].lower()))
+ self.idle_id = GLib.timeout_add_seconds(3, self._nec_archiving_error)
+ gajim.connections[self.account]. \
+ set_archive_preferences(items, default.lower())
+
+ def on_close_button_clicked(self, widget):
+ self.window.destroy()
+
+ def on_archiving_preferences_window_destroy(self, widget):
+ gajim.ged.remove_event_handler(
+ 'archiving-313-preferences-changed-received', ged.GUI1,
+ self._nec_archiving_313_changed_received)
+ gajim.ged.remove_event_handler(
+ 'archiving-error-received', ged.GUI1, self._nec_archiving_error)
+ if 'archiving_preferences' in gajim.interface.instances[self.account]:
+ del gajim.interface.instances[self.account]['archiving_preferences']
+
+
+class ItemArchiving313PreferencesWindow:
+
+ def __init__(self, account, archive, transient):
+
+ self.account = account
+ self.archive = archive
+
+ self.xml = gtkgui_helpers.get_gtk_builder(
+ 'archiving_313_preferences_item.ui')
+ self.window = self.xml.get_object('item_dialog')
+ self.window.set_transient_for(transient)
+ # Add Widgets
+ for widget in ('jid_entry', 'pref_cb'):
+ setattr(self, widget, self.xml.get_object(widget))
+
+ self.window.set_title(_('Add Jabber ID'))
+ self.pref_cb.set_active(0)
+ self.window.show_all()
+ self.xml.connect_signals(self)
+
+ def on_ok_button_clicked(self, widget):
+ if self.pref_cb.get_active() == 0:
+ pref = 'Always'
+ else:
+ pref = 'Never'
+ text = self.jid_entry.get_text()
+ if not text:
+ self.window.destroy()
+ return
+ else:
+ self.archive.archive_items_liststore.append((text, pref))
+ self.window.destroy()
+
+ def on_cancel_button_clicked(self, widget):
+ self.window.destroy()
+
+ def on_item_archiving_preferences_window_destroy(self, widget):
+ key_name = 'item_archiving_preferences'
+ if key_name in gajim.interface.instances[self.account]:
+ del gajim.interface.instances[self.account][key_name]
+
+
class PrivacyListWindow:
"""
Window that is used for creating NEW or EDITING already there privacy lists
diff --git a/src/roster_window.py b/src/roster_window.py
index 7da2a4546..e53f809a4 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -2830,8 +2830,12 @@ class RosterWindow:
gajim.interface.instances[account]['archiving_preferences'].window.\
present()
else:
- gajim.interface.instances[account]['archiving_preferences'] = \
- dialogs.ArchivingPreferencesWindow(account)
+ if gajim.connections[account].archiving_313_supported:
+ gajim.interface.instances[account]['archiving_preferences'] = \
+ dialogs.Archiving313PreferencesWindow(account)
+ else:
+ gajim.interface.instances[account]['archiving_preferences'] = \
+ dialogs.ArchivingPreferencesWindow(account)
def on_privacy_lists_menuitem_activate(self, widget, account):
if 'privacy_lists' in gajim.interface.instances[account]:
@@ -6099,8 +6103,10 @@ class RosterWindow:
self.on_privacy_lists_menuitem_activate, account)
else:
privacy_lists_menuitem.set_sensitive(False)
- if gajim.connections[account].archive_pref_supported:
- archiving_preferences_menuitem.connect('activate',
+ if gajim.connections[account].archive_pref_supported or \
+ gajim.connections[account].archiving_313_supported:
+ archiving_preferences_menuitem.connect(
+ 'activate',
self.on_archiving_preferences_menuitem_activate, account)
else:
archiving_preferences_menuitem.set_sensitive(False)