Ejemplo n.º 1
0
void fetion_got__chat()
{
	conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who, 
			session->account);

	if (!conv) {
		conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who);
	}

	if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) {
		fetion_request_custom_smiley(slplink, smile, fetion_got_custom_smiley, NULL, obj);
	}

}
Ejemplo n.º 2
0
void flist_fetch_emoticon(FListAccount *fla, const gchar *smiley, const gchar *character, PurpleConversation *convo) {
    FListFetchIcon *fli;
    int len;
    
    if(!purple_conv_custom_smiley_add(convo, smiley, "none", "0", TRUE)) {
        return; /* for some reason or another we can't add it */
    }
    
    fli = g_new0(FListFetchIcon, 1);
    fli->character = g_strdup(character);
    fli->fla = fla;
    fli->convo = g_strdup(purple_conversation_get_name(convo));
    fli->smiley = g_strdup(smiley);
    
    len = g_slist_length(fla->icon_requests);
    if(len < FLIST_MAX_ICON_REQUESTS) {
        flist_fetch_icon_real(fla, fli);
    } else {
        fla->icon_request_queue = g_slist_append(fla->icon_request_queue, fli);
    }
}
Ejemplo n.º 3
0
void PurpleLine::write_message(line::Message &msg, bool replay) {
    std::string text;
    int flags = 0;
    time_t mtime = (time_t)(msg.createdTime / 1000);

    bool sent = (msg.from == profile.mid);

    if (std::find(recent_messages.cbegin(), recent_messages.cend(), msg.id)
        != recent_messages.cend())
    {
        // We already processed this message. User is probably talking with himself.
        return;
    }

    // Hack
    if (msg.from == msg.to)
        push_recent_message(msg.id);

    PurpleConversation *conv = purple_find_conversation_with_account(
        (msg.toType == line::MIDType::USER ? PURPLE_CONV_TYPE_IM : PURPLE_CONV_TYPE_CHAT),
        ((!sent && msg.toType == line::MIDType::USER) ? msg.from.c_str() : msg.to.c_str()),
        acct);

    // If this is a new received IM, create the conversation if it doesn't exist
    if (!conv && !sent && msg.toType == line::MIDType::USER)
        conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, acct, msg.from.c_str());

    // If this is a new conversation, we're not replaying history and history hasn't been fetched
    // yet, queue the message instead of showing it.
    if (conv && !replay) {
        auto *queue = (std::vector<line::Message> *)
            purple_conversation_get_data(conv, "line-message-queue");

        if (queue) {
            queue->push_back(msg);
            return;
        }
    }

    // Replaying messages from history
    // Unfortunately Pidgin displays messages with this flag with odd formatting and no username.
    // Disable for now.
    //if (replay)
    //    flags |= PURPLE_MESSAGE_NO_LOG;

    switch (msg.contentType) {
        case line::ContentType::NONE: // actually text
        case line::ContentType::LOCATION:
            if (msg.__isset.location) {
                line::Location &loc = msg.location;

                text = markup_escape(loc.title)
                    + " | <a href=\"https://maps.google.com/?q=" + url_encode(loc.address)
                    + "&ll=" + std::to_string(loc.latitude)
                    + "," + std::to_string(loc.longitude)
                    + "\">"
                    + (loc.address.size()
                        ? markup_escape(loc.address)
                        : "(no address)")
                    + "</a>";
            } else {
                text = markup_escape(msg.text);
            }
            break;

        case line::ContentType::STICKER:
            {
                std::string id = get_sticker_id(msg);

                if (id == "")  {
                    text = "<em>[Broken sticker]</em>";

                    purple_debug_warning("line", "Got a broken sticker.\n");
                } else {
                    text = id;

                    if (conv
                        && purple_conv_custom_smiley_add(conv, id.c_str(), "id", id.c_str(), TRUE))
                    {
                        http.request(get_sticker_url(msg),
                            [this, id, conv](int status, const guchar *data, gsize len)
                            {
                                if (status == 200 && data && len > 0) {
                                    purple_conv_custom_smiley_write(
                                        conv,
                                        id.c_str(),
                                        data,
                                        len);
                                } else {
                                    purple_debug_warning(
                                        "line",
                                        "Couldn't download sticker. Status: %d\n",
                                        status);
                                }

                                purple_conv_custom_smiley_close(conv, id.c_str());
                            });
                    }
                }
            }
            break;

        case line::ContentType::IMAGE:
        case line::ContentType::VIDEO: // Videos could really benefit from streaming...
            {
                std::string type_std = line::_ContentType_VALUES_TO_NAMES.at(msg.contentType);

                std::string id = "[LINE " + type_std + " " + msg.id + "]";

                text = id;

                if (conv) {
                    text += " <font color=\"#888888\">/open "
                        + conv_attachment_add(conv, msg.contentType, msg.id)
                        + "</font>";
                }

                if (!conv
                    || !purple_conv_custom_smiley_add(conv, id.c_str(), "id", id.c_str(), TRUE))
                {
                    break;
                }

                if (msg.contentPreview.size() > 0) {
                    purple_conv_custom_smiley_write(
                        conv,
                        id.c_str(),
                        (const guchar *)msg.contentPreview.c_str(),
                        msg.contentPreview.size());

                    purple_conv_custom_smiley_close(conv, id.c_str());
                } else {
                    std::string preview_url = msg.contentMetadata.count("PREVIEW_URL")
                        ? msg.contentMetadata["PREVIEW_URL"]
                        : std::string(LINE_OS_URL) + "os/m/" + msg.id + "/preview";

                    http.request(preview_url, HTTPFlag::AUTH | HTTPFlag::LARGE,
                        [this, id, conv](int status, const guchar *data, gsize len)
                        {
                            if (status == 200 && data && len > 0) {
                                purple_conv_custom_smiley_write(
                                    conv,
                                    id.c_str(),
                                    data,
                                    len);
                            } else {
                                purple_debug_warning(
                                    "line",
                                    "Couldn't download image message. Status: %d\n",
                                    status);
                            }

                            purple_conv_custom_smiley_close(conv, id.c_str());
                        });
                }
            }
            break;

        case line::ContentType::AUDIO:
            {
                text = "[Audio message";

                if (msg.contentMetadata.count("AUDLEN")) {
                    int len = 0;

                    try {
                        len = std::stoi(msg.contentMetadata["AUDLEN"]);
                    } catch(...) { /* ignore */ }

                    if (len > 0) {
                        text += " "
                            + std::to_string(len / 1000)
                            + "."
                            + std::to_string((len % 1000) / 100)
                            + "s";
                    }
                }

                text += "]";

                if (conv) {
                    text += " <font color=\"#888888\">/open "
                        + conv_attachment_add(conv, msg.contentType, msg.id)
                        + "</font>";
                }
            }
            break;

        // TODO: other content types

        default:
            text = "<em>[Not implemented: ";
            text += line::_ContentType_VALUES_TO_NAMES.at(msg.contentType);
            text += " message]</em>";
            break;
    }

    if (sent) {
        // Messages sent by user (sync from other devices)

        write_message(conv, msg.from, text, mtime, flags | PURPLE_MESSAGE_SEND);
    } else {
        // Messages received from other users

        flags |= PURPLE_MESSAGE_RECV;

        if (replay) {
            // Write replayed messages instead of serv_got_* to avoid Pidgin's IM sound

            write_message(conv, msg.from, text, mtime, flags);
        } else {
            if (msg.toType == line::MIDType::USER) {
                serv_got_im(
                    conn,
                    msg.from.c_str(),
                    text.c_str(),
                    (PurpleMessageFlags)flags,
                    mtime);
            } else if (msg.toType == line::MIDType::GROUP || msg.toType == line::MIDType::ROOM) {
                serv_got_chat_in(
                    conn,
                    purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
                    msg.from.c_str(),
                    (PurpleMessageFlags)flags,
                    text.c_str(),
                    mtime);
            }
        }
    }
}
Ejemplo n.º 4
0
void msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
    MsnSession *session;
    MsnSlpLink *slplink;
    MsnSwitchBoard *swboard;
    MsnObject *obj;
    char **tokens;
    char *smile, *body_str;
    const char *body, *who, *sha1;
    guint tok;
    size_t body_len;

    PurpleConversation *conv;

    session = cmdproc->servconn->session;

    if (!purple_account_get_bool(session->account, "custom_smileys", TRUE))
        return;

    swboard = cmdproc->data;
    conv = swboard->conv;

    body = msn_message_get_bin_data(msg, &body_len);
    if (!body || !body_len)
        return;
    body_str = g_strndup(body, body_len);

    /* MSN Messenger 7 may send more than one MSNObject in a single message...
     * Maybe 10 tokens is a reasonable max value. */
    tokens = g_strsplit(body_str, "\t", 10);

    g_free(body_str);

    for (tok = 0; tok < 9; tok += 2) {
        if (tokens[tok] == NULL || tokens[tok + 1] == NULL) {
            break;
        }

        smile = tokens[tok];
        obj = msn_object_new_from_string(purple_url_decode(tokens[tok + 1]));

        if (obj == NULL)
            break;

        who = msn_object_get_creator(obj);
        sha1 = msn_object_get_sha1(obj);

        slplink = msn_session_get_slplink(session, who);
        if (slplink->swboard != swboard) {
            if (slplink->swboard != NULL)
                /*
                 * Apparently we're using a different switchboard now or
                 * something?  I don't know if this is normal, but it
                 * definitely happens.  So make sure the old switchboard
                 * doesn't still have a reference to us.
                 */
                slplink->swboard->slplinks = g_list_remove(slplink->swboard->slplinks, slplink);
            slplink->swboard = swboard;
            slplink->swboard->slplinks = g_list_prepend(slplink->swboard->slplinks, slplink);
        }

        /* If the conversation doesn't exist then this is a custom smiley
         * used in the first message in a MSN conversation: we need to create
         * the conversation now, otherwise the custom smiley won't be shown.
         * This happens because every GtkIMHtml has its own smiley tree: if
         * the conversation doesn't exist then we cannot associate the new
         * smiley with its GtkIMHtml widget. */
        if (!conv) {
            conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who);
        }

        if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) {
            msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj);
        }

        msn_object_destroy(obj);
        obj =   NULL;
        who =   NULL;
        sha1 = NULL;
    }
    g_strfreev(tokens);
}
Ejemplo n.º 5
0
void
msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg)
{
	MsnSession *session;
	MsnSlpLink *slplink;
	MsnObject *obj;
	char **tokens;
	char *smile, *body_str;
	const char *body, *who, *sha1;
	guint tok;
	size_t body_len;

	PurpleConversation *conv;

	session = cmdproc->session;

	if (!purple_account_get_bool_without_default_value(session->account, "custom_smileys"))
		return;

	body = msn_message_get_bin_data(msg, &body_len);
	body_str = g_strndup(body, body_len);

	/* MSN Messenger 7 may send more than one MSNObject in a single message...
	 * Maybe 10 tokens is a reasonable max value. */
	tokens = g_strsplit(body_str, "\t", 10);

	g_free(body_str);

	for (tok = 0; tok < 9; tok += 2) {
		if (tokens[tok] == NULL || tokens[tok + 1] == NULL) {
			break;
		}

		smile = tokens[tok];
		{
			gchar *tmp;
			tmp = pecan_url_decode (tokens[tok + 1]);
			obj = msn_object_new_from_string(tmp);
			g_free(tmp);
		}

		if (obj == NULL)
			break;

		who = msn_object_get_creator(obj);
		sha1 = msn_object_get_sha1(obj);

		slplink = msn_session_get_slplink(session, who);

		conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, who,
													 session->account);

		/* If the conversation doesn't exist then this is a custom smiley
		 * used in the first message in a MSN conversation: we need to create
		 * the conversation now, otherwise the custom smiley won't be shown.
		 * This happens because every GtkIMHtml has its own smiley tree: if
		 * the conversation doesn't exist then we cannot associate the new
		 * smiley with its GtkIMHtml widget. */
		if (!conv) {
			//conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, session->account, who);
		}

		if (purple_conv_custom_smiley_add(conv, smile, "sha1", sha1, TRUE)) {
			msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj);
		}

		msn_object_destroy(obj);
		obj =   NULL;
		who =   NULL;
		sha1 = NULL;
	}
	g_strfreev(tokens);
}