summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-02-19 12:31:20 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-02-19 12:31:20 +0300
commit46fd8bbce689895bfbaaa08d9bad73b879e17172 (patch)
tree965513d22957bad31ea5d6fb2ea8f9ea94c9cd75
parent845d6d07ee1c6c87c7dacae4f0ba0a803a5aff3d (diff)
Twitter:
- fixes #2218 (add support for private messages); - code optimization; - support for JSON requests; - fixed base url;
-rw-r--r--protocols/Twitter/res/twitter.rc23
-rw-r--r--protocols/Twitter/src/chat.cpp14
-rw-r--r--protocols/Twitter/src/connection.cpp18
-rw-r--r--protocols/Twitter/src/contacts.cpp8
-rw-r--r--protocols/Twitter/src/http.h2
-rw-r--r--protocols/Twitter/src/oauth.cpp16
-rw-r--r--protocols/Twitter/src/proto.cpp10
-rw-r--r--protocols/Twitter/src/proto.h3
-rw-r--r--protocols/Twitter/src/resource.h6
-rw-r--r--protocols/Twitter/src/stdafx.h1
-rw-r--r--protocols/Twitter/src/twitter.cpp21
-rw-r--r--protocols/Twitter/src/ui.cpp37
-rw-r--r--protocols/Twitter/src/utility.cpp42
-rw-r--r--protocols/Twitter/twitter.vcxproj3
-rw-r--r--protocols/Twitter/twitter.vcxproj.filters102
15 files changed, 182 insertions, 124 deletions
diff --git a/protocols/Twitter/res/twitter.rc b/protocols/Twitter/res/twitter.rc
index 567ea1fd01..53e79c8576 100644
--- a/protocols/Twitter/res/twitter.rc
+++ b/protocols/Twitter/res/twitter.rc
@@ -50,17 +50,15 @@ END
// Dialog
//
-IDD_TWITTERACCOUNT DIALOGEX 0, 0, 186, 134
+IDD_TWITTERACCOUNT DIALOGEX 0, 0, 186, 74
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN
- LTEXT "Server:",IDC_STATIC,0,32,53,8
- COMBOBOX IDC_SERVER,54,30,131,12,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
CONTROL "Create a new Twitter account",IDC_NEWACCOUNTLINK,
- "Hyperlink",WS_TABSTOP,0,75,174,12
- EDITTEXT IDC_GROUP,54,52,131,12,ES_AUTOHSCROLL
- LTEXT "Default group:",IDC_STATIC,0,53,54,14
+ "Hyperlink",WS_TABSTOP,6,55,174,12
+ EDITTEXT IDC_GROUP,0,36,179,12,ES_AUTOHSCROLL
+ LTEXT "Default group:",IDC_STATIC,0,26,54,9
LTEXT "Username:",IDC_STATIC,0,9,51,13
LTEXT "<Sign in to link your Twitter account>",IDC_USERNAME,55,9,122,18
END
@@ -83,8 +81,6 @@ FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
GROUPBOX "Miscellaneous options",IDC_MISC,17,14,269,82
CONTROL "Use group chat for Twitter feed",IDC_CHATFEED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,25,28,183,10
- LTEXT "Base URL:",IDC_STATIC,25,43,41,8
- COMBOBOX IDC_BASEURL,72,41,95,30,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
LTEXT "Polling rate:",IDC_STATIC,25,60,42,8
LTEXT "Once every",IDC_STATIC,72,60,40,8
EDITTEXT IDC_POLLRATE,113,58,30,14,ES_AUTOHSCROLL | ES_NUMBER
@@ -139,6 +135,7 @@ END
// remains consistent on all systems.
IDI_TWITTER ICON "twitter.ico"
+
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
@@ -191,6 +188,16 @@ END
#endif // APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// AFX_DIALOG_LAYOUT
+//
+
+IDD_TWITTERACCOUNT AFX_DIALOG_LAYOUT
+BEGIN
+ 0
+END
+
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
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;
}
diff --git a/protocols/Twitter/twitter.vcxproj b/protocols/Twitter/twitter.vcxproj
index ce6809dcde..de942094ac 100644
--- a/protocols/Twitter/twitter.vcxproj
+++ b/protocols/Twitter/twitter.vcxproj
@@ -30,4 +30,7 @@
<Project>{f6a9340e-b8d9-4c75-be30-47dc66d0abc7}</Project>
</ProjectReference>
</ItemGroup>
+ <ItemGroup>
+ <Image Include="res\twitter.ico" />
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/protocols/Twitter/twitter.vcxproj.filters b/protocols/Twitter/twitter.vcxproj.filters
index 902edc4d65..5e2b48561e 100644
--- a/protocols/Twitter/twitter.vcxproj.filters
+++ b/protocols/Twitter/twitter.vcxproj.filters
@@ -5,14 +5,110 @@
<ClInclude Include="src\*.h">
<Filter>Header Files</Filter>
</ClInclude>
- <ClCompile Include="src\*.cpp;src\*.cxx">
+ <ClCompile Include="src\connection.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="src\contacts.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\oauth.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\proto.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\StringUtil.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\theme.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\twitter.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\ui.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\utility.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\stdafx.cxx">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ResourceCompile Include="res\*.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="src\*.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="src\stdafx.cxx">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="src\*.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
<ResourceCompile Include="res\*.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
- <None Include="res\*.ico;res\*.bmp;res\*.cur">
+ </ItemGroup>
+ <ItemGroup>
+ <Image Include="res\twitter.ico">
<Filter>Resource Files</Filter>
- </None>
+ </Image>
</ItemGroup>
</Project> \ No newline at end of file