From 36b11989c21feab57daa31846533d1cb6725515b Mon Sep 17 00:00:00 2001 From: Tobias Weimer Date: Tue, 16 Oct 2012 18:41:01 +0000 Subject: Updated Twitter to version 1.0.0.2: Revision: 16 Autor: seventh.adept Datum: Dienstag, 16. Oktober 2012 15:33:18 Meldung: forgot to bump the version in version.h to 1.0.0.2 Revision: 15 Autor: seventh.adept Datum: Dienstag, 16. Oktober 2012 15:03:41 Meldung: - Updated plugin to work with API v1.1 - Made an attempt to fix truncated retweets. My work around isn't pretty and can fail, if anyone wants to help give me a yell - added comments Revision: 14 Autor: seventh.adept Datum: Donnerstag, 7. Juni 2012 15:38:40 Meldung: fixed the "&" issue in tweets version bump 1.0.0.1 git-svn-id: http://svn.miranda-ng.org/main/trunk@1960 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Twitter/res/twitter.rc | 10 ++-- protocols/Twitter/src/connection.cpp | 16 +++++-- protocols/Twitter/src/main.cpp | 2 +- protocols/Twitter/src/proto.cpp | 8 ++-- protocols/Twitter/src/twitter.cpp | 91 +++++++++++++++++++++++++++++++----- protocols/Twitter/src/twitter.h | 2 + 6 files changed, 103 insertions(+), 26 deletions(-) diff --git a/protocols/Twitter/res/twitter.rc b/protocols/Twitter/res/twitter.rc index ad75909610..9c8104c65b 100644 --- a/protocols/Twitter/res/twitter.rc +++ b/protocols/Twitter/res/twitter.rc @@ -197,8 +197,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,0 - PRODUCTVERSION 1,0,0,0 + FILEVERSION 1,0,0,2 + PRODUCTVERSION 1,0,0,2 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -214,12 +214,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "Twitter protocol plugin for Miranda NG" - VALUE "FileVersion", "1.0.0.0" + VALUE "FileVersion", "1.0.0.2" VALUE "InternalName", "twitter" - VALUE "LegalCopyright", "Copyright © 2009-2011" + VALUE "LegalCopyright", "Copyright © 2009-2012" VALUE "OriginalFilename", "twitter.dll" VALUE "ProductName", "Miranda-Twitter" - VALUE "ProductVersion", "1.0.0.0" + VALUE "ProductVersion", "1.0.0.2" END END BLOCK "VarFileInfo" diff --git a/protocols/Twitter/src/connection.cpp b/protocols/Twitter/src/connection.cpp index 488bd3e657..b7bfadfdf0 100644 --- a/protocols/Twitter/src/connection.cpp +++ b/protocols/Twitter/src/connection.cpp @@ -134,6 +134,10 @@ bool TwitterProto::NegotiateConnection() DBFreeVariant(&dbv); } + // twitter 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 + DBWriteContactSettingString(0,m_szModuleName,TWITTER_KEY_BASEURL,"https://api.twitter.com/1.1/"); if((oauthToken.size() <= 1) || (oauthTokenSecret.size() <= 1)) { // first, reset all the keys so we can start fresh @@ -419,6 +423,7 @@ struct update_avatar std::string url; }; +/* void *p should always be a struct of type update_avatar */ void TwitterProto::UpdateAvatarWorker(void *p) { if(p == 0) @@ -426,11 +431,14 @@ void TwitterProto::UpdateAvatarWorker(void *p) std::auto_ptr data( static_cast(p)); DBVARIANT dbv; + // DBGetContactSettingString returns 0 when it suceeds, so if this suceeds it will return 0, or false. + // therefore if it returns 1, or true, we want to return as there is no such user. + // as a side effect, dbv now has the username in it i think if(DBGetContactSettingTString(data->hContact,m_szModuleName,TWITTER_KEY_UN,&dbv)) return; - std::string ext = data->url.substr(data->url.rfind('.')); - std::tstring filename = GetAvatarFolder() + _T('\\') + dbv.ptszVal + (TCHAR*)_A2T(ext.c_str()); + std::string ext = data->url.substr(data->url.rfind('.')); // finds the filetype of the avatar + std::tstring filename = GetAvatarFolder() + _T('\\') + dbv.ptszVal + (TCHAR*)_A2T(ext.c_str()); // local filename and path DBFreeVariant(&dbv); PROTO_AVATAR_INFORMATIONT ai = {sizeof(ai)}; @@ -442,11 +450,11 @@ void TwitterProto::UpdateAvatarWorker(void *p) return; // lets just ignore unknown formats... if not it crashes miranda. should probably speak to borkra about this. } - _tcsncpy(ai.filename,filename.c_str(),MAX_PATH); + _tcsncpy(ai.filename,filename.c_str(),MAX_PATH); // puts the local file name in the avatar struct, to a max of 260 chars (as of now) LOG( _T("***** Updating avatar: %s"), data->url.c_str()); WaitForSingleObjectEx(avatar_lock_,INFINITE,true); - if(CallService(MS_SYSTEM_TERMINATED,0,0)) + if(CallService(MS_SYSTEM_TERMINATED,0,0)) // if miranda is shutting down... { LOG( _T("***** Terminating avatar update early: %s"),data->url.c_str()); return; diff --git a/protocols/Twitter/src/main.cpp b/protocols/Twitter/src/main.cpp index d5612be8b4..e354725dce 100644 --- a/protocols/Twitter/src/main.cpp +++ b/protocols/Twitter/src/main.cpp @@ -34,7 +34,7 @@ PLUGININFOEX pluginInfo={ "Provides basic support for Twitter protocol.", "dentist, omniwolf, Thief", "", - "© 2009-2010 dentist, 2010-2011 omniwolf and Thief", + "© 2009-2010 dentist, 2010-2012 omniwolf and Thief", "http://miranda-ng.org/", UNICODE_AWARE, //{BC09A71B-B86E-4d33-B18D-82D30451DD3C} diff --git a/protocols/Twitter/src/proto.cpp b/protocols/Twitter/src/proto.cpp index ae843d8b07..2b1e60a8f9 100644 --- a/protocols/Twitter/src/proto.cpp +++ b/protocols/Twitter/src/proto.cpp @@ -83,10 +83,10 @@ TwitterProto::TwitterProto(const char *proto_name,const TCHAR *username) //wstring ConsumerKey = L"T6XLGzrkfsJAgU59dbIjSA"; //wstring ConsumerSecret = L"xsvm2NAksjsJGw63RMWAtec3Lz5uiBusfVt48gbdKLg"; - AccessUrl = L"http://twitter.com/oauth/access_token"; - AuthorizeUrl = L"http://twitter.com/oauth/authorize?oauth_token=%s"; - RequestUrl = L"http://twitter.com/oauth/request_token?some_other_parameter=hello&another_one=goodbye#meep"; // threw in some parameters for fun, and to test UrlGetQuery - UserTimelineUrl = L"http://twitter.com/statuses/user_timeline.json"; + AccessUrl = _T("http://api.twitter.com/oauth/access_token"); + AuthorizeUrl = _T("http://api.twitter.com/oauth/authorize?oauth_token=%s"); + RequestUrl = _T("http://api.twitter.com/oauth/request_token?some_other_parameter=hello&another_one=goodbye#meep"); // threw in some parameters for fun, and to test UrlGetQuery + UserTimelineUrl = _T("http://twitter.com/statuses/user_timeline.json"); } TwitterProto::~TwitterProto() diff --git a/protocols/Twitter/src/twitter.cpp b/protocols/Twitter/src/twitter.cpp index b9a6c7242b..794959b328 100644 --- a/protocols/Twitter/src/twitter.cpp +++ b/protocols/Twitter/src/twitter.cpp @@ -78,7 +78,7 @@ static T retrieve(const js::object &o,const std::string &key,bool allow_null = f -twitter::twitter() : base_url_("https://twitter.com/") +twitter::twitter() : base_url_("https://api.twitter.com/1.1/") {} bool twitter::set_credentials(const std::string &username, const std::wstring &consumerKey, const std::wstring &consumerSecret, @@ -120,8 +120,53 @@ const std::string & twitter::get_base_url() const return base_url_; } +// this whole function is wrong i think. should be calling friends/ids, not followers +/*js::array twitter::buildFriendList() { + + INT_PTR friendCursor = -1; + js::array IDs; // an array for the userIDs. i dunno if js::array is the right thing to use..? + js::array masterIDs; // the list that contains all the users that the user follows + + std::vector friends; + + while (friendCursor != 0) { + http::response resp = slurp(base_url_ + "/1.1/followers/ids.json?cursor=" + friendCursor + "&screen_name=" + username_,http::get); + if(resp.code != 200) + throw bad_response(); + + const js::variant var = json::parse( resp.data.begin(),resp.data.end() ); // pull the data out of the http response + if(var->type() == typeid(js::object)) // make sure the parsed data is of type js::object (??) + { + const js::object &friendIDs = boost::any_cast(*var); // cast the object into the type we can use + if(friendIDs.find("error") != friendIDs.end()) // don't really know why error should be at the end here? + throw std::exception("error while parsing friendIDs object from ids.json"); + + // ok need to find out how to convert all the IDs into an array. dunno if i can magically make it happen, or + // if i will have to parse it myself and add them one by one :( + IDs = retrieve(friendIDs,"ids"); + for(js::array::const_iterator i=IDs.begin(); i!=IDs.end(); ++i) { + //LOG("friends ID: " + i); + // add array to master array + js::object one = boost::any_cast(**i); + masterIDs.push_back(one); // i don't understand this. how do we push into the array? should i just use C++ arrays (list?) and bail on boost? + } + + // now we need to pick out the cursor stuff, and keep punching IDs into the array + } + else { + throw std::exception("in buildFriendList(), return type is not js::object"); + } + } + + +}*/ + + std::vector twitter::get_friends() { + // maybe once i have the buildFriendLIst() func working.. but for now let's just get twitter working. + //js::array friendArray = buildFriendList(); + std::vector friends; http::response resp = slurp(base_url_+"statuses/friends.json",http::get); @@ -304,23 +349,45 @@ std::vector twitter::get_statuses(int count,twitter_id id) { const js::object &one = boost::any_cast(**i); const js::object &user = retrieve(one,"user"); + //size_t RTcount = retrieve(one,"retweet_count", true); // why doesn't this work?? it can't cast the output into an int even though twitter api says it's an int twitter_user u; u.username = retrieve(user,"screen_name"); - bool isTruncated = retrieve(one,"truncated"); - - if (isTruncated) { // the tweet will be truncated unless we take action. i hate you twitter API - // here we grab the "retweeted_status" um.. section? it's in here that all the info we need is - const js::object &Retweet = retrieve(one,"retweeted_status"); - const js::object &RTUser = retrieve(Retweet,"user"); - - std::string retweeteesName = retrieve(RTUser,"screen_name"); // the user that is being retweeted - std::string retweetText = retrieve(Retweet,"text"); // their tweet in all it's untruncated glory - u.status.text = "RT @" + retweeteesName + " " + retweetText; // mash it together in some format people will understand + std::string rawText = retrieve(one,"text"); + if (rawText.length() == 140) { // might be a truncated tweet + if (rawText.substr(0, 4) == "RT @") { // starting to look like a RT... + if (rawText.substr(136, 4) == " ...") { // ok this is the best I can do. it starts with "RT @", ends with " ...", and is the full 140 chars + + + //if (RTcount > 0) { // the tweet will be truncated unless we take action. i hate you twitter API + //MessageBox(NULL, L"retweeted: TRUE", L"long tweets", MB_OK); + // here we grab the "retweeted_status" um.. section? it's in here that all the info we need is + // at this point the user will get no tweets and an error popup if the tweet happens to be exactly 140 chars, start with + // "RT @", end in " ...", and notactually be a real retweet. it's possible but unlikely, wish i knew how to get + // the retweet_count variable to work :( + const js::object &Retweet = retrieve(one,"retweeted_status"); + const js::object &RTUser = retrieve(Retweet,"user"); + + std::string retweeteesName = retrieve(RTUser,"screen_name"); // the user that is being retweeted + std::string retweetText = retrieve(Retweet,"text"); // their tweet in all it's untruncated glory + u.status.text = "RT @" + retweeteesName + " " + retweetText; // mash it together in some format people will understand + } + } } else { // if it's not truncated, then the twitter API returns the native RT correctly anyway, - u.status.text = retrieve(one,"text"); // so we can just pretend it doesn't happen + + //std::string twt = retrieve(one,"text"); // no need to do this anymore, we already grabbed it above in rawText + + // ok here i'm trying some way to fix all the "&" things that are showing up + // i dunno why it's happening, so i'll just find and replace each occurance :/ + size_t pos = 0; + while((pos = rawText.find("&", pos)) != std::string::npos) { + rawText.replace(pos, 5, "&"); + pos += 1; + } + + u.status.text = rawText; // so we can just pretend it doesn't happen } u.status.id = retrieve(one,"id"); diff --git a/protocols/Twitter/src/twitter.h b/protocols/Twitter/src/twitter.h index 10c1115967..b087643ee8 100644 --- a/protocols/Twitter/src/twitter.h +++ b/protocols/Twitter/src/twitter.h @@ -85,6 +85,8 @@ public: bool get_info(const std::string &name,twitter_user *); bool get_info_by_email(const std::string &email,twitter_user *); std::vector get_friends(); + + //js::array buildFriendList(); twitter_user add_friend(const std::string &name); void remove_friend(const std::string &name); -- cgit v1.2.3