summaryrefslogtreecommitdiff
path: root/protocols/FacebookRM
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2016-04-17 19:02:56 +0000
committerRobert Pösel <robyer@seznam.cz>2016-04-17 19:02:56 +0000
commit4e7d6200d3674f9afdcb996f3c4deb2812e36807 (patch)
tree70b05c873f8bbdc38f490f1ee763d949136d90e3 /protocols/FacebookRM
parent9355a504ac39e7a7c2f207e289ea7f3628de459b (diff)
Facebook: Fix and rework getting message's attachments
git-svn-id: http://svn.miranda-ng.org/main/trunk@16706 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/FacebookRM')
-rw-r--r--protocols/FacebookRM/src/constants.h3
-rw-r--r--protocols/FacebookRM/src/json.cpp188
-rw-r--r--protocols/FacebookRM/src/process.cpp2
3 files changed, 23 insertions, 170 deletions
diff --git a/protocols/FacebookRM/src/constants.h b/protocols/FacebookRM/src/constants.h
index 8ab4171eda..62d70c59ab 100644
--- a/protocols/FacebookRM/src/constants.h
+++ b/protocols/FacebookRM/src/constants.h
@@ -67,6 +67,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define FACEBOOK_IGNORE_COUNTER_LIMIT 30 // how many consequent requests it should keep info about duplicit message ids
#define FACEBOOK_PING_TIME 600 // every 10 minutes send activity_ping (it is just random/guessed value)
+#define MAX_NEWSFEED_LEN 500
+#define MAX_LINK_DESCRIPTION_LEN 200
+
// Defaults
#define FACEBOOK_MINIMAL_POLL_RATE 10
#define FACEBOOK_DEFAULT_POLL_RATE 24 // in seconds
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp
index 24709c4aab..29a7a42912 100644
--- a/protocols/FacebookRM/src/json.cpp
+++ b/protocols/FacebookRM/src/json.cpp
@@ -283,147 +283,17 @@ std::string absolutizeUrl(std::string &url) {
return url;
}
-void parseAttachments(FacebookProto *proto, std::string *message_text, const JSONNode &it, const std::string &thread_id, std::string other_user_fbid)
-{
- // Process attachements and stickers
- const JSONNode &has_attachment = it["has_attachment"];
- if (!has_attachment || !has_attachment.as_bool())
- return;
-
- // Append attachements
- std::string type;
- std::string attachments_text;
- const JSONNode &attachments = it["attachments"];
- for (auto itAttachment = attachments.begin(); itAttachment != attachments.end(); ++itAttachment) {
- const JSONNode &attach_type = (*itAttachment)["attach_type"]; // "sticker", "photo", "file", "share"
- if (attach_type) {
- // Get attachment type - "file" has priority over other types
- if (type.empty() || type != "file")
- type = attach_type.as_string();
- }
-
- if (type == "photo") {
- std::string filename = (*itAttachment)["name"].as_string();
- std::string link = (*itAttachment)["hires_url"].as_string();
-
- const JSONNode &metadata = (*itAttachment)["metadata"];
- if (metadata) {
- std::string id = metadata["fbid"].as_string();
- const JSONNode &data = it["attachment_map"][id.c_str()];
- filename = data["filename"].as_string();
- link = data["image_data"]["url"].as_string();
- }
-
- if (!link.empty()) {
- attachments_text += "\n" + (!filename.empty() ? "<" + filename + "> " : "") + absolutizeUrl(link) + "\n";
- }
- }
- else if (type == "file") {
- std::string filename = (*itAttachment)["name"].as_string();
- std::string link = (*itAttachment)["url"].as_string();
-
- if (!link.empty()) {
- attachments_text += "\n" + (!filename.empty() ? "<" + filename + "> " : "") + absolutizeUrl(link) + "\n";
- }
- }
- else if (type == "share") {
- const JSONNode &share = (*itAttachment)["share"];
- if (share) {
- std::string title = share["title"].as_string();
- std::string description = share["description"].as_string();
- std::string link = share["uri"].as_string();
-
- if (link.find("l." FACEBOOK_SERVER_DOMAIN) != std::string::npos) {
- // de-facebook this link
- link = utils::url::decode(utils::text::source_get_value2(&link, "l.php?u=", "&", true));
- }
-
- if (!link.empty()) {
- attachments_text += "\n";
- if (!title.empty())
- attachments_text += title + "\n";
- if (!description.empty())
- attachments_text += description + "\n";
- attachments_text += absolutizeUrl(link) + "\n";
- }
- }
- }
- else if (type == "sticker") {
- std::string link = (*itAttachment)["url"].as_string();
- if (!link.empty()) {
- attachments_text += "\n" + absolutizeUrl(link) + "\n";
- }
-
- const JSONNode &metadata = (*itAttachment)["metadata"];
- if (metadata) {
- const JSONNode &stickerId_ = metadata["stickerID"];
- if (stickerId_) {
- std::string sticker = "[[sticker:" + stickerId_.as_string() + "]]\n";
- attachments_text += sticker;
-
- if (other_user_fbid.empty() && !thread_id.empty())
- other_user_fbid = proto->ThreadIDToContactID(thread_id);
-
- // Stickers as smileys
- if (proto->getByte(FACEBOOK_KEY_CUSTOM_SMILEYS, DEFAULT_CUSTOM_SMILEYS)) {
- // FIXME: rewrite smileyadd to use custom smileys per protocol and not per contact and then remove this ugliness
- if (!other_user_fbid.empty()) {
- MCONTACT hContact = proto->ContactIDToHContact(other_user_fbid);
- proto->StickerAsSmiley(sticker, link, hContact);
- }
- }
- }
- }
- }
- }
-
- // TODO: have this as extra event, not replace or append message content
- if (!message_text->empty())
- *message_text += "\n\n";
-
- if (!attachments_text.empty()) {
- // we can't use this as offline messages doesn't have it
- /* const JSONNode &admin_snippet = it["admin_snippet");
- if (admin_snippet != NULL) {
- *message_text += admin_snippet);
- } */
-
- std::tstring newText;
- if (type == "sticker")
- newText = TranslateT("a sticker");
- else if (type == "share")
- newText = TranslateT("a link");
- else if (type == "file")
- newText = (attachments.size() > 1) ? TranslateT("files") : TranslateT("a file");
- else if (type == "photo")
- newText = (attachments.size() > 1) ? TranslateT("photos") : TranslateT("a photo");
- else
- newText = _A2T(type.c_str());
-
- TCHAR title[200];
- mir_sntprintf(title, TranslateT("User sent %s:"), newText.c_str());
-
- *message_text += T2Utf(title);
- *message_text += attachments_text;
- }
- else {
- *message_text += T2Utf(TranslateT("User sent an unsupported attachment. Open your browser to see it."));
- }
-}
-
-void parseAttachments2(FacebookProto *proto, std::string *message_text, const JSONNode &it, std::string other_user_fbid)
+void parseAttachments(FacebookProto *proto, std::string *message_text, const JSONNode &delta_, std::string other_user_fbid, bool legacy)
{
std::string attachments_text;
std::string type;
- const JSONNode &attach_ = it["attachments"]["mercury"];
-
- if (!attach_)
+ const JSONNode &attachments_ = delta_["attachments"];
+ if (!attachments_)
return;
-
- /* const JSONNode &attachments = it["attachments"];
- for (auto itAttachment = attachments.begin(); itAttachment != attachments.end(); ++itAttachment) {
- const JSONNode &attach_ = (*itAttachment)["mercury"];*/
+
+ for (auto itAttachment = attachments_.begin(); itAttachment != attachments_.end(); ++itAttachment) {
+ const JSONNode &attach_ = legacy ? (*itAttachment) : (*itAttachment)["mercury"];
type = attach_["attach_type"].as_string(); // "sticker", "photo", "file", "share"
@@ -431,14 +301,6 @@ void parseAttachments2(FacebookProto *proto, std::string *message_text, const JS
std::string filename = attach_["name"].as_string();
std::string link = attach_["hires_url"].as_string();
- const JSONNode &metadata = attach_["metadata"];
- if (metadata) {
- std::string id = metadata["fbid"].as_string();
- const JSONNode &data = it["attachment_map"][id.c_str()];
- filename = data["filename"].as_string();
- link = data["image_data"]["url"].as_string();
- }
-
if (!link.empty()) {
attachments_text += "\n" + (!filename.empty() ? "<" + filename + "> " : "") + absolutizeUrl(link) + "\n";
}
@@ -454,10 +316,14 @@ void parseAttachments2(FacebookProto *proto, std::string *message_text, const JS
else if (type == "share") {
const JSONNode &share = attach_["share"];
if (share) {
- std::string title = share["title"].as_string();
- std::string description = share["description"].as_string();
+ std::string title = share["title"] ? share["title"].as_string() : "";
+ std::string description = share["description"] ? share["description"].as_string() : "";
std::string link = share["uri"].as_string();
+ // shorten long descriptions
+ if (description.length() > MAX_LINK_DESCRIPTION_LEN)
+ description = description.substr(0, MAX_LINK_DESCRIPTION_LEN) + "...";
+
if (link.find("l." FACEBOOK_SERVER_DOMAIN) != std::string::npos) {
// de-facebook this link
link = utils::url::decode(utils::text::source_get_value2(&link, "l.php?u=", "&", true));
@@ -498,32 +364,24 @@ void parseAttachments2(FacebookProto *proto, std::string *message_text, const JS
}
}
else {
- proto->debugLogA("json::parseAttachments2 - Unknown attachment type '%s'", type.c_str());
+ proto->debugLogA("json::parseAttachments (%s) - Unknown attachment type '%s'", legacy ? "legacy" : "not legacy", type.c_str());
}
- // }
+ }
// TODO: have this as extra event, not replace or append message content
if (!message_text->empty())
*message_text += "\n\n";
if (!attachments_text.empty()) {
- // we can't use this as offline messages doesn't have it
- /* const JSONNode &admin_snippet = it["admin_snippet");
- if (admin_snippet != NULL) {
- *message_text += admin_snippet);
- } */
-
std::tstring newText;
if (type == "sticker")
newText = TranslateT("a sticker");
else if (type == "share")
newText = TranslateT("a link");
else if (type == "file")
- // newText = (attachments.size() > 1) ? TranslateT("files") : TranslateT("a file");
- newText = TranslateT("a file");
+ newText = (attachments_.size() > 1) ? TranslateT("files") : TranslateT("a file");
else if (type == "photo")
- // newText = (attachments.size() > 1) ? TranslateT("photos") : TranslateT("a photo");
- newText = TranslateT("a photo");
+ newText = (attachments_.size() > 1) ? TranslateT("photos") : TranslateT("a photo");
else
newText = _A2T(type.c_str());
@@ -582,11 +440,11 @@ int facebook_json_parser::parse_messages(std::string *pData, std::vector< facebo
}
const JSONNode &sender_fbid = meta_["actorFbId"]; // who send the message
- const JSONNode &body = delta_["body"];
+ const JSONNode &body = delta_["body"]; // message text, could be empty if there is only attachment (or sticker)
const JSONNode &mid = meta_["messageId"];
const JSONNode &timestamp = meta_["timestamp"];
- if (!sender_fbid || !body || !mid || !timestamp)
+ if (!sender_fbid || !mid || !timestamp)
continue;
std::string id = sender_fbid.as_string();
@@ -600,18 +458,12 @@ int facebook_json_parser::parse_messages(std::string *pData, std::vector< facebo
std::string thread_id = !other_user_id_ && thread_fbid_ ? "id." + thread_fbid_.as_string() : ""; // NOTE: we must add "id." prefix as this is threadFbId and we want threadId (but only for multi chats)
// Process attachements and stickers
- parseAttachments2(proto, &message_text, delta_, other_user_id); // FIXME: Rework and fix parsing attachments
+ parseAttachments(proto, &message_text, delta_, other_user_id, false);
// Ignore duplicits or messages sent from miranda
if (ignore_duplicits(proto, message_id, message_text))
continue;
- message_text = utils::text::trim(utils::text::slashu_to_utf8(message_text), true);
- if (message_text.empty()) {
- proto->debugLogA("json::parse_messages - Received empty message. Received only some attachment?");
- // continue;
- }
-
facebook_message* message = new facebook_message();
message->isChat = other_user_id.empty();
message->isIncoming = (id != proto->facy.self_.user_id);
@@ -1101,7 +953,7 @@ int facebook_json_parser::parse_thread_messages(std::string *data, std::vector<
author_id = author_id.substr(pos + 1);
// Process attachements and stickers
- parseAttachments(proto, &message_text, *it, thread_id, other_user_id);
+ parseAttachments(proto, &message_text, *it, other_user_id, true);
if (filtered.as_bool() && message_text.empty())
message_text = Translate("This message is no longer available, because it was marked as abusive or spam.");
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index ae521345a9..991a180136 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -22,8 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-#define MAX_NEWSFEED_LEN 500
-
/**
* Helper function for loading name from database (or use default one specified as parameter), used for title of few notifications.
*/