diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index bcf0af2..9760972 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -23,7 +23,7 @@ #include "Entry.hh" #include "http/Agent.hh" -#include "http/ResponseLog.hh" +// #include "http/ResponseLog.hh" #include "http/XmlResponse.hh" #include "protocol/Json.hh" #include "protocol/OAuth2.hh" @@ -97,7 +97,6 @@ Drive::Drive( OAuth2& auth ) : if ( file.Kind() != "folder" ) { Resource *p = m_state.FindFolderByHref( file.ParentHref() ) ; -Trace( "finding parent of %1%: %2%", file.Title(), (void*)p ) ; if ( file.Filename().empty() ) Log( "file \"%1%\" is a google document, ignored", file.Title() ) ; @@ -118,8 +117,8 @@ Trace( "finding parent of %1%: %2%", file.Title(), (void*)p ) ; if ( has_next ) { - http::ResponseLog log2( "second-", ".xml", &xrsp ) ; - http.Get( nss["@href"], &log2, m_http_hdr ) ; +// http::ResponseLog log2( "second-", ".xml", &xrsp ) ; + http.Get( nss["@href"], &xrsp, m_http_hdr ) ; resp = xrsp.Response() ; } } while ( has_next ) ; @@ -133,9 +132,9 @@ void Drive::SaveState() void Drive::ConstructDirTree( http::Agent *http ) { http::XmlResponse xml ; - http::ResponseLog log( "dir-", ".xml", &xml ) ; +// http::ResponseLog log( "dir-", ".xml", &xml ) ; - http->Get( feed_base + "/-/folder?max-results=10&showroot=true", &log, m_http_hdr ) ; + http->Get( feed_base + "/-/folder?max-results=10&showroot=true", &xml, m_http_hdr ) ; xml::Node resp = xml.Response() ; diff --git a/libgrive/src/drive/Resource.cc b/libgrive/src/drive/Resource.cc index d24e8d0..f1b2994 100644 --- a/libgrive/src/drive/Resource.cc +++ b/libgrive/src/drive/Resource.cc @@ -45,7 +45,10 @@ Resource::Resource() : { } -/// construct from previously serialized JSON object +/// Construct from previously serialized JSON object. The state of the +/// resource is treated as local_deleted by default. It is because the +/// state will be updated by scanning the local directory. If the state +/// is not updated during scanning, that means the resource is deleted. Resource::Resource( const Json& json, Resource *parent ) : m_entry ( json["name"].Str(), @@ -56,8 +59,11 @@ Resource::Resource( const Json& json, Resource *parent ) : DateTime( json["mtime"]["sec"].Int(), json["mtime"]["nsec"].Int() ), parent != 0 ? parent->SelfHref() : "" ), m_parent( parent ), - m_state( local_new ) + m_state( local_deleted ) { + // if the file exists in local directory, FromLocal() will mark the + // state as local_changed + FromLocal() ; } Resource::Resource( const xml::Node& entry ) : @@ -79,7 +85,6 @@ Resource::Resource( const fs::path& path ) : m_parent( 0 ), m_state ( local_new ) { - } /// Update the state according to information (i.e. Entry) from remote. This function @@ -94,12 +99,32 @@ void Resource::FromRemote( const Entry& remote ) // use mtime to check which one is more recent else { - m_state = ( remote.MTime() > m_entry.MTime() ? remote_changed : local_changed ) ; + assert( m_state == local_new || m_state == local_changed || m_state == local_deleted ) ; + + m_state = ( remote.MTime() > m_entry.MTime() ? remote_changed : m_state ) ; } m_entry = remote ; } +void Resource::FromLocal() +{ + fs::path path = Path() ; + if ( !fs::exists( path ) ) + m_state = local_deleted ; + + // to save time, compare mtime before checksum + else if ( m_entry.MTime() > os::FileMTime( path ) ) + { + if ( m_entry.MD5() == crypt::MD5( path ) ) + m_state = local_new ; + else + m_state = local_changed ; + } + else + m_state = local_changed ; +} + std::string Resource::SelfHref() const { return m_entry.SelfHref() ; diff --git a/libgrive/src/drive/Resource.hh b/libgrive/src/drive/Resource.hh index b271018..ca8de94 100644 --- a/libgrive/src/drive/Resource.hh +++ b/libgrive/src/drive/Resource.hh @@ -71,6 +71,8 @@ public : bool IsInRootTree() const ; void FromRemote( const Entry& e ) ; + void FromLocal() ; + void Sync( http::Agent *http, const http::Headers& auth ) ; void Delete( http::Agent* http, const http::Headers& auth ) ; @@ -96,6 +98,9 @@ private : /// than remote. We should upload local copy to overwrite remote. local_changed, + /// Resource deleted from local since last time grive has checked. + local_deleted, + /// Resource created in google drive, but not exist in local. /// We should download the file. remote_new, diff --git a/libgrive/src/drive/State.cc b/libgrive/src/drive/State.cc index 99582ae..c114c0a 100644 --- a/libgrive/src/drive/State.cc +++ b/libgrive/src/drive/State.cc @@ -75,11 +75,7 @@ void State::FromLocal( const fs::path& p, gr::Resource* folder ) else { Resource *c = folder->FindChild( fname ) ; - if ( c != 0 ) - { - Trace( "wow! file %1% is loaded from previous state", fname ) ; - } - else + if ( c == 0 ) { c = new Resource( i->path() ) ; folder->AddChild( c ) ; @@ -133,14 +129,12 @@ bool State::Update( const Entry& e ) { assert( !e.ParentHref().empty() ) ; - Resource *r = m_res.FindByHref( e.SelfHref() ) ; - if ( r != 0 ) + if ( Resource *res = m_res.FindByHref( e.SelfHref() ) ) { -Trace( "wow! find %1% from state file?", r->Name() ) ; + m_res.Update( res, e ) ; + return true ; } - - Resource *parent = m_res.FindByHref( e.ParentHref() ) ; - if ( parent != 0 ) + else if ( Resource *parent = m_res.FindByHref( e.ParentHref() ) ) { assert( parent->IsFolder() ) ;