From 502d7dc9fe93070ec6750d45ce8c224959ba0a1e Mon Sep 17 00:00:00 2001 From: James Booth Date: Mon, 18 Feb 2013 22:51:05 +0000 Subject: [PATCH] Show available resources for current account with "/account" --- src/command/command.c | 17 ++++-- src/ui/windows.c | 138 +++++++++++++++++++++++++++++++++--------- src/xmpp/connection.c | 23 +++++++ src/xmpp/connection.h | 2 + src/xmpp/presence.c | 8 +++ src/xmpp/xmpp.h | 1 + 6 files changed, 155 insertions(+), 34 deletions(-) diff --git a/src/command/command.c b/src/command/command.c index 0b6f5312..4324c7f5 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -184,9 +184,9 @@ static struct cmd_t main_commands[] = NULL } } }, { "/account", - _cmd_account, parse_args, 1, 4, - { "/account command [account] [property] [value]", "Manage accounts.", - { "/account command [account] [property] [value]", + _cmd_account, parse_args, 0, 4, + { "/account [command] [account] [property] [value]", "Manage accounts.", + { "/account [command] [account] [property] [value]", "---------------------------------------------", "Commands for creating and managing accounts.", "list : List all accounts.", @@ -197,6 +197,7 @@ static struct cmd_t main_commands[] = "rename account newname : Rename account to newname.", "set account property value : Set 'property' of 'account' to 'value'.", "", + "When connected, the /account command can be called with no arguments, to info about the current account.", "The 'property' may be one of.", "jid : The Jabber ID of the account, the account name will be used if this property is not set.", "server : The chat service server, if different to the domain part of the JID.", @@ -1079,7 +1080,15 @@ _cmd_account(gchar **args, struct cmd_help_t help) { char *command = args[0]; - if (strcmp(command, "list") == 0) { + if (command == NULL) { + if (jabber_get_connection_status() != JABBER_CONNECTED) { + cons_show("Usage: %s", help.usage); + } else { + ProfAccount *account = accounts_get_account(jabber_get_account_name()); + cons_show_account(account); + accounts_free_account(account); + } + } else if (strcmp(command, "list") == 0) { gchar **accounts = accounts_get_list(); cons_show_account_list(accounts); g_strfreev(accounts); diff --git a/src/ui/windows.c b/src/ui/windows.c index a7d82a6e..e5670ac4 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -1331,6 +1331,114 @@ cons_show_account_list(gchar **accounts) } } +void +cons_show_account(ProfAccount *account) +{ + cons_show(""); + cons_show("Account %s:", account->name); + if (account->enabled) { + cons_show ("enabled : TRUE"); + } else { + cons_show ("enabled : FALSE"); + } + cons_show ("jid : %s", account->jid); + if (account->resource != NULL) { + cons_show ("resource : %s", account->resource); + } + if (account->server != NULL) { + cons_show ("server : %s", account->server); + } + if (account->last_presence != NULL) { + cons_show ("Last presence : %s", account->last_presence); + } + if (account->login_presence != NULL) { + cons_show ("Login presence : %s", account->login_presence); + } + cons_show ("Priority : chat:%d, online:%d, away:%d, xa:%d, dnd:%d", + account->priority_chat, account->priority_online, account->priority_away, + account->priority_xa, account->priority_dnd); + + GList *resources = jabber_get_available_resources(); + GList *ordered_resources = NULL; + + WINDOW *win = console->win; + if (resources != NULL) { + _win_show_time(win, '-'); + wprintw(win, "Resources:\n"); + + // sort in order of availabiltiy + while (resources != NULL) { + Resource *resource = resources->data; + ordered_resources = g_list_insert_sorted(ordered_resources, + resource, (GCompareFunc)resource_compare_availability); + resources = g_list_next(resources); + } + } + + while (ordered_resources != NULL) { + Resource *resource = ordered_resources->data; + const char *resource_presence = string_from_resource_presence(resource->presence); + _win_show_time(win, '-'); + _presence_colour_on(win, resource_presence); + wprintw(win, " %s (%d), %s", resource->name, resource->priority, resource_presence); + if (resource->status != NULL) { + wprintw(win, ", \"%s\"", resource->status); + } + wprintw(win, "\n"); + _presence_colour_off(win, resource_presence); + + if (resource->caps_str != NULL) { + Capabilities *caps = caps_get(resource->caps_str); + if (caps != NULL) { + // show identity + if ((caps->category != NULL) || (caps->type != NULL) || (caps->name != NULL)) { + _win_show_time(win, '-'); + wprintw(win, " Identity: "); + if (caps->name != NULL) { + wprintw(win, "%s", caps->name); + if ((caps->category != NULL) || (caps->type != NULL)) { + wprintw(win, " "); + } + } + if (caps->type != NULL) { + wprintw(win, "%s", caps->type); + if (caps->category != NULL) { + wprintw(win, " "); + } + } + if (caps->category != NULL) { + wprintw(win, "%s", caps->category); + } + wprintw(win, "\n"); + } + if (caps->software != NULL) { + _win_show_time(win, '-'); + wprintw(win, " Software: %s", caps->software); + } + if (caps->software_version != NULL) { + wprintw(win, ", %s", caps->software_version); + } + if ((caps->software != NULL) || (caps->software_version != NULL)) { + wprintw(win, "\n"); + } + if (caps->os != NULL) { + _win_show_time(win, '-'); + wprintw(win, " OS: %s", caps->os); + } + if (caps->os_version != NULL) { + wprintw(win, ", %s", caps->os_version); + } + if ((caps->os != NULL) || (caps->os_version != NULL)) { + wprintw(win, "\n"); + } + } + } + + ordered_resources = g_list_next(ordered_resources); + } + +} + void win_show_status(void) { @@ -1372,36 +1480,6 @@ win_room_show_status(const char * const contact) } } -void -cons_show_account(ProfAccount *account) -{ - cons_show("%s account details:", account->name); - if (account->enabled) { - cons_show ("enabled : TRUE"); - } else { - cons_show ("enabled : FALSE"); - } - cons_show ("jid : %s", account->jid); - if (account->resource != NULL) { - cons_show ("resource : %s", account->resource); - } - if (account->server != NULL) { - cons_show ("server : %s", account->server); - } - if (account->last_presence != NULL) { - cons_show ("Last presence : %s", account->last_presence); - } - if (account->login_presence != NULL) { - cons_show ("Login presence : %s", account->login_presence); - } - cons_show ("Priority (chat) : %d", account->priority_chat); - cons_show ("Priority (online) : %d", account->priority_online); - cons_show ("Priority (away) : %d", account->priority_away); - cons_show ("Priority (xa) : %d", account->priority_xa); - cons_show ("Priority (dnd) : %d", account->priority_dnd); - cons_show(""); -} - void cons_show_ui_prefs(void) { diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index 5d509d87..2c0c5186 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -52,6 +52,8 @@ static struct _jabber_conn_t { int tls_disabled; } jabber_conn; +static GHashTable *available_resources; + // for auto reconnect static struct { char *name; @@ -92,6 +94,8 @@ jabber_init(const int disable_tls) jabber_conn.tls_disabled = disable_tls; presence_init(); caps_init(); + available_resources = g_hash_table_new_full(g_str_hash, g_str_equal, free, + (GDestroyNotify)resource_destroy); } jabber_conn_status_t @@ -201,6 +205,12 @@ jabber_set_autoping(const int seconds) } } +GList * +jabber_get_available_resources(void) +{ + return g_hash_table_get_values(available_resources); +} + jabber_conn_status_t jabber_get_connection_status(void) { @@ -252,6 +262,18 @@ connection_set_priority(const int priority) jabber_conn.priority = priority; } +void +connection_add_available_resource(Resource *resource) +{ + g_hash_table_replace(available_resources, strdup(resource->name), resource); +} + +void +connection_remove_available_resource(const char * const resource) +{ + g_hash_table_remove(available_resources, resource); +} + void connection_free_resources(void) { @@ -261,6 +283,7 @@ connection_free_resources(void) FREE_SET_NULL(saved_details.altdomain); FREE_SET_NULL(saved_account.name); FREE_SET_NULL(saved_account.passwd); + g_hash_table_destroy(available_resources); chat_sessions_clear(); presence_free_sub_requests(); xmpp_conn_release(jabber_conn.conn); diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h index abe989cd..c242f65f 100644 --- a/src/xmpp/connection.h +++ b/src/xmpp/connection.h @@ -32,5 +32,7 @@ int connection_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); void connection_set_priority(int priority); void connection_set_presence_message(const char * const message); +void connection_add_available_resource(Resource *resource); +void connection_remove_available_resource(const char * const resource); #endif diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index 4d152a20..28e2039e 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -343,6 +343,8 @@ _unavailable_handler(xmpp_conn_t * const conn, if (strcmp(my_jid->barejid, from_jid->barejid) !=0) { prof_handle_contact_offline(from_jid->barejid, from_jid->resourcepart, status_str); + } else { + connection_remove_available_resource(from_jid->resourcepart); } jid_destroy(my_jid); @@ -425,6 +427,12 @@ _available_handler(xmpp_conn_t * const conn, Resource *resource = resource_new(from_jid->resourcepart, presence, status_str, priority, caps_key); prof_handle_contact_online(from_jid->barejid, resource, last_activity); + } else { + // handle self presence + resource_presence_t presence = resource_presence_from_string(show_str); + Resource *resource = resource_new(from_jid->resourcepart, presence, + status_str, priority, caps_key); + connection_add_available_resource(resource); } jid_destroy(my_jid); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 44f89407..3fc9c633 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -70,6 +70,7 @@ jabber_conn_status_t jabber_get_connection_status(void); char * jabber_get_presence_message(void); void jabber_set_autoping(int seconds); char* jabber_get_account_name(void); +GList * jabber_get_available_resources(void); // message functions void message_send(const char * const msg, const char * const recipient);