void SpectrumConversation::handleMessage(AbstractUser *user, const char *who, const char *msg, PurpleMessageFlags flags, time_t mtime, const std::string ¤tBody) { std::string name(who); // Remove resource if it's XMPP JID size_t pos = name.find("/"); if (pos != std::string::npos) name.erase((int) pos, name.length() - (int) pos); AbstractSpectrumBuddy *s_buddy = NULL; #ifndef TESTS User *u = (User *) user; s_buddy = u->getRosterItem(name); #endif if (s_buddy && s_buddy->getFlags() & SPECTRUM_BUDDY_JID_ESCAPING) name = JID::escapeNode(name); else if (s_buddy) std::for_each( name.begin(), name.end(), replaceBadJidCharacters() ); // OK else if (m_room.empty()) name = JID::escapeNode(name); // Escape HTML characters. char *newline = purple_strdup_withhtml(msg); char *strip, *xhtml, *xhtml_linkified; purple_markup_html_to_xhtml(newline, &xhtml, &strip); xhtml_linkified = purple_markup_linkify(xhtml); std::string message(strip); std::string m(xhtml_linkified); g_free(newline); g_free(xhtml); g_free(xhtml_linkified); g_free(strip); std::string to; if (getResource().empty()) to = user->jid(); else to = user->jid() + "/" + getResource(); if (flags & PURPLE_MESSAGE_ERROR) { Message s(Message::Error, to, currentBody); if (!m_room.empty()) s.setFrom(m_room + "/" + name); else { std::transform(name.begin(), name.end(), name.begin(),(int(*)(int)) std::tolower); s.setFrom(name + std::string(getType() == SPECTRUM_CONV_CHAT ? "" : ("%" + JID(user->username()).server())) + "@" + Transport::instance()->jid() + "/bot"); } Error *c = new Error(StanzaErrorTypeModify, StanzaErrorNotAcceptable); c->setText(tr(user->getLang(), message)); s.addExtension(c); Transport::instance()->send(s.tag()); return; } Message s(Message::Chat, to, message); if (!m_room.empty()) s.setFrom(m_room + "/" + name); else { std::transform(name.begin(), name.end(), name.begin(),(int(*)(int)) std::tolower); s.setFrom(name + std::string(getType() == SPECTRUM_CONV_CHAT ? "" : ("%" + JID(user->username()).server())) + "@" + Transport::instance()->jid() + "/bot"); } // chatstates if (purple_value_get_boolean(user->getSetting("enable_chatstate"))) { if (user->hasFeature(GLOOX_FEATURE_CHATSTATES, getResource())) { ChatState *c = new ChatState(ChatStateActive); s.addExtension(c); } } // Delayed messages, we have to count with some delay if (mtime && (unsigned long) time(NULL)-10 > (unsigned long) mtime/* && (unsigned long) time(NULL) - 31536000 < (unsigned long) mtime*/) { char buf[80]; strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", gmtime(&mtime)); std::string timestamp(buf); DelayedDelivery *d = new DelayedDelivery(name + "@" + Transport::instance()->jid() + "/bot", timestamp); s.addExtension(d); } Tag *stanzaTag = s.tag(); std::string res = getResource(); if (user->hasFeature(GLOOX_FEATURE_XHTML_IM, res) && m != message) { if (m.find("<body") != 0) { m = "<body>" + m + "</body>"; } Transport::instance()->parser()->getTag(m, sendXhtmlTag, stanzaTag); return; } Transport::instance()->send(stanzaTag); }
Data IMInvoker::purpleValueToData(PURPLE_VALUE* value) { Data data; #if LIBPURPLE_VERSION_MAJOR >= 3 if (false) { } else if (g_type_check_value_holds(value, G_TYPE_CHAR)) { data = Data(g_value_get_schar(value), Data::VERBATIM); } else if (g_type_check_value_holds(value, G_TYPE_UCHAR)) { data = Data(g_value_get_uchar(value), Data::VERBATIM); } else if (g_type_check_value_holds(value, G_TYPE_BOOLEAN)) { data = Data(g_value_get_boolean(value)); } else if (g_type_check_value_holds(value, G_TYPE_INT)) { data = Data(g_value_get_int(value)); } else if (g_type_check_value_holds(value, G_TYPE_UINT)) { data = Data(g_value_get_uint(value)); } else if (g_type_check_value_holds(value, G_TYPE_LONG)) { data = Data(g_value_get_long(value)); } else if (g_type_check_value_holds(value, G_TYPE_ULONG)) { data = Data(g_value_get_ulong(value)); } else if (g_type_check_value_holds(value, G_TYPE_INT64)) { data = Data(g_value_get_int64(value)); } else if (g_type_check_value_holds(value, G_TYPE_FLOAT)) { data = Data(g_value_get_float(value)); } else if (g_type_check_value_holds(value, G_TYPE_DOUBLE)) { data = Data(g_value_get_double(value)); } else if (g_type_check_value_holds(value, G_TYPE_STRING)) { const gchar* tmp = g_value_get_string(value); if (tmp == NULL) { data = Data("", Data::VERBATIM); } else { data = Data(g_value_get_string(value), Data::VERBATIM); } } else if (g_type_check_value_holds(value, G_TYPE_OBJECT) || g_type_check_value_holds(value, G_TYPE_PARAM) || g_type_check_value_holds(value, G_TYPE_POINTER) || g_type_check_value_holds(value, G_TYPE_FLAGS) || g_type_check_value_holds(value, G_TYPE_ENUM)) { LOG(ERROR) << "purple thingy not supported"; } else { LOG(ERROR) << "purple thingy unknown"; } #else switch (purple_value_get_type(value)) { case PURPLE_TYPE_BOOLEAN: if (purple_value_get_boolean(value)) data = Data("true"); data = Data("false"); break; case PURPLE_TYPE_STRING: if (purple_value_get_string(value)) { data = Data(purple_value_get_string(value), Data::VERBATIM); } break; case PURPLE_TYPE_CHAR: Data(purple_value_get_char(value)); break; case PURPLE_TYPE_UCHAR: Data(purple_value_get_uchar(value)); break; case PURPLE_TYPE_SHORT: Data(purple_value_get_short(value)); break; case PURPLE_TYPE_USHORT: Data(purple_value_get_ushort(value)); break; case PURPLE_TYPE_INT: Data(purple_value_get_int(value)); break; case PURPLE_TYPE_UINT: Data(purple_value_get_uint(value)); break; case PURPLE_TYPE_LONG: Data(purple_value_get_long(value)); break; case PURPLE_TYPE_ULONG: Data(purple_value_get_ulong(value)); break; case PURPLE_TYPE_INT64: Data(purple_value_get_int64(value)); break; case PURPLE_TYPE_UINT64: Data(purple_value_get_uint64(value)); break; case PURPLE_TYPE_OBJECT: case PURPLE_TYPE_POINTER: case PURPLE_TYPE_ENUM: case PURPLE_TYPE_BOXED: case PURPLE_TYPE_UNKNOWN: case PURPLE_TYPE_SUBTYPE: LOG(ERROR) << "purple thingy not supported"; break; } #endif return data; }