/dev/tomkiewicz/new-smileys: e4a656378516: Remote smileys: parti...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Fri Apr 4 08:04:55 EDT 2014
Changeset: e4a656378516673d849fa98e3a4bf4c445b8ca14
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-04 14:04 +0200
Branch: default
URL: https://hg.pidgin.im/dev/tomkiewicz/new-smileys/rev/e4a656378516
Description:
Remote smileys: partial implementation with XMPP
diffstat:
libpurple/conversation.c | 25 ++++++++-
libpurple/protocols/jabber/message.c | 96 +++++++++++++++++++++--------------
libpurple/smiley-list.c | 10 +++-
libpurple/smiley-remote.c | 80 +++++++++++++++++++++++++++--
libpurple/smiley-remote.h | 8 +++
5 files changed, 171 insertions(+), 48 deletions(-)
diffs (truncated from 377 to 300 lines):
diff --git a/libpurple/conversation.c b/libpurple/conversation.c
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -948,6 +948,7 @@ purple_conversation_add_remote_smiley(Pu
{
PurpleConversationPrivate *priv = PURPLE_CONVERSATION_GET_PRIVATE(conv);
PurpleSmiley *smiley;
+ PurpleRemoteSmiley *rsmiley;
g_return_val_if_fail(priv != NULL, NULL);
g_return_val_if_fail(shortcut != NULL, NULL);
@@ -958,13 +959,33 @@ purple_conversation_add_remote_smiley(Pu
smiley = purple_smiley_list_get_by_shortcut(
priv->remote_smileys, shortcut);
- if (!PURPLE_IS_REMOTE_SMILEY(smiley)) {
+ if (smiley && !PURPLE_IS_REMOTE_SMILEY(smiley)) {
purple_debug_warning("conversation", "Invalid type of smiley "
"stored in remote smileys list");
return NULL;
}
- return PURPLE_REMOTE_SMILEY(smiley);
+ /* smiley was already added */
+ if (smiley)
+ return NULL;
+
+ rsmiley = g_object_new(PURPLE_TYPE_REMOTE_SMILEY,
+ "shortcut", shortcut,
+ "is-ready", FALSE,
+ NULL);
+
+ if (!purple_smiley_list_add(priv->remote_smileys,
+ PURPLE_SMILEY(rsmiley)))
+ {
+ purple_debug_error("conversation", "failed adding remote "
+ "smiley to the list");
+ g_object_unref(rsmiley);
+ return NULL;
+ }
+
+ /* priv->remote_smileys holds the only one ref */
+ g_object_unref(rsmiley);
+ return rsmiley;
}
PurpleSmileyList *
diff --git a/libpurple/protocols/jabber/message.c b/libpurple/protocols/jabber/message.c
--- a/libpurple/protocols/jabber/message.c
+++ b/libpurple/protocols/jabber/message.c
@@ -482,23 +482,63 @@ jabber_message_add_remote_smileys(Jabber
}
}
-#if 0
static void
-jabber_message_request_data_cb(JabberData *data, gchar *alt,
- gpointer userdata)
+jabber_message_remote_smiley_got(JabberData *data, gchar *alt, gpointer _smiley)
{
- PurpleConversation *conv = PURPLE_CONVERSATION(userdata);
+ PurpleRemoteSmiley *smiley = _smiley;
+
+ g_free(alt); /* we really don't need it */
if (data) {
- purple_conversation_custom_smiley_write(conv, alt,
- jabber_data_get_data(data),
- jabber_data_get_size(data));
- purple_conversation_custom_smiley_close(conv, alt);
+ purple_debug_info("jabber",
+ "smiley data retrieved successfully");
+ purple_remote_smiley_write(smiley, jabber_data_get_data(data),
+ jabber_data_get_size(data));
+ purple_remote_smiley_close(smiley);
+ } else {
+ purple_debug_error("jabber", "failed retrieving smiley data");
+ purple_remote_smiley_failed(smiley);
}
- g_free(alt);
+ g_object_unref(smiley);
}
-#endif
+
+static void
+jabber_message_remote_smiley_add(JabberStream *js, PurpleConversation *conv,
+ const gchar *from, const gchar *shortcut, const gchar *cid)
+{
+ PurpleRemoteSmiley *smiley;
+ const JabberData *jdata;
+
+ purple_debug_misc("jabber", "about to add remote smiley %s to the conv",
+ shortcut);
+
+ smiley = purple_conversation_add_remote_smiley(conv, shortcut);
+ if (!smiley) {
+ purple_debug_misc("jabber", "smiley was already present");
+ return;
+ }
+
+ /* TODO: cache lookup by "cid" */
+
+ jdata = jabber_data_find_remote_by_cid(js, from, cid);
+ if (jdata) {
+ purple_debug_info("jabber", "smiley data is already known");
+
+ purple_remote_smiley_write(smiley, jabber_data_get_data(jdata),
+ jabber_data_get_size(jdata));
+ purple_remote_smiley_close(smiley);
+ } else {
+ gchar *alt = g_strdup(shortcut); /* it it really necessary? */
+
+ purple_debug_info("jabber", "smiley data is unknown, "
+ "need to request it");
+
+ g_object_ref(smiley);
+ jabber_data_request(js, cid, from, alt, FALSE,
+ jabber_message_remote_smiley_got, smiley);
+ }
+}
void jabber_message_parse(JabberStream *js, PurpleXmlNode *packet)
{
@@ -602,7 +642,7 @@ void jabber_message_parse(JabberStream *
const PurpleConnection *gc = js->gc;
PurpleAccount *account = purple_connection_get_account(gc);
PurpleConversation *conv = NULL;
- GList *smiley_refs = NULL;
+ GList *smiley_refs = NULL, *it;
gchar *reformatted_xhtml;
if (purple_account_get_bool(account, "custom_smileys", TRUE)) {
@@ -654,39 +694,19 @@ void jabber_message_parse(JabberStream *
/* note: if there were no smileys in the incoming message, or
if receiving custom smileys is turned off, smiley_refs will
be NULL */
- for (; conv && smiley_refs ; smiley_refs = g_list_delete_link(smiley_refs, smiley_refs)) {
- JabberSmileyRef *ref = (JabberSmileyRef *) smiley_refs->data;
- const gchar *cid = ref->cid;
- gchar *alt = g_strdup(ref->alt);
+ for (it = smiley_refs; it; it = g_list_next(it)) {
+ JabberSmileyRef *ref = it->data;
- purple_debug_info("jabber",
- "about to add custom smiley %s to the conv\n", alt);
-#if 0
- if (purple_conversation_custom_smiley_add(conv, alt, "cid", cid,
- TRUE)) {
- const JabberData *data =
- jabber_data_find_remote_by_cid(js, from, cid);
- /* if data is already known, we write it immediatly */
- if (data) {
- purple_debug_info("jabber",
- "data is already known\n");
- purple_conversation_custom_smiley_write(conv, alt,
- jabber_data_get_data(data),
- jabber_data_get_size(data));
- purple_conversation_custom_smiley_close(conv, alt);
- } else {
- /* we need to request the smiley (data) */
- purple_debug_info("jabber",
- "data is unknown, need to request it\n");
- jabber_data_request(js, cid, from, alt, FALSE,
- jabber_message_request_data_cb, conv);
- }
+ if (conv) {
+ jabber_message_remote_smiley_add(js,
+ conv, from, ref->alt, ref->cid);
}
-#endif
+
g_free(ref->cid);
g_free(ref->alt);
g_free(ref);
}
+ g_list_free(smiley_refs);
/* Convert all newlines to whitespace. Technically, even regular, non-XML HTML is supposed to ignore newlines, but Pidgin has, as convention
* treated \n as a newline for compatibility with other protocols
diff --git a/libpurple/smiley-list.c b/libpurple/smiley-list.c
--- a/libpurple/smiley-list.c
+++ b/libpurple/smiley-list.c
@@ -128,6 +128,11 @@ purple_smiley_list_add(PurpleSmileyList
priv->smileys_end);
smiley_path = purple_smiley_get_path(smiley);
+
+ /* TODO: add to the table, when smiley sets the path */
+ if (!smiley_path)
+ return TRUE;
+
if (g_hash_table_lookup(priv->path_map, smiley_path) == NULL) {
g_hash_table_insert(priv->path_map,
g_strdup(smiley_path), smiley);
@@ -160,7 +165,8 @@ purple_smiley_list_remove(PurpleSmileyLi
path = purple_smiley_get_path(smiley);
g_hash_table_remove(priv->shortcut_map, shortcut);
- g_hash_table_remove(priv->path_map, path);
+ if (path)
+ g_hash_table_remove(priv->path_map, path);
if (purple_smiley_parse_escape())
shortcut = tmp = g_markup_escape_text(shortcut, -1);
@@ -171,7 +177,7 @@ purple_smiley_list_remove(PurpleSmileyLi
_list_remove_link2(&priv->smileys, &priv->smileys_end, list_elem);
/* re-add entry to path_map if smiley was not unique */
- for (it = priv->smileys; it; it = g_list_next(it)) {
+ for (it = priv->smileys; it && path; it = g_list_next(it)) {
PurpleSmiley *smiley = it->data;
if (g_strcmp0(purple_smiley_get_path(smiley), path) == 0) {
diff --git a/libpurple/smiley-remote.c b/libpurple/smiley-remote.c
--- a/libpurple/smiley-remote.c
+++ b/libpurple/smiley-remote.c
@@ -22,6 +22,7 @@
#include "internal.h"
#include "glibcompat.h"
+#include "debug.h"
#include "smiley.h"
#include "smiley-remote.h"
@@ -29,6 +30,9 @@
(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_REMOTE_SMILEY, PurpleRemoteSmileyPrivate))
typedef struct {
+ GString *contents;
+
+ gboolean failed;
} PurpleRemoteSmileyPrivate;
#if 0
@@ -56,24 +60,87 @@ static GParamSpec *properties[PROP_LAST]
* API implementation
******************************************************************************/
+void
+purple_remote_smiley_write(PurpleRemoteSmiley *smiley, const guchar *data,
+ gsize size)
+{
+ PurpleRemoteSmileyPrivate *priv =
+ PURPLE_REMOTE_SMILEY_GET_PRIVATE(smiley);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(!priv->failed);
+ g_return_if_fail(!purple_smiley_is_ready(PURPLE_SMILEY(smiley)));
+ g_return_if_fail(data != NULL || size == 0);
+
+ if (size == 0)
+ return;
+
+ g_string_append_len(priv->contents, (const gchar*)data, size);
+}
+
+void
+purple_remote_smiley_close(PurpleRemoteSmiley *smiley)
+{
+ PurpleRemoteSmileyPrivate *priv =
+ PURPLE_REMOTE_SMILEY_GET_PRIVATE(smiley);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(!priv->failed);
+ g_return_if_fail(!purple_smiley_is_ready(PURPLE_SMILEY(smiley)));
+
+ if (priv->contents->len == 0) {
+ purple_debug_error("smiley-remote", "Smiley is empty");
+ purple_remote_smiley_failed(smiley);
+ return;
+ }
+
+ g_object_set(smiley, "is-ready", TRUE, NULL);
+ /* TODO: call ready signal */
+}
+
+void
+purple_remote_smiley_failed(PurpleRemoteSmiley *smiley)
+{
+ PurpleRemoteSmileyPrivate *priv =
+ PURPLE_REMOTE_SMILEY_GET_PRIVATE(smiley);
+
+ g_return_if_fail(priv != NULL);
+ g_return_if_fail(!purple_smiley_is_ready(PURPLE_SMILEY(smiley)));
+
+ if (priv->failed)
+ return;
+
+ g_object_set(smiley, "failed", TRUE, NULL);
+ /* TODO: call failed signal */
+}
+
/******************************************************************************
* Object stuff
******************************************************************************/
-#if 0
static void
purple_remote_smiley_init(GTypeInstance *instance, gpointer klass)
More information about the Commits
mailing list