about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2013-03-24 21:46:00 +0000
committerJames Booth <boothj5@gmail.com>2013-03-24 21:46:00 +0000
commitb6095ca9550941df5872a25979924053391cb6d1 (patch)
tree3affc8f9a0919598a28efe3f61b9147c3b740c23 /src
parent270dae472fe72ab65bc570616d62c38a0836dcda (diff)
downloadprofani-tty-b6095ca9550941df5872a25979924053391cb6d1.tar.gz
Show message in console when receiving chat room invites
Diffstat (limited to 'src')
-rw-r--r--src/profanity.c8
-rw-r--r--src/profanity.h3
-rw-r--r--src/ui/ui.h2
-rw-r--r--src/ui/windows.c14
-rw-r--r--src/xmpp/message.c88
-rw-r--r--src/xmpp/stanza.h4
-rw-r--r--src/xmpp/xmpp.h5
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
@@ -1398,6 +1398,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)
 {
     int size = g_strv_length(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
@@ -143,6 +146,85 @@ message_send_gone(const char * const recipient)
 }
 
 static int
+_conference_message_handler(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata)
+{
+/*
+ * <message to="prof2@panesar" from="test@conference.panesar">
+ *      <x xmlns="http://jabber.org/protocol/muc#user">
+ *          <invite from="prof4@panesar/2572c43f-aa3d-42fa-a74e-c322a80a90b8">
+ *              <reason>Join the room!</reason>
+ *          </invite>
+ *      </x>
+ *      <x jid="test@conference.panesar" xmlns="jabber:x:conference">
+ *          Join the room!
+ *      </x>
+ *      <body>
+ *          prof4@panesar/2572c43f-aa3d-42fa-a74e-c322a80a90b8 invited you to the room test@conference.panesar (Join the room!)
+ *      </body>
+ * </message>
+ *
+ */
+
+    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;