summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2015-01-29 21:36:42 +0000
committerGeorge Hazan <george.hazan@gmail.com>2015-01-29 21:36:42 +0000
commitbd33df2d4b9534d2241283f2b20d83f5b1811ebc (patch)
tree3feb09d69f76d9a8af368a62b554de9b868e4647
parent7442e2473e41113ca0fbb40c7816267b3e5cbd16 (diff)
media files detection
git-svn-id: http://svn.miranda-ng.org/main/trunk@11954 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp11
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/FMessage.h3
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp114
-rw-r--r--protocols/WhatsApp/src/messages.cpp48
4 files changed, 98 insertions, 78 deletions
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<ProtocolTreeNode*> 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 = &paramFMessage->media_url;
- break;
- default:
- msg = &paramFMessage->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<char*>(msg->c_str());
- recv.timestamp = paramFMessage->timestamp;
+ recv.szMessage = const_cast<char*>(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)