2017-03-02 14:37:32 +00:00
|
|
|
using Gee;
|
|
|
|
|
|
|
|
using Xmpp;
|
|
|
|
using Dino.Entities;
|
|
|
|
|
|
|
|
namespace Dino {
|
|
|
|
|
2017-03-19 11:55:36 +00:00
|
|
|
public class RosterManager : StreamInteractionModule, Object {
|
|
|
|
public static ModuleIdentity<RosterManager> IDENTITY = new ModuleIdentity<RosterManager>("roster_manager");
|
|
|
|
public string id { get { return IDENTITY.id; } }
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-03-19 11:55:36 +00:00
|
|
|
public signal void removed_roster_item(Account account, Jid jid, Roster.Item roster_item);
|
|
|
|
public signal void updated_roster_item(Account account, Jid jid, Roster.Item roster_item);
|
2018-08-10 00:40:20 +00:00
|
|
|
public signal void mutual_subscription(Account account, Jid jid);
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-03-19 11:55:36 +00:00
|
|
|
private StreamInteractor stream_interactor;
|
2017-05-21 21:30:30 +00:00
|
|
|
private Database db;
|
|
|
|
private Gee.Map<Account, RosterStoreImpl> roster_stores = new HashMap<Account, RosterStoreImpl>(Account.hash_func, Account.equals_func);
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-05-21 21:30:30 +00:00
|
|
|
public static void start(StreamInteractor stream_interactor, Database db) {
|
|
|
|
RosterManager m = new RosterManager(stream_interactor, db);
|
2017-03-19 11:55:36 +00:00
|
|
|
stream_interactor.add_module(m);
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-05-21 21:30:30 +00:00
|
|
|
public RosterManager(StreamInteractor stream_interactor, Database db) {
|
2017-03-19 11:55:36 +00:00
|
|
|
this.stream_interactor = stream_interactor;
|
2017-05-21 21:30:30 +00:00
|
|
|
this.db = db;
|
2017-03-19 11:55:36 +00:00
|
|
|
stream_interactor.account_added.connect(on_account_added);
|
2017-05-21 21:30:30 +00:00
|
|
|
stream_interactor.module_manager.initialize_account_modules.connect((account, modules) => {
|
|
|
|
if (!roster_stores.has_key(account)) roster_stores[account] = new RosterStoreImpl(account, db);
|
|
|
|
modules.add(new Roster.VersioningModule(roster_stores[account]));
|
|
|
|
});
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-05-21 21:30:30 +00:00
|
|
|
public Collection<Roster.Item> get_roster(Account account) {
|
2019-10-18 12:31:23 +00:00
|
|
|
if (roster_stores[account] == null) return new ArrayList<Roster.Item>();
|
2017-05-21 21:30:30 +00:00
|
|
|
return roster_stores[account].get_roster();
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-03-19 11:55:36 +00:00
|
|
|
public Roster.Item? get_roster_item(Account account, Jid jid) {
|
2019-10-18 12:31:23 +00:00
|
|
|
if (roster_stores[account] == null) return null;
|
2017-05-21 21:30:30 +00:00
|
|
|
return roster_stores[account].get_item(jid);
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-03-19 11:55:36 +00:00
|
|
|
public void remove_jid(Account account, Jid jid) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).remove_jid(stream, jid.bare_jid);
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-03-19 11:55:36 +00:00
|
|
|
public void add_jid(Account account, Jid jid, string? handle) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).add_jid(stream, jid.bare_jid, handle);
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-06-16 12:29:02 +00:00
|
|
|
public void set_jid_handle(Account account, Jid jid, string? handle) {
|
2018-01-12 20:03:09 +00:00
|
|
|
XmppStream? stream = stream_interactor.get_stream(account);
|
|
|
|
if (stream != null) stream.get_module(Xmpp.Roster.Module.IDENTITY).set_jid_handle(stream, jid.bare_jid, handle);
|
2017-06-16 12:29:02 +00:00
|
|
|
}
|
|
|
|
|
2017-03-19 11:55:36 +00:00
|
|
|
private void on_account_added(Account account) {
|
2018-05-09 21:19:22 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).received_roster.connect_after( (stream, roster) => {
|
2017-05-21 21:30:30 +00:00
|
|
|
foreach (Roster.Item roster_item in roster) {
|
|
|
|
on_roster_item_updated(account, roster_item);
|
|
|
|
}
|
2017-03-19 11:55:36 +00:00
|
|
|
});
|
2018-05-09 21:19:22 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).item_removed.connect_after( (stream, roster_item) => {
|
2018-01-12 20:03:09 +00:00
|
|
|
removed_roster_item(account, roster_item.jid, roster_item);
|
2017-03-19 11:55:36 +00:00
|
|
|
});
|
2018-05-09 21:19:22 +00:00
|
|
|
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).item_updated.connect_after( (stream, roster_item) => {
|
2017-03-19 11:55:36 +00:00
|
|
|
on_roster_item_updated(account, roster_item);
|
|
|
|
});
|
2018-08-10 00:40:20 +00:00
|
|
|
|
|
|
|
stream_interactor.module_manager.get_module(account, Roster.Module.IDENTITY).mutual_subscription.connect_after( (stream, jid) => {
|
|
|
|
mutual_subscription(account, jid);
|
|
|
|
});
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-05-21 21:30:30 +00:00
|
|
|
private void on_roster_item_updated(Account account, Roster.Item roster_item) {
|
2018-01-12 20:03:09 +00:00
|
|
|
updated_roster_item(account, roster_item.jid, roster_item);
|
2017-05-21 21:30:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public class RosterStoreImpl : Roster.Storage, Object {
|
|
|
|
private Account account;
|
|
|
|
private Database db;
|
|
|
|
|
2018-01-12 20:03:09 +00:00
|
|
|
private HashMap<Jid, Roster.Item> items = new HashMap<Jid, Roster.Item>(Jid.hash_bare_func, Jid.equals_bare_func);
|
2017-05-21 21:30:30 +00:00
|
|
|
|
|
|
|
public class RosterStoreImpl(Account account, Database db) {
|
|
|
|
this.account = account;
|
|
|
|
this.db = db;
|
|
|
|
|
|
|
|
foreach (Qlite.Row row in db.roster.select().with(db.roster.account_id, "=", account.id)) {
|
2019-12-22 03:10:53 +00:00
|
|
|
try {
|
|
|
|
Roster.Item item = new Roster.Item();
|
|
|
|
item.jid = new Jid(row[db.roster.jid]);
|
|
|
|
item.name = row[db.roster.handle];
|
|
|
|
item.subscription = row[db.roster.subscription];
|
|
|
|
items[item.jid] = item;
|
|
|
|
} catch (InvalidJidError e) {
|
|
|
|
warning("Ignoring roster entry with invalid Jid: %s", e.message);
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-05-21 21:30:30 +00:00
|
|
|
public string? get_roster_version() {
|
2017-05-24 15:28:39 +00:00
|
|
|
return account.roster_version;
|
2017-05-21 21:30:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public Collection<Roster.Item> get_roster() {
|
|
|
|
return items.values;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Roster.Item? get_item(Jid jid) {
|
2018-01-12 20:03:09 +00:00
|
|
|
return items.has_key(jid) ? items[jid] : null;
|
2017-05-21 21:30:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void set_roster_version(string version) {
|
2017-05-24 15:28:39 +00:00
|
|
|
account.roster_version = version;
|
2017-05-21 21:30:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void set_roster(Collection<Roster.Item> items) {
|
|
|
|
db.roster.delete().with(db.roster.account_id, "=", account.id).perform();
|
|
|
|
foreach (Roster.Item item in items) {
|
|
|
|
set_item(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void set_item(Roster.Item item) {
|
|
|
|
items[item.jid] = item;
|
2020-06-10 21:40:00 +00:00
|
|
|
db.roster.upsert()
|
|
|
|
.value(db.roster.account_id, account.id, true)
|
|
|
|
.value(db.roster.jid, item.jid.to_string(), true)
|
2017-06-16 12:29:02 +00:00
|
|
|
.value(db.roster.handle, item.name)
|
2017-05-21 21:30:30 +00:00
|
|
|
.value(db.roster.subscription, item.subscription)
|
|
|
|
.perform();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void remove_item(Roster.Item item) {
|
|
|
|
items.unset(item.jid);
|
|
|
|
db.roster.delete()
|
|
|
|
.with(db.roster.account_id, "=", account.id)
|
2018-01-12 20:03:09 +00:00
|
|
|
.with(db.roster.jid, "=", item.jid.to_string()).perform();
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
2017-03-19 11:55:36 +00:00
|
|
|
}
|
|
|
|
|
2017-06-16 12:29:02 +00:00
|
|
|
}
|