From b6095ca9550941df5872a25979924053391cb6d1 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 24 Mar 2013 21:46:00 +0000 Subject: [PATCH] Show message in console when receiving chat room invites --- src/profanity.c | 8 +++++ src/profanity.h | 3 ++ src/ui/ui.h | 2 ++ src/ui/windows.c | 14 ++++++++ src/xmpp/message.c | 88 ++++++++++++++++++++++++++++++++++++++++++++-- src/xmpp/stanza.h | 4 +++ src/xmpp/xmpp.h | 5 +++ 7 files changed, 121 insertions(+), 3 deletions(-) diff --git a/src/profanity.c b/src/profanity.c index db354e29..2d37b817 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -316,6 +316,14 @@ prof_handle_leave_room(const char * const room) muc_leave_room(room); } +void prof_handle_room_invite(jabber_invite_t invite_type, + const char * const invitor, const char * const room, + const char * const reason) +{ + cons_show_room_invite(invitor, room, reason); + win_current_page_off(); +} + void prof_handle_contact_online(char *contact, Resource *resource, GDateTime *last_activity) diff --git a/src/profanity.h b/src/profanity.h index f55426b8..2afe2a00 100644 --- a/src/profanity.h +++ b/src/profanity.h @@ -66,6 +66,9 @@ void prof_handle_room_nick_change(const char * const room, const char * const nick); void prof_handle_room_broadcast(const char *const room_jid, const char * const message); +void prof_handle_room_invite(jabber_invite_t invite_type, + const char * const invitor, const char * const room, + const char * const reason); void prof_handle_idle(void); void prof_handle_activity(void); void prof_handle_version_result(const char * const jid, diff --git a/src/ui/ui.h b/src/ui/ui.h index 73aa5855..226dadbd 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -176,6 +176,8 @@ void cons_show_account_list(gchar **accounts); void cons_show_room_list(GSList *room, const char * const conference_node); void cons_show_disco_items(GSList *items, const char * const jid); void cons_show_disco_info(const char *from, GSList *identities, GSList *features); +void cons_show_room_invite(const char * const invitor, const char * const room, + const char * const reason); // status bar actions void status_bar_refresh(void); diff --git a/src/ui/windows.c b/src/ui/windows.c index 06645f5d..2905610e 100644 --- a/src/ui/windows.c +++ b/src/ui/windows.c @@ -1397,6 +1397,20 @@ cons_show_status(const char * const contact) } } +void +cons_show_room_invite(const char * const invitor, const char * const room, + const char * const reason) +{ + cons_show(""); + _win_show_time(console->win, '-'); + wprintw(console->win, "%s has invited you to join %s", invitor, room); + if (reason != NULL) { + wprintw(console->win, ", \"%s\"", reason); + } + wprintw(console->win, "\n"); + cons_show("Type \"/join %s\" to join the room", room); +} + void cons_show_account_list(gchar **accounts) { diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 57615a54..ace42a31 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -41,6 +41,8 @@ static int _groupchat_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); static int _chat_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata); +static int _conference_message_handler(xmpp_conn_t * const conn, + xmpp_stanza_t * const stanza, void * const userdata); void message_add_handlers(void) @@ -48,9 +50,10 @@ message_add_handlers(void) xmpp_conn_t * const conn = connection_get_conn(); xmpp_ctx_t * const ctx = connection_get_ctx(); - HANDLE(NULL, STANZA_TYPE_ERROR, connection_error_handler); - HANDLE(NULL, STANZA_TYPE_GROUPCHAT, _groupchat_message_handler); - HANDLE(NULL, STANZA_TYPE_CHAT, _chat_message_handler); + HANDLE(NULL, STANZA_TYPE_ERROR, connection_error_handler); + HANDLE(NULL, STANZA_TYPE_GROUPCHAT, _groupchat_message_handler); + HANDLE(NULL, STANZA_TYPE_CHAT, _chat_message_handler); + HANDLE(NULL, NULL, _conference_message_handler); } void @@ -142,6 +145,85 @@ message_send_gone(const char * const recipient) chat_session_set_sent(recipient); } +static int +_conference_message_handler(xmpp_conn_t * const conn, + xmpp_stanza_t * const stanza, void * const userdata) +{ +/* + * + * + * + * Join the room! + * + * + * + * Join the room! + * + * + * prof4@panesar/2572c43f-aa3d-42fa-a74e-c322a80a90b8 invited you to the room test@conference.panesar (Join the room!) + * + * + * + */ + + xmpp_stanza_t *x_muc = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + xmpp_stanza_t *x_groupchat = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_CONFERENCE); + char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); + char *room = NULL; + char *invitor = NULL; + char *reason = NULL; + + if (from == NULL) { + log_warning("Message received with no from attribute, ignoring"); + return 1; + } + + // XEP-0045 + if (x_muc != NULL) { + room = from; + + xmpp_stanza_t *invite = xmpp_stanza_get_child_by_name(x_muc, STANZA_NAME_INVITE); + if (invite == NULL) { + return 1; + } + + char *invitor_jid = xmpp_stanza_get_attribute(invite, STANZA_ATTR_FROM); + if (invitor_jid == NULL) { + log_warning("Chat room invite received with no from attribute"); + return 1; + } + + Jid *jidp = jid_create(invitor_jid); + invitor = jidp->barejid; + + xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(invite, STANZA_NAME_REASON); + if (reason_st != NULL) { + reason = xmpp_stanza_get_text(reason_st); + } + + prof_handle_room_invite(INVITE_MEDIATED, invitor, room, reason); + jid_destroy(jidp); + + // XEP-0429 + } else if (x_groupchat != NULL) { + room = xmpp_stanza_get_attribute(x_groupchat, STANZA_ATTR_JID); + if (room == NULL) { + return 1; + } + + Jid *jidp = jid_create(from); + invitor = jidp->barejid; + + reason = xmpp_stanza_get_attribute(x_groupchat, STANZA_ATTR_REASON); + + prof_handle_room_invite(INVITE_DIRECT, invitor, room, reason); + + jid_destroy(jidp); + } + + return 1; +} + static int _groupchat_message_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index cee1de88..f86b213d 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -49,6 +49,8 @@ #define STANZA_NAME_C "c" #define STANZA_NAME_IDENTITY "identity" #define STANZA_NAME_FEATURE "feature" +#define STANZA_NAME_INVITE "invite" +#define STANZA_NAME_REASON "reason" #define STANZA_TYPE_CHAT "chat" #define STANZA_TYPE_GROUPCHAT "groupchat" @@ -79,6 +81,7 @@ #define STANZA_ATTR_VAR "var" #define STANZA_ATTR_HASH "hash" #define STANZA_ATTR_CATEGORY "category" +#define STANZA_ATTR_REASON "reason" #define STANZA_TEXT_AWAY "away" #define STANZA_TEXT_DND "dnd" @@ -94,6 +97,7 @@ #define STANZA_NS_LASTACTIVITY "jabber:iq:last" #define STANZA_NS_DATA "jabber:x:data" #define STANZA_NS_VERSION "jabber:iq:version" +#define STANZA_NS_CONFERENCE "jabber:x:conference" #define STANZA_DATAFORM_SOFTWARE "urn:xmpp:dataforms:softwareinfo" diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 4a1e0b15..f7a4f0b3 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -46,6 +46,11 @@ typedef enum { PRESENCE_UNSUBSCRIBED } jabber_subscr_t; +typedef enum { + INVITE_DIRECT, + INVITE_MEDIATED +} jabber_invite_t; + typedef struct capabilities_t { char *category; char *type;