diff options
-rw-r--r-- | src/command/command.c | 60 | ||||
-rw-r--r-- | src/contact.c | 14 | ||||
-rw-r--r-- | src/contact.h | 1 | ||||
-rw-r--r-- | src/ui/console.c | 60 | ||||
-rw-r--r-- | src/ui/ui.h | 1 | ||||
-rw-r--r-- | src/xmpp/roster.c | 81 | ||||
-rw-r--r-- | src/xmpp/xmpp.h | 4 |
7 files changed, 220 insertions, 1 deletions
diff --git a/src/command/command.c b/src/command/command.c index fff81351..41413320 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -276,7 +276,7 @@ static struct cmd_t main_commands[] = NULL } } }, { "/roster", - _cmd_roster, parse_args_with_freetext, 0, 3, + _cmd_roster, parse_args_with_freetext, 0, 4, { "/roster [add|remove|nick] [jid] [handle]", "Manage your roster.", { "/roster [add|remove|nick] [jid] [handle]", "----------------------------------------", @@ -927,6 +927,7 @@ cmd_init(void) roster_ac = autocomplete_new(); autocomplete_add(roster_ac, strdup("add")); autocomplete_add(roster_ac, strdup("nick")); + autocomplete_add(roster_ac, strdup("group")); autocomplete_add(roster_ac, strdup("remove")); theme_load_ac = NULL; @@ -2091,6 +2092,63 @@ _cmd_roster(gchar **args, struct cmd_help_t help) return TRUE; } + // group command + if (strcmp(args[0], "group") == 0) { + char *command = args[1]; + char *group = args[2]; + char *jid = args[3]; + + if (command == NULL) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + if (strcmp(command, "show") == 0) { + if (group == NULL) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + GSList *list = roster_get_group(group); + cons_show_roster_group(group, list); + return TRUE; + } + + if (strcmp(command, "add") == 0) { + if ((group == NULL) || (jid == NULL)) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + PContact contact = roster_get_contact(jid); + if (contact == NULL) { + cons_show("Contact not found in roster: %s", jid); + return TRUE; + } + + roster_add_to_group(group, jid); + + return TRUE; + } + + if (strcmp(command, "remove") == 0) { + if ((group == NULL) || (jid == NULL)) { + cons_show("Usage: %s", help.usage); + return TRUE; + } + + PContact contact = roster_get_contact(jid); + if (contact == NULL) { + cons_show("Contact not found in roster: %s", jid); + return TRUE; + } + + roster_remove_from_group(group, jid); + + return TRUE; + } + } + cons_show("Usage: %s", help.usage); return TRUE; } diff --git a/src/contact.c b/src/contact.c index 009478a0..bab3d89c 100644 --- a/src/contact.c +++ b/src/contact.c @@ -101,6 +101,20 @@ p_contact_set_groups(const PContact contact, GSList *groups) contact->groups = groups; } +gboolean +p_contact_in_group(const PContact contact, const char * const group) +{ + GSList *groups = contact->groups; + while (groups != NULL) { + if (strcmp(groups->data, group) == 0) { + return TRUE; + } + groups = g_slist_next(groups); + } + + return FALSE; +} + GSList * p_contact_groups(const PContact contact) { diff --git a/src/contact.h b/src/contact.h index 3aa8e6a3..cfd8b4d4 100644 --- a/src/contact.h +++ b/src/contact.h @@ -52,5 +52,6 @@ gboolean p_contact_has_available_resource(const PContact contact); Resource * p_contact_get_resource(const PContact contact, const char * const resource); void p_contact_set_groups(const PContact contact, GSList *groups); GSList * p_contact_groups(const PContact contact); +gboolean p_contact_in_group(const PContact contact, const char * const group); #endif diff --git a/src/ui/console.c b/src/ui/console.c index 95c7d9b0..992ac9b5 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1240,6 +1240,49 @@ cons_navigation_help(void) } void +cons_show_roster_group(const char * const group, GSList *list) +{ + GSList *curr = list; + cons_show(""); + + if (curr != NULL) { + cons_show("%s:", group); + } else { + cons_show("No group named %s exists.", group); + } + + while(curr) { + + PContact contact = curr->data; + GString *title = g_string_new(" "); + title = g_string_append(title, p_contact_barejid(contact)); + if (p_contact_name(contact) != NULL) { + title = g_string_append(title, " ("); + title = g_string_append(title, strdup(p_contact_name(contact))); + title = g_string_append(title, ")"); + } + cons_show(title->str); + g_string_free(title, TRUE); + + GString *sub = g_string_new(" Subscription : "); + sub = g_string_append(sub, p_contact_subscription(contact)); + if (p_contact_pending_out(contact)) { + sub = g_string_append(sub, ", request sent"); + } + if (presence_sub_request_exists(p_contact_barejid(contact))) { + sub = g_string_append(sub, ", request received"); + } + cons_show(sub->str); + g_string_free(sub, TRUE); + + curr = g_slist_next(curr); + } + + ui_console_dirty(); + cons_alert(); +} + +void cons_show_roster(GSList *list) { GSList *curr = list; @@ -1247,6 +1290,7 @@ cons_show_roster(GSList *list) cons_show("Roster:"); while(curr) { + PContact contact = curr->data; GString *title = g_string_new(" "); title = g_string_append(title, p_contact_barejid(contact)); @@ -1268,6 +1312,22 @@ cons_show_roster(GSList *list) } cons_show(sub->str); g_string_free(sub, TRUE); + + GSList *groups = p_contact_groups(contact); + if (groups != NULL) { + GString *groups_str = g_string_new(" Groups : "); + while (groups != NULL) { + g_string_append(groups_str, strdup(groups->data)); + if (g_slist_next(groups) != NULL) { + g_string_append(groups_str, ", "); + } + groups = g_slist_next(groups); + } + + cons_show(groups_str->str); + g_string_free(groups_str, TRUE); + } + curr = g_slist_next(curr); } diff --git a/src/ui/ui.h b/src/ui/ui.h index 6eb0d814..a41a8cff 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -168,6 +168,7 @@ void cons_show_error(const char * const cmd, ...); void cons_highlight_show(const char * const cmd); void cons_show_contacts(GSList * list); void cons_show_roster(GSList * list); +void cons_show_roster_group(const char * const group, GSList * list); void cons_show_wins(void); void cons_show_status(const char * const barejid); void cons_show_info(PContact pcontact); diff --git a/src/xmpp/roster.c b/src/xmpp/roster.c index 234bfad2..2126efd8 100644 --- a/src/xmpp/roster.c +++ b/src/xmpp/roster.c @@ -286,6 +286,63 @@ roster_change_name(const char * const barejid, const char * const new_name) } } +void +roster_add_to_group(const char * const group, const char * const barejid) +{ + PContact contact = g_hash_table_lookup(contacts, barejid); + + if (contact != NULL) { + if (p_contact_in_group(contact, group)) { + return; + } + + GSList *groups = p_contact_groups(contact); + GSList *new_groups = NULL; + while (groups != NULL) { + new_groups = g_slist_append(new_groups, strdup(groups->data)); + groups = g_slist_next(groups); + } + + new_groups = g_slist_append(new_groups, strdup(group)); + + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_create_roster_set(ctx, barejid, + p_contact_name(contact), new_groups); + xmpp_send(conn, iq); + xmpp_stanza_release(iq); + } +} + +void +roster_remove_from_group(const char * const group, const char * const barejid) +{ + PContact contact = g_hash_table_lookup(contacts, barejid); + + if (contact != NULL) { + if (!p_contact_in_group(contact, group)) { + return; + } + + GSList *groups = p_contact_groups(contact); + GSList *new_groups = NULL; + while (groups != NULL) { + if (strcmp(groups->data, group) != 0) { + new_groups = g_slist_append(new_groups, strdup(groups->data)); + } + groups = g_slist_next(groups); + } + + xmpp_conn_t * const conn = connection_get_conn(); + xmpp_ctx_t * const ctx = connection_get_ctx(); + xmpp_stanza_t *iq = stanza_create_roster_set(ctx, barejid, + p_contact_name(contact), new_groups); + xmpp_send(conn, iq); + xmpp_stanza_release(iq); + } + +} + gboolean roster_has_pending_subscriptions(void) { @@ -321,6 +378,30 @@ roster_get_contacts(void) return result; } +GSList * +roster_get_group(const char * const group) +{ + GSList *result = NULL; + GHashTableIter iter; + gpointer key; + gpointer value; + + g_hash_table_iter_init(&iter, contacts); + while (g_hash_table_iter_next(&iter, &key, &value)) { + GSList *groups = p_contact_groups(value); + while (groups != NULL) { + if (strcmp(groups->data, group) == 0) { + result = g_slist_insert_sorted(result, value, (GCompareFunc)_compare_contacts); + break; + } + groups = g_slist_next(groups); + } + } + + // resturn all contact structs + return result; +} + char * roster_find_contact(char *search_str) { diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 345fa8f1..7d077237 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -146,5 +146,9 @@ void roster_change_name(const char * const barejid, const char * const new_name) char * roster_barejid_from_name(const char * const name); void roster_add_new(const char * const barejid, const char * const name); void roster_remove(const char * const barejid); +GSList * roster_get_group(const char * const group); +void roster_add_to_group(const char * const group, const char * const barejid); +void roster_remove_from_group(const char * const group, + const char * const barejid); #endif |