2017-03-02 14:37:32 +00:00
|
|
|
using Dino.Entities;
|
|
|
|
|
2019-12-17 22:52:05 +00:00
|
|
|
namespace Dino {
|
2022-03-30 16:36:07 +00:00
|
|
|
|
2019-12-17 22:52:05 +00:00
|
|
|
extern const string VERSION;
|
2022-03-30 16:36:07 +00:00
|
|
|
public string get_version() { return VERSION; }
|
|
|
|
public string get_short_version() {
|
|
|
|
if (!VERSION.contains("~")) return VERSION;
|
|
|
|
return VERSION.split("~")[0] + "+";
|
|
|
|
}
|
2019-12-17 22:52:05 +00:00
|
|
|
|
|
|
|
public interface Application : GLib.Application {
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-05-04 20:05:48 +00:00
|
|
|
public abstract Database db { get; set; }
|
2017-08-21 15:16:25 +00:00
|
|
|
public abstract Dino.Entities.Settings settings { get; set; }
|
2017-08-25 19:20:09 +00:00
|
|
|
public abstract StreamInteractor stream_interactor { get; set; }
|
2017-05-04 20:05:48 +00:00
|
|
|
public abstract Plugins.Registry plugin_registry { get; set; }
|
|
|
|
public abstract SearchPathGenerator? search_path_generator { get; set; }
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2019-10-18 12:55:57 +00:00
|
|
|
internal static string print_xmpp;
|
2017-04-03 13:09:30 +00:00
|
|
|
|
|
|
|
private const OptionEntry[] options = {
|
|
|
|
{ "print-xmpp", 0, 0, OptionArg.STRING, ref print_xmpp, "Print XMPP stanzas identified by DESC to stderr", "DESC" },
|
|
|
|
{ null }
|
|
|
|
};
|
|
|
|
|
2017-08-17 09:38:41 +00:00
|
|
|
public abstract void handle_uri(string jid, string query, Gee.Map<string, string> options);
|
|
|
|
|
2017-05-04 20:05:48 +00:00
|
|
|
public void init() throws Error {
|
2017-03-12 12:19:04 +00:00
|
|
|
if (DirUtils.create_with_parents(get_storage_dir(), 0700) == -1) {
|
2017-03-30 19:26:17 +00:00
|
|
|
throw new Error(-1, 0, "Could not create storage dir \"%s\": %s", get_storage_dir(), FileUtils.error_from_errno(errno).to_string());
|
2017-03-12 12:19:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.db = new Database(Path.build_filename(get_storage_dir(), "dino.db"));
|
2017-08-21 15:16:25 +00:00
|
|
|
this.settings = new Dino.Entities.Settings.from_db(db);
|
2017-08-25 19:20:09 +00:00
|
|
|
this.stream_interactor = new StreamInteractor(db);
|
2017-03-02 14:37:32 +00:00
|
|
|
|
2017-08-25 19:20:09 +00:00
|
|
|
MessageProcessor.start(stream_interactor, db);
|
|
|
|
MessageStorage.start(stream_interactor, db);
|
|
|
|
PresenceManager.start(stream_interactor);
|
2020-02-20 15:59:34 +00:00
|
|
|
CounterpartInteractionManager.start(stream_interactor);
|
2017-10-31 14:19:30 +00:00
|
|
|
BlockingManager.start(stream_interactor);
|
2019-05-29 14:52:36 +00:00
|
|
|
ConversationManager.start(stream_interactor, db);
|
2017-08-25 19:20:09 +00:00
|
|
|
MucManager.start(stream_interactor);
|
2019-05-29 14:52:36 +00:00
|
|
|
AvatarManager.start(stream_interactor, db);
|
2017-08-25 19:20:09 +00:00
|
|
|
RosterManager.start(stream_interactor, db);
|
2017-08-29 22:03:37 +00:00
|
|
|
FileManager.start(stream_interactor, db);
|
2021-03-19 22:07:40 +00:00
|
|
|
Calls.start(stream_interactor, db);
|
|
|
|
CallStore.start(stream_interactor, db);
|
2018-07-16 19:26:39 +00:00
|
|
|
ContentItemStore.start(stream_interactor, db);
|
2020-04-29 19:31:23 +00:00
|
|
|
ChatInteraction.start(stream_interactor);
|
2018-11-06 23:17:24 +00:00
|
|
|
NotificationEvents.start(stream_interactor);
|
2018-07-09 22:31:39 +00:00
|
|
|
SearchProcessor.start(stream_interactor, db);
|
2018-11-16 15:27:31 +00:00
|
|
|
Register.start(stream_interactor, db);
|
2020-03-29 18:23:47 +00:00
|
|
|
EntityInfo.start(stream_interactor, db);
|
2020-04-03 20:49:59 +00:00
|
|
|
MessageCorrection.start(stream_interactor, db);
|
2021-02-17 17:22:19 +00:00
|
|
|
FileTransferStorage.start(stream_interactor, db);
|
2022-10-11 11:37:48 +00:00
|
|
|
Reactions.start(stream_interactor, db);
|
2023-01-06 12:19:42 +00:00
|
|
|
Replies.start(stream_interactor, db);
|
|
|
|
FallbackBody.start(stream_interactor, db);
|
2017-03-20 21:12:20 +00:00
|
|
|
|
2017-12-14 01:01:55 +00:00
|
|
|
create_actions();
|
|
|
|
|
2018-03-10 18:46:08 +00:00
|
|
|
startup.connect(() => {
|
2017-08-25 19:20:09 +00:00
|
|
|
stream_interactor.connection_manager.log_options = print_xmpp;
|
2017-11-22 19:06:50 +00:00
|
|
|
Idle.add(() => {
|
|
|
|
restore();
|
|
|
|
return false;
|
|
|
|
});
|
2017-03-20 21:12:20 +00:00
|
|
|
});
|
2017-10-30 00:43:26 +00:00
|
|
|
shutdown.connect(() => {
|
|
|
|
stream_interactor.connection_manager.make_offline_all();
|
|
|
|
});
|
2017-08-17 09:38:41 +00:00
|
|
|
open.connect((files, hint) => {
|
|
|
|
if (files.length != 1) {
|
|
|
|
warning("Can't handle more than one URI at once.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
File file = files[0];
|
|
|
|
if (!file.has_uri_scheme("xmpp")) {
|
|
|
|
warning("xmpp:-URI expected");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
string uri = file.get_uri();
|
|
|
|
if (!uri.contains(":")) {
|
|
|
|
warning("Invalid URI");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
string r = uri.split(":", 2)[1];
|
|
|
|
string[] m = r.split("?", 2);
|
|
|
|
string jid = m[0];
|
|
|
|
while (jid[0] == '/') {
|
|
|
|
jid = jid.substring(1);
|
|
|
|
}
|
2019-12-22 03:10:53 +00:00
|
|
|
jid = Uri.unescape_string(jid);
|
|
|
|
try {
|
|
|
|
jid = new Xmpp.Jid(jid).to_string();
|
|
|
|
} catch (Xmpp.InvalidJidError e) {
|
|
|
|
warning("Received invalid jid in xmpp:-URI: %s", e.message);
|
|
|
|
}
|
2017-08-17 09:38:41 +00:00
|
|
|
string query = "message";
|
2019-12-17 22:52:05 +00:00
|
|
|
Gee.Map<string, string> options = new Gee.HashMap<string, string>();
|
2017-08-17 09:38:41 +00:00
|
|
|
if (m.length == 2) {
|
|
|
|
string[] cmds = m[1].split(";");
|
|
|
|
query = cmds[0];
|
|
|
|
for (int i = 1; i < cmds.length; ++i) {
|
|
|
|
string[] opt = cmds[i].split("=", 2);
|
2019-12-22 03:10:53 +00:00
|
|
|
options[Uri.unescape_string(opt[0])] = opt.length == 2 ? Uri.unescape_string(opt[1]) : "";
|
2017-08-17 09:38:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
activate();
|
|
|
|
handle_uri(jid, query, options);
|
|
|
|
});
|
2017-04-03 13:09:30 +00:00
|
|
|
add_main_option_entries(options);
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
2017-03-12 12:19:04 +00:00
|
|
|
|
|
|
|
public static string get_storage_dir() {
|
|
|
|
return Path.build_filename(Environment.get_user_data_dir(), "dino");
|
|
|
|
}
|
2017-03-20 21:12:20 +00:00
|
|
|
|
2017-08-21 15:16:25 +00:00
|
|
|
public static unowned Application get_default() {
|
|
|
|
return (Dino.Application) GLib.Application.get_default();
|
|
|
|
}
|
|
|
|
|
2017-12-14 01:01:55 +00:00
|
|
|
public void create_actions() {
|
|
|
|
SimpleAction accept_subscription_action = new SimpleAction("accept-subscription", VariantType.INT32);
|
|
|
|
accept_subscription_action.activate.connect((variant) => {
|
|
|
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation_by_id(variant.get_int32());
|
|
|
|
if (conversation == null) return;
|
|
|
|
stream_interactor.get_module(PresenceManager.IDENTITY).approve_subscription(conversation.account, conversation.counterpart);
|
|
|
|
stream_interactor.get_module(PresenceManager.IDENTITY).request_subscription(conversation.account, conversation.counterpart);
|
|
|
|
});
|
|
|
|
add_action(accept_subscription_action);
|
|
|
|
}
|
|
|
|
|
2017-03-20 21:12:20 +00:00
|
|
|
protected void add_connection(Account account) {
|
2019-10-18 12:10:50 +00:00
|
|
|
if ((get_flags() & ApplicationFlags.IS_SERVICE) == ApplicationFlags.IS_SERVICE) hold();
|
2018-11-16 15:27:31 +00:00
|
|
|
stream_interactor.connect_account(account);
|
2017-03-20 21:12:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void remove_connection(Account account) {
|
2019-10-18 12:10:50 +00:00
|
|
|
if ((get_flags() & ApplicationFlags.IS_SERVICE) == ApplicationFlags.IS_SERVICE) release();
|
2019-11-27 17:46:29 +00:00
|
|
|
stream_interactor.disconnect_account.begin(account);
|
2017-03-20 21:12:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void restore() {
|
|
|
|
foreach (Account account in db.get_accounts()) {
|
|
|
|
if (account.enabled) add_connection(account);
|
|
|
|
}
|
|
|
|
}
|
2017-03-02 14:37:32 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 15:59:34 +00:00
|
|
|
}
|