diff options
Diffstat (limited to 'protocols/Twitter/src')
| -rw-r--r-- | protocols/Twitter/src/chat.cpp | 14 | ||||
| -rw-r--r-- | protocols/Twitter/src/connection.cpp | 18 | ||||
| -rw-r--r-- | protocols/Twitter/src/contacts.cpp | 8 | ||||
| -rw-r--r-- | protocols/Twitter/src/http.h | 2 | ||||
| -rw-r--r-- | protocols/Twitter/src/oauth.cpp | 16 | ||||
| -rw-r--r-- | protocols/Twitter/src/proto.cpp | 10 | ||||
| -rw-r--r-- | protocols/Twitter/src/proto.h | 3 | ||||
| -rw-r--r-- | protocols/Twitter/src/resource.h | 6 | ||||
| -rw-r--r-- | protocols/Twitter/src/stdafx.h | 1 | ||||
| -rw-r--r-- | protocols/Twitter/src/twitter.cpp | 21 | ||||
| -rw-r--r-- | protocols/Twitter/src/ui.cpp | 37 | ||||
| -rw-r--r-- | protocols/Twitter/src/utility.cpp | 42 | 
12 files changed, 65 insertions, 113 deletions
diff --git a/protocols/Twitter/src/chat.cpp b/protocols/Twitter/src/chat.cpp index 72705dd926..733e4aacee 100644 --- a/protocols/Twitter/src/chat.cpp +++ b/protocols/Twitter/src/chat.cpp @@ -23,17 +23,15 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  void CTwitterProto::UpdateChat(const twitter_user &update)
  {
 +	CMStringA chatText = update.status.text.c_str();
 +	chatText.Replace("%", "%%");
 +
  	GCEVENT gce = { m_szModuleName, m_szChatId, GC_EVENT_MESSAGE };
  	gce.dwFlags = GCEF_UTF8 + GCEF_ADDTOLOG;
  	gce.bIsMe = (update.username.c_str() == m_szUserName);
  	gce.pszUID.a = update.username.c_str();
 -	//TODO: write code here to replace % with %% in update.status.text (which is a CMStringA)
 -
 -	CMStringA chatText = update.status.text.c_str();
 -	chatText.Replace("%", "%%");
 -
  	gce.pszText.a = chatText.c_str();
 -	gce.time = static_cast<DWORD>(update.status.time);
 +	gce.time = (DWORD)update.status.time;
  	MCONTACT hContact = UsernameToHContact(update.username.c_str());
  	CMStringA szNick = db_get_sm(hContact, "CList", "MyHandle");
 @@ -43,10 +41,6 @@ void CTwitterProto::UpdateChat(const twitter_user &update)  		gce.pszNick.a = update.username.c_str();
  	Chat_Event(&gce);
 -
 -	mir_free(const_cast<wchar_t*>(gce.pszNick.w));
 -	mir_free(const_cast<wchar_t*>(gce.pszUID.w));
 -	mir_free(const_cast<wchar_t*>(gce.pszText.w));
  }
  int CTwitterProto::OnChatOutgoing(WPARAM, LPARAM lParam)
 diff --git a/protocols/Twitter/src/connection.cpp b/protocols/Twitter/src/connection.cpp index b927de5c4d..6995fe942c 100644 --- a/protocols/Twitter/src/connection.cpp +++ b/protocols/Twitter/src/connection.cpp @@ -93,14 +93,6 @@ bool CTwitterProto::NegotiateConnection()  	if (m_szUserName.IsEmpty())
  		m_szUserName = getMStringA(TWITTER_KEY_UN);
 -	// CTwitterProto changed the base URL in v1.1 of the API, I don't think users will need to modify it, so
 -	// i'll be forcing it to the new API URL here. After a while I can get rid of this as users will
 -	// have either had this run at least once, or have reset their miranda profile. 14/10/2012
 -	if (getByte("UpgradeBaseURL", 1)) {
 -		setString(TWITTER_KEY_BASEURL, "https://api.twitter.com/");
 -		setByte("UpgradeBaseURL", 0);
 -	}
 -
  	if (szOauthToken.IsEmpty() || szOauthTokenSecret.IsEmpty()) {
  		// first, reset all the keys so we can start fresh
  		debugLogA("**NegotiateConnection - Reset OAuth Keys");
 @@ -196,8 +188,6 @@ bool CTwitterProto::NegotiateConnection()  		m_szAccessTokenSecret = szOauthTokenSecret;
  	}
 -	m_szBaseUrl = getMStringA(TWITTER_KEY_BASEURL);
 -
  	debugLogA("**NegotiateConnection - Setting Consumer Keys and verifying creds...");
  	if (m_szUserName.IsEmpty()) {
 @@ -205,7 +195,7 @@ bool CTwitterProto::NegotiateConnection()  		debugLogA("**NegotiateConnection - Missing the Nick key in the database.  Everything will still work, but it's nice to have");
  	}
 -	auto *req = new AsyncHttpRequest(REQUEST_GET, m_szBaseUrl + "1.1/account/verify_credentials.json");
 +	auto *req = new AsyncHttpRequest(REQUEST_GET, "/account/verify_credentials.json");
  	if (Execute(req).code != 200) {
  		debugLogA("**NegotiateConnection - Verifying credentials failed!  No internet maybe?");
 @@ -355,7 +345,7 @@ void CTwitterProto::UpdateAvatar(MCONTACT hContact, const CMStringA &url, bool f  void CTwitterProto::UpdateFriends()
  {
 -	auto *req = new AsyncHttpRequest(REQUEST_GET, m_szBaseUrl + "1.1/friends/list.json");
 +	auto *req = new AsyncHttpRequest(REQUEST_GET, "/friends/list.json");
  	http::response resp = Execute(req);
  	if (resp.code != 200) {
  		debugLogA("Friend list reading failed");
 @@ -448,7 +438,7 @@ void CTwitterProto::ShowContactPopup(MCONTACT hContact, const CMStringA &text, c  void CTwitterProto::UpdateStatuses(bool pre_read, bool popups, bool tweetToMsg)
  {
 -	auto *req = new AsyncHttpRequest(REQUEST_GET, m_szBaseUrl + "1.1/statuses/home_timeline.json");
 +	auto *req = new AsyncHttpRequest(REQUEST_GET, "/statuses/home_timeline.json");
  	req << INT_PARAM("count", 200);
  	if (since_id_ != 0)
  		req << INT64_PARAM("since_id", since_id_);
 @@ -545,7 +535,7 @@ void CTwitterProto::UpdateStatuses(bool pre_read, bool popups, bool tweetToMsg)  void CTwitterProto::UpdateMessages(bool pre_read)
  {
 -	auto *req = new AsyncHttpRequest(REQUEST_GET, m_szBaseUrl + "1.1/direct_messages/events/list.json");
 +	auto *req = new AsyncHttpRequest(REQUEST_GET, "/direct_messages/events/list.json");
  	req << INT_PARAM("count", 50);
  	if (dm_since_id_ != 0)
  		req << INT64_PARAM("since_id", dm_since_id_);
 diff --git a/protocols/Twitter/src/contacts.cpp b/protocols/Twitter/src/contacts.cpp index 01524b6a12..cd8fb08162 100644 --- a/protocols/Twitter/src/contacts.cpp +++ b/protocols/Twitter/src/contacts.cpp @@ -43,7 +43,7 @@ MCONTACT CTwitterProto::AddToList(int, PROTOSEARCHRESULT *psr)  	return AddToClientList(_T2A(psr->nick.w), "");
  }
 -// *************************
 +/////////////////////////////////////////////////////////////////////////////////////////
  void CTwitterProto::UpdateInfoWorker(void *arg)
  {
 @@ -79,7 +79,7 @@ int CTwitterProto::GetInfo(MCONTACT hContact, int info_type)  	return 1;
  }
 -// *************************
 +/////////////////////////////////////////////////////////////////////////////////////////
  struct search_query
  {
 @@ -136,7 +136,7 @@ HANDLE CTwitterProto::SearchByEmail(const wchar_t *email)  	return (HANDLE)1;
  }
 -// *************************
 +/////////////////////////////////////////////////////////////////////////////////////////
  void CTwitterProto::GetAwayMsgWorker(void *arg)
  {
 @@ -195,7 +195,7 @@ int CTwitterProto::OnMarkedRead(WPARAM, LPARAM hDbEvent)  	return 0;
  }
 -// *************************
 +/////////////////////////////////////////////////////////////////////////////////////////
  bool CTwitterProto::IsMyContact(MCONTACT hContact, bool include_chat)
  {
 diff --git a/protocols/Twitter/src/http.h b/protocols/Twitter/src/http.h index 0522fa53ab..ab91b177a7 100644 --- a/protocols/Twitter/src/http.h +++ b/protocols/Twitter/src/http.h @@ -19,6 +19,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #pragma once
 +#define TWITTER_BASE_URL "https://api.twitter.com/1.1"
 +
  namespace http
  {
  	struct response
 diff --git a/protocols/Twitter/src/oauth.cpp b/protocols/Twitter/src/oauth.cpp index ee42730b47..bb4ba506e2 100644 --- a/protocols/Twitter/src/oauth.cpp +++ b/protocols/Twitter/src/oauth.cpp @@ -62,17 +62,13 @@ static CMStringA OAuthNormalizeRequestParameters(const CMStringA &requestParamet  	return res;
  }
 -CMStringA CTwitterProto::BuildSignedOAuthParameters(
 -	const CMStringA &requestParameters,
 -	const CMStringA &url,
 -	const CMStringA &httpMethod,
 -	const CMStringA &postData)
 +CMStringA CTwitterProto::BuildSignedOAuthParameters(const CMStringA &request, const CMStringA &url, const char *httpMethod, const char *postData)
  {
  	CMStringA timestamp(FORMAT, "%lld", _time64(0));
  	CMStringA nonce = OAuthCreateNonce();
  	// create oauth requestParameters
 -	auto *req = new AsyncHttpRequest(httpMethod == "GET" ? REQUEST_GET : REQUEST_POST, url);
 +	auto *req = new AsyncHttpRequest(!mir_strcmp(httpMethod, "GET") ? REQUEST_GET : REQUEST_POST, url);
  	req << CHAR_PARAM("oauth_timestamp", timestamp) << CHAR_PARAM("oauth_nonce", nonce) << CHAR_PARAM("oauth_version", "1.0")
  		<< CHAR_PARAM("oauth_signature_method", "HMAC-SHA1") << CHAR_PARAM("oauth_consumer_key", OAUTH_CONSUMER_KEY) << CHAR_PARAM("oauth_callback", "oob");
 @@ -86,12 +82,12 @@ CMStringA CTwitterProto::BuildSignedOAuthParameters(  	// create a parameter list containing both oauth and original parameters
  	// this will be used to create the parameter signature
 -	if (!requestParameters.IsEmpty()) {
 +	if (!request.IsEmpty()) {
  		req->m_szParam.AppendChar('&');
 -		req->m_szParam.Append(requestParameters);
 +		req->m_szParam.Append(request);
  	}
 -	if (!postData.IsEmpty()) {
 +	if (!mir_strlen(postData)) {
  		req->m_szParam.AppendChar('&');
  		req->m_szParam.Append(postData);
  	}
 @@ -100,7 +96,7 @@ CMStringA CTwitterProto::BuildSignedOAuthParameters(  	// all of the necessary information needed to generate a valid signature
  	CMStringA normalUrl = OAuthNormalizeUrl(url);
  	CMStringA normalizedParameters = OAuthNormalizeRequestParameters(req->m_szParam, true);
 -	CMStringA signatureBase = httpMethod + "&" + mir_urlEncode(normalUrl) + "&" + mir_urlEncode(normalizedParameters);
 +	CMStringA signatureBase = CMStringA(httpMethod) + "&" + mir_urlEncode(normalUrl) + "&" + mir_urlEncode(normalizedParameters);
  	// obtain a signature and add it to header requestParameters
  	CMStringA signature = OAuthCreateSignature(signatureBase, OAUTH_CONSUMER_SECRET, m_szAccessTokenSecret);
 diff --git a/protocols/Twitter/src/proto.cpp b/protocols/Twitter/src/proto.cpp index 01da0ec206..8ab85237b1 100644 --- a/protocols/Twitter/src/proto.cpp +++ b/protocols/Twitter/src/proto.cpp @@ -26,7 +26,6 @@ static volatile LONG g_msgid = 1;  CTwitterProto::CTwitterProto(const char *proto_name, const wchar_t *username) :
  	PROTO<CTwitterProto>(proto_name, username),
  	m_szChatId(mir_utf8encodeW(username)),
 -	m_szBaseUrl("https://api.twitter.com/"),
  	m_arChatMarks(10, NumericKeySortT)
  {
  	CreateProtoService(PS_CREATEACCMGRUI, &CTwitterProto::SvcCreateAccMgrUI);
 @@ -138,13 +137,10 @@ void CTwitterProto::SendSuccess(void *p)  	auto *data = (TSendDirect*)p;
 -	DBVARIANT dbv;
 -	if (!db_get_s(data->hContact, m_szModuleName, TWITTER_KEY_UN, &dbv)) {
 -		mir_cslock s(twitter_lock_);
 -		send_direct(dbv.pszVal, data->msg);
 -
 +	CMStringA id(getMStringA(data->hContact, TWITTER_KEY_ID));
 +	if (!id.IsEmpty()) {
 +		send_direct(id, data->msg);
  		ProtoBroadcastAck(data->hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)data->msgid, 0);
 -		db_free(&dbv);
  	}
  	delete data;
 diff --git a/protocols/Twitter/src/proto.h b/protocols/Twitter/src/proto.h index 6067841973..498925ff4a 100644 --- a/protocols/Twitter/src/proto.h +++ b/protocols/Twitter/src/proto.h @@ -78,7 +78,6 @@ class CTwitterProto : public PROTO<CTwitterProto>  	CMStringA m_szUserName;
  	CMStringA m_szPassword;
 -	CMStringA m_szBaseUrl;
  	CMStringA m_szConsumerKey;
  	CMStringA m_szConsumerSecret;
  	CMStringA m_szAccessToken;
 @@ -113,7 +112,7 @@ class CTwitterProto : public PROTO<CTwitterProto>  	CMStringA UrlGetQuery(const CMStringA &url);
 -	CMStringA BuildSignedOAuthParameters(const CMStringA &requestParameters, const CMStringA &url, const CMStringA &httpMethod, const CMStringA &postData);
 +	CMStringA BuildSignedOAuthParameters(const CMStringA &requestParameters, const CMStringA &url, const char *httpMethod, const char *postData);
  	CMStringA OAuthCreateNonce();
  	CMStringA OAuthCreateSignature(const CMStringA &signatureBase, const CMStringA &consumerSecret, const CMStringA &requestTokenSecret);
 diff --git a/protocols/Twitter/src/resource.h b/protocols/Twitter/src/resource.h index ffbfaaa57c..7add011e15 100644 --- a/protocols/Twitter/src/resource.h +++ b/protocols/Twitter/src/resource.h @@ -1,6 +1,6 @@  //{{NO_DEPENDENCIES}}
  // Microsoft Visual C++ generated include file.
 -// Used by CTwitterProto.rc
 +// Used by w:\miranda-ng\protocols\Twitter\res\twitter.rc
  //
  #define IDD_TWITTERACCOUNT              101
  #define IDI_TWITTER                     102
 @@ -16,7 +16,6 @@  #define IDC_USERDETAILS                 1006
  #define IDC_MISC                        1007
  #define IDC_CHATFEED                    1008
 -#define IDC_BASEURL                     1009
  #define IDC_POLLRATE                    1010
  #define IDC_COLBACK                     1011
  #define IDC_COLTEXT                     1012
 @@ -32,7 +31,6 @@  #define IDC_PREVIEW                     1022
  #define IDC_NOSIGNONPOPUPS              1023
  #define IDC_RECONNECT                   1024
 -#define IDC_SERVER                      1025
  #define IDC_PIN                         1026
  #define IDC_GROUP                       1027
  #define IDC_USERNAME                    1028
 @@ -42,7 +40,7 @@  // 
  #ifdef APSTUDIO_INVOKED
  #ifndef APSTUDIO_READONLY_SYMBOLS
 -#define _APS_NEXT_RESOURCE_VALUE        110
 +#define _APS_NEXT_RESOURCE_VALUE        111
  #define _APS_NEXT_COMMAND_VALUE         40001
  #define _APS_NEXT_CONTROL_VALUE         1030
  #define _APS_NEXT_SYMED_VALUE           101
 diff --git a/protocols/Twitter/src/stdafx.h b/protocols/Twitter/src/stdafx.h index f7bc9d7241..239dbcb540 100644 --- a/protocols/Twitter/src/stdafx.h +++ b/protocols/Twitter/src/stdafx.h @@ -69,7 +69,6 @@ using std::map;  #define TWITTER_KEY_OAUTH_TOK_SEC    "OAuthTokenSecret"
  #define TWITTER_KEY_OAUTH_ACCESS_TOK "OAuthAccessToken"
  #define TWITTER_KEY_OAUTH_ACCESS_SEC "OAuthAccessTokenSecret"
 -#define TWITTER_KEY_BASEURL          "BaseURL"
  #define TWITTER_KEY_CHATFEED         "ChatFeed"
  #define TWITTER_KEY_POLLRATE         "PollRate"
  #define TWITTER_KEY_GROUP            "DefaultGroup"
 diff --git a/protocols/Twitter/src/twitter.cpp b/protocols/Twitter/src/twitter.cpp index 16b105ab67..2baa2110b6 100644 --- a/protocols/Twitter/src/twitter.cpp +++ b/protocols/Twitter/src/twitter.cpp @@ -37,7 +37,7 @@ bool CTwitterProto::get_info(const CMStringA &name, twitter_user *info)  	if (!info)
  		return false;
 -	auto *req = new AsyncHttpRequest(REQUEST_GET, m_szBaseUrl + "1.1/users/show/" + mir_urlEncode(name.c_str()).c_str() + ".json");
 +	auto *req = new AsyncHttpRequest(REQUEST_GET, "/users/show/" + mir_urlEncode(name) + ".json");
  	http::response resp = Execute(req);
  	if (resp.code != 200)
  		return false;
 @@ -60,7 +60,7 @@ bool CTwitterProto::get_info_by_email(const CMStringA &email, twitter_user *info  	if (!info)
  		return false;
 -	auto *req = new AsyncHttpRequest(REQUEST_GET, m_szBaseUrl + "1.1/users/show.json?email=" + mir_urlEncode(email));
 +	auto *req = new AsyncHttpRequest(REQUEST_GET, "/users/show.json?email=" + mir_urlEncode(email));
  	http::response resp = Execute(req);
  	if (resp.code != 200)
  		return false;
 @@ -80,7 +80,7 @@ bool CTwitterProto::get_info_by_email(const CMStringA &email, twitter_user *info  bool CTwitterProto::add_friend(const CMStringA &name, twitter_user &ret)
  {
 -	auto *req = new AsyncHttpRequest(REQUEST_POST, m_szBaseUrl + "1.1/friendships/create/" + mir_urlEncode(name) + ".json");
 +	auto *req = new AsyncHttpRequest(REQUEST_POST, "/friendships/create/" + mir_urlEncode(name) + ".json");
  	http::response resp = Execute(req);
  	if (resp.code != 200)
  		return false;
 @@ -104,7 +104,7 @@ bool CTwitterProto::add_friend(const CMStringA &name, twitter_user &ret)  void CTwitterProto::remove_friend(const CMStringA &name)
  {
 -	auto *req = new AsyncHttpRequest(REQUEST_POST, m_szBaseUrl + "1.1/friendships/destroy/" + mir_urlEncode(name) + ".json");
 +	auto *req = new AsyncHttpRequest(REQUEST_POST, "/friendships/destroy/" + mir_urlEncode(name) + ".json");
  	Execute(req);
  }
 @@ -114,7 +114,7 @@ void CTwitterProto::mark_read(MCONTACT hContact, const CMStringA &msgId)  	if (id.IsEmpty())
  		return;
 -	auto *req = new AsyncHttpRequest(REQUEST_POST, m_szBaseUrl + "1.1/direct_messages/mark_read.json");
 +	auto *req = new AsyncHttpRequest(REQUEST_POST, "/direct_messages/mark_read.json");
  	req << CHAR_PARAM("recipient_id", id) << CHAR_PARAM("last_read_event_id", msgId);
  	Execute(req);
  }
 @@ -124,15 +124,20 @@ void CTwitterProto::set_status(const CMStringA &text)  	if (text.IsEmpty())
  		return;
 -	auto *req = new AsyncHttpRequest(REQUEST_POST, m_szBaseUrl + "1.1/statuses/update.json");
 +	auto *req = new AsyncHttpRequest(REQUEST_POST, "/statuses/update.json");
  	req << CHAR_PARAM("status", text);
  	Execute(req);
  }
  void CTwitterProto::send_direct(const CMStringA &name, const CMStringA &text)
  {
 -	auto *req = new AsyncHttpRequest(REQUEST_POST, m_szBaseUrl + "1.1/direct_messages/events/new.json");
 -	req << CHAR_PARAM("text", text) << CHAR_PARAM("screen_name", name);
 +	auto *req = new AsyncHttpRequest(REQUEST_POST, "/direct_messages/events/new.json");
 +	JSONNode target; target.set_name("target"); target << CHAR_PARAM("recipient_id", name);
 +	JSONNode msgData; msgData.set_name("message_data"); msgData << CHAR_PARAM("text", text);
 +	JSONNode msgCreate; msgCreate.set_name("message_create"); msgCreate << msgData << target;
 +	JSONNode event; event.set_name("event"); event << CHAR_PARAM("type", "message_create") << msgCreate;	
 +	JSONNode body; body << event;
 +	req->m_szParam = body.write().c_str();
  	Execute(req);
  }
 diff --git a/protocols/Twitter/src/ui.cpp b/protocols/Twitter/src/ui.cpp index 405faaa5c5..713b90b2a0 100644 --- a/protocols/Twitter/src/ui.cpp +++ b/protocols/Twitter/src/ui.cpp @@ -19,11 +19,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #include "stdafx.h"
  #include "ui.h"
 -static const wchar_t *sites[] = {
 -	L"https://api.twitter.com/",
 -	L"https://identi.ca/api/"
 -};
 -
  INT_PTR CALLBACK first_run_dialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  {
  	CTwitterProto *proto;
 @@ -46,15 +41,6 @@ INT_PTR CALLBACK first_run_dialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM  			SetDlgItemTextA(hwndDlg, IDC_USERNAME, dbv.pszVal);
  			db_free(&dbv);
  		}
 -
 -		for (auto &it : sites)
 -			SendDlgItemMessage(hwndDlg, IDC_SERVER, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(it));
 -
 -		if (!proto->getString(TWITTER_KEY_BASEURL, &dbv)) {
 -			SetDlgItemTextA(hwndDlg, IDC_SERVER, dbv.pszVal);
 -			db_free(&dbv);
 -		}
 -		else SendDlgItemMessage(hwndDlg, IDC_SERVER, CB_SETCURSEL, 0, 0);
  		return true;
  	case WM_COMMAND:
 @@ -76,14 +62,8 @@ INT_PTR CALLBACK first_run_dialog(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM  	case WM_NOTIFY: // might be able to get rid of this bit?
  		if (reinterpret_cast<NMHDR*>(lParam)->code == PSN_APPLY) {
  			proto = reinterpret_cast<CTwitterProto*>(GetWindowLongPtr(hwndDlg, GWLP_USERDATA));
 -			char str[128];
 -			wchar_t tstr[128];
 -
 -			GetDlgItemTextA(hwndDlg, IDC_SERVER, str, _countof(str) - 1);
 -			if (str[mir_strlen(str) - 1] != '/')
 -				mir_strncat(str, "/", _countof(str) - mir_strlen(str));
 -			proto->setString(TWITTER_KEY_BASEURL, str);
 +			wchar_t tstr[128];
  			GetDlgItemText(hwndDlg, IDC_GROUP, tstr, _countof(tstr));
  			proto->setWString(TWITTER_KEY_GROUP, tstr);
 @@ -177,15 +157,6 @@ INT_PTR CALLBACK options_proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPar  		CheckDlgButton(hwndDlg, IDC_CHATFEED, proto->getByte(TWITTER_KEY_CHATFEED) ? BST_CHECKED : BST_UNCHECKED);
 -		for (auto &it : sites)
 -			SendDlgItemMessage(hwndDlg, IDC_BASEURL, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>(it));
 -
 -		if (!proto->getString(TWITTER_KEY_BASEURL, &dbv)) {
 -			SetDlgItemTextA(hwndDlg, IDC_BASEURL, dbv.pszVal);
 -			db_free(&dbv);
 -		}
 -		else SendDlgItemMessage(hwndDlg, IDC_BASEURL, CB_SETCURSEL, 0, 0);
 -
  		char pollrate_str[32];
  		mir_snprintf(pollrate_str, "%d", proto->getDword(TWITTER_KEY_POLLRATE, 80));
  		SetDlgItemTextA(hwndDlg, IDC_POLLRATE, pollrate_str);
 @@ -208,7 +179,6 @@ INT_PTR CALLBACK options_proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPar  				switch (LOWORD(wParam)) {
  				case IDC_UN:
  				case IDC_PW:
 -				case IDC_BASEURL:
  					ShowWindow(GetDlgItem(hwndDlg, IDC_RECONNECT), SW_SHOW);
  				}
  				SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
 @@ -224,11 +194,6 @@ INT_PTR CALLBACK options_proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPar  			GetDlgItemTextA(hwndDlg, IDC_UN, str, _countof(str));
  			proto->setString(TWITTER_KEY_UN, str);
 -			GetDlgItemTextA(hwndDlg, IDC_BASEURL, str, _countof(str) - 1);
 -			if (str[mir_strlen(str) - 1] != '/')
 -				mir_strncat(str, "/", _countof(str) - mir_strlen(str));
 -			proto->setString(TWITTER_KEY_BASEURL, str);
 -
  			proto->setByte(TWITTER_KEY_CHATFEED, IsDlgButtonChecked(hwndDlg, IDC_CHATFEED) != 0);
  			GetDlgItemTextA(hwndDlg, IDC_POLLRATE, str, _countof(str));
 diff --git a/protocols/Twitter/src/utility.cpp b/protocols/Twitter/src/utility.cpp index 38452f9608..3abe268171 100644 --- a/protocols/Twitter/src/utility.cpp +++ b/protocols/Twitter/src/utility.cpp @@ -22,13 +22,21 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  http::response CTwitterProto::Execute(AsyncHttpRequest *pReq)
  {
 +	if (pReq->m_szUrl[0] == '/')
 +		pReq->m_szUrl.Insert(0, TWITTER_BASE_URL);
 +
 +	bool bIsJson = false;
  	if (!pReq->m_szParam.IsEmpty()) {
  		if (pReq->requestType == REQUEST_POST) {
 -			pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
 +			if (pReq->m_szParam[0] == '{') {
 +				bIsJson = true;
 +				pReq->AddHeader("Content-Type", "application/json");
 +			}
 +			else pReq->AddHeader("Content-Type", "application/x-www-form-urlencoded");
  			pReq->AddHeader("Cache-Control", "no-cache");
  			pReq->dataLength = (int)pReq->m_szParam.GetLength();
 -			pReq->pData = pReq->m_szParam.GetBuffer();
 +			pReq->pData = pReq->m_szParam.Detach();
  		}
  		else {
  			pReq->m_szUrl.AppendChar('?');
 @@ -40,7 +48,7 @@ http::response CTwitterProto::Execute(AsyncHttpRequest *pReq)  	if (pReq->requestType == REQUEST_GET)
  		auth = OAuthWebRequestSubmit(pReq->m_szUrl, "GET", "");
  	else
 -		auth = OAuthWebRequestSubmit(pReq->m_szUrl, "POST", pReq->m_szParam);
 +		auth = OAuthWebRequestSubmit(pReq->m_szUrl, "POST", (bIsJson) ? "" : pReq->pData);
  	pReq->AddHeader("Authorization", auth);
  	pReq->szUrl = pReq->m_szUrl.GetBuffer();
 @@ -73,19 +81,19 @@ bool save_url(HNETLIBUSER hNetlib, const CMStringA &url, const CMStringW &filena  	req.szUrl = const_cast<char*>(url.c_str());
  	NLHR_PTR resp(Netlib_HttpTransaction(hNetlib, &req));
 -	if (resp) {
 -		bool success = (resp->resultCode == 200);
 -		if (success) {
 -			// Create folder if necessary
 -			CreatePathToFileW(filename);
 -
 -			// Write to file
 -			FILE *f = _wfopen(filename, L"wb");
 -			fwrite(resp->pData, 1, resp->dataLength, f);
 -			fclose(f);
 -		}
 -		return success;
 -	}
 +	if (!resp)
 +		return false;
 +	
 +	if (resp->resultCode != 200)
 +		return false;
 +	
 +	// Create folder if necessary
 +	CreatePathToFileW(filename);
 -	return false;
 +	// Write to file
 +	FILE *f = _wfopen(filename, L"wb");
 +	fwrite(resp->pData, 1, resp->dataLength, f);
 +	fclose(f);
 +	
 +	return true;
  }
  | 
