summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2014-11-17 22:23:42 +0000
committerRobert Pösel <robyer@seznam.cz>2014-11-17 22:23:42 +0000
commit989fa6c77d1b8fd1b9dc412b6948947cf5b170cb (patch)
treed27341054c2f5ea2f8415d4202166341f3aa12f6
parent6029781c4a2ca30552d96de331a640c653d8bfba (diff)
Facebook: Experimental messages sync at login (for last 24-hours only) (patch by Vojtěch Kinkor, thanks)
git-svn-id: http://svn.miranda-ng.org/main/trunk@11006 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/FacebookRM/res/facebook.rc19
-rw-r--r--protocols/FacebookRM/src/communication.cpp11
-rw-r--r--protocols/FacebookRM/src/connection.cpp12
-rw-r--r--protocols/FacebookRM/src/constants.h2
-rw-r--r--protocols/FacebookRM/src/db.h3
-rw-r--r--protocols/FacebookRM/src/dialogs.cpp2
-rw-r--r--protocols/FacebookRM/src/entities.h4
-rw-r--r--protocols/FacebookRM/src/json.cpp1
-rw-r--r--protocols/FacebookRM/src/process.cpp80
-rw-r--r--protocols/FacebookRM/src/proto.h1
-rw-r--r--protocols/FacebookRM/src/resource.h1
-rw-r--r--protocols/FacebookRM/src/utils.cpp2
12 files changed, 118 insertions, 20 deletions
diff --git a/protocols/FacebookRM/res/facebook.rc b/protocols/FacebookRM/res/facebook.rc
index 6456390d9c..61cd38d25d 100644
--- a/protocols/FacebookRM/res/facebook.rc
+++ b/protocols/FacebookRM/res/facebook.rc
@@ -140,7 +140,7 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,121,272,8
END
-IDD_OPTIONS_ADVANCED DIALOGEX 0, 0, 308, 230
+IDD_OPTIONS_ADVANCED DIALOGEX 0, 0, 308, 242
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 400, 0, 0x1
@@ -162,7 +162,7 @@ BEGIN
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,129,281,10
CONTROL "Use local time for received messages",IDC_USE_LOCAL_TIME,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,142,281,10
- GROUPBOX "Message sessions",IDC_STATIC,7,114,294,111
+ GROUPBOX "Message sessions",IDC_STATIC,7,114,294,126
CONTROL "Keep messages as unread on server (don't send ""seen"" info)",IDC_KEEP_UNREAD,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,155,281,10
CONTROL "Receive messages from ""inbox"" folder only",IDC_INBOX_ONLY,
@@ -173,7 +173,9 @@ BEGIN
EDITTEXT IDC_MESSAGES_COUNT,249,192,34,14,ES_AUTOHSCROLL
CONTROL "",IDC_MESSAGES_COUNT_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,283,192,11,14
CONTROL "Do not open chat windows on creation",IDC_HIDE_CHATS,
- "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,210,281,10
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,225,281,10
+ CONTROL "Synchronize last 24 hours on login",IDC_LOGIN_SYNC,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,212,281,10
END
IDD_CAPTCHAFORM DIALOGEX 0, 0, 258, 224
@@ -193,7 +195,6 @@ BEGIN
END
-
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
@@ -264,15 +265,7 @@ BEGIN
VERTGUIDE, 156
VERTGUIDE, 294
TOPMARGIN, 7
- BOTTOMMARGIN, 228
- END
-
- IDD_CAPTCHA, DIALOG
- BEGIN
- LEFTMARGIN, 7
- RIGHTMARGIN, 226
- TOPMARGIN, 7
- BOTTOMMARGIN, 103
+ BOTTOMMARGIN, 240
END
END
#endif // APSTUDIO_INVOKED
diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp
index 053ed0c0e4..11c4e066d8 100644
--- a/protocols/FacebookRM/src/communication.cpp
+++ b/protocols/FacebookRM/src/communication.cpp
@@ -238,6 +238,7 @@ DWORD facebook_client::choose_security_level(RequestType request_type)
// case REQUEST_MESSAGE_SEND_CHAT:
// case REQUEST_MESSAGE_SEND_INBOX:
// case REQUEST_THREAD_INFO:
+// case REQUEST_THREAD_SYNC:
// case REQUEST_MESSAGES_RECEIVE:
// case REQUEST_VISIBILITY:
// case REQUEST_POKE:
@@ -264,6 +265,7 @@ int facebook_client::choose_method(RequestType request_type)
case REQUEST_MESSAGE_SEND_CHAT:
case REQUEST_MESSAGE_SEND_INBOX:
case REQUEST_THREAD_INFO:
+ case REQUEST_THREAD_SYNC:
case REQUEST_VISIBILITY:
case REQUEST_POKE:
case REQUEST_ASYNC:
@@ -341,6 +343,7 @@ std::string facebook_client::choose_server(RequestType request_type, std::string
// case REQUEST_MESSAGE_SEND_CHAT:
// case REQUEST_MESSAGE_SEND_INBOX:
// case REQUEST_THREAD_INFO:
+// case REQUEST_THREAD_SYNC:
// case REQUEST_VISIBILITY:
// case REQUEST_POKE:
// case REQUEST_ASYNC:
@@ -520,6 +523,9 @@ std::string facebook_client::choose_action(RequestType request_type, std::string
case REQUEST_THREAD_INFO:
return "/ajax/mercury/thread_info.php?__a=1";
+ case REQUEST_THREAD_SYNC:
+ return "/ajax/mercury/thread_sync.php";
+
case REQUEST_MESSAGES_RECEIVE:
{
std::string action = "/pull?channel=" + (this->chat_channel_.empty() ? "p_" + self_.user_id : this->chat_channel_);
@@ -1315,6 +1321,11 @@ int facebook_client::send_message(MCONTACT hContact, std::string message_recipie
if (mid.empty())
mid = utils::text::source_get_value(&resp.data, 2, "\"mid\":\"", "\"");
parent->setString(hContact, FACEBOOK_KEY_MESSAGE_ID, mid.c_str());
+
+ // Remember last action timestamp
+ std::string timestamp = utils::text::source_get_value(&resp.data, 2, "\"timestamp\":", ",");
+ parent->setString(FACEBOOK_KEY_LAST_ACTION_TIMESTAMP, timestamp.c_str());
+
messages_ignore.insert(std::make_pair(mid, 0));
} break;
diff --git a/protocols/FacebookRM/src/connection.cpp b/protocols/FacebookRM/src/connection.cpp
index 1582056033..a53e3e488c 100644
--- a/protocols/FacebookRM/src/connection.cpp
+++ b/protocols/FacebookRM/src/connection.cpp
@@ -52,7 +52,8 @@ void FacebookProto::ChangeStatus(void*)
OnLeaveChat(NULL, NULL);
SetAllContactStatuses(ID_STATUS_OFFLINE);
ToggleStatusMenuItems(false);
- delSetting("LogonTS");
+ // setString(FACEBOOK_KEY_LAST_ACTION_TIMESTAMP, utils::time::mili_timestamp().c_str()); // TODO RM: this should't be here because of different local/server time
+ delSetting(FACEBOOK_KEY_LOGON_TS);
facy.clear_cookies();
facy.clear_notifications();
@@ -104,8 +105,11 @@ void FacebookProto::ChangeStatus(void*)
// Process friendship requests
ForkThread(&FacebookProto::ProcessFriendRequests, NULL);
- // Get unread messages
- ForkThread(&FacebookProto::ProcessUnreadMessages, NULL);
+ // Sync threads, get messages - or get unread messages
+ if (getBool(FACEBOOK_KEY_LOGIN_SYNC, DEFAULT_LOGIN_SYNC))
+ ForkThread(&FacebookProto::SyncThreads, NULL);
+ else
+ ForkThread(&FacebookProto::ProcessUnreadMessages, NULL);
// Get notifications
ForkThread(&FacebookProto::ProcessNotifications, NULL);
@@ -113,7 +117,7 @@ void FacebookProto::ChangeStatus(void*)
// Load pages for post status dialog
ForkThread(&FacebookProto::ProcessPages, NULL);
- setDword("LogonTS", (DWORD)time(NULL));
+ setDword(FACEBOOK_KEY_LOGON_TS, (DWORD)time(NULL));
ForkThread(&FacebookProto::UpdateLoop, NULL);
ForkThread(&FacebookProto::MessageLoop, NULL);
diff --git a/protocols/FacebookRM/src/constants.h b/protocols/FacebookRM/src/constants.h
index d7211b2f1b..b0ec0d555b 100644
--- a/protocols/FacebookRM/src/constants.h
+++ b/protocols/FacebookRM/src/constants.h
@@ -80,6 +80,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DEFAULT_KEEP_UNREAD 0
#define DEFAULT_INBOX_ONLY 0
#define DEFAULT_FILTER_ADS 0
+#define DEFAULT_LOGIN_SYNC 0
#define DEFAULT_MESSAGES_ON_OPEN 0
#define DEFAULT_MESSAGES_ON_OPEN_COUNT 10
#define DEFAULT_HIDE_CHATS 0
@@ -141,6 +142,7 @@ enum RequestType {
REQUEST_TYPING_SEND, // sending typing notification
REQUEST_THREAD_INFO, // getting thread info
+ REQUEST_THREAD_SYNC, // getting thread sync (changes since something)
REQUEST_UNREAD_THREADS, // getting unread threads
REQUEST_ASYNC, // marking messages read and getting other things
REQUEST_MARK_READ, // marking messages read (new)
diff --git a/protocols/FacebookRM/src/db.h b/protocols/FacebookRM/src/db.h
index 1bc512c4ca..4cf23ee489 100644
--- a/protocols/FacebookRM/src/db.h
+++ b/protocols/FacebookRM/src/db.h
@@ -61,6 +61,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define FACEBOOK_KEY_LOAD_PAGES "LoadPages"
#define FACEBOOK_KEY_INBOX_ONLY "InboxOnly"
#define FACEBOOK_KEY_FILTER_ADS "FilterAds"
+#define FACEBOOK_KEY_LOGON_TS "LogonTS"
+#define FACEBOOK_KEY_LOGIN_SYNC "LoginSync" // (byte) 0 = get only unread messages, 1 = sync messages since last activity (default is 0)
+#define FACEBOOK_KEY_LAST_ACTION_TIMESTAMP "LastActionTimestamp"
#define FACEBOOK_KEY_MESSAGES_ON_OPEN "MessagesOnOpen"
#define FACEBOOK_KEY_MESSAGES_ON_OPEN_COUNT "MessagesOnOpenCount"
#define FACEBOOK_KEY_HIDE_CHATS "HideChats"
diff --git a/protocols/FacebookRM/src/dialogs.cpp b/protocols/FacebookRM/src/dialogs.cpp
index 122cecc084..bf2687a79d 100644
--- a/protocols/FacebookRM/src/dialogs.cpp
+++ b/protocols/FacebookRM/src/dialogs.cpp
@@ -450,6 +450,7 @@ INT_PTR CALLBACK FBOptionsAdvancedProc(HWND hwnd, UINT message, WPARAM wparam, L
LoadDBCheckState(proto, hwnd, IDC_INBOX_ONLY, FACEBOOK_KEY_INBOX_ONLY, DEFAULT_INBOX_ONLY);
LoadDBCheckState(proto, hwnd, IDC_KEEP_UNREAD, FACEBOOK_KEY_KEEP_UNREAD, DEFAULT_KEEP_UNREAD);
LoadDBCheckState(proto, hwnd, IDC_MESSAGES_ON_OPEN, FACEBOOK_KEY_MESSAGES_ON_OPEN, DEFAULT_MESSAGES_ON_OPEN);
+ LoadDBCheckState(proto, hwnd, IDC_LOGIN_SYNC, FACEBOOK_KEY_LOGIN_SYNC, DEFAULT_LOGIN_SYNC);
LoadDBCheckState(proto, hwnd, IDC_HIDE_CHATS, FACEBOOK_KEY_HIDE_CHATS, DEFAULT_HIDE_CHATS);
int count = proto->getByte(FACEBOOK_KEY_MESSAGES_ON_OPEN_COUNT, 10);
@@ -502,6 +503,7 @@ INT_PTR CALLBACK FBOptionsAdvancedProc(HWND hwnd, UINT message, WPARAM wparam, L
StoreDBCheckState(proto, hwnd, IDC_LOAD_PAGES, FACEBOOK_KEY_LOAD_PAGES);
StoreDBCheckState(proto, hwnd, IDC_INBOX_ONLY, FACEBOOK_KEY_INBOX_ONLY);
StoreDBCheckState(proto, hwnd, IDC_KEEP_UNREAD, FACEBOOK_KEY_KEEP_UNREAD);
+ StoreDBCheckState(proto, hwnd, IDC_LOGIN_SYNC, FACEBOOK_KEY_LOGIN_SYNC);
StoreDBCheckState(proto, hwnd, IDC_MESSAGES_ON_OPEN, FACEBOOK_KEY_MESSAGES_ON_OPEN);
StoreDBCheckState(proto, hwnd, IDC_HIDE_CHATS, FACEBOOK_KEY_HIDE_CHATS);
diff --git a/protocols/FacebookRM/src/entities.h b/protocols/FacebookRM/src/entities.h
index 94fb9196f3..3636b3508c 100644
--- a/protocols/FacebookRM/src/entities.h
+++ b/protocols/FacebookRM/src/entities.h
@@ -106,6 +106,7 @@ struct facebook_message
std::string message_text;
std::string message_id;
std::string thread_id;
+ std::string timestamp;
DWORD time;
bool isIncoming;
bool isUnread;
@@ -116,7 +117,7 @@ struct facebook_message
facebook_message()
{
- this->user_id = this->message_text = this->sender_name = this->message_id = this->thread_id = "";
+ this->user_id = this->message_text = this->sender_name = this->message_id = this->thread_id = this->timestamp = "";
this->time = 0;
this->isUnread = this->isIncoming = true;
this->isChat = false;
@@ -131,6 +132,7 @@ struct facebook_message
this->message_text = msg.message_text;
this->message_id = msg.message_id;
this->message_id = msg.thread_id;
+ this->timestamp = msg.timestamp;
this->time = msg.time;
this->isIncoming = msg.isIncoming;
this->isUnread = msg.isUnread;
diff --git a/protocols/FacebookRM/src/json.cpp b/protocols/FacebookRM/src/json.cpp
index 2162ed0021..12a90a2020 100644
--- a/protocols/FacebookRM/src/json.cpp
+++ b/protocols/FacebookRM/src/json.cpp
@@ -543,6 +543,7 @@ int facebook_json_parser::parse_messages(void* data, std::vector< facebook_messa
message->isUnread = true;
message->isIncoming = (id != proto->facy.self_.user_id);
message->message_text = message_text;
+ message->timestamp = json_as_pstring(timestamp);
message->time = utils::time::fix_timestamp(json_as_float(timestamp));
message->user_id = id;
message->message_id = message_id;
diff --git a/protocols/FacebookRM/src/process.cpp b/protocols/FacebookRM/src/process.cpp
index 39c9811c62..579779e201 100644
--- a/protocols/FacebookRM/src/process.cpp
+++ b/protocols/FacebookRM/src/process.cpp
@@ -556,6 +556,83 @@ CODE_BLOCK_END
OnDbEventRead(hContact, NULL);
}
+void FacebookProto::SyncThreads(void*)
+{
+ facy.handle_entry("SyncThreads");
+
+ if (isOffline())
+ return;
+
+ // get timestamp of last action (last message or possibly logout time)
+ ptrA ptrtimestamp(getStringA(FACEBOOK_KEY_LAST_ACTION_TIMESTAMP));
+
+ std::string timestamp = "0";
+ if (ptrtimestamp != NULL)
+ timestamp = std::string(ptrtimestamp); // FIXME: is std::string(..) needed?
+
+ unsigned __int64 time = _atoi64(timestamp.c_str());
+
+ if (time > 100000000000) {
+ time /= 1000;
+ }
+
+ if (time < (unsigned) ::time(NULL) - 24*60*60) {
+ time_t last = ::time(NULL) - 24*60*60;
+ timestamp = utils::conversion::to_string((void*)&last, UTILS_CONV_TIME_T) + "000";
+
+ ForkThread(&FacebookProto::ProcessUnreadMessages, NULL); // for older unread messages (necessary?)
+ }
+
+ setString(FACEBOOK_KEY_LAST_ACTION_TIMESTAMP, utils::time::mili_timestamp().c_str());
+
+
+ // receive messages from all folders by default, use hidden setting to receive only inbox messages
+ bool inboxOnly = getBool(FACEBOOK_KEY_INBOX_ONLY, 0);
+
+ std::string data = "client=mercury";
+ data += "&last_action_timestamp=" + timestamp;
+ data += "&__user=" + facy.self_.user_id;
+ data += "&fb_dtsg=" + facy.dtsg_;
+ data += "&folders[0]=inbox";
+ if (!inboxOnly)
+ data += "&folders[1]=other";
+ data += "&__req=7&__a=1&__dyn=&__req=&__rev=&ttstamp=" + facy.ttstamp();
+
+ debugLogA("Sync timestamp: %s", timestamp.c_str());
+
+ http::response resp = facy.flap(REQUEST_THREAD_SYNC, &data);
+
+ if (resp.code != HTTP_CODE_OK || resp.data.empty()) {
+ facy.handle_error("LoadLastMessages");
+ return;
+ }
+
+
+CODE_BLOCK_TRY
+
+ std::vector<facebook_message*> messages;
+ std::map<std::string, facebook_chatroom*> chatrooms;
+
+ facebook_json_parser* p = new facebook_json_parser(this);
+ p->parse_thread_messages(&resp.data, &messages, &chatrooms, false, false, 20);
+ delete p;
+
+
+ bool local_timestamp = getBool(FACEBOOK_KEY_LOCAL_TIMESTAMP_UNREAD, 0);
+ ReceiveMessages(messages, local_timestamp, true);
+
+ debugLogA("***** Thread messages processed");
+
+CODE_BLOCK_CATCH
+
+ debugLogA("***** Error processing thread messages: %s", e.what());
+
+CODE_BLOCK_END
+
+ facy.handle_success("SyncThreads");
+
+}
+
void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, bool local_timestamp, bool check_duplicates)
{
@@ -659,7 +736,8 @@ void FacebookProto::ReceiveMessages(std::vector<facebook_message*> messages, boo
// Save last (this) message ID
setString(hChatContact, FACEBOOK_KEY_MESSAGE_ID, messages[i]->message_id.c_str());
-
+ setString(FACEBOOK_KEY_LAST_ACTION_TIMESTAMP, messages[i]->timestamp.c_str());
+
// Save TID if not exists already
ptrA tid(getStringA(hChatContact, FACEBOOK_KEY_TID));
if (!tid || strcmp(tid, messages[i]->thread_id.c_str()))
diff --git a/protocols/FacebookRM/src/proto.h b/protocols/FacebookRM/src/proto.h
index a18d8e4275..45e70fc114 100644
--- a/protocols/FacebookRM/src/proto.h
+++ b/protocols/FacebookRM/src/proto.h
@@ -178,6 +178,7 @@ public:
void __cdecl SearchIdAckThread(void*);
void __cdecl ProcessPages(void*);
void __cdecl LoadLastMessages(void*);
+ void __cdecl SyncThreads(void*);
// Worker threads
void __cdecl SignOn(void*);
diff --git a/protocols/FacebookRM/src/resource.h b/protocols/FacebookRM/src/resource.h
index 90fa4d1472..a16c1e325d 100644
--- a/protocols/FacebookRM/src/resource.h
+++ b/protocols/FacebookRM/src/resource.h
@@ -43,6 +43,7 @@
#define IDC_OTHER_ENABLE 1043
#define IDC_CLIENT_ENABLE 1044
#define IDC_FILTER_ADS 1045
+#define IDC_LOGIN_SYNC 1046
#define IDC_SYSTRAY_NOTIFY 1098
#define IDC_PREVIEW 1099
#define IDC_SET_STATUS 1126
diff --git a/protocols/FacebookRM/src/utils.cpp b/protocols/FacebookRM/src/utils.cpp
index 2a4c263d5f..1ecaa1328c 100644
--- a/protocols/FacebookRM/src/utils.cpp
+++ b/protocols/FacebookRM/src/utils.cpp
@@ -51,7 +51,7 @@ std::string utils::time::mili_timestamp()
std::string timestamp = utils::time::unix_timestamp();
GetSystemTime(&st);
timestamp.append(utils::conversion::to_string((void*)&st.wMilliseconds, UTILS_CONV_UNSIGNED_NUMBER));
- return timestamp;
+ return timestamp.substr(0,13);
}
DWORD utils::time::fix_timestamp(unsigned __int64 mili_timestamp)