From 67f7907942b58a7b445e4da25c2398abb8db8572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Sun, 28 Jul 2013 09:14:46 +0000 Subject: Facebook: Post status improvements (part 1) - ability to post URL attachments git-svn-id: http://svn.miranda-ng.org/main/trunk@5502 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/FacebookRM/src/client.h | 2 +- protocols/FacebookRM/src/communication.cpp | 82 ++++++++++++++++++++++-------- protocols/FacebookRM/src/constants.h | 4 +- protocols/FacebookRM/src/dialogs.cpp | 15 +++++- protocols/FacebookRM/src/entities.h | 9 ++++ protocols/FacebookRM/src/proto.cpp | 16 ++++-- protocols/FacebookRM/src/resource.h | 2 + protocols/FacebookRM/src/utils.cpp | 39 ++++++++++++++ protocols/FacebookRM/src/utils.h | 1 + 9 files changed, 142 insertions(+), 28 deletions(-) (limited to 'protocols/FacebookRM/src') diff --git a/protocols/FacebookRM/src/client.h b/protocols/FacebookRM/src/client.h index 652c20fc23..152c5564c0 100644 --- a/protocols/FacebookRM/src/client.h +++ b/protocols/FacebookRM/src/client.h @@ -160,7 +160,7 @@ public: // Status handling - bool set_status(const std::string &text); + bool post_status(status_data *data); //////////////////////////////////////////////////////////// diff --git a/protocols/FacebookRM/src/communication.cpp b/protocols/FacebookRM/src/communication.cpp index eb1f54bb97..c79342c25d 100644 --- a/protocols/FacebookRM/src/communication.cpp +++ b/protocols/FacebookRM/src/communication.cpp @@ -235,7 +235,9 @@ DWORD facebook_client::choose_security_level(RequestType request_type) // case REQUEST_FEEDS: // case REQUEST_NOTIFICATIONS: // case REQUEST_RECONNECT: -// case REQUEST_STATUS_SET: +// case REQUEST_POST_STATUS: +// case REQUEST_STATUS_COMPOSER: +// case REQUEST_LINK_SCRAPER: // case REQUEST_MESSAGE_SEND: // case REQUEST_MESSAGE_SEND2: // case REQUEST_THREAD_INFO: @@ -260,7 +262,9 @@ int facebook_client::choose_method(RequestType request_type) case REQUEST_LOGIN: case REQUEST_SETUP_MACHINE: case REQUEST_BUDDY_LIST: - case REQUEST_STATUS_SET: + case REQUEST_POST_STATUS: + case REQUEST_STATUS_COMPOSER: + case REQUEST_LINK_SCRAPER: case REQUEST_MESSAGE_SEND: case REQUEST_MESSAGE_SEND2: case REQUEST_THREAD_INFO: @@ -333,7 +337,9 @@ std::string facebook_client::choose_server(RequestType request_type, std::string // case REQUEST_FEEDS: // case REQUEST_NOTIFICATIONS: // case REQUEST_RECONNECT: -// case REQUEST_STATUS_SET: +// case REQUEST_POST_STATUS: +// case REQUEST_STATUS_COMPOSER: +// case REQUEST_LINK_SCRAPER: // case REQUEST_MESSAGE_SEND: // case REQUEST_MESSAGE_SEND2: // case REQUEST_THREAD_INFO: @@ -481,9 +487,21 @@ std::string facebook_client::choose_action(RequestType request_type, std::string return action; } - case REQUEST_STATUS_SET: + case REQUEST_POST_STATUS: return "/ajax/updatestatus.php?__a=1"; + case REQUEST_STATUS_COMPOSER: + return "/ajax/profile/composer.php?__a=1"; + + case REQUEST_LINK_SCRAPER: + { + std::string action = "/ajax/composerx/attachment/link/scraper/?__a=1&composerurihash=2&scrape_url="; + if (get_data != NULL) { + action += utils::url::encode(*get_data); + } + return action; + } + case REQUEST_MESSAGE_SEND: return "/ajax/mercury/send_messages.php?__a=1"; @@ -1222,39 +1240,63 @@ bool facebook_client::send_message(std::string message_recipient, std::string me } } -bool facebook_client::set_status(const std::string &status_text) +bool facebook_client::post_status(status_data *status) { - handle_entry("set_status"); - - if (status_text.empty()) - return handle_success("set_status"); - - std::string text = utils::url::encode(status_text); - ptrA place(parent->getStringA(FACEBOOK_KEY_PLACE)); + handle_entry("post_status"); + + if (status == NULL || status->text.empty()) + return handle_success("post_status"); + + std::string data; + RequestType request = REQUEST_POST_STATUS; + + if (!status->url.empty()) { + data = "fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0"); + data += "&composerid=u_jsonp_2_b"; + data += "&targetid=" + (status->user_id.empty() ? this->self_.user_id : status->user_id); + data += "&istimeline=1&composercontext=composer&onecolumn=1&nctr[_mod]=pagelet_timeline_recent&__a=1&ttstamp=0"; + data += "&__user=" + this->self_.user_id; + data += "&loaded_components[0]=maininput&loaded_components[1]=backdateicon&loaded_components[2]=withtaggericon&loaded_components[3]=cameraicon&loaded_components[4]=placetaggericon&loaded_components[5]=mainprivacywidget&loaded_components[6]=withtaggericon&loaded_components[7]=backdateicon&loaded_components[8]=placetaggericon&loaded_components[9]=cameraicon&loaded_components[10]=mainprivacywidget&loaded_components[11]=maininput&loaded_components[12]=explicitplaceinput&loaded_components[13]=hiddenplaceinput&loaded_components[14]=placenameinput&loaded_components[15]=hiddensessionid&loaded_components[16]=withtagger&loaded_components[17]=backdatepicker&loaded_components[18]=placetagger&loaded_components[19]=citysharericon"; + http::response resp = flap(REQUEST_LINK_SCRAPER, &data, &status->url); + resp.data = utils::text::special_expressions_decode(utils::text::slashu_to_utf8(resp.data)); + + data = "&xhpc_context=profile&xhpc_ismeta=1&xhpc_timeline=1&xhpc_composerid=u_jsonp_2_0&is_explicit_place=&composertags_place=&composer_session_id=&composertags_city=&disable_location_sharing=false&composer_predicted_city=&nctr[_mod]=pagelet_composer&__a=1&__dyn=&__req=1f&ttstamp=0"; + std::string form = utils::text::source_get_value(&resp.data, 2, ""); + utils::text::replace_all(&form, "\\\"", "\""); + data += "&" + utils::text::source_get_form_data(&form) + "&"; + //data += "&no_picture=0"; + + request = REQUEST_STATUS_COMPOSER; + } - std::string data = "fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0"); - data += "&xhpc_context=home&xhpc_ismeta=1&xhpc_timeline=&xhpc_composerid=u_jsonp_2_0&is_explicit_place=&composertags_place=&composer_session_id=0&composertags_city=&disable_location_sharing=false&composer_predicted_city=&nctr[_mod]=pagelet_composer&__a=1&__dyn=&__req=1f&phstamp=0"; - data += "&xhpc_targetid=" + this->self_.user_id; + std::string text = utils::url::encode(status->text); + + data += "fb_dtsg=" + (this->dtsg_.length() ? this->dtsg_ : "0"); + data += "&xhpc_targetid=" + (status->user_id.empty() ? this->self_.user_id : status->user_id); data += "&__user=" + this->self_.user_id; data += "&xhpc_message=" + text; data += "&xhpc_message_text=" + text; data += "&audience[0][value]=" + get_privacy_type(); - data += "&composertags_place_name="; - data += ptrA(mir_urlEncode(place)); + if (!status->place.empty()) { + data += "&composertags_place_name="; + data += utils::url::encode(status->place); + } - http::response resp = flap(REQUEST_STATUS_SET, &data); + http::response resp = flap(request, &data); validate_response(&resp); + if (resp.error_number != 0 && !resp.error_text.empty()) + client_notify(_A2T(resp.error_text.c_str())); switch (resp.code) { case HTTP_CODE_OK: - return handle_success("set_status"); + return handle_success("post_status"); case HTTP_CODE_FAKE_ERROR: case HTTP_CODE_FAKE_DISCONNECTED: default: - return handle_error("set_status"); + return handle_error("post_status"); } } diff --git a/protocols/FacebookRM/src/constants.h b/protocols/FacebookRM/src/constants.h index 437b831b81..1c833dd4d6 100644 --- a/protocols/FacebookRM/src/constants.h +++ b/protocols/FacebookRM/src/constants.h @@ -93,7 +93,9 @@ enum RequestType { REQUEST_NOTIFICATIONS, // getting notifications REQUEST_LOAD_REQUESTS, // getting friend requests - REQUEST_STATUS_SET, // setting my "What's on my mind?" + REQUEST_POST_STATUS, // posting status to our or friends's wall + REQUEST_STATUS_COMPOSER, // posting status to our or friends's wall with url links + REQUEST_LINK_SCRAPER, // getting data for some url link REQUEST_SEARCH, // searching REQUEST_POKE, // sending pokes REQUEST_NOTIFICATIONS_READ, // marking notifications read diff --git a/protocols/FacebookRM/src/dialogs.cpp b/protocols/FacebookRM/src/dialogs.cpp index 2aec1f4595..f1ed65eebc 100644 --- a/protocols/FacebookRM/src/dialogs.cpp +++ b/protocols/FacebookRM/src/dialogs.cpp @@ -125,6 +125,7 @@ INT_PTR CALLBACK FBMindProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara proto = reinterpret_cast(lparam); SetWindowLongPtr(hwnd,GWLP_USERDATA,lparam); SendDlgItemMessage(hwnd,IDC_MINDMSG,EM_LIMITTEXT,FACEBOOK_MIND_LIMIT,0); + SendDlgItemMessage(hwnd,IDC_URL,EM_LIMITTEXT,1024,0); ptrT place = db_get_tsa(NULL, proto->m_szModuleName, FACEBOOK_KEY_PLACE); SetDlgItemText(hwnd, IDC_PLACE, place != NULL ? place : _T("Miranda NG")); @@ -160,25 +161,35 @@ INT_PTR CALLBACK FBMindProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lpara else if (LOWORD(wparam) == IDOK) { TCHAR mindMessageT[FACEBOOK_MIND_LIMIT+1]; + TCHAR urlT[1024]; TCHAR placeT[100]; proto = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); GetDlgItemText(hwnd,IDC_MINDMSG, mindMessageT, SIZEOF(mindMessageT)); GetDlgItemText(hwnd,IDC_PLACE, placeT, SIZEOF(placeT)); + GetDlgItemText(hwnd,IDC_URL, urlT, SIZEOF(urlT)); ShowWindow(hwnd,SW_HIDE); ptrA place( mir_utf8encodeT(placeT)); proto->setString(FACEBOOK_KEY_PLACE, place); - proto->setByte(FACEBOOK_KEY_PRIVACY_TYPE, SendDlgItemMessage(hwnd, IDC_PRIVACY, CB_GETCURSEL, 0, 0)); + int privacy_type = SendDlgItemMessage(hwnd, IDC_PRIVACY, CB_GETCURSEL, 0, 0); + proto->setByte(FACEBOOK_KEY_PRIVACY_TYPE, privacy_type); char *narrow = mir_utf8encodeT(mindMessageT); if (proto->last_status_msg_ != narrow) proto->last_status_msg_ = narrow; utils::mem::detract(narrow); + status_data *data = new status_data(); + data->place = place; + data->text = proto->last_status_msg_; + data->url = _T2A(urlT); + data->privacy = privacy_types[privacy_type].id; +// data->user_id = user_id; + //char *narrow = mir_t2a_cp(mindMessage,CP_UTF8); - proto->ForkThread(&FacebookProto::SetAwayMsgWorker, NULL); + proto->ForkThread(&FacebookProto::SetAwayMsgWorker, data); EndDialog(hwnd, wparam); return TRUE; diff --git a/protocols/FacebookRM/src/entities.h b/protocols/FacebookRM/src/entities.h index 26f64e79c1..11f7d262a3 100644 --- a/protocols/FacebookRM/src/entities.h +++ b/protocols/FacebookRM/src/entities.h @@ -138,4 +138,13 @@ struct popup_data FacebookProto *proto; std::string url; std::string notification_id; +}; + +struct status_data +{ + std::string user_id; + std::string text; + std::string url; + std::string place; + std::string privacy; }; \ No newline at end of file diff --git a/protocols/FacebookRM/src/proto.cpp b/protocols/FacebookRM/src/proto.cpp index 41ac1cef71..1773b51ff2 100644 --- a/protocols/FacebookRM/src/proto.cpp +++ b/protocols/FacebookRM/src/proto.cpp @@ -203,10 +203,18 @@ int FacebookProto::SetAwayMsg(int status, const PROTOCHAR *msg) return 0; } -void FacebookProto::SetAwayMsgWorker(void *) -{ - if (!last_status_msg_.empty()) - facy.set_status(last_status_msg_); +void FacebookProto::SetAwayMsgWorker(void *p) +{ + if (p != NULL) { + status_data *data = static_cast(p); + facy.post_status(data); + delete data; + } else if (!last_status_msg_.empty()) { + status_data data; + data.text = last_status_msg_; + data.privacy = facy.get_privacy_type(); + facy.post_status(&data); + } } HANDLE FacebookProto::SearchBasic(const PROTOCHAR* id) diff --git a/protocols/FacebookRM/src/resource.h b/protocols/FacebookRM/src/resource.h index 6c7a59d2dc..1643894516 100644 --- a/protocols/FacebookRM/src/resource.h +++ b/protocols/FacebookRM/src/resource.h @@ -59,6 +59,8 @@ #define IDC_URL_SERVER 1202 #define IDC_PLACE 1203 #define IDC_PRIVACY 1204 +#define IDC_WALL 1205 +#define IDC_URL 1206 // Next default values for new objects // diff --git a/protocols/FacebookRM/src/utils.cpp b/protocols/FacebookRM/src/utils.cpp index 0a03ec29eb..3155c720f8 100644 --- a/protocols/FacebookRM/src/utils.cpp +++ b/protocols/FacebookRM/src/utils.cpp @@ -426,6 +426,45 @@ std::string utils::text::source_get_value2(std::string* data, const char *term, return ret; } +std::string utils::text::source_get_form_data(std::string* data) +{ + std::string values = ""; + + std::string::size_type start = 0; + start = data->find("find("name=\"", start); + if (pos != std::string::npos) { + pos += 6; + std::string::size_type end = data->find("\"", pos); + if (end != std::string::npos) + attr = data->substr(pos, end - pos); + + + end = data->find(">", pos); + pos = data->find("value=\"", pos); + if (pos != std::string::npos && end != std::string::npos && pos < end) { + pos += 7; + end = data->find("\"", pos); + if (end != std::string::npos) + value = data->substr(pos, end - pos); + } + } + + if (!attr.empty()) { + if (!values.empty()) + values += "&"; + values += attr + "=" + value; + } + start = data->find("* results); void append_ordinal(unsigned long value, std::string* data); }; -- cgit v1.2.3