summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2015-04-29 17:27:23 +0000
committerGeorge Hazan <george.hazan@gmail.com>2015-04-29 17:27:23 +0000
commitcdd84a443d08a4f5748b52b102ce17dfd267acc5 (patch)
treee2899cfeaa8f8127dd3674ec43a66f152b146b2b
parent57cc565a85d08a1fefb0035374f9e4d061500723 (diff)
twitter moved to the kernel json driver
git-svn-id: http://svn.miranda-ng.org/main/trunk@13248 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r--protocols/Twitter/src/connection.cpp12
-rw-r--r--protocols/Twitter/src/stdafx.h1
-rw-r--r--protocols/Twitter/src/tinyjson.hpp586
-rw-r--r--protocols/Twitter/src/twitter.cpp334
-rw-r--r--protocols/Twitter/src/ui.cpp14
-rw-r--r--protocols/Twitter/src/utility.cpp14
-rw-r--r--protocols/Twitter/src/utility.h6
-rw-r--r--protocols/Twitter/src/version.h2
-rw-r--r--protocols/Twitter/twitter.vcxproj.filters331
9 files changed, 140 insertions, 1160 deletions
diff --git a/protocols/Twitter/src/connection.cpp b/protocols/Twitter/src/connection.cpp
index a92ea20cc6..f40a6294f3 100644
--- a/protocols/Twitter/src/connection.cpp
+++ b/protocols/Twitter/src/connection.cpp
@@ -281,17 +281,6 @@ bool TwitterProto::NegotiateConnection()
}
}
- /* if( !db_get_s(0,m_szModuleName,TWITTER_KEY_PASS,&dbv)) {
- CallService(MS_DB_CRYPT_DECODESTRING,strlen(dbv.pszVal)+1,
- reinterpret_cast<LPARAM>(dbv.pszVal));
- pass = dbv.pszVal;
- db_free(&dbv);
- }
- else {
- ShowPopup(TranslateT("Please enter a password."));
- return false;
- }*/
-
if (!db_get_s(0, m_szModuleName, TWITTER_KEY_BASEURL, &dbv)) {
mir_cslock s(twitter_lock_);
twit_.set_base_url(dbv.pszVal);
@@ -308,7 +297,6 @@ bool TwitterProto::NegotiateConnection()
bool success;
{
mir_cslock s(twitter_lock_);
-
success = twit_.set_credentials(screenName, ConsumerKey, ConsumerSecret, oauthAccessToken, oauthAccessTokenSecret, L"", true);
}
diff --git a/protocols/Twitter/src/stdafx.h b/protocols/Twitter/src/stdafx.h
index b3ea09eaac..9c12e052fa 100644
--- a/protocols/Twitter/src/stdafx.h
+++ b/protocols/Twitter/src/stdafx.h
@@ -62,6 +62,7 @@ typedef std::basic_string<TCHAR> tstring;
#include <m_icolib.h>
#include <m_utils.h>
#include <m_hotkeys.h>
+#include <m_json.h>
#include <win2k.h>
#pragma warning(pop)
diff --git a/protocols/Twitter/src/tinyjson.hpp b/protocols/Twitter/src/tinyjson.hpp
deleted file mode 100644
index 173b6b149c..0000000000
--- a/protocols/Twitter/src/tinyjson.hpp
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * TinyJson 1.3.0
- * A Minimalistic JSON Reader Based On Boost.Spirit, Boost.Any, and Boost.Smart_Ptr.
- *
- * Copyright (c) 2008 Thomas Jansen (thomas@beef.de)
- *
- * Distributed under the Boost Software License, Version 1.0. (See accompanying
- * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- *
- * See http://blog.beef.de/projects/tinyjson/ for documentation.
- *
- * (view source with tab-size = 3)
- *
- * 16 Mar 2009 - allow root of JSON to be array (Jim Porter)
- * 29 Mar 2008 - use strict_real_p for number parsing, small cleanup (Thomas Jansen)
- * 26 Mar 2008 - made json::grammar a template (Boris Schaeling)
- * 20 Mar 2008 - optimized by using boost::shared_ptr (Thomas Jansen)
- * 29 Jan 2008 - Small bugfixes (Thomas Jansen)
- * 04 Jan 2008 - Released to the public (Thomas Jansen)
- * 13 Nov 2007 - initial release (Thomas Jansen) *
- *
- * 29 Mar 2008
- */
-
-
-#ifndef TINYJSON_HPP
-#define TINYJSON_HPP
-
-#include <boost/shared_ptr.hpp>
-#include <boost/any.hpp>
-#include <boost/spirit/include/classic_core.hpp>
-#include <boost/spirit/include/classic_loops.hpp>
-#include <boost/lexical_cast.hpp>
-
-#include <string>
-#include <stack>
-#include <utility>
-#include <deque>
-#include <map>
-
-
-namespace json
-{
- boost::spirit::classic::int_parser<long long> const
- longlong_p = boost::spirit::classic::int_parser<long long>();
-
- // ==========================================================================================================
- // === U N I C O D E _ C O N V E R T ===
- // ==========================================================================================================
-
- template< typename Char >
- struct unicodecvt
- {
- static std::basic_string< Char > convert(int iUnicode)
- {
- return std::basic_string< Char >(1, static_cast< Char >(iUnicode));
- }
- };
-
-
- // ---[ TEMPLATE SPECIALIZATION FOR CHAR ]--------------------------------------------------------------------
-
- template<>
- struct unicodecvt< char >
- {
- static std::string convert(int iUnicode)
- {
- std::string strString;
-
- if(iUnicode < 0x0080)
- {
- // character 0x0000 - 0x007f...
-
- strString.push_back(0x00 | ((iUnicode & 0x007f) >> 0));
- }
- else if(iUnicode < 0x0800)
- {
- // character 0x0080 - 0x07ff...
-
- strString.push_back(0xc0 | ((iUnicode & 0x07c0) >> 6));
- strString.push_back(0x80 | ((iUnicode & 0x003f) >> 0));
- }
- else
- {
- // character 0x0800 - 0xffff...
-
- strString.push_back(0xe0 | ((iUnicode & 0x00f000) >> 12));
- strString.push_back(0x80 | ((iUnicode & 0x000fc0) >> 6));
- strString.push_back(0x80 | ((iUnicode & 0x00003f) >> 0));
- }
-
- return strString;
- }
- };
-
-
- // ==========================================================================================================
- // === T H E J S O N G R A M M A R ===
- // ==========================================================================================================
-
- template< typename Char >
- class grammar : public boost::spirit::classic::grammar< grammar< Char > >
- {
- public:
-
- // ---[ TYPEDEFINITIONS ]---------------------------------------------------------------------------------
-
- typedef boost::shared_ptr< boost::any > variant; // pointer to a shared variant
-
- typedef std::stack< variant > stack; // a stack of json variants
- typedef std::pair< std::basic_string< Char >, variant > pair; // a pair as it appears in json
-
- typedef std::deque< variant > array; // an array of json variants
- typedef std::map< std::basic_string< Char >, variant > object; // an object with json pairs
-
- protected:
-
- // ---[ SEMANTIC ACTION: PUSH A STRING ON THE STACK (AND ENCODE AS UTF-8) ]-------------------------------
-
- struct push_string
- {
- stack & m_stack;
- push_string(stack & stack) : m_stack(stack) { }
-
- template <typename Iterator>
- void operator() (Iterator szStart, Iterator szEnd) const
- {
- // 1: skip the quotes...
-
- ++szStart;
- --szEnd;
-
- // 2: traverse through the original string and check for escape codes..
-
- std::basic_string< typename Iterator::value_type > strString;
-
- while(szStart < szEnd)
- {
- // 2.1: if it's no escape code, just append to the resulting string...
-
- if(*szStart != static_cast< typename Iterator::value_type >('\\'))
- {
- // 2.1.1: append the character...
-
- strString.push_back(*szStart);
- }
- else
- {
- // 2.1.2: otherwise, check the escape code...
-
- ++szStart;
-
- switch(*szStart)
- {
- default:
-
- strString.push_back(*szStart);
- break;
-
- case 'b':
-
- strString.push_back(static_cast< typename Iterator::value_type >('\b'));
- break;
-
- case 'f':
-
- strString.push_back(static_cast< typename Iterator::value_type >('\f'));
- break;
-
- case 'n':
-
- strString.push_back(static_cast< typename Iterator::value_type >('\n'));
- break;
-
- case 'r':
-
- strString.push_back(static_cast< typename Iterator::value_type >('\r'));
- break;
-
- case 't':
-
- strString.push_back(static_cast< typename Iterator::value_type >('\t'));
- break;
-
- case 'u':
- {
- // 2.1.2.1: convert the following hex value into an int...
-
- int iUnicode;
- std::basic_istringstream< Char >(std::basic_string< typename Iterator::value_type >(&szStart[1], 4)) >> std::hex >> iUnicode;
-
- szStart += 4;
-
- // 2.1.2.2: append the unicode int...
-
- strString.append(unicodecvt< typename Iterator::value_type >::convert(iUnicode));
- }
- }
- }
-
- // 2.2: go on with the next character...
-
- ++szStart;
- }
-
- // 3: finally, push the string on the stack...
-
- m_stack.push(variant(new boost::any(strString)));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: PUSH A REAL ON THE STACK ]-------------------------------------------------------
-
- struct push_double
- {
- stack & m_stack;
- push_double(stack & stack) : m_stack(stack) { }
-
- void operator() (double dValue) const
- {
- m_stack.push(variant(new boost::any(dValue)));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: PUSH AN INT ON THE STACK ]-------------------------------------------------------
-
- struct push_int
- {
- stack & m_stack;
- push_int(stack & stack) : m_stack(stack) { }
-
- void operator() (long long iValue) const
- {
- m_stack.push(variant(new boost::any(iValue)));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: PUSH A BOOLEAN ON THE STACK ]----------------------------------------------------
-
- struct push_boolean
- {
- stack & m_stack;
- push_boolean(stack & stack) : m_stack(stack) { }
-
- template <typename Iterator>
- void operator() (Iterator szStart, Iterator /* szEnd */ ) const
- {
- // 1: push a boolean that is "true" if the string starts with 't' and "false" otherwise...
-
- m_stack.push(variant(new boost::any(*szStart == static_cast< typename Iterator::value_type >('t'))));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: PUSH A NULL VALUE ON THE STACK ]-------------------------------------------------
-
- struct push_null
- {
- stack & m_stack;
- push_null(stack & stack) : m_stack(stack) { }
-
- template <typename Iterator>
- void operator() (Iterator /* szStart */ , Iterator /* szEnd */ ) const
- {
- m_stack.push(variant(new boost::any()));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: CREATE A "JSON PAIR" ON THE STACK ]----------------------------------------------
-
- struct create_pair
- {
- stack & m_stack;
- create_pair(stack & stack) : m_stack(stack) { }
-
- template <typename Iterator>
- void operator() (Iterator /* szStart */, Iterator /* szEnd */ ) const
- {
- // 1: get the variant from the stack...
-
- variant var = m_stack.top();
- m_stack.pop();
-
- // 2: get the name from the stack...
-
- std::basic_string< typename Iterator::value_type > strName;
-
- try
- {
- strName = boost::any_cast< std::basic_string< typename Iterator::value_type > >(*m_stack.top());
- }
- catch(boost::bad_any_cast &) { /* NOTHING */ }
-
- m_stack.pop();
-
- // 3: push a pair of both on the stack...
-
- m_stack.push(variant(new boost::any(pair(strName, var))));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: BEGIN AN ARRAY ]-----------------------------------------------------------------
-
- class array_delimiter { /* EMPTY CLASS */ };
-
- struct begin_array
- {
- stack & m_stack;
- begin_array(stack & stack) : m_stack(stack) { }
-
- template <typename Iterator>
- void operator() (Iterator /* cCharacter */) const
- {
- m_stack.push(variant(new boost::any(array_delimiter())));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: CREATE AN ARRAY FROM THE VALUES ON THE STACK ]-----------------------------------
-
- struct end_array
- {
- stack & m_stack;
- end_array(stack & stack) : m_stack(stack) { }
-
- // - -[ functional operator ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- template <typename Iterator>
- void operator() (Iterator /* cCharacter */) const
- {
- // 1: create an array object and push everything in it, that's on the stack...
-
- variant varArray(new boost::any(array()));
-
- while(!m_stack.empty())
- {
- // 1.1: get the top most variant of the stack...
-
- variant var = m_stack.top();
- m_stack.pop();
-
- // 1.2: is it the end of the array? if yes => break the loop...
-
- if(boost::any_cast< array_delimiter >(var.get()) != NULL)
- {
- break;
- }
-
- // 1.3: otherwise, add to the array...
-
- boost::any_cast< array >(varArray.get())->push_front(var);
- }
-
- // 2: finally, push the array at the end of the stack...
-
- m_stack.push(varArray);
- }
- };
-
-
- // ---[ SEMANTIC ACTION: BEGIN AN OBJECT ]----------------------------------------------------------------
-
- class object_delimiter { /* EMPTY CLASS */ };
-
- struct begin_object
- {
- stack & m_stack;
- begin_object(stack & stack) : m_stack(stack) { }
-
- template <typename Iterator>
- void operator() (Iterator /* cCharacter */) const
- {
- m_stack.push(variant(new boost::any(object_delimiter())));
- }
- };
-
-
- // ---[ SEMANTIC ACTION: CREATE AN OBJECT FROM THE VALUES ON THE STACK ]----------------------------------
-
- struct end_object
- {
- stack & m_stack;
- end_object(stack & stack) : m_stack(stack) { }
-
- template <typename Iterator>
- void operator() (Iterator /* cCharacter */) const
- {
- // 1: create an array object and push everything in it, that's on the stack...
-
- variant varObject(new boost::any(object()));
-
- while(!m_stack.empty())
- {
- // 1.1: get the top most variant of the stack...
-
- variant var = m_stack.top();
- m_stack.pop();
-
- // 1.2: is it the end of the array? if yes => break the loop...
-
- if(boost::any_cast< object_delimiter >(var.get()) != NULL)
- {
- break;
- }
-
- // 1.3: if this is not a pair, we have a problem...
-
- pair * pPair = boost::any_cast< pair >(var.get());
- if(!pPair)
- {
- /* BIG PROBLEM!! */
-
- continue;
- }
-
- // 1.4: set the child of this object...
-
- boost::any_cast< object >(varObject.get())->insert(std::make_pair(pPair->first, pPair->second));
- }
-
- // 2: finally, push the array at the end of the stack...
-
- m_stack.push(varObject);
- }
- };
-
- public:
-
- stack & m_stack;
- grammar(stack & stack) : m_stack(stack) { }
-
- // ---[ THE ACTUAL GRAMMAR DEFINITION ]-------------------------------------------------------------------
-
- template <typename SCANNER>
- class definition
- {
- boost::spirit::classic::rule< SCANNER > m_start;
- boost::spirit::classic::rule< SCANNER > m_object;
- boost::spirit::classic::rule< SCANNER > m_array;
- boost::spirit::classic::rule< SCANNER > m_pair;
- boost::spirit::classic::rule< SCANNER > m_value;
- boost::spirit::classic::rule< SCANNER > m_string;
- boost::spirit::classic::rule< SCANNER > m_number;
- boost::spirit::classic::rule< SCANNER > m_boolean;
- boost::spirit::classic::rule< SCANNER > m_null;
-
- public:
-
- boost::spirit::classic::rule< SCANNER > const & start() const { return m_start; }
-
- // - -[ create the definition ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- definition(grammar const & self)
- {
- using namespace boost::spirit::classic;
-
- // 0: JSON can either be an object or an array
-
- m_start
- = m_object
- | m_array;
-
- // 1: an object is an unordered set of pairs (seperated by commas)...
-
- m_object
- = ch_p('{') [ begin_object(self.m_stack) ] >>
- !(m_pair >> *(ch_p(',') >> m_pair)) >>
- ch_p('}') [ end_object (self.m_stack) ];
-
- // 2: an array is an ordered collection of values (seperated by commas)...
-
- m_array
- = ch_p('[') [ begin_array(self.m_stack) ] >>
- !(m_value >> *(ch_p(',') >> m_value)) >>
- ch_p(']') [ end_array (self.m_stack) ];
-
- // 3: a pair is given by a name and a value...
-
- m_pair
- = ( m_string >> ch_p(':') >> m_value )
- [ create_pair(self.m_stack) ]
- ;
-
- // 4: a value can be a string in double quotes, a number, a boolean, an object or an array.
-
- m_value
- = m_string
- | m_number
- | m_object
- | m_array
- | m_boolean
- | m_null
- ;
-
- // 5: a string is a collection of zero or more unicode characters, wrapped in double quotes...
-
- m_string
- = lexeme_d
- [
- ( ch_p('"') >> *(
- ( (anychar_p - (ch_p('"') | ch_p('\\')))
- | ch_p('\\') >>
- ( ch_p('\"')
- | ch_p('\\')
- | ch_p('/')
- | ch_p('b')
- | ch_p('f')
- | ch_p('n')
- | ch_p('r')
- | ch_p('t')
- | (ch_p('u') >> repeat_p(4)[ xdigit_p ])
- )
- )) >> ch_p('"')
- )
- [ push_string(self.m_stack) ]
- ]
- ;
-
- // 6: a number is very much like a C or java number...
-
- m_number
- = strict_real_p [ push_double(self.m_stack) ]
- | longlong_p [ push_int (self.m_stack) ]
- ;
-
- // 7: a boolean can be "true" or "false"...
-
- m_boolean
- = ( str_p("true")
- | str_p("false")
- )
- [ push_boolean(self.m_stack) ]
- ;
-
- // 8: finally, a value also can be a 'null', i.e. an empty item...
-
- m_null
- = str_p("null")
- [ push_null(self.m_stack) ]
- ;
- }
- };
- };
-
-
- // ==========================================================================================================
- // === T H E F I N A L P A R S I N G R O U T I N E ===
- // ==========================================================================================================
-
- template <typename Iterator>
- typename json::grammar< typename Iterator::value_type >::variant parse(Iterator const & szFirst, Iterator const & szEnd)
- {
- // 1: parse the input...
-
- json::grammar< typename Iterator::value_type >::stack st;
- json::grammar< typename Iterator::value_type > gr(st);
-
- boost::spirit::classic::parse_info<Iterator> pi = boost::spirit::classic::parse(szFirst, szEnd, gr, boost::spirit::classic::space_p);
-
- // 2: skip any spaces at the end of the parsed section...
-
- while((pi.stop != szEnd) && (*pi.stop == static_cast< typename Iterator::value_type >(' ')))
- {
- ++pi.stop;
- }
-
- // 3: if the input's end wasn't reached or if there is more than one object on the stack => cancel...
-
- if((pi.stop != szEnd) || (st.size() != 1))
- {
- return json::grammar< typename Iterator::value_type >::variant(new boost::any());
- }
-
- // 4: otherwise, return the result...
-
- return st.top();
- }
-};
-
-
-#endif // TINYJSON_HPP
diff --git a/protocols/Twitter/src/twitter.cpp b/protocols/Twitter/src/twitter.cpp
index 1a762ec08d..06ac5f8792 100644
--- a/protocols/Twitter/src/twitter.cpp
+++ b/protocols/Twitter/src/twitter.cpp
@@ -18,57 +18,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
#include "twitter.h"
-
-#include "tinyjson.hpp"
-#include <boost/lexical_cast.hpp>
-
-typedef json::grammar<char> js;
+#include "utility.h"
// utility functions
-template <typename T>
-static T cast_and_decode(boost::any &a, bool allow_null)
-{
- if (allow_null && a.type() == typeid(void))
- return T();
- return boost::any_cast<T>(a);
-}
-
-template <>
-static std::string cast_and_decode<std::string>(boost::any &a, bool allow_null)
-{
- if (allow_null && a.type() == typeid(void))
- return std::string();
- std::string s = boost::any_cast<std::string>(a);
-
- // Twitter *only* encodes < and >, so decode them
- size_t off;
- while ((off = s.find("&lt;")) != std::string::npos)
- s.replace(off, 4, "<");
- while ((off = s.find("&gt;")) != std::string::npos)
- s.replace(off, 4, ">");
-
- return s;
-}
-
-template <typename T>
-static T retrieve(const js::object &o, const std::string &key, bool allow_null = false)
-{
- using boost::any_cast;
-
- js::object::const_iterator i = o.find(key);
- if (i == o.end())
- throw std::exception(("unable to retrieve key '" + key + "'").c_str());
- try {
- return cast_and_decode<T>(*i->second, allow_null);
- }
- catch (const boost::bad_any_cast &) {
- throw std::exception(("unable to cast key '" + key + "' to target type").c_str());
- }
-}
-
-
-
twitter::twitter() : base_url_("https://api.twitter.com/")
{}
@@ -113,85 +66,39 @@ 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<twitter_user> 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<js::object>(*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<js::array>(friendIDs,"ids");
- for(js::array::const_iterator i=IDs.begin(); i!=IDs.end(); ++i) {
- //debugLogA("friends ID: " + i);
- // add array to master array
- js::object one = boost::any_cast<js::object>(**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_user> 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<twitter_user> friends;
http::response resp = slurp(base_url_ + "1.1/statuses/friends.json", http::get);
if (resp.code != 200)
throw bad_response();
- const js::variant var = json::parse(resp.data.begin(), resp.data.end());
- if (var->type() != typeid(js::array))
+ JSONNODE *root = json_parse(resp.data.c_str());
+ if (root == NULL)
throw std::exception("unable to parse response");
- const js::array &list = boost::any_cast<js::array>(*var);
- for (js::array::const_iterator i = list.begin(); i != list.end(); ++i) {
- if ((*i)->type() == typeid(js::object)) {
- const js::object &one = boost::any_cast<js::object>(**i);
+ JSONNODE *nodes = json_as_array(root);
+ for (int i = 0;; i++) {
+ JSONNODE *pNode = json_at(nodes, i);
+ if (pNode == NULL)
+ break;
- twitter_user user;
- user.username = retrieve<std::string>(one, "screen_name");
- user.real_name = retrieve<std::string>(one, "name", true);
- user.profile_image_url = retrieve<std::string>(one, "profile_image_url", true);
+ twitter_user user;
+ user.username = json_as_pstring(json_get(pNode, "screen_name"));
+ user.real_name = json_as_pstring(json_get(pNode, "name"));
+ user.profile_image_url = json_as_pstring(json_get(pNode, "profile_image_url"));
- if (one.find("status") != one.end()) {
- js::object &status = retrieve<js::object>(one, "status");
- user.status.text = retrieve<std::string>(status, "text");
+ JSONNODE *pStatus = json_get(pNode, "status");
+ if (pStatus != NULL) {
+ user.status.text = json_as_pstring(json_get(pStatus, "text"));
+ user.status.id = json_as_int(json_get(pStatus, "id"));
- user.status.id = retrieve<long long>(status, "id");
-
- std::string timestr = retrieve<std::string>(status, "created_at");
- user.status.time = parse_time(timestr);
- }
-
- friends.push_back(user);
+ std::string timestr = json_as_pstring(json_get(pStatus, "created_at"));
+ user.status.time = parse_time(timestr);
}
+
+ friends.push_back(user);
}
return friends;
@@ -208,20 +115,17 @@ bool twitter::get_info(const std::string &name, twitter_user *info)
if (resp.code != 200)
throw bad_response();
- const js::variant var = json::parse(resp.data.begin(), resp.data.end());
- if (var->type() == typeid(js::object)) {
- const js::object &user_info = boost::any_cast<js::object>(*var);
- if (user_info.find("error") != user_info.end())
- return false;
-
- info->username = retrieve<std::string>(user_info, "screen_name");
- info->real_name = retrieve<std::string>(user_info, "name", true);
- info->profile_image_url = retrieve<std::string>(user_info, "profile_image_url", true);
+ JSONNODE *root = json_parse(resp.data.c_str());
+ if (root == NULL)
+ return false;
- return true;
- }
- else
+ if (json_get(root, "error") != NULL)
return false;
+
+ info->username = json_as_pstring(json_get(root, "screen_name"));
+ info->real_name = json_as_pstring(json_get(root, "name"));
+ info->profile_image_url = json_as_pstring(json_get(root, "profile_image_url"));
+ return true;
}
bool twitter::get_info_by_email(const std::string &email, twitter_user *info)
@@ -235,44 +139,40 @@ bool twitter::get_info_by_email(const std::string &email, twitter_user *info)
if (resp.code != 200)
throw bad_response();
- js::variant var = json::parse(resp.data.begin(), resp.data.end());
- if (var->type() == typeid(js::object)) {
- const js::object &user_info = boost::any_cast<js::object>(*var);
- if (user_info.find("error") != user_info.end())
- return false;
-
- info->username = retrieve<std::string>(user_info, "screen_name");
- info->real_name = retrieve<std::string>(user_info, "name", true);
- info->profile_image_url = retrieve<std::string>(user_info, "profile_image_url", true);
+ JSONNODE *root = json_parse(resp.data.c_str());
+ if (root == NULL)
+ return false;
- return true;
- }
- else
+ if (json_get(root, "error") != NULL)
return false;
+
+ info->username = json_as_pstring(json_get(root, "screen_name"));
+ info->real_name = json_as_pstring(json_get(root, "name"));
+ info->profile_image_url = json_as_pstring(json_get(root, "profile_image_url"));
+ return true;
}
twitter_user twitter::add_friend(const std::string &name)
{
std::string url = base_url_ + "1.1/friendships/create/" + http::url_encode(name) + ".json";
- twitter_user ret;
http::response resp = slurp(url, http::post);
if (resp.code != 200)
throw bad_response();
- js::variant var = json::parse(resp.data.begin(), resp.data.end());
- if (var->type() != typeid(js::object))
+ JSONNODE *root = json_parse(resp.data.c_str());
+ if (root == NULL)
throw std::exception("unable to parse response");
- const js::object &user_info = boost::any_cast<js::object>(*var);
- ret.username = retrieve<std::string>(user_info, "screen_name");
- ret.real_name = retrieve<std::string>(user_info, "name", true);
- ret.profile_image_url = retrieve<std::string>(user_info, "profile_image_url", true);
-
- if (user_info.find("status") != user_info.end()) {
- // TODO: fill in more fields
- const js::object &status = retrieve<js::object>(user_info, "status");
- ret.status.text = retrieve<std::string>(status, "text");
+ twitter_user ret;
+ ret.username = json_as_pstring(json_get(root, "screen_name"));
+ ret.real_name = json_as_pstring(json_get(root, "name"));
+ ret.profile_image_url = json_as_pstring(json_get(root, "profile_image_url"));
+
+ JSONNODE *pStatus = json_get(root, "status");
+ if (pStatus != NULL) {
+ ret.status.text = json_as_pstring(json_get(pStatus, "text"));
+ ret.status.id = json_as_int(json_get(pStatus, "id"));
}
return ret;
@@ -307,70 +207,67 @@ void twitter::send_direct(const std::string &name, const std::string &text)
std::vector<twitter_user> twitter::get_statuses(int count, twitter_id id)
{
- using boost::lexical_cast;
std::vector<twitter_user> statuses;
std::string url = base_url_ + "1.1/statuses/home_timeline.json?count=" +
- lexical_cast<std::string>(count);
+ int2str(count);
if (id != 0)
- url += "&since_id=" + boost::lexical_cast<std::string>(id);
+ url += "&since_id=" + int2str(id);
http::response resp = slurp(url, http::get);
if (resp.code != 200)
throw bad_response();
- js::variant var = json::parse(resp.data.begin(), resp.data.end());
- if (var->type() != typeid(js::array))
+ JSONNODE *root = json_parse(resp.data.c_str());
+ if (root == NULL)
throw std::exception("unable to parse response");
- const js::array &list = boost::any_cast<js::array>(*var);
- for (js::array::const_iterator i = list.begin(); i != list.end(); ++i) {
- if ((*i)->type() == typeid(js::object)) {
- const js::object &one = boost::any_cast<js::object>(**i);
- const js::object &user = retrieve<js::object>(one, "user");
-
- twitter_user u;
- u.username = retrieve<std::string>(user, "screen_name");
- u.profile_image_url = retrieve<std::string>(user, "profile_image_url");
-
- // the tweet will be truncated unless we take action. i hate you twitter API
- if (one.find("retweeted_status") != one.end()) {
- //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<js::object>(one, "retweeted_status");
- const js::object &RTUser = retrieve<js::object>(Retweet, "user");
-
- std::string retweeteesName = retrieve<std::string>(RTUser, "screen_name"); // the user that is being retweeted
- std::string retweetText = retrieve<std::string>(Retweet, "text"); // their tweet in all it's untruncated glory
-
- // fix "&amp;" in the tweets :(
- for (size_t pos = 0; (pos = retweetText.find("&amp;", pos)) != std::string::npos; pos++) {
- retweetText.replace(pos, 5, "&");
- }
-
- 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,
- std::string rawText = retrieve<std::string>(one, "text");
- // ok here i'm trying some way to fix all the "&amp;" things that are showing up
- // i dunno why it's happening, so i'll just find and replace each occurance :/
- for (size_t pos = 0; (pos = rawText.find("&amp;", pos)) != std::string::npos; pos++) {
- rawText.replace(pos, 5, "&");
- }
-
- u.status.text = rawText;
- }
-
- u.status.id = retrieve<long long>(one, "id");
- std::string timestr = retrieve<std::string>(one, "created_at");
- u.status.time = parse_time(timestr);
-
- statuses.push_back(u);
+ JSONNODE *pNodes = json_as_array(root);
+ for (int i = 0;; i++) {
+ JSONNODE *pNode = json_at(pNodes, i);
+ if (pNode == NULL)
+ break;
+
+ JSONNODE *pUser = json_get(pNode, "user");
+
+ twitter_user u;
+ u.username = json_as_pstring(json_get(pUser, "screen_name"));
+ u.profile_image_url = json_as_pstring(json_get(pUser, "profile_image_url"));
+
+ // the tweet will be truncated unless we take action. i hate you twitter API
+ JSONNODE *pStatus = json_get(pNode, "retweeted_status");
+ if (pStatus != NULL) {
+ // 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 :(
+ JSONNODE *pUser2 = json_get(pStatus, "user");
+
+ std::string retweeteesName = json_as_pstring(json_get(pUser2, "screen_name")); // the user that is being retweeted
+ std::string retweetText = json_as_pstring(json_get(pUser2, "text")); // their tweet in all it's untruncated glory
+
+ // fix "&amp;" in the tweets :(
+ for (size_t pos = 0; (pos = retweetText.find("&amp;", pos)) != std::string::npos; pos++)
+ retweetText.replace(pos, 5, "&");
+
+ 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,
+ std::string rawText = json_as_pstring(json_get(pNode, "text"));
+ // ok here i'm trying some way to fix all the "&amp;" things that are showing up
+ // i dunno why it's happening, so i'll just find and replace each occurance :/
+ for (size_t pos = 0; (pos = rawText.find("&amp;", pos)) != std::string::npos; pos++)
+ rawText.replace(pos, 5, "&");
+
+ u.status.text = rawText;
}
+
+ u.status.id = json_as_int(json_get(pNode, "id"));
+ std::string timestr = json_as_pstring(json_get(pNode, "created_at"));
+ u.status.time = parse_time(timestr);
+
+ statuses.push_back(u);
}
@@ -383,31 +280,30 @@ std::vector<twitter_user> twitter::get_direct(twitter_id id)
std::string url = base_url_ + "1.1/direct_messages.json";
if (id != 0)
- url += "?since_id=" + boost::lexical_cast<std::string>(id);
+ url += "?since_id=" + int2str(id);
http::response resp = slurp(url, http::get);
if (resp.code != 200)
throw bad_response();
- js::variant var = json::parse(resp.data.begin(), resp.data.end());
- if (var->type() != typeid(js::array))
+ JSONNODE *root = json_parse(resp.data.c_str());
+ if (root == NULL)
throw std::exception("unable to parse response");
- const js::array &list = boost::any_cast<js::array>(*var);
- for (js::array::const_iterator i = list.begin(); i != list.end(); ++i) {
- if ((*i)->type() == typeid(js::object)) {
- const js::object &one = boost::any_cast<js::object>(**i);
-
- twitter_user u;
- u.username = retrieve<std::string>(one, "sender_screen_name");
+ JSONNODE *pNodes = json_as_array(root);
+ for (int i = 0;; i++) {
+ JSONNODE *pNode = json_at(pNodes, i);
+ if (pNode == NULL)
+ break;
- u.status.text = retrieve<std::string>(one, "text");
- u.status.id = retrieve<long long>(one, "id");
- std::string timestr = retrieve<std::string>(one, "created_at");
- u.status.time = parse_time(timestr);
+ twitter_user u;
+ u.username = json_as_pstring(json_get(pNode, "sender_screen_name"));
- messages.push_back(u);
- }
+ u.status.text = json_as_pstring(json_get(pNode, "text"));
+ u.status.id = json_as_int(json_get(pNode, "id"));
+ std::string timestr = json_as_pstring(json_get(pNode, "created_at"));
+ u.status.time = parse_time(timestr);
+ messages.push_back(u);
}
return messages;
@@ -422,8 +318,8 @@ string twitter::urlencode(const string &c)
if ((48 <= c[i] && c[i] <= 57) ||//0-9
(65 <= c[i] && c[i] <= 90) ||//ABC...XYZ
(97 <= c[i] && c[i] <= 122) || //abc...xyz
- (c[i] == '~' || c[i] == '-' || c[i] == '_' || c[i] == '.')
- ) {
+ (c[i] == '~' || c[i] == '-' || c[i] == '_' || c[i] == '.'))
+ {
escaped.append(&c[i], 1);
}
else {
diff --git a/protocols/Twitter/src/ui.cpp b/protocols/Twitter/src/ui.cpp
index c9b78db00f..de33178bbd 100644
--- a/protocols/Twitter/src/ui.cpp
+++ b/protocols/Twitter/src/ui.cpp
@@ -229,16 +229,12 @@ INT_PTR CALLBACK options_proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPar
GetDlgItemTextA(hwndDlg, IDC_UN, str, SIZEOF(str));
db_set_s(0, proto->ModuleName(), TWITTER_KEY_UN, str);
- /*GetDlgItemTextA(hwndDlg,IDC_PW,str,SIZEOF(str));
- CallService(MS_DB_CRYPT_ENCODESTRING,sizeof(str),reinterpret_cast<LPARAM>(str));
- db_set_s(0,proto->ModuleName(),TWITTER_KEY_PASS,str);*/
-
GetDlgItemTextA(hwndDlg, IDC_BASEURL, str, SIZEOF(str) - 1);
if (str[strlen(str) - 1] != '/')
strncat(str, "/", sizeof(str));
db_set_s(0, proto->ModuleName(), TWITTER_KEY_BASEURL, str);
- db_set_b(0, proto->ModuleName(), TWITTER_KEY_CHATFEED, IsDlgButtonChecked(hwndDlg, IDC_CHATFEED));
+ db_set_b(0, proto->ModuleName(), TWITTER_KEY_CHATFEED, IsDlgButtonChecked(hwndDlg, IDC_CHATFEED) != 0);
GetDlgItemTextA(hwndDlg, IDC_POLLRATE, str, SIZEOF(str));
int rate = atoi(str);
@@ -246,7 +242,7 @@ INT_PTR CALLBACK options_proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPar
rate = 80;
db_set_dw(0, proto->ModuleName(), TWITTER_KEY_POLLRATE, rate);
- db_set_b(0, proto->ModuleName(), TWITTER_KEY_TWEET_TO_MSG, IsDlgButtonChecked(hwndDlg, IDC_TWEET_MSG));
+ db_set_b(0, proto->ModuleName(), TWITTER_KEY_TWEET_TO_MSG, IsDlgButtonChecked(hwndDlg, IDC_TWEET_MSG) != 0);
proto->UpdateSettings();
return true;
@@ -275,7 +271,7 @@ namespace popup_options
{
if (IsDlgButtonChecked(hwndDlg, IDC_COL_WINDOWS)) {
if (for_db)
- return -1;
+ return (COLORREF)-1;
else
return GetSysColor(COLOR_WINDOWTEXT);
}
@@ -289,7 +285,7 @@ namespace popup_options
{
if (IsDlgButtonChecked(hwndDlg, IDC_COL_WINDOWS)) {
if (for_db)
- return -1;
+ return (COLORREF)-1;
else
return GetSysColor(COLOR_WINDOW);
}
@@ -449,7 +445,7 @@ INT_PTR CALLBACK popup_options_proc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARA
if (reinterpret_cast<NMHDR*>(lParam)->code == PSN_APPLY) {
proto = reinterpret_cast<TwitterProto*>(GetWindowLongPtr(hwndDlg, GWLP_USERDATA));
- db_set_b(0, proto->ModuleName(), TWITTER_KEY_POPUP_SHOW, IsDlgButtonChecked(hwndDlg, IDC_SHOWPOPUPS));
+ db_set_b(0, proto->ModuleName(), TWITTER_KEY_POPUP_SHOW, IsDlgButtonChecked(hwndDlg, IDC_SHOWPOPUPS) != 0);
db_set_b(0, proto->ModuleName(), TWITTER_KEY_POPUP_SIGNON, BST_UNCHECKED == IsDlgButtonChecked(hwndDlg, IDC_NOSIGNONPOPUPS));
// ***** Write color settings
diff --git a/protocols/Twitter/src/utility.cpp b/protocols/Twitter/src/utility.cpp
index 46e3c07d60..dcdda75a9e 100644
--- a/protocols/Twitter/src/utility.cpp
+++ b/protocols/Twitter/src/utility.cpp
@@ -26,6 +26,20 @@ std::string b64encode(const std::string &s)
return std::string(ptrA(mir_base64_encode((BYTE*)s.c_str(), (unsigned)s.length())));
}
+std::string int2str(int32_t iVal)
+{
+ char buf[100];
+ _itoa_s(iVal, buf, 10);
+ return std::string(buf);
+}
+
+std::string int2str(uint64_t iVal)
+{
+ char buf[100];
+ _i64toa_s(iVal, buf, _countof(buf), 10);
+ return std::string(buf);
+}
+
http::response mir_twitter::slurp(const std::string &url, http::method meth, OAuthParameters postParams)
{
NETLIBHTTPREQUEST req = { sizeof(req) };
diff --git a/protocols/Twitter/src/utility.h b/protocols/Twitter/src/utility.h
index fec8d6b23c..3736ca2928 100644
--- a/protocols/Twitter/src/utility.h
+++ b/protocols/Twitter/src/utility.h
@@ -23,6 +23,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
std::string b64encode(const std::string &s);
+std::string int2str(int32_t);
+std::string int2str(uint64_t);
+
class mir_twitter : public twitter
{
public:
@@ -51,8 +54,7 @@ public:
std::wstring OAuthWebRequestSubmit(
const OAuthParameters& parameters,
- const std::wstring& url
- );
+ const std::wstring& url);
std::wstring UrlGetQuery( const std::wstring& url );
diff --git a/protocols/Twitter/src/version.h b/protocols/Twitter/src/version.h
index b4ea3e65fb..9776a81b61 100644
--- a/protocols/Twitter/src/version.h
+++ b/protocols/Twitter/src/version.h
@@ -1,5 +1,5 @@
#define __MAJOR_VERSION 1
-#define __MINOR_VERSION 2
+#define __MINOR_VERSION 3
#define __RELEASE_NUM 0
#define __BUILD_NUM 1
diff --git a/protocols/Twitter/twitter.vcxproj.filters b/protocols/Twitter/twitter.vcxproj.filters
index 6e2fab6493..de5ad9f66c 100644
--- a/protocols/Twitter/twitter.vcxproj.filters
+++ b/protocols/Twitter/twitter.vcxproj.filters
@@ -1,335 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(ProjectDir)..\..\build\vc.common\common.filters" />
- <ItemGroup>
- <ClCompile Include="src\stdafx.cxx">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- <ClCompile Include="src\chat.cpp">
- <Filter>Source Files</Filter>
- </ClCompile>
- <ClCompile Include="src\connection.cpp" />
- <ClCompile Include="src\contacts.cpp" />
- <ClCompile Include="src\http.cpp" />
- <ClCompile Include="src\main.cpp" />
- <ClCompile Include="src\oauth.cpp" />
- <ClCompile Include="src\proto.cpp" />
- <ClCompile Include="src\StringUtil.cpp" />
- <ClCompile Include="src\theme.cpp" />
- <ClCompile Include="src\twitter.cpp" />
- <ClCompile Include="src\ui.cpp" />
- <ClCompile Include="src\utility.cpp" />
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="src\*.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- <ClInclude Include="src\http.h">
- <Filter>Header Files</Filter>
- </ClInclude>
- <ClInclude Include="src\oauth.dev.h" />
- <ClInclude Include="src\proto.h" />
- <ClInclude Include="src\resource.h" />
- <ClInclude Include="src\stdafx.h" />
- <ClInclude Include="src\StringUtil.h" />
- <ClInclude Include="src\theme.h" />
- <ClInclude Include="src\twitter.h" />
- <ClInclude Include="src\ui.h" />
- <ClInclude Include="src\utility.h" />
- <ClInclude Include="src\version.h" />
- </ItemGroup>
- <ItemGroup>
- <ResourceCompile Include="res\twitter.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- <ResourceCompile Include="res\version.rc" />
- <ResourceCompile Include="res\twitter.rc">
- <Filter>Resource Files</Filter>
- </ResourceCompile>
- <ResourceCompile Include="res\version.rc" />
- </ItemGroup>
</Project> \ No newline at end of file