diff --git a/libgrive/src/drive/Collection.cc b/libgrive/src/drive/Collection.cc index 5418601..13b24e6 100644 --- a/libgrive/src/drive/Collection.cc +++ b/libgrive/src/drive/Collection.cc @@ -22,6 +22,8 @@ #include "protocol/Json.hh" #include "util/Path.hh" #include "util/OS.hh" +#include "xml/Node.hh" +#include "xml/NodeSet.hh" #include @@ -36,6 +38,11 @@ Collection::Collection( const Json& entry ) : { } +Collection::Collection( const xml::Node& entry ) : + m_entry ( entry ), + m_parent ( 0 ) +{ +} Collection::Collection( const std::string& title, const std::string& href ) : @@ -99,6 +106,12 @@ bool Collection::IsCollection( const Json& entry ) node["label"].As() == "folder" ; } +bool Collection::IsCollection( const xml::Node& entry ) +{ + return entry["category"].Find( "@scheme", "http://schemas.google.com/g/2005#kind" )["@label"].front().Value() + == "folder" ; +} + void Collection::Swap( Collection& coll ) { m_entry.Swap( coll.m_entry ) ; diff --git a/libgrive/src/drive/Collection.hh b/libgrive/src/drive/Collection.hh index 9289ae2..1908626 100644 --- a/libgrive/src/drive/Collection.hh +++ b/libgrive/src/drive/Collection.hh @@ -34,11 +34,13 @@ class Collection { public : explicit Collection( const Json& entry ) ; + explicit Collection( const xml::Node& entry ) ; Collection( const std::string& title, const std::string& href ) ; // default copy ctor & op= are fine static bool IsCollection( const Json& entry ) ; + static bool IsCollection( const xml::Node& entry ) ; static std::string ParentHref( const Json& entry ) ; std::string Title() const ; diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index e816c48..302970b 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -33,6 +33,7 @@ #include "util/OS.hh" #include "util/Path.hh" #include "xml/Node.hh" +#include "xml/NodeSet.hh" // standard C++ library #include @@ -56,19 +57,20 @@ Drive::Drive( OAuth2& auth ) : http::Agent http ; ConstructDirTree( &http ) ; - http::JsonResponse str ; - http.Get( root_url + "?alt=json&showfolders=true", &str, m_http_hdr ) ; - Json resp = str.Response() ; + http::XmlResponse xrsp ; + http::ResponseLog log( "first-", ".xml", &xrsp ) ; - Json resume_link ; - if ( resp["feed"]["link"].FindInArray( "rel", "http://schemas.google.com/g/2005#resumable-create-media", resume_link ) ) - m_resume_link = resume_link["href"].As() ; + http.Get( root_url + "?showfolders=true", &log, 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"] ; + bool has_next = false ; do { - Json::Array entries = resp["feed"]["entry"].As() ; - for ( Json::Array::iterator i = entries.begin() ; i != entries.end() ; ++i ) + xml::NodeSet entries = resp["entry"] ; + for ( xml::NodeSet::iterator i = entries.begin() ; i != entries.end() ; ++i ) { if ( !Collection::IsCollection( *i ) ) { @@ -76,13 +78,13 @@ Drive::Drive( OAuth2& auth ) : } } - Json next ; - has_next = resp["feed"]["link"].FindInArray( "rel", "next", next ) ; + xml::NodeSet nss = resp["link"].Find( "@rel", "next" ) ; + has_next = !nss.empty() ; if ( has_next ) { - http.Get( next["href"].Str(), &str, m_http_hdr ) ; - resp = str.Response() ; + http.Get( nss["@href"], &xrsp, m_http_hdr ) ; + resp = xrsp.Response() ; } } while ( has_next ) ; } @@ -117,31 +119,36 @@ void Drive::ConstructDirTree( http::Agent *http ) http::XmlResponse xml ; http::ResponseLog log( "dir-", ".xml", &xml ) ; - http->Get( root_url + "/-/folder?showroot=true&max-results=10", &log, m_http_hdr ) ; + http->Get( root_url + "/-/folder?max-results=10", &log, m_http_hdr ) ; + +// http::JsonResponse jrsp ; +// http->Get( root_url + "/-/folder?alt=json", &jrsp, m_http_hdr ) ; +// Json resp = jrsp.Response() ; + + xml::Node resp = xml.Response() ; - http::JsonResponse jrsp ; - http->Get( root_url + "/-/folder?alt=json", &jrsp, m_http_hdr ) ; - Json resp = jrsp.Response() ; - assert( m_coll.empty() ) ; while ( true ) { - Json::Array entries = resp["feed"]["entry"].As() ; + xml::NodeSet entries = resp["entry"] ; // first, get all collections from the query result - for ( Json::Array::const_iterator i = entries.begin() ; i != entries.end() ; ++i ) + for ( xml::NodeSet::iterator i = entries.begin() ; i != entries.end() ; ++i ) { if ( Collection::IsCollection( *i ) ) m_coll.push_back( Collection( *i ) ) ; } - Json next ; - if ( !resp["feed"]["link"].FindInArray( "rel", "next", next ) ) +// Json next ; +// if ( !resp["feed"]["link"].FindInArray( "rel", "next", next ) ) +// break ; + xml::NodeSet next = resp["link"].Find( "@rel", "next" ) ; + if ( next.empty() ) break ; - http->Get( next["href"].Str(), &jrsp, m_http_hdr ) ; - resp = jrsp.Response() ; + http->Get( next["@href"], &xml, m_http_hdr ) ; + resp = xml.Response() ; } // second, build up linkage between parent and child @@ -171,10 +178,10 @@ void Drive::ConstructDirTree( http::Agent *http ) m_root.CreateSubDir( Path() ) ; } -void Drive::UpdateFile( const Json& entry, http::Agent *http ) +void Drive::UpdateFile( const xml::Node& entry, http::Agent *http ) { // only handle uploaded files - if ( entry.Has( "docs$suggestedFilename" ) ) + if ( !entry["docs:suggestedFilename"].empty() ) { Entry file( entry ) ; diff --git a/libgrive/src/drive/Drive.hh b/libgrive/src/drive/Drive.hh index 29befe4..8e89ef8 100644 --- a/libgrive/src/drive/Drive.hh +++ b/libgrive/src/drive/Drive.hh @@ -30,6 +30,10 @@ namespace http { class Agent ; } +namespace xml +{ + class Node ; +} class OAuth2 ; class Json ; @@ -45,7 +49,7 @@ public : ~Drive( ) ; private : - void UpdateFile( const Json& entry, http::Agent *http ) ; + void UpdateFile( const xml::Node& entry, http::Agent *http ) ; void ConstructDirTree( http::Agent *http ) ; diff --git a/libgrive/src/drive/Entry.cc b/libgrive/src/drive/Entry.cc index 518b81e..4582621 100644 --- a/libgrive/src/drive/Entry.cc +++ b/libgrive/src/drive/Entry.cc @@ -85,7 +85,7 @@ void Entry::Update( const Json& entry ) FindInArray( "rel", "http://schemas.google.com/g/2005#resumable-edit-media", node ) ? node["href"].Str() : std::string() ; - // convert to lower case for easy comparison + // convert to lower case for easy comparison std::transform( m_server_md5.begin(), m_server_md5.end(), @@ -111,6 +111,16 @@ void Entry::Update( const xml::Node& n ) xml::NodeSet parents = n["link"].Find( "@rel", "http://schemas.google.com/docs/2007#parent" ) ; for ( xml::NodeSet::iterator i = parents.begin() ; i != parents.end() ; ++i ) m_parent_hrefs.push_back( (*i)["@href"] ) ; + + if ( !m_parent_hrefs.empty() ) + m_parent_href = m_parent_hrefs.front() ; + + // convert to lower case for easy comparison + std::transform( + m_server_md5.begin(), + m_server_md5.end(), + m_server_md5.begin(), + tolower ) ; } std::string Entry::Parent( const Json& entry ) diff --git a/libgrive/src/xml/Node.cc b/libgrive/src/xml/Node.cc index 1fe071e..a3da539 100644 --- a/libgrive/src/xml/Node.cc +++ b/libgrive/src/xml/Node.cc @@ -416,6 +416,12 @@ std::size_t Node::size() const return m_ptr->Size() ; } +NodeSet Node::Children() const +{ + assert( m_ptr != 0 ) ; + return NodeSet( begin(), end() ) ; +} + NodeSet Node::Attr() const { assert( m_ptr != 0 ) ; diff --git a/libgrive/src/xml/Node.hh b/libgrive/src/xml/Node.hh index d8c6055..aa55056 100644 --- a/libgrive/src/xml/Node.hh +++ b/libgrive/src/xml/Node.hh @@ -75,9 +75,11 @@ public : iterator begin() const ; iterator end() const ; std::size_t size() const ; + NodeSet Children() const ; NodeSet Attr() const ; std::string Attr( const std::string& attr ) const ; + bool HasAttr( const std::string& attr ) const ; private : explicit Node( Impl *impl ) ;