From 53883ab8bdb487b92a0c5cf5b631af00f78db92b Mon Sep 17 00:00:00 2001 From: Matchman Green Date: Wed, 16 May 2012 00:54:58 +0800 Subject: [PATCH] move the .grive from home directory to current directory. get change stamp --- grive/src/Config.cc | 39 ++++++++++------------ grive/src/Config.hh | 3 ++ grive/src/main.cc | 6 ++-- libgrive/src/drive/CommonUri.hh | 6 ++-- libgrive/src/drive/Drive.cc | 58 +++++++++++++++------------------ libgrive/src/drive/Drive.hh | 9 ++++- libgrive/src/protocol/Json.cc | 46 ++++++++++++++++---------- libgrive/src/protocol/Json.hh | 12 ++++--- libgrive/src/protocol/OAuth2.cc | 9 +++-- 9 files changed, 103 insertions(+), 85 deletions(-) diff --git a/grive/src/Config.cc b/grive/src/Config.cc index ea9b88d..f5717d4 100644 --- a/grive/src/Config.cc +++ b/grive/src/Config.cc @@ -28,32 +28,14 @@ const std::string& Config::Filename() { static const char *env_cfg = ::getenv( "GR_CONFIG" ) ; static const std::string filename = - (env_cfg != 0) ? env_cfg : std::string( ::getenv( "HOME") ) + "/.grive" ; + (env_cfg != 0) ? env_cfg : /*std::string( ::getenv( "HOME") ) +*/ ".grive_state" ; return filename ; } -Config::Config() +Config::Config() : + m_cfg( Read( Filename() ) ) { - std::ifstream ifile( Filename().c_str() ) ; - if ( ifile ) - { - try - { - std::string cfg_str( - (std::istreambuf_iterator( ifile )), - (std::istreambuf_iterator()) ) ; - - m_cfg = Json::Parse( cfg_str ) ; - } - catch ( Exception& e ) - { - throw Error() - << File( Filename() ) - << expt::ErrMsg("Cannot open config file ") - << expt::Nested(e) ; - } - } } void Config::Save( ) @@ -67,4 +49,19 @@ Json& Config::Get() return m_cfg ; } +Json Config::Read( const std::string& filename ) +{ + try + { + return Json::ParseFile( filename ) ; + } + catch ( Exception& e ) + { + throw Error() + << File( filename ) + << expt::ErrMsg("Cannot open config file ") + << expt::Nested(e) ; + } +} + } // end of namespace diff --git a/grive/src/Config.hh b/grive/src/Config.hh index a8c0872..11188fa 100644 --- a/grive/src/Config.hh +++ b/grive/src/Config.hh @@ -37,6 +37,9 @@ public : Json& Get() ; void Save() ; +private : + Json Read( const std::string& filename ) ; + private : Json m_cfg ; } ; diff --git a/grive/src/main.cc b/grive/src/main.cc index cab2067..8c671d5 100644 --- a/grive/src/main.cc +++ b/grive/src/main.cc @@ -73,7 +73,7 @@ int main( int argc, char **argv ) // save to config config.Get().Add( "refresh_token", Json( token.RefreshToken() ) ) ; assert( config.Get()["refresh_token"].Str() == token.RefreshToken() ) ; - config.Save( ) ; + config.Save() ; break ; } @@ -113,9 +113,11 @@ int main( int argc, char **argv ) try { OAuth2 token( refresh_token, client_id, client_secret ) ; - Drive drive( token ) ; + Drive drive( token, config.Get() ) ; drive.Update() ; + + config.Save() ; } catch ( gr::Exception& e ) { diff --git a/libgrive/src/drive/CommonUri.hh b/libgrive/src/drive/CommonUri.hh index ce8ef05..d9ac0f5 100644 --- a/libgrive/src/drive/CommonUri.hh +++ b/libgrive/src/drive/CommonUri.hh @@ -23,9 +23,9 @@ namespace gr { - const std::string feed_base = "https://docs.google.com/feeds/default/private/full" ; - - const std::string feed_changes = "https://docs.google.com/feeds/default/private/changes" ; + const std::string feed_base = "https://docs.google.com/feeds/default/private/full" ; + const std::string feed_changes = "https://docs.google.com/feeds/default/private/changes" ; + const std::string feed_metadata = "https://docs.google.com/feeds/metadata/default" ; const std::string root_href = "https://docs.google.com/feeds/default/private/full/folder%3Aroot" ; diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index 503a2c2..1acecf2 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -49,54 +49,50 @@ namespace gr { -Drive::Drive( OAuth2& auth ) : - m_auth( auth ) +Drive::Drive( OAuth2& auth, const Json& state ) : + m_auth( auth ), + m_state( state ) { m_http_hdr.push_back( "Authorization: Bearer " + m_auth.AccessToken() ) ; m_http_hdr.push_back( "GData-Version: 3.0" ) ; - + + std::string prev_change_stamp ; + if ( m_state.Has( "change_stamp" ) ) + prev_change_stamp = m_state["change_stamp"].Str() ; + http::Agent http ; + http::XmlResponse xrsp ; + http.Get( feed_metadata, &xrsp, m_http_hdr ) ; + + std::string change_stamp = xrsp.Response()["docs:largestChangestamp"]["@value"] ; + Trace( "change stamp is %1%", change_stamp ) ; + + m_state.Add( "change_stamp", Json( change_stamp ) ) ; + ConstructDirTree( &http ) ; - http::XmlResponse xrsp ; - http::ResponseLog log( "first-", ".xml", &xrsp ) ; +// http::ResponseLog log( "first-", ".xml", &xrsp ) ; - std::string change_stamp ; - - std::ifstream sfile( ".grive_state" ) ; - if ( sfile ) - { - std::string state_str( - (std::istreambuf_iterator( sfile )), - (std::istreambuf_iterator()) ) ; - sfile.close() ; - - Json state = Json::Parse( state_str ) ; - change_stamp = state["change_stamp"].Str() ; - Trace( "config change stamp is %1%", change_stamp ) ; - } - - std::string uri = feed_changes + "?showfolders=true&showroot=true" ; - if ( !change_stamp.empty() ) + std::string uri = feed_base + "?showfolders=true&showroot=true" ; +/* if ( !change_stamp.empty() ) { int ichangestamp = std::atoi( change_stamp.c_str() ) + 1 ; uri = (boost::format( "%1%&start-index=%2%" ) % uri % ichangestamp ).str() ; } - - http.Get( uri, &log, m_http_hdr ) ; +*/ + http.Get( uri, &xrsp, m_http_hdr ) ; xml::Node resp = xrsp.Response() ; m_resume_link = resp["link"]. Find( "@rel", "http://schemas.google.com/g/2005#resumable-create-media" )["@href"] ; - change_stamp = resp["docs:largestChangestamp"]["@value"] ; - Trace( "change stamp is %1%", change_stamp ) ; +// change_stamp = resp["docs:largestChangestamp"]["@value"] ; - std::ofstream osfile( ".grive_state" ) ; - Json state ; - state.Add( "change_stamp", Json( change_stamp ) ) ; - osfile << state ; - osfile.close() ; +// std::ofstream osfile( ".grive_state" ) ; +// Json state ; +// state.Add( "change_stamp", Json( change_stamp ) ) ; +// osfile << state ; +// osfile.close() ; bool has_next = false ; do diff --git a/libgrive/src/drive/Drive.hh b/libgrive/src/drive/Drive.hh index 81f6768..99d708d 100644 --- a/libgrive/src/drive/Drive.hh +++ b/libgrive/src/drive/Drive.hh @@ -20,6 +20,8 @@ #pragma once #include "Collection.hh" + +#include "protocol/Json.hh" #include "util/Exception.hh" #include @@ -46,10 +48,13 @@ public : typedef std::vector::iterator FolderListIterator ; public : - Drive( OAuth2& auth ) ; + Drive( OAuth2& auth, const Json& state ) ; ~Drive( ) ; void Update() ; + void Sync() ; + + Json State() const ; struct Error : virtual Exception {} ; @@ -69,6 +74,8 @@ private : FolderList m_coll ; std::vector m_files ; + + Json m_state ; } ; } // end of namespace diff --git a/libgrive/src/protocol/Json.cc b/libgrive/src/protocol/Json.cc index 036376e..5ffb19d 100644 --- a/libgrive/src/protocol/Json.cc +++ b/libgrive/src/protocol/Json.cc @@ -19,6 +19,8 @@ #include "Json.hh" +#include "util/StdioFile.hh" + #include #include @@ -55,6 +57,27 @@ Json Json::Parse( const std::string& str ) return Json( json, NotOwned() ) ; } +Json Json::ParseFile( const std::string& filename ) +{ + StdioFile file( filename, "r" ) ; + struct json_tokener *tok = ::json_tokener_new() ; + + struct json_object *json = 0 ; + + char buf[80] ; + std::size_t count = 0 ; + + while ( (count = file.Read( buf, sizeof(buf) ) ) > 0 ) + json = ::json_tokener_parse_ex( tok, buf, count ) ; + + if ( json == 0 ) + throw Error() << expt::ErrMsg( ::json_tokener_errors[tok->err] ) ; + + ::json_tokener_free( tok ) ; + + return Json( json, NotOwned() ) ; +} + Json::Json( struct json_object *json, NotOwned ) : m_json( json ) { @@ -137,8 +160,7 @@ void Json::Add( const std::string& key, const Json& json ) ::json_object_object_add( m_json, key.c_str(), json.m_json ) ; } -template <> -bool Json::As() const +bool Json::Bool() const { assert( m_json != 0 ) ; return ::json_object_get_boolean( m_json ) ; @@ -151,8 +173,7 @@ bool Json::Is() const return ::json_object_is_type( m_json, json_type_boolean ) ; } -template <> -std::string Json::As() const +std::string Json::Str() const { assert( m_json != 0 ) ; return ::json_object_get_string( m_json ) ; @@ -165,8 +186,7 @@ bool Json::Is() const return ::json_object_is_type( m_json, json_type_string ) ; } -template <> -int Json::As() const +int Json::Int() const { assert( m_json != 0 ) ; return ::json_object_get_int( m_json ) ; @@ -191,8 +211,7 @@ Json::Type Json::DataType() const return static_cast( ::json_object_get_type( m_json ) ) ; } -template <> -Json::Object Json::As() const +Json::Object Json::AsObject() const { Object result ; @@ -211,8 +230,7 @@ bool Json::Is() const return ::json_object_is_type( m_json, json_type_object ) ; } -template <> -Json::Array Json::As() const +Json::Array Json::AsArray() const { std::size_t count = ::json_object_array_length( m_json ) ; Array result ; @@ -237,7 +255,7 @@ Json Json::FindInArray( const std::string& key, const std::string& value ) const for ( std::size_t i = 0 ; i < count ; ++i ) { Json item( ::json_object_array_get_idx( m_json, i ) ) ; - if ( item.Has(key) && item[key].As() == value ) + if ( item.Has(key) && item[key].Str() == value ) return item ; } throw Error() << expt::ErrMsg( "cannot find " + key + " = " + value + " in array" ) ; @@ -256,10 +274,4 @@ bool Json::FindInArray( const std::string& key, const std::string& value, Json& } } -std::string Json::Str() const -{ - return As() ; -} - - } diff --git a/libgrive/src/protocol/Json.hh b/libgrive/src/protocol/Json.hh index 0755209..d9f4066 100644 --- a/libgrive/src/protocol/Json.hh +++ b/libgrive/src/protocol/Json.hh @@ -46,18 +46,20 @@ public : ~Json( ) ; static Json Parse( const std::string& str ) ; + static Json ParseFile( const std::string& filename ) ; Json operator[]( const std::string& key ) const ; Json operator[]( const std::size_t& idx ) const ; Json& operator=( const Json& rhs ) ; void Swap( Json& other ) ; - - template - T As() const ; - - // As() shortcut + std::string Str() const ; + int Int() const ; + double Double() const ; + bool Bool() const ; + Array AsArray() const ; + Object AsObject() const ; template bool Is() const ; diff --git a/libgrive/src/protocol/OAuth2.cc b/libgrive/src/protocol/OAuth2.cc index fa6cd4a..a2e3b78 100644 --- a/libgrive/src/protocol/OAuth2.cc +++ b/libgrive/src/protocol/OAuth2.cc @@ -65,8 +65,8 @@ void OAuth2::Auth( const std::string& auth_code ) http.Post( token_url, post, &resp ) ; Json jresp = resp.Response() ; - m_access = jresp["access_token"].As() ; - m_refresh = jresp["refresh_token"].As() ; + m_access = jresp["access_token"].Str() ; + m_refresh = jresp["refresh_token"].Str() ; } std::string OAuth2::MakeAuthURL( @@ -81,8 +81,7 @@ std::string OAuth2::MakeAuthURL( h.Escape( "https://www.googleapis.com/auth/userinfo.profile" ) + "+" + h.Escape( "https://docs.google.com/feeds/" ) + "+" + h.Escape( "https://docs.googleusercontent.com/" ) + "+" + - h.Escape( "https://spreadsheets.google.com/feeds/" ) + /*"+" + - h.Escape( "https://www.googleapis.com/auth/drive.file/" ) +*/ + h.Escape( "https://spreadsheets.google.com/feeds/" ) + "&redirect_uri=urn:ietf:wg:oauth:2.0:oob" "&response_type=code" "&client_id=" + client_id ; @@ -101,7 +100,7 @@ void OAuth2::Refresh( ) http.Post( token_url, post, &resp ) ; - m_access = resp.Response()["access_token"].As() ; + m_access = resp.Response()["access_token"].Str() ; } std::string OAuth2::RefreshToken( ) const