adds setting screen
This commit is contained in:
60
src/service/dbus-service-base.vala
Normal file
60
src/service/dbus-service-base.vala
Normal file
@@ -0,0 +1,60 @@
|
||||
public abstract class DBusServiceBase : Object {
|
||||
protected uint dbus_watch_id;
|
||||
public bool is_connected { get; private set; default = false; }
|
||||
|
||||
protected const string DBUS_PATH = "/net/buzzert/kordophonecd/daemon";
|
||||
protected const string DBUS_NAME = "net.buzzert.kordophonecd";
|
||||
|
||||
protected DBusServiceBase() {
|
||||
connect_to_dbus.begin((obj, res) => {
|
||||
connect_to_dbus.end(res);
|
||||
});
|
||||
}
|
||||
|
||||
~DBusServiceBase() {
|
||||
if (dbus_watch_id > 0) {
|
||||
Bus.unwatch_name(dbus_watch_id);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void setup_signals();
|
||||
protected abstract async Object? get_proxy() throws Error;
|
||||
protected abstract string get_service_name();
|
||||
|
||||
private async void connect_to_dbus() {
|
||||
try {
|
||||
debug("Trying to connect to %s service at path: %s", get_service_name(), DBUS_PATH);
|
||||
|
||||
var proxy = yield get_proxy();
|
||||
if (proxy == null) {
|
||||
throw new Error(1337, 1, "Failed to get proxy");
|
||||
}
|
||||
|
||||
// If we get here, connection succeeded
|
||||
debug("Connected to %s service at path: %s", get_service_name(), DBUS_PATH);
|
||||
is_connected = true;
|
||||
|
||||
setup_signals();
|
||||
|
||||
} catch (Error e) {
|
||||
debug("Failed to connect to %s at %s: %s", get_service_name(), DBUS_PATH, e.message);
|
||||
}
|
||||
|
||||
if (!is_connected) {
|
||||
warning("Failed to connect to %s on any known path", get_service_name());
|
||||
|
||||
// Watch for the service to appear
|
||||
dbus_watch_id = Bus.watch_name(BusType.SESSION,
|
||||
DBUS_NAME,
|
||||
BusNameWatcherFlags.AUTO_START,
|
||||
() => {
|
||||
connect_to_dbus.begin();
|
||||
},
|
||||
null);
|
||||
}
|
||||
}
|
||||
|
||||
protected Error create_not_connected_error() {
|
||||
return new Error(1337, 1, @"$(get_service_name()) not connected");
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,6 @@ namespace DBusService {
|
||||
[DBus (name = "Username")]
|
||||
public abstract string username { owned get; set; }
|
||||
|
||||
[DBus (name = "CredentialItem")]
|
||||
public abstract GLib.ObjectPath credential_item { owned get; set; }
|
||||
|
||||
[DBus (name = "SetServer")]
|
||||
public abstract void set_server(string url, string user) throws DBusError, IOError;
|
||||
|
||||
|
||||
@@ -80,12 +80,6 @@
|
||||
<property name="ServerURL" type="s" access="readwrite"/>
|
||||
<property name="Username" type="s" access="readwrite"/>
|
||||
|
||||
<!-- Secret-Service handle (object path) -->
|
||||
<property name="CredentialItem" type="o" access="readwrite">
|
||||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal"
|
||||
value="true"/>
|
||||
</property>
|
||||
|
||||
<!-- helpers for atomic updates -->
|
||||
<method name="SetServer">
|
||||
<arg name="url" type="s" direction="in"/>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using GLib;
|
||||
using Gee;
|
||||
|
||||
public class Repository : Object
|
||||
{
|
||||
public class Repository : DBusServiceBase {
|
||||
public signal void conversations_updated();
|
||||
public signal void messages_updated(string conversation_guid);
|
||||
|
||||
@@ -15,24 +14,38 @@ public class Repository : Object
|
||||
}
|
||||
|
||||
private static Repository instance = null;
|
||||
private DBusService.Repository dbus_repository;
|
||||
private uint dbus_watch_id;
|
||||
private DBusService.Repository? dbus_repository;
|
||||
|
||||
private Repository() {
|
||||
connect_to_dbus.begin((obj, res) => {
|
||||
connect_to_dbus.end(res);
|
||||
});
|
||||
base();
|
||||
}
|
||||
|
||||
~Repository() {
|
||||
if (dbus_watch_id > 0) {
|
||||
Bus.unwatch_name(dbus_watch_id);
|
||||
}
|
||||
protected override string get_service_name() {
|
||||
return "Repository";
|
||||
}
|
||||
|
||||
protected override async Object? get_proxy() throws Error {
|
||||
dbus_repository = yield Bus.get_proxy(BusType.SESSION, DBUS_NAME, DBUS_PATH);
|
||||
dbus_repository.get_version(); // Test the connection
|
||||
return dbus_repository;
|
||||
}
|
||||
|
||||
protected override void setup_signals() {
|
||||
dbus_repository.conversations_updated.connect(() => {
|
||||
conversations_updated();
|
||||
});
|
||||
|
||||
dbus_repository.messages_updated.connect((conversation_guid) => {
|
||||
messages_updated(conversation_guid);
|
||||
});
|
||||
|
||||
// Initial load
|
||||
conversations_updated();
|
||||
}
|
||||
|
||||
public Conversation[] get_conversations() throws Error {
|
||||
if (dbus_repository == null) {
|
||||
throw new Error(1337, 1, "Repository not connected");
|
||||
if (!is_connected || dbus_repository == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
|
||||
var conversations = dbus_repository.get_conversations();
|
||||
@@ -46,8 +59,8 @@ public class Repository : Object
|
||||
}
|
||||
|
||||
public Message[] get_messages(string conversation_guid, string last_message_id = "") throws Error {
|
||||
if (dbus_repository == null) {
|
||||
throw new Error(1337, 1, "Repository not connected");
|
||||
if (!is_connected || dbus_repository == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
|
||||
var messages = dbus_repository.get_messages(conversation_guid, last_message_id);
|
||||
@@ -61,56 +74,10 @@ public class Repository : Object
|
||||
}
|
||||
|
||||
public string send_message(string conversation_guid, string message) throws Error {
|
||||
if (dbus_repository == null) {
|
||||
throw new Error(1337, 1, "Repository not connected");
|
||||
if (!is_connected || dbus_repository == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
|
||||
return dbus_repository.send_message(conversation_guid, message);
|
||||
}
|
||||
|
||||
private async void connect_to_dbus() {
|
||||
bool connected = false;
|
||||
const string path = "/net/buzzert/kordophonecd/daemon";
|
||||
|
||||
try {
|
||||
debug("Trying to connect to DBus service at path: %s", path);
|
||||
dbus_repository = yield Bus.get_proxy(BusType.SESSION,
|
||||
"net.buzzert.kordophonecd",
|
||||
path);
|
||||
|
||||
// Test the connection
|
||||
dbus_repository.get_version();
|
||||
|
||||
// If we get here, connection succeeded
|
||||
debug("Connected to DBus service at path: %s", path);
|
||||
connected = true;
|
||||
|
||||
// Listen for updates
|
||||
dbus_repository.conversations_updated.connect(() => {
|
||||
conversations_updated();
|
||||
});
|
||||
|
||||
dbus_repository.messages_updated.connect((conversation_guid) => {
|
||||
messages_updated(conversation_guid);
|
||||
});
|
||||
|
||||
// Initial load
|
||||
conversations_updated();
|
||||
} catch (Error e) {
|
||||
debug("Failed to connect to kordophonecd at %s: %s", path, e.message);
|
||||
}
|
||||
|
||||
if (!connected) {
|
||||
warning("Failed to connect to kordophonecd on any known path");
|
||||
|
||||
// Watch for the service to appear
|
||||
dbus_watch_id = Bus.watch_name(BusType.SESSION,
|
||||
"net.buzzert.kordophonecd",
|
||||
BusNameWatcherFlags.AUTO_START,
|
||||
() => {
|
||||
connect_to_dbus.begin();
|
||||
},
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
115
src/service/settings.vala
Normal file
115
src/service/settings.vala
Normal file
@@ -0,0 +1,115 @@
|
||||
using GLib;
|
||||
|
||||
public class Settings : DBusServiceBase {
|
||||
public signal void config_changed();
|
||||
public signal void settings_ready();
|
||||
|
||||
public static Settings get_instance() {
|
||||
if (instance == null) {
|
||||
instance = new Settings();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static Settings instance = null;
|
||||
private DBusService.Settings? dbus_settings;
|
||||
private Secret.Service secret_service;
|
||||
|
||||
private Settings() {
|
||||
base();
|
||||
|
||||
try {
|
||||
secret_service = Secret.Service.get_sync(Secret.ServiceFlags.OPEN_SESSION);
|
||||
} catch (Error e) {
|
||||
warning("Failed to get secret service: %s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
protected override string get_service_name() {
|
||||
return "Settings";
|
||||
}
|
||||
|
||||
protected override async Object? get_proxy() throws Error {
|
||||
dbus_settings = yield Bus.get_proxy(BusType.SESSION, DBUS_NAME, DBUS_PATH);
|
||||
return dbus_settings;
|
||||
}
|
||||
|
||||
protected override void setup_signals() {
|
||||
dbus_settings.config_changed.connect(() => {
|
||||
config_changed();
|
||||
});
|
||||
|
||||
settings_ready();
|
||||
}
|
||||
|
||||
public string get_server_url() throws Error {
|
||||
if (!is_connected || dbus_settings == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
return dbus_settings.server_u_r_l;
|
||||
}
|
||||
|
||||
public void set_server_url(string url) throws Error {
|
||||
if (!is_connected || dbus_settings == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
dbus_settings.server_u_r_l = url;
|
||||
}
|
||||
|
||||
public string get_username() throws Error {
|
||||
if (!is_connected || dbus_settings == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
return dbus_settings.username;
|
||||
}
|
||||
|
||||
public void set_username(string username) throws Error {
|
||||
if (!is_connected || dbus_settings == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
dbus_settings.username = username;
|
||||
}
|
||||
|
||||
public void set_server(string url, string username) throws Error {
|
||||
if (!is_connected || dbus_settings == null) {
|
||||
throw create_not_connected_error();
|
||||
}
|
||||
dbus_settings.set_server(url, username);
|
||||
}
|
||||
|
||||
private HashTable<string, string> password_attributes() {
|
||||
var attributes = new HashTable<string, string>(str_hash, str_equal);
|
||||
attributes["service"] = "net.buzzert.kordophonecd";
|
||||
attributes["target"] = "default";
|
||||
attributes["username"] = get_username();
|
||||
return attributes;
|
||||
}
|
||||
|
||||
public string get_password() throws Error {
|
||||
var attributes = password_attributes();
|
||||
var password = secret_service.lookup_sync(null, attributes, null);
|
||||
if (password == null) {
|
||||
warning("No password found for user %s", get_username());
|
||||
return "";
|
||||
}
|
||||
|
||||
return password.get_text();
|
||||
}
|
||||
|
||||
public void set_password(string password) throws Error {
|
||||
var attributes = password_attributes();
|
||||
bool result = secret_service.store_sync(
|
||||
null,
|
||||
attributes,
|
||||
Secret.COLLECTION_DEFAULT,
|
||||
"Kordophone Keystore",
|
||||
new Secret.Value(password, password.length, "text/plain"),
|
||||
null
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
warning("Failed to store password for user %s", get_username());
|
||||
throw new Error(1337, 1, "Failed to store password");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user