diff options
| author | Robert Pösel <robyer@seznam.cz> | 2013-07-26 17:28:35 +0000 | 
|---|---|---|
| committer | Robert Pösel <robyer@seznam.cz> | 2013-07-26 17:28:35 +0000 | 
| commit | 9754f5e5ca8fda43bacbe3c42909dd57cc36eaa1 (patch) | |
| tree | ee8a4bad617eceabb8a7aa7791cb60931dc35bc1 /protocols/FacebookRM/src | |
| parent | 12718514fb673dbb72f7d93ea3bb34c9574bd69a (diff) | |
Facebook: Improved receiving messages with attachments (files, photos, stickers)
git-svn-id: http://svn.miranda-ng.org/main/trunk@5491 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/FacebookRM/src')
| -rw-r--r-- | protocols/FacebookRM/src/json.cpp | 134 | ||||
| -rw-r--r-- | protocols/FacebookRM/src/utils.cpp | 1 | 
2 files changed, 86 insertions, 49 deletions
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp index 283eb19fa5..bb5e3ada78 100644 --- a/protocols/FacebookRM/src/json.cpp +++ b/protocols/FacebookRM/src/json.cpp @@ -269,81 +269,71 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa  		std::string t = json_as_string(type);
  		if (t == "msg" || t == "offline_msg") {
 -			// direct message
 +			// we use this only for outgoing messages
 -			JSONNODE *from = json_get(it, "from");
 -			if (from == NULL)
 -				continue;
 -
 -			char *from_id = json_as_string(from);
 -
  			JSONNODE *msg = json_get(it, "msg");
  			if (msg == NULL)
  				continue;
 +			JSONNODE *from = json_get(it, "from");
 +			JSONNODE *from_name = json_get(it, "from_name");
  			JSONNODE *text = json_get(msg, "text");
  			JSONNODE *messageId = json_get(msg, "messageId");
  			JSONNODE *time = json_get(msg, "time");
  			// JSONNODE *tab_type = json_get(it, "tab_type"); // e.g. "friend"
 -			if (text == NULL || messageId == NULL)
 +			if (from == NULL || from_name == NULL || text == NULL || messageId == NULL || time == NULL)
  				continue;
 -			std::string message_id = json_as_string(messageId);
 -			std::string message_text = json_as_string(text);
 +			char *from_id = json_as_string(from);
 -			// ignore duplicits or messages sent from miranda
 -			if (ignore_duplicits(proto, message_id, message_text))
 +			// ignore incomming messages
 +			if (from_id != proto->facy.self_.user_id)
  				continue;
 +			std::string message_id = json_as_string(messageId);
 +			std::string message_text = json_as_string(text);
 +
  			message_text = utils::text::trim(utils::text::special_expressions_decode(utils::text::slashu_to_utf8(message_text)), true);
  			if (message_text.empty())
 -				continue;			
 +				continue;
  			JSONNODE *truncated = json_get(msg, "truncated");
  			if (truncated != NULL && json_as_int(truncated) == 1) {
 -				// If we got truncated message, we can ignore it, because we should get it again as "messaging" type
 -				std::string msg = "????? We got truncated message so we ignore it\n";
 +				std::string msg = "????? We got truncated message\n";
  				msg += utils::text::special_expressions_decode(utils::text::slashu_to_utf8(message_text));
  				proto->Log(msg.c_str());
 -			} else if (from_id == proto->facy.self_.user_id) {
 -				// Outgoing message
 -				JSONNODE *to = json_get(it, "to");
 -				if (to == NULL)
 -					continue;
 +			}
 -				// TODO: put also outgoing messages into messages array and process it elsewhere
 -				HANDLE hContact = proto->ContactIDToHContact(json_as_string(to));
 -				if (!hContact) // TODO: add this contact?
 -					continue;
 +			// ignore duplicits or messages sent from miranda
 +			if (ignore_duplicits(proto, message_id, message_text))
 +				continue;
 -				DBEVENTINFO dbei = {0};
 -				dbei.cbSize = sizeof(dbei);
 -				dbei.eventType = EVENTTYPE_MESSAGE;
 -				dbei.flags = DBEF_SENT | DBEF_UTF;
 -				dbei.szModule = proto->m_szModuleName;
 +			// Outgoing message
 +			JSONNODE *to = json_get(it, "to");
 +			if (to == NULL)
 +				continue;
 -				bool local_time = proto->getByte(FACEBOOK_KEY_LOCAL_TIMESTAMP, 0) != 0;
 -				dbei.timestamp = local_time || time == NULL ? ::time(NULL) : utils::time::fix_timestamp(json_as_float(time));
 +			// TODO: put also outgoing messages into messages array and process it elsewhere
 +			HANDLE hContact = proto->ContactIDToHContact(json_as_string(to));
 +			if (!hContact) // TODO: add this contact?
 +				continue;
 -				dbei.cbBlob = (DWORD)message_text.length() + 1;
 -				dbei.pBlob = (PBYTE)message_text.c_str();
 -				db_event_add(hContact, &dbei);
 +			DBEVENTINFO dbei = {0};
 +			dbei.cbSize = sizeof(dbei);
 +			dbei.eventType = EVENTTYPE_MESSAGE;
 +			dbei.flags = DBEF_SENT | DBEF_UTF;
 +			dbei.szModule = proto->m_szModuleName;
 -				continue;
 -			} else {
 -				// Incomming message
 -  				facebook_message* message = new facebook_message();
 -				message->message_text = message_text;
 -				message->time = utils::time::fix_timestamp(json_as_float(time));
 -				message->user_id = from_id;
 -				message->message_id = message_id;
 +			bool local_time = proto->getByte(FACEBOOK_KEY_LOCAL_TIMESTAMP, 0) != 0;
 +			dbei.timestamp = local_time ? ::time(NULL) : utils::time::fix_timestamp(json_as_float(time));
 -				messages->push_back(message);
 -			}
 +			dbei.cbBlob = (DWORD)message_text.length() + 1;
 +			dbei.pBlob = (PBYTE)message_text.c_str();
 +			db_event_add(hContact, &dbei);
  		} else if (t == "messaging") {
 -			// messages
 +			// we use this only for incomming messages (and getting seen info)
  			JSONNODE *type = json_get(it, "event");
  			if (type == NULL)
 @@ -380,14 +370,60 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa  				JSONNODE *mid = json_get(msg, "mid");
  				JSONNODE *timestamp = json_get(msg, "timestamp");
 -				if (sender_fbid == NULL || body == NULL || mid == NULL)
 +				if (sender_fbid == NULL || sender_name == NULL || body == NULL || mid == NULL || timestamp == NULL)
  					continue;
  				std::string id = json_as_string(sender_fbid);
  				std::string message_id = json_as_string(mid);
  				std::string message_text = json_as_string(body);
 -				// Ignore messages from myself
 +				// Process attachements and stickers
 +				JSONNODE *has_attachment = json_get(msg, "has_attachment");
 +				if (has_attachment != NULL && json_as_bool(has_attachment)) {
 +					JSONNODE *admin_snippet = json_get(msg, "admin_snippet");
 +					if (admin_snippet != NULL) {
 +						// TODO: have this as extra event, not replace or append message content
 +						if (!message_text.empty())
 +							message_text += "\n\n";
 +						message_text += json_as_string(admin_snippet);
 +
 +						// Append attachements
 +						JSONNODE *attachments = json_get(msg, "attachments");
 +						for (unsigned int j = 0; j < json_size(attachments); j++) {
 +							JSONNODE *itAttachment = json_at(attachments, j);
 +
 +							// TODO: behave different for stickers and classic attachements?
 +							// JSONNODE *attach_type = json_get(itAttachment, "attach_type"); // "sticker", "photo", "file"
 +
 +							JSONNODE *name = json_get(itAttachment, "name");
 +							JSONNODE *url = json_get(itAttachment, "url");
 +							if (url != NULL) {
 +								std::string link = json_as_string(url);
 +							
 +								if (link.find("/ajax/mercury/attachments/photo/view/") != std::string::npos)
 +									// fix photo url
 +									link = utils::url::decode(utils::text::source_get_value(&link, 2, "?uri=", "&"));
 +								else if (link.find("/") == 0) {
 +									// make absolute url
 +									bool useHttps = proto->getByte(FACEBOOK_KEY_FORCE_HTTPS, 1) > 0;
 +									link = (useHttps ? HTTP_PROTO_SECURE : HTTP_PROTO_REGULAR) + std::string(FACEBOOK_SERVER_REGULAR) + link;
 +								}
 +								
 +								if (!link.empty()) {
 +									std::string filename;
 +									if (name != NULL)
 +										filename = json_as_string(name);
 +									if (filename == "null")
 +										filename.clear();
 +
 +									message_text += "\n" + (!filename.empty() ? "<" + filename + "> " : "") + link + "\n";
 +								}
 +							}
 +						}
 +					}
 +				}
 +
 +				// Ignore messages from myself, as there is no id of recipient
  				if (id == proto->facy.self_.user_id)
  					continue;
 @@ -401,7 +437,7 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa  				facebook_message* message = new facebook_message();
  				message->message_text = message_text;
 -				message->sender_name = utils::text::special_expressions_decode(utils::text::slashu_to_utf8(id));
 +				message->sender_name = utils::text::special_expressions_decode(utils::text::slashu_to_utf8(json_as_string(sender_name)));
  				message->time = utils::time::fix_timestamp(json_as_float(timestamp));
  				message->user_id = id; // TODO: Check if we have contact with this ID in friendlist and otherwise do something different?
  				message->message_id = message_id;
 @@ -476,7 +512,7 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa  				if (time_ == NULL)
  					continue;
  				JSONNODE *time = json_get(time_, "time");
 -				if (time == NULL || text == NULL || url == NULL || alert_id == NULL)
 +				if (time == NULL || text == NULL || url == NULL || alert_id == NULL || time == NULL)
  					continue;
  				unsigned __int64 timestamp = json_as_float(time);
 diff --git a/protocols/FacebookRM/src/utils.cpp b/protocols/FacebookRM/src/utils.cpp index f0cae3be7e..0a03ec29eb 100644 --- a/protocols/FacebookRM/src/utils.cpp +++ b/protocols/FacebookRM/src/utils.cpp @@ -34,6 +34,7 @@ std::string utils::url::decode(std::string data)  	utils::text::replace_all(&data, "%3F", "?");
  	utils::text::replace_all(&data, "%3D", "=");
  	utils::text::replace_all(&data, "%26", "&");
 +	utils::text::replace_all(&data, "%3A", ":");
  	return data;
  }
  | 
