diff options
author | Robert Pösel <robyer@seznam.cz> | 2014-11-17 22:23:42 +0000 |
---|---|---|
committer | Robert Pösel <robyer@seznam.cz> | 2014-11-17 22:23:42 +0000 |
commit | 989fa6c77d1b8fd1b9dc412b6948947cf5b170cb (patch) | |
tree | d27341054c2f5ea2f8415d4202166341f3aa12f6 | |
parent | 6029781c4a2ca30552d96de331a640c653d8bfba (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.rc | 19 | ||||
-rw-r--r-- | protocols/FacebookRM/src/communication.cpp | 11 | ||||
-rw-r--r-- | protocols/FacebookRM/src/connection.cpp | 12 | ||||
-rw-r--r-- | protocols/FacebookRM/src/constants.h | 2 | ||||
-rw-r--r-- | protocols/FacebookRM/src/db.h | 3 | ||||
-rw-r--r-- | protocols/FacebookRM/src/dialogs.cpp | 2 | ||||
-rw-r--r-- | protocols/FacebookRM/src/entities.h | 4 | ||||
-rw-r--r-- | protocols/FacebookRM/src/json.cpp | 1 | ||||
-rw-r--r-- | protocols/FacebookRM/src/process.cpp | 80 | ||||
-rw-r--r-- | protocols/FacebookRM/src/proto.h | 1 | ||||
-rw-r--r-- | protocols/FacebookRM/src/resource.h | 1 | ||||
-rw-r--r-- | protocols/FacebookRM/src/utils.cpp | 2 |
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)
|