]> www.infradead.org Git - pidgin-chime.git/commitdiff
Add attachment upload support for chats
authorDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 20 May 2020 14:09:30 +0000 (15:09 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 20 May 2020 14:09:30 +0000 (15:09 +0100)
Based on PR#36 by Guilherme Melo but teaching Pidgin that chats can
have files instead of manually adding a separate 'Send File' menu item:
https://bitbucket.org/pidgin/main/pull-requests/701

configure.ac
prpl/attachments.c
prpl/chat.c
prpl/chime.c
prpl/chime.h

index e6b848baaa4af3054232f57348e3df3e55abc583..c183fa848152db31ea3b06810bd4a67927d1abc6 100644 (file)
@@ -102,6 +102,7 @@ fi
 
 LIBS="$LIBS $PURPLE_LIBS"
 AC_CHECK_FUNC(purple_request_screenshare_media, [AC_DEFINE(HAVE_SCREENSHARE, 1, [Have purple_request_screenshare_media()])], [])
+AC_CHECK_FUNC(serv_chat_send_file, [AC_DEFINE(HAVE_CHAT_SEND_FILE, 1, [Have serv_chat_send_file()])], [])
 LIBS="$oldLIBS"
 
 gstplugindir="$($PKG_CONFIG --variable=pluginsdir gstreamer-1.0)"
index 0621cbc8d0cb0cd9af8deb2dfef30c589b1046dc..39aa0743311a718dca6f01d1765a93aed02d1e10 100644 (file)
@@ -249,6 +249,8 @@ static void deep_free_upload_data(PurpleXfer *xfer)
                purple_xfer_cancel_local(xfer);
        }
 
+       g_clear_object(&data->obj);
+
        g_free(data->content);
        g_free(data->content_type);
        g_free(data->upload_id);
@@ -549,7 +551,8 @@ static void chime_send_init(PurpleXfer *xfer)
        purple_debug_info("chime", "Starting to handle upload of file '%s'\n", xfer->local_filename);
 
        struct purple_chime *pc = purple_connection_get_protocol_data(xfer->account->gc);
-       struct chime_im *im = g_hash_table_lookup(pc->ims_by_email, xfer->who);
+       ChimeObject *obj = CHIME_OBJECT (xfer->data);
+       xfer->data = NULL;
 
        g_return_if_fail(CHIME_IS_CONNECTION(pc->cxn));
        ChimeConnectionPrivate *priv = CHIME_CONNECTION_GET_PRIVATE(pc->cxn);
@@ -562,11 +565,12 @@ static void chime_send_init(PurpleXfer *xfer)
                purple_debug_error("chime", _("Could not read file '%s' (errno=%d, errstr=%s)\n"),
                                   xfer->local_filename, error->code, error->message);
                g_clear_error(&error);
+               g_object_unref(obj);
                return;
        }
        AttachmentUpload *data = g_new0(AttachmentUpload, 1);
        data->conn = pc->cxn;
-       data->obj = im->m.obj;
+       data->obj = obj;
        data->content = file_contents;
        data->content_length = length;
        get_mime_type(xfer->local_filename, &data->content_type);
@@ -599,8 +603,21 @@ static void chime_send_cancel(PurpleXfer *xfer)
 
 void chime_send_file(PurpleConnection *gc, const char *who, const char *filename)
 {
+       struct purple_chime *pc = purple_connection_get_protocol_data(gc);
+       struct chime_im *im = g_hash_table_lookup(pc->ims_by_email, who);
+
        purple_debug_info("chime", "chime_send_file(who=%s, file=%s\n", who, filename);
 
+       if (!im)
+               return;
+
+       chime_send_file_object(gc, im->m.obj, who, filename);
+}
+
+void chime_send_file_object(PurpleConnection *gc, ChimeObject *obj, const char *who, const char *filename)
+{
+       purple_debug_info("chime", "chime_send_file_object(who=%s, file=%s\n", who, filename);
+
        PurpleXfer *xfer;
        xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who);
        if (xfer) {
@@ -609,6 +626,9 @@ void chime_send_file(PurpleConnection *gc, const char *who, const char *filename
                purple_xfer_set_cancel_send_fnc(xfer, chime_send_cancel);
        }
 
+       /* This is only in xfer->data until chime_send_init() runs. */
+       xfer->data = g_object_ref(obj);
+
        if (filename) {
                purple_xfer_request_accepted(xfer, filename);
        } else {
index 250ed87033b132780236b92e514750e90e8bdf88..944633a387468e11c48ca35255b95431e996e2d2 100644 (file)
@@ -1250,6 +1250,14 @@ static void leave_room(PurpleBuddy *buddy, gpointer _chat)
        chime_connection_remove_room_member_async(cxn, room, me, NULL, leave_room_cb, chat);
 }
 
+void chime_purple_chat_send_file(PurpleConnection *conn, int id, const char *filename)
+{
+       struct purple_chime *pc = purple_connection_get_protocol_data(conn);
+       struct chime_chat *chat = g_hash_table_lookup(pc->live_chats, GUINT_TO_POINTER(id));
+
+       chime_send_file_object(conn, chat->m.obj, purple_conversation_get_name(chat->conv), filename);
+}
+
 GList *chime_purple_chat_menu(PurpleChat *pchat)
 {
 
index 5ecfc8a5fbd1853121136f83537c481eeb1e5f64..b164a8d962357b4af2ef6dd5eacbed656205eaca 100644 (file)
@@ -394,11 +394,12 @@ static PurplePluginProtocolInfo chime_prpl_info = {
        .send_file = chime_send_file,
        .get_media_caps = chime_purple_get_media_caps,
        .initiate_media = chime_purple_initiate_media,
-       .add_buddies_with_invite = NULL, /* We *really* depend on 2.8.0, and this is
-                                         * immediately before .get_cb_alias() */
 #ifdef PRPL_HAS_GET_CB_ALIAS
        .get_cb_alias = chime_purple_get_cb_alias,
 #endif
+#ifdef HAVE_CHAT_SEND_FILE
+       .chat_send_file = chime_purple_chat_send_file,
+#endif
 };
 
 static void chime_purple_show_about_plugin(PurplePluginAction *action)
@@ -518,15 +519,21 @@ static void chime_purple_init_plugin(PurplePlugin *plugin)
 
        chime_prpl_info.protocol_options = opts;
 
-#ifndef PRPL_HAS_GET_CB_ALIAS
-       PurplePluginProtocolInfo *i = g_malloc0(sizeof (*i) + sizeof(void *));
+#ifndef HAVE_CHAT_SEND_FILE
+       /* If built against a Pidgin that doesn't yet support chat_send_file(),
+        * or indeed get_cb_alias(), copy the struct and extend it manually. */
+       PurplePluginProtocolInfo *i = g_malloc0(sizeof (*i) + 3 * sizeof(void *));
        memcpy(i, &chime_prpl_info, sizeof(*i));
        chime_plugin_info.extra_info = i;
 
-       /* Now add the .get_cb_alias method */
-       i->struct_size += sizeof(void *);
-       i++;
-       *(void **)i = chime_purple_get_cb_alias;
+       /* ->add_buddies_with_invite() was 2.8.0; We know we have that */
+       void **p = (void **)&i->add_buddies_with_invite;
+       p++;
+       *p++ = chime_purple_get_cb_alias;
+       *p++ = NULL; /* chat_can_receive_file() but they all can */
+       *p++ = chime_purple_chat_send_file;
+
+       i->struct_size += (unsigned long)p - (unsigned long)i;
 #endif
 }
 
index e86e8ed63f1546c49efe72fd36433204f4b9dcb4..8b5ebb4d1141433627b7122c778e7a8dce73512c 100644 (file)
@@ -108,6 +108,7 @@ struct chime_chat *do_join_chat(PurpleConnection *conn, ChimeConnection *cxn, Ch
 void chime_purple_chat_join_audio(struct chime_chat *chat);
 GList *chime_purple_chat_menu(PurpleChat *chat);
 char *chime_purple_get_cb_alias(PurpleConnection *conn, int id, const gchar *who);
+void chime_purple_chat_send_file(PurpleConnection *gc, int id, const char *filename);
 
 /* conversations.c */
 void on_chime_new_conversation(ChimeConnection *cxn, ChimeConversation *conv, PurpleConnection *conn);
@@ -173,5 +174,6 @@ ChimeAttachment *extract_attachment(JsonNode *record);
 
 void download_attachment(ChimeConnection *cxn, ChimeAttachment *att, AttachmentContext *ctx);
 void chime_send_file(PurpleConnection *gc, const char *who, const char *filename);
+void chime_send_file_object(PurpleConnection *gc, ChimeObject *obj, const char *who, const char *filename);
 
 #endif /* __CHIME_H__ */