From b51e5c593f15b27fd17a88fb8c967305bcdd2530 Mon Sep 17 00:00:00 2001 From: Matchman Green Date: Wed, 9 May 2012 23:52:06 +0800 Subject: [PATCH 1/3] reuse the Entry class in Collection --- libgrive/src/drive/Collection.cc | 26 ++++++++++++---------- libgrive/src/drive/Collection.hh | 9 ++++---- libgrive/src/drive/Drive.cc | 19 ++++------------ libgrive/src/drive/Entry.cc | 38 ++++++++++++++++++++++++++------ libgrive/src/drive/Entry.hh | 12 ++++++---- libgrive/src/util/DateTime.cc | 6 +++++ libgrive/src/util/DateTime.hh | 2 ++ 7 files changed, 70 insertions(+), 42 deletions(-) diff --git a/libgrive/src/drive/Collection.cc b/libgrive/src/drive/Collection.cc index 5b61817..5418601 100644 --- a/libgrive/src/drive/Collection.cc +++ b/libgrive/src/drive/Collection.cc @@ -31,8 +31,7 @@ namespace gr { Collection::Collection( const Json& entry ) : - m_title ( entry["title"]["$t"].As() ), - m_href ( entry["link"].FindInArray( "rel", "self" )["href"].As() ), + m_entry ( entry ), m_parent ( 0 ) { } @@ -40,8 +39,7 @@ Collection::Collection( const Json& entry ) : Collection::Collection( const std::string& title, const std::string& href ) : - m_title ( title ), - m_href ( href ), + m_entry ( title, href ), m_parent( 0 ) { } @@ -53,14 +51,14 @@ std::string Collection::ParentHref( const Json& entry ) node["href"].As() : std::string() ; } -const std::string& Collection::Href() const +std::string Collection::Href() const { - return m_href ; + return m_entry.SelfHref() ; } -const std::string& Collection::Title() const +std::string Collection::Title() const { - return m_title ; + return m_entry.Title() ; } const Collection* Collection::Parent() const @@ -73,6 +71,11 @@ Collection* Collection::Parent() return m_parent ; } +std::string Collection::ParentHref() const +{ + return m_entry.ParentHref() ; +} + void Collection::AddChild( Collection *child ) { assert( child != 0 ) ; @@ -98,8 +101,7 @@ bool Collection::IsCollection( const Json& entry ) void Collection::Swap( Collection& coll ) { - m_title.swap( coll.m_title ) ; - m_href.swap( coll.m_href ) ; + m_entry.Swap( coll.m_entry ) ; std::swap( m_parent, coll.m_parent ) ; m_child.swap( coll.m_child ) ; m_leaves.swap( coll.m_leaves ) ; @@ -107,7 +109,7 @@ void Collection::Swap( Collection& coll ) void Collection::CreateSubDir( const Path& prefix ) { - Path dir = prefix / m_title ; + Path dir = prefix / m_entry.Title() ; os::MakeDir( dir ) ; for ( std::vector::iterator i = m_child.begin() ; i != m_child.end() ; ++i ) @@ -126,7 +128,7 @@ void Collection::ForEachFile( Path Collection::Dir() const { assert( m_parent != this ) ; - return m_parent != 0 ? (m_parent->Dir() / m_title) : Path() ; + return m_parent != 0 ? (m_parent->Dir() / m_entry.Title()) : Path() ; } } // end of namespace diff --git a/libgrive/src/drive/Collection.hh b/libgrive/src/drive/Collection.hh index 3c785fe..9289ae2 100644 --- a/libgrive/src/drive/Collection.hh +++ b/libgrive/src/drive/Collection.hh @@ -19,6 +19,7 @@ #pragma once +#include "Entry.hh" #include "util/Function.hh" #include @@ -40,10 +41,11 @@ public : static bool IsCollection( const Json& entry ) ; static std::string ParentHref( const Json& entry ) ; - const std::string& Title() const ; - const std::string& Href() const ; + std::string Title() const ; + std::string Href() const ; const Collection* Parent() const ; Collection* Parent() ; + std::string ParentHref() const ; Path Dir() const ; void AddChild( Collection *child ) ; @@ -58,8 +60,7 @@ public : const std::string& prefix = "." ) ; private : - std::string m_title ; - std::string m_href ; + Entry m_entry ; // not owned Collection *m_parent ; diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index b65e82c..5bf2cb3 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -125,7 +125,6 @@ abc << xml.Response()["feed"] ; assert( m_coll.empty() ) ; - std::map parent_href ; while ( true ) { Json::Array entries = resp["feed"]["entry"].As() ; @@ -134,15 +133,8 @@ abc << xml.Response()["feed"] ; for ( Json::Array::const_iterator i = entries.begin() ; i != entries.end() ; ++i ) { if ( Collection::IsCollection( *i ) ) - { m_coll.push_back( Collection( *i ) ) ; - parent_href.insert( - std::make_pair( - m_coll.back().Href(), - Collection::ParentHref( *i ) ) ) ; - } } - assert( m_coll.size() == parent_href.size() ) ; Json next ; if ( !resp["feed"]["link"].FindInArray( "rel", "next", next ) ) @@ -156,14 +148,11 @@ abc << xml.Response()["feed"] ; std::sort( m_coll.begin(), m_coll.end(), SortCollectionByHref() ) ; for ( FolderListIterator i = m_coll.begin() ; i != m_coll.end() ; ++i ) { - assert( parent_href.find( i->Href() ) != parent_href.end() ) ; - std::string parent = parent_href[i->Href()] ; - - if ( parent.empty() ) + if ( i->ParentHref().empty() ) m_root.AddChild( &*i ) ; else { - FolderListIterator pit = FindFolder( parent ) ; + FolderListIterator pit = FindFolder( i->ParentHref() ) ; if ( pit != m_coll.end() ) { // it shouldn't happen, just in case @@ -193,9 +182,9 @@ void Drive::UpdateFile( const Json& entry ) Path path = Path() / file.Filename() ; // determine which folder the file belongs to - if ( !file.Parent().empty() ) + if ( !file.ParentHref().empty() ) { - FolderListIterator pit = FindFolder( file.Parent() ) ; + FolderListIterator pit = FindFolder( file.ParentHref() ) ; if ( pit != m_coll.end() ) path = pit->Dir() / file.Filename() ; } diff --git a/libgrive/src/drive/Entry.cc b/libgrive/src/drive/Entry.cc index 406e1fc..f52df34 100644 --- a/libgrive/src/drive/Entry.cc +++ b/libgrive/src/drive/Entry.cc @@ -46,6 +46,12 @@ Entry::Entry( const Json& entry ) Update( entry ) ; } +Entry::Entry( const std::string& title, const std::string& href ) : + m_title( title ), + m_self_href( href ) +{ +} + void Entry::Update( const Json& entry ) { m_title = entry["title"]["$t"].Str() ; @@ -53,8 +59,9 @@ void Entry::Update( const Json& entry ) m_filename = entry.Has("docs$suggestedFilename") ? entry["docs$suggestedFilename"]["$t"].Str() : "" ; - m_href = entry["content"]["src"].Str() ; - m_parent = Parent( entry ) ; + m_content_src = entry["content"]["src"].Str() ; + m_self_href = entry["link"].FindInArray( "rel", "self" )["href"].Str() ; + m_parent_href = Parent( entry ) ; m_server_modified = DateTime( entry["updated"]["$t"].Str() ) ; m_etag = entry["gd$etag"].Str() ; @@ -112,21 +119,21 @@ DateTime Entry::ServerModified() const return m_server_modified ; } -std::string Entry::Href() const +std::string Entry::SelfHref() const { - return m_href ; + return m_self_href ; } -std::string Entry::Parent() const +std::string Entry::ParentHref() const { - return m_parent ; + return m_parent_href ; } void Entry::Download( const Path& file, const http::Headers& auth ) const { gr::Download dl( file.Str(), Download::NoChecksum() ) ; http::Agent http ; - long r = http.Get( m_href, &dl, auth ) ; + long r = http.Get( m_content_src, &dl, auth ) ; if ( r <= 400 ) os::SetFileTime( file, m_server_modified ) ; } @@ -199,4 +206,21 @@ std::cout << root_url + "/" + m_resource_id + "?delete=true" << std::endl ; http->Custom( "DELETE", root_url + "/" + m_resource_id + "?delete=true", &str, hdr ) ; } +void Entry::Swap( Entry& e ) +{ + m_title.swap( e.m_title ) ; + m_filename.swap( e.m_filename ) ; + m_kind.swap( e.m_kind ) ; + m_server_md5.swap( e.m_server_md5 ) ; + m_etag.swap( e.m_etag ) ; + m_resource_id.swap( e.m_resource_id ) ; + + m_self_href.swap( e.m_self_href ) ; + m_parent_href.swap( e.m_parent_href ) ; + m_content_src.swap( e.m_content_src ) ; + m_upload_link.swap( e.m_upload_link ) ; + + m_server_modified.Swap( e.m_server_modified ) ; +} + } // end of namespace diff --git a/libgrive/src/drive/Entry.hh b/libgrive/src/drive/Entry.hh index 68f28b1..c199241 100644 --- a/libgrive/src/drive/Entry.hh +++ b/libgrive/src/drive/Entry.hh @@ -37,6 +37,7 @@ class Entry public : explicit Entry( const Path& file ) ; explicit Entry( const Json& entry ) ; + Entry( const std::string& title, const std::string& href ) ; std::string Title() const ; std::string Filename() const ; @@ -47,13 +48,15 @@ public : std::string ResourceID() const ; std::string ETag() const ; - std::string Href() const ; - std::string Parent() const ; + std::string SelfHref() const ; + std::string ParentHref() const ; void Download( const Path& file, const http::Headers& auth ) const ; bool Upload( std::streambuf *file, const http::Headers& auth ) ; void Delete( gr::http::Agent* http, const gr::http::Headers& auth ) ; + void Swap( Entry& e ) ; + private : void Update( const Json& entry ) ; static std::string Parent( const Json& entry ) ; @@ -66,8 +69,9 @@ private : std::string m_etag ; std::string m_resource_id ; - std::string m_href ; - std::string m_parent ; + std::string m_self_href ; + std::string m_content_src ; + std::string m_parent_href ; std::string m_upload_link ; DateTime m_server_modified ; diff --git a/libgrive/src/util/DateTime.cc b/libgrive/src/util/DateTime.cc index 76e553e..354ee8e 100644 --- a/libgrive/src/util/DateTime.cc +++ b/libgrive/src/util/DateTime.cc @@ -129,4 +129,10 @@ bool DateTime::operator<=( const DateTime& dt ) const return !( *this > dt ) ; } +void DateTime::Swap( DateTime& dt ) +{ + std::swap( m_sec, dt.m_sec ) ; + std::swap( m_nsec, dt.m_nsec ) ; +} + } // end of namespace diff --git a/libgrive/src/util/DateTime.hh b/libgrive/src/util/DateTime.hh index 0f796ec..585668e 100644 --- a/libgrive/src/util/DateTime.hh +++ b/libgrive/src/util/DateTime.hh @@ -47,6 +47,8 @@ public : bool operator<( const DateTime& dt ) const ; bool operator<=( const DateTime& dt ) const ; + void Swap( DateTime& dt ) ; + private : std::time_t m_sec ; unsigned long m_nsec ; From efaa5df229cbadb34d88384cf4ba3c51873856c9 Mon Sep 17 00:00:00 2001 From: Matchman Green Date: Thu, 10 May 2012 00:22:27 +0800 Subject: [PATCH 2/3] renamed HTTP.(hh|cc) to Agent --- libgrive/src/drive/Drive.cc | 6 +++--- libgrive/src/drive/Entry.cc | 4 ++++ libgrive/src/drive/Entry.hh | 8 +++++++- libgrive/src/http/{HTTP.cc => Agent.cc} | 2 +- libgrive/src/http/{HTTP.hh => Agent.hh} | 0 libgrive/src/protocol/OAuth2.cc | 2 +- 6 files changed, 16 insertions(+), 6 deletions(-) rename libgrive/src/http/{HTTP.cc => Agent.cc} (99%) rename libgrive/src/http/{HTTP.hh => Agent.hh} (100%) diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index 5bf2cb3..0e176c2 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -22,7 +22,7 @@ #include "CommonUri.hh" #include "Entry.hh" -#include "http/HTTP.hh" +#include "http/Agent.hh" #include "http/XmlResponse.hh" #include "protocol/Json.hh" #include "protocol/JsonResponse.hh" @@ -188,12 +188,12 @@ void Drive::UpdateFile( const Json& entry ) if ( pit != m_coll.end() ) path = pit->Dir() / file.Filename() ; } - + // compare checksum first if file exists std::ifstream ifile( path.Str().c_str(), std::ios::binary | std::ios::in ) ; if ( ifile && file.ServerMD5() == crypt::MD5(ifile.rdbuf()) ) changed = false ; - + // if the checksum is different, file is changed and we need to update if ( changed ) { diff --git a/libgrive/src/drive/Entry.cc b/libgrive/src/drive/Entry.cc index f52df34..2b12cf4 100644 --- a/libgrive/src/drive/Entry.cc +++ b/libgrive/src/drive/Entry.cc @@ -46,6 +46,10 @@ Entry::Entry( const Json& entry ) Update( entry ) ; } +Entry::Entry( const xml::Node& n ) +{ +} + Entry::Entry( const std::string& title, const std::string& href ) : m_title( title ), m_self_href( href ) diff --git a/libgrive/src/drive/Entry.hh b/libgrive/src/drive/Entry.hh index c199241..2cba2c8 100644 --- a/libgrive/src/drive/Entry.hh +++ b/libgrive/src/drive/Entry.hh @@ -21,13 +21,18 @@ #include -#include "http/HTTP.hh" +#include "http/Agent.hh" #include "util/DateTime.hh" #include namespace gr { +namespace xml +{ + class Node ; +} + class Json ; class OAuth2 ; class Path ; @@ -37,6 +42,7 @@ class Entry public : explicit Entry( const Path& file ) ; explicit Entry( const Json& entry ) ; + explicit Entry( const xml::Node& n ) ; Entry( const std::string& title, const std::string& href ) ; std::string Title() const ; diff --git a/libgrive/src/http/HTTP.cc b/libgrive/src/http/Agent.cc similarity index 99% rename from libgrive/src/http/HTTP.cc rename to libgrive/src/http/Agent.cc index 89f4787..0d352bb 100644 --- a/libgrive/src/http/HTTP.cc +++ b/libgrive/src/http/Agent.cc @@ -17,7 +17,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "HTTP.hh" +#include "Agent.hh" #include "Download.hh" #include "Exception.hh" diff --git a/libgrive/src/http/HTTP.hh b/libgrive/src/http/Agent.hh similarity index 100% rename from libgrive/src/http/HTTP.hh rename to libgrive/src/http/Agent.hh diff --git a/libgrive/src/protocol/OAuth2.cc b/libgrive/src/protocol/OAuth2.cc index 439683b..fa6cd4a 100644 --- a/libgrive/src/protocol/OAuth2.cc +++ b/libgrive/src/protocol/OAuth2.cc @@ -22,7 +22,7 @@ #include "JsonResponse.hh" #include "Json.hh" -#include "http/HTTP.hh" +#include "http/Agent.hh" // for debugging #include From 55fb39cbc14a6c231eed35327a044f7a4982124e Mon Sep 17 00:00:00 2001 From: Matchman Green Date: Thu, 10 May 2012 00:30:01 +0800 Subject: [PATCH 3/3] adding log to http agent --- libgrive/src/drive/Drive.cc | 8 ++++---- libgrive/src/drive/Drive.hh | 2 +- libgrive/src/drive/Entry.cc | 14 ++++++-------- libgrive/src/drive/Entry.hh | 4 ++-- libgrive/src/http/Agent.cc | 11 +++++++++++ libgrive/src/http/Agent.hh | 4 +++- 6 files changed, 27 insertions(+), 16 deletions(-) diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index 0e176c2..58fd943 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -71,7 +71,7 @@ Drive::Drive( OAuth2& auth ) : { if ( !Collection::IsCollection( *i ) ) { - UpdateFile( *i ) ; + UpdateFile( *i, &http ) ; } } @@ -171,7 +171,7 @@ abc << xml.Response()["feed"] ; m_root.CreateSubDir( Path() ) ; } -void Drive::UpdateFile( const Json& entry ) +void Drive::UpdateFile( const Json& entry, http::Agent *http ) { // only handle uploaded files if ( entry.Has( "docs$suggestedFilename" ) ) @@ -204,7 +204,7 @@ void Drive::UpdateFile( const Json& entry ) if ( !ifile || remote > local ) { std::cout << "downloading " << path << std::endl ; - file.Download( path, m_http_hdr ) ; + file.Download( http, path, m_http_hdr ) ; } else { @@ -212,7 +212,7 @@ std::cout << "local " << path << " is newer" << std::endl ; // re-reading the file ifile.seekg(0) ; - if ( !file.Upload( ifile.rdbuf(), m_http_hdr ) ) + if ( !file.Upload( http, ifile.rdbuf(), m_http_hdr ) ) std::cout << path << " is read only" << std::endl ; } } diff --git a/libgrive/src/drive/Drive.hh b/libgrive/src/drive/Drive.hh index 3571cbb..29befe4 100644 --- a/libgrive/src/drive/Drive.hh +++ b/libgrive/src/drive/Drive.hh @@ -45,7 +45,7 @@ public : ~Drive( ) ; private : - void UpdateFile( const Json& entry ) ; + void UpdateFile( const Json& entry, http::Agent *http ) ; void ConstructDirTree( http::Agent *http ) ; diff --git a/libgrive/src/drive/Entry.cc b/libgrive/src/drive/Entry.cc index 2b12cf4..800169a 100644 --- a/libgrive/src/drive/Entry.cc +++ b/libgrive/src/drive/Entry.cc @@ -133,16 +133,15 @@ std::string Entry::ParentHref() const return m_parent_href ; } -void Entry::Download( const Path& file, const http::Headers& auth ) const +void Entry::Download( gr::http::Agent* http, const Path& file, const http::Headers& auth ) const { gr::Download dl( file.Str(), Download::NoChecksum() ) ; - http::Agent http ; - long r = http.Get( m_content_src, &dl, auth ) ; + long r = http->Get( m_content_src, &dl, auth ) ; if ( r <= 400 ) os::SetFileTime( file, m_server_modified ) ; } -bool Entry::Upload( std::streambuf *file, const http::Headers& auth ) +bool Entry::Upload( gr::http::Agent* http, std::streambuf *file, const http::Headers& auth ) { // upload link missing means that file is read only if ( m_upload_link.empty() ) @@ -171,10 +170,9 @@ bool Entry::Upload( std::streambuf *file, const http::Headers& auth ) hdr.push_back( "Expect:" ) ; http::StringResponse str ; - http::Agent http ; - http.Put( m_upload_link, meta, &str, hdr ) ; + http->Put( m_upload_link, meta, &str, hdr ) ; - std::string uplink = http.RedirLocation() ; + std::string uplink = http->RedirLocation() ; // parse the header and find "Location" http::Headers uphdr ; @@ -182,7 +180,7 @@ bool Entry::Upload( std::streambuf *file, const http::Headers& auth ) uphdr.push_back( "Accept:" ) ; http::XmlResponse xml ; - http.Put( uplink, data, &xml, uphdr ) ; + http->Put( uplink, data, &xml, uphdr ) ; std::cout << xml.Response() << std::endl ; diff --git a/libgrive/src/drive/Entry.hh b/libgrive/src/drive/Entry.hh index 2cba2c8..4aec1dd 100644 --- a/libgrive/src/drive/Entry.hh +++ b/libgrive/src/drive/Entry.hh @@ -57,8 +57,8 @@ public : std::string SelfHref() const ; std::string ParentHref() const ; - void Download( const Path& file, const http::Headers& auth ) const ; - bool Upload( std::streambuf *file, const http::Headers& auth ) ; + void Download( gr::http::Agent* http, const Path& file, const http::Headers& auth ) const ; + bool Upload( gr::http::Agent* http, std::streambuf *file, const http::Headers& auth ) ; void Delete( gr::http::Agent* http, const gr::http::Headers& auth ) ; void Swap( Entry& e ) ; diff --git a/libgrive/src/http/Agent.cc b/libgrive/src/http/Agent.cc index 0d352bb..e7d4316 100644 --- a/libgrive/src/http/Agent.cc +++ b/libgrive/src/http/Agent.cc @@ -71,6 +71,8 @@ struct Agent::Impl CURL *curl ; std::string location ; char error[CURL_ERROR_SIZE] ; + + std::string log_prefix ; } ; Agent::Agent() : @@ -90,6 +92,15 @@ Agent::~Agent() ::curl_easy_cleanup( m_pimpl->curl ); } +void Agent::SetLogFile( const std::string& prefix ) +{ + m_pimpl->log_prefix = prefix ; +} + +std::string Agent::LogFilename() const +{ +} + std::size_t Agent::HeaderCallback( void *ptr, size_t size, size_t nmemb, Agent *pthis ) { char *str = reinterpret_cast(ptr) ; diff --git a/libgrive/src/http/Agent.hh b/libgrive/src/http/Agent.hh index a1e2f81..bf8e163 100644 --- a/libgrive/src/http/Agent.hh +++ b/libgrive/src/http/Agent.hh @@ -41,7 +41,8 @@ public : Agent() ; ~Agent() ; - // TODO: implement put from file, or some callback interface to pull data + void SetLogFile( const std::string& prefix ) ; + long Put( const std::string& url, const std::string& data, @@ -75,6 +76,7 @@ private : static std::size_t Receive( void* ptr, size_t size, size_t nmemb, Receivable *recv ) ; void SetHeader( const http::Headers& hdr ) ; + std::string LogFilename() const ; private : struct Impl ;