From bd33df2d4b9534d2241283f2b20d83f5b1811ebc Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 29 Jan 2015 21:36:42 +0000 Subject: media files detection git-svn-id: http://svn.miranda-ng.org/main/trunk@11954 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp | 11 +- protocols/WhatsApp/src/WhatsAPI++/FMessage.h | 3 + protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp | 114 +++++++++++---------- protocols/WhatsApp/src/messages.cpp | 48 +++++---- 4 files changed, 98 insertions(+), 78 deletions(-) (limited to 'protocols') diff --git a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp index e3c3367b04..d5b5189b44 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp @@ -18,9 +18,8 @@ FMessage::FMessage() : this->latitude = 0; this->media_duration_seconds = 0; this->media_size = 0; - this->media_name = ""; - this->media_url = ""; - this->data = ""; + this->bindata = 0; + this->bindata_len = 0; } FMessage::FMessage(const std::string &remote_jid, bool from_me, const std::string &id) : @@ -32,8 +31,8 @@ FMessage::FMessage(const std::string &remote_jid, bool from_me, const std::strin this->latitude = 0; this->media_duration_seconds = 0; this->media_size = 0; - this->media_name = ""; - this->media_url = ""; + this->bindata = 0; + this->bindata_len = 0; } std::string FMessage::getMessage_WA_Type_StrValue(unsigned char type) @@ -60,6 +59,8 @@ std::string FMessage::getMessage_WA_Type_StrValue(unsigned char type) FMessage::~FMessage() { + if (this->bindata != NULL) + free(this->bindata); } Key::Key(const std::string& remote_jid, bool from_me, const std::string& id) diff --git a/protocols/WhatsApp/src/WhatsAPI++/FMessage.h b/protocols/WhatsApp/src/WhatsAPI++/FMessage.h index e53b7d88dd..7a7432c7f7 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/FMessage.h +++ b/protocols/WhatsApp/src/WhatsAPI++/FMessage.h @@ -39,6 +39,9 @@ struct FMessage bool offline; std::string media_url; std::string media_name; + unsigned char *bindata; + size_t bindata_len; + long long media_size; int media_duration_seconds; double latitude; diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp index b5f52bb1e2..113d2c6bf3 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp @@ -341,69 +341,73 @@ void WAConnection::parseMessage(ProtocolTreeNode *messageNode) throw (WAExceptio sendSubjectReceived(from, id); } else if (typeAttribute == "text") { - FMessage fmessage; + ProtocolTreeNode *body = messageNode->getChild("body"); + if (from.empty() || body == NULL || body->data == NULL || body->data->empty()) + return; + + FMessage fmessage(from, false, id); fmessage.wants_receipt = false; fmessage.timestamp = atoi(attribute_t.c_str()); - bool duplicate = false; - - std::vector messageChildren(messageNode->getAllChildren()); - for (size_t i = 0; i < messageChildren.size(); i++) { - ProtocolTreeNode *childNode = messageChildren[i]; - if (ProtocolTreeNode::tagEquals(childNode, "body")) { - fmessage.key = Key(from, false, id); - fmessage.notifyname = notify; - fmessage.data = childNode->getDataAsString(); - fmessage.status = FMessage::STATUS_UNSENT; - } - else if (ProtocolTreeNode::tagEquals(childNode, "media") && !id.empty()) { - fmessage.media_wa_type = FMessage::getMessage_WA_Type(childNode->getAttributeValue("type")); - fmessage.media_url = childNode->getAttributeValue("url"); - fmessage.media_name = childNode->getAttributeValue("file"); - fmessage.media_size = Utilities::parseLongLong(childNode->getAttributeValue("size")); - fmessage.media_duration_seconds = atoi(childNode->getAttributeValue("seconds").c_str()); - - if (fmessage.media_wa_type == FMessage::WA_TYPE_LOCATION) { - const string &latitudeString = childNode->getAttributeValue("latitude"); - const string &longitudeString = childNode->getAttributeValue("longitude"); - if (latitudeString.empty() || longitudeString.empty()) - throw WAException("location message missing lat or long attribute", WAException::CORRUPT_STREAM_EX, 0); - - double latitude = atof(latitudeString.c_str()); - double longitude = atof(longitudeString.c_str()); - fmessage.latitude = latitude; - fmessage.longitude = longitude; - } + fmessage.notifyname = notify; + fmessage.data = body->getDataAsString(); + fmessage.status = FMessage::STATUS_UNSENT; + if (fmessage.timestamp == 0) { + fmessage.timestamp = time(NULL); + fmessage.offline = false; + } + if (m_pEventHandler != NULL) + m_pEventHandler->onMessageForMe(&fmessage, false); + } + else if (typeAttribute == "media") { + if (from.empty() || id.empty()) + return; - if (fmessage.media_wa_type == FMessage::WA_TYPE_CONTACT) { - ProtocolTreeNode *contactChildNode = childNode->getChild(0); - if (contactChildNode != NULL) { - fmessage.media_name = contactChildNode->getAttributeValue("name"); - fmessage.data = contactChildNode->getDataAsString(); - } - } - else { - const string &encoding = childNode->getAttributeValue("encoding"); - if (encoding.empty() || encoding == "text") - fmessage.data = childNode->getDataAsString(); - else { - logData("Media data encoding type '%s'", encoding.empty() ? "text" : encoding.c_str()); - fmessage.data = (childNode->data == NULL ? "" : std::string(base64_encode(childNode->data->data(), childNode->data->size()))); - } - } + ProtocolTreeNode *media = messageNode->getChild("media"); + if (from.empty() || media == NULL || media->data == NULL || media->data->empty()) + return; - fmessage.key = Key(from, false, id); - fmessage.notifyname = notify; - fmessage.remote_resource = author; - } + FMessage fmessage(from, false, id); + fmessage.wants_receipt = false; + fmessage.timestamp = atoi(attribute_t.c_str()); + fmessage.notifyname = notify; + fmessage.remote_resource = author; + fmessage.media_wa_type = FMessage::getMessage_WA_Type(media->getAttributeValue("type")); + fmessage.media_url = media->getAttributeValue("url"); + fmessage.media_name = media->getAttributeValue("file"); + fmessage.media_size = Utilities::parseLongLong(media->getAttributeValue("size")); + fmessage.media_duration_seconds = atoi(media->getAttributeValue("seconds").c_str()); + + if (fmessage.media_wa_type == FMessage::WA_TYPE_LOCATION) { + const string &latitudeString = media->getAttributeValue("latitude"); + const string &longitudeString = media->getAttributeValue("longitude"); + if (latitudeString.empty() || longitudeString.empty()) + throw WAException("location message missing lat or long attribute", WAException::CORRUPT_STREAM_EX, 0); + + double latitude = atof(latitudeString.c_str()); + double longitude = atof(longitudeString.c_str()); + fmessage.latitude = latitude; + fmessage.longitude = longitude; } - if (fmessage.timestamp == 0) { - fmessage.timestamp = time(NULL); - fmessage.offline = false; + if (fmessage.media_wa_type == FMessage::WA_TYPE_CONTACT) { + ProtocolTreeNode *contactChildNode = media->getChild(0); + if (contactChildNode != NULL) { + fmessage.media_name = contactChildNode->getAttributeValue("name"); + fmessage.data = contactChildNode->getDataAsString(); + } + } + else { + const string &encoding = media->getAttributeValue("encoding"); + if (encoding.empty() || encoding == "text") + fmessage.data = media->getDataAsString(); + else { + fmessage.bindata = (unsigned char*)malloc(fmessage.bindata_len = media->data->size()); + memcpy(fmessage.bindata, media->data->data(), fmessage.bindata_len); + } } - if (!fmessage.key.remote_jid.empty() && m_pEventHandler != NULL) - m_pEventHandler->onMessageForMe(&fmessage, duplicate); + if (m_pEventHandler != NULL) + m_pEventHandler->onMessageForMe(&fmessage, false); } else if (typeAttribute == "notification") { logData("Notification node %s", messageNode->toString().c_str()); diff --git a/protocols/WhatsApp/src/messages.cpp b/protocols/WhatsApp/src/messages.cpp index e139af9512..36c4bcc1da 100644 --- a/protocols/WhatsApp/src/messages.cpp +++ b/protocols/WhatsApp/src/messages.cpp @@ -7,34 +7,46 @@ int WhatsAppProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) return Proto_RecvMessage(hContact, pre); } -void WhatsAppProto::onMessageForMe(FMessage* paramFMessage, bool paramBoolean) +void WhatsAppProto::onMessageForMe(FMessage *pMsg, bool paramBoolean) { - bool isChatRoom = !paramFMessage->remote_resource.empty(); - - std::string* msg; - switch (paramFMessage->media_wa_type) { - case FMessage::WA_TYPE_IMAGE: - case FMessage::WA_TYPE_AUDIO: - case FMessage::WA_TYPE_VIDEO: - msg = ¶mFMessage->media_url; - break; - default: - msg = ¶mFMessage->data; + bool isChatRoom = !pMsg->remote_resource.empty(); + + std::string msg; + if (!pMsg->media_url.empty()) { + msg = pMsg->media_url; + if (pMsg->bindata_len) { + TCHAR tszFilePath[MAX_PATH], tszFileName[MAX_PATH]; + GetTempPath(_countof(tszFilePath), tszFilePath); + mir_sntprintf(tszFileName, _countof(tszFileName), _T("%s\\%s.jpg"), tszFilePath, _A2T(pMsg->media_name.c_str())); + FILE *out = _tfopen(tszFileName, _T("wb")); + if (out != NULL) { + fwrite(pMsg->bindata, 1, pMsg->bindata_len, out); + fclose(out); + + std::string szFileName((const char*)_T2A(tszFileName)); + std::replace(szFileName.begin(), szFileName.end(), '\\', '/'); + std::replace(szFileName.begin(), szFileName.end(), ' ', '+'); + + msg.append("\nfile://"); + msg += szFileName; + } + } } + else msg = pMsg->data; if (isChatRoom) - msg->insert(0, std::string("[").append(paramFMessage->notifyname).append("]: ")); + msg.insert(0, std::string("[").append(pMsg->notifyname).append("]: ")); - MCONTACT hContact = this->AddToContactList(paramFMessage->key.remote_jid, 0, false, - isChatRoom ? NULL : paramFMessage->notifyname.c_str(), isChatRoom); + MCONTACT hContact = this->AddToContactList(pMsg->key.remote_jid, 0, false, + isChatRoom ? NULL : pMsg->notifyname.c_str(), isChatRoom); PROTORECVEVENT recv = { 0 }; recv.flags = PREF_UTF; - recv.szMessage = const_cast(msg->c_str()); - recv.timestamp = paramFMessage->timestamp; + recv.szMessage = const_cast(msg.c_str()); + recv.timestamp = pMsg->timestamp; ProtoChainRecvMsg(hContact, &recv); - m_pConnection->sendMessageReceived(paramFMessage); + m_pConnection->sendMessageReceived(pMsg); } int WhatsAppProto::SendMsg(MCONTACT hContact, int flags, const char *msg) -- cgit v1.2.3