diff --git a/libgrive/src/drive/Resource.cc b/libgrive/src/drive/Resource.cc index ae531fb..143aea2 100644 --- a/libgrive/src/drive/Resource.cc +++ b/libgrive/src/drive/Resource.cc @@ -102,13 +102,32 @@ Resource::Resource( const fs::path& path ) : /// Update the state according to information (i.e. Entry) from remote. This function /// compares the modification time and checksum of both copies and determine which /// one is newer. -void Resource::FromRemote( const Entry& remote ) +void Resource::FromRemote( const Entry& remote, const DateTime& last_sync ) { - // sync folder is easy + fs::path path = Path() ; + + // sync folder if ( remote.Kind() == "folder" && IsFolder() ) { - Log( "folder %1% is in sync", Name(), log::verbose ) ; - m_state = sync ; + // already sync + if ( fs::is_directory( path ) ) + { + Log( "folder %1% is in sync", path, log::verbose ) ; + m_state = sync ; + } + + // remote file created after last sync, so remote is newer + else if ( remote.MTime() > last_sync ) + { + Log( "creating %1% directory", path, log::info ) ; + fs::create_directories( path ) ; + m_state = sync ; + } + else + { + Trace( "should I delete the local directory %1%?", path ) ; + m_state = local_deleted ; + } } // if checksum is equal, no need to compare the mtime @@ -118,17 +137,32 @@ void Resource::FromRemote( const Entry& remote ) m_state = sync ; } + // local not exists + else if ( !fs::exists( path ) ) + { + if ( remote.MTime() > last_sync ) + { + Trace( "new file found in remote", path ) ; + m_state = remote_new ; + } + else + { + Trace( "should I delete the local file %1%?", path ) ; + m_state = local_deleted ; + } + } + // use mtime to check which one is more recent else { - assert( m_state == local_new || m_state == local_changed || m_state == local_deleted ) ; + assert( m_state == local_new || m_state == local_changed || m_state == remote_deleted ) ; // if remote is modified if ( remote.MTime() > m_entry.MTime() ) m_state = remote_changed ; // remote also has the file, so it's not new in local - else if ( m_state == local_new || m_state == local_deleted ) + else if ( m_state == local_new || m_state == remote_deleted ) m_state = local_changed ; Log( "%1% state is %2%", Name(), m_state, log::verbose ) ; @@ -150,9 +184,11 @@ void Resource::FromLocal( const DateTime& last_sync ) else { - // assume file is local_deleted?? very strange. change it tomorrow + // if the file is not created after last sync, assume file is + // remote_deleted first, it will be updated to sync/remote_changed + // in FromRemote() DateTime mtime = os::FileMTime( path ) ; - m_state = ( mtime > last_sync ? local_new : local_deleted ) ; + m_state = ( mtime > last_sync ? local_new : remote_deleted ) ; Log( "%1% found on disk: %2%", Name(), m_state ) ; } @@ -275,6 +311,10 @@ void Resource::Sync( http::Agent *http, const http::Headers& auth ) m_state = sync ; break ; + case remote_deleted : + Log( "sync %1% deleted in remote. delete?", Path(), log::verbose ) ; + break ; + case sync : Log( "sync %1% already in sync", Path(), log::verbose ) ; break ; @@ -448,7 +488,8 @@ std::ostream& operator<<( std::ostream& os, Resource::State s ) { static const char *state[] = { - "sync", "local_new", "local_changed", "local_deleted", "remote_new", "remote_changed" + "sync", "local_new", "local_changed", "local_deleted", "remote_new", + "remote_changed", "remote_deleted" } ; assert( s >= 0 && s < Count(state) ) ; return os << state[s] ; diff --git a/libgrive/src/drive/Resource.hh b/libgrive/src/drive/Resource.hh index aad5c01..25b2299 100644 --- a/libgrive/src/drive/Resource.hh +++ b/libgrive/src/drive/Resource.hh @@ -71,7 +71,7 @@ public : bool IsInRootTree() const ; bool IsRoot() const ; - void FromRemote( const Entry& e ) ; + void FromRemote( const Entry& remote, const DateTime& last_sync ) ; void FromLocal( const DateTime& last_sync ) ; void Sync( http::Agent *http, const http::Headers& auth ) ; diff --git a/libgrive/src/drive/ResourceTree.cc b/libgrive/src/drive/ResourceTree.cc index 2dfc88f..0523ce3 100644 --- a/libgrive/src/drive/ResourceTree.cc +++ b/libgrive/src/drive/ResourceTree.cc @@ -160,11 +160,11 @@ void ResourceTree::Erase( Resource *coll ) s.erase( s.find( coll ) ) ; } -void ResourceTree::Update( Resource *coll, const Entry& e ) +void ResourceTree::Update( Resource *coll, const Entry& e, const DateTime& last_sync ) { assert( coll != 0 ) ; - coll->FromRemote( e ) ; + coll->FromRemote( e, last_sync ) ; ReInsert( coll ) ; } @@ -177,33 +177,5 @@ ResourceTree::iterator ResourceTree::end() { return m_set.get().end() ; } -/* -void ResourceTree::Read( const Json& json ) -{ - Clear() ; - - assert( m_root == 0 ) ; - m_root = new Resource ; - AddTree( m_root, json ) ; -} -void ResourceTree::AddTree( Resource *node, const Json& json ) -{ - assert( node != 0 ) ; - m_set.insert( node ) ; - - std::vector array = json["child"].AsArray() ; - for ( std::vector::iterator i = array.begin() ; i != array.end() ; ++i ) - { - Resource *c = new Resource( *i, node ) ; - node->AddChild( c ) ; - AddTree( c, *i ) ; - } -} - -Json ResourceTree::Serialize() const -{ - return m_root->Serialize() ; -} -*/ } // end of namespace diff --git a/libgrive/src/drive/ResourceTree.hh b/libgrive/src/drive/ResourceTree.hh index 9484565..b7a2344 100644 --- a/libgrive/src/drive/ResourceTree.hh +++ b/libgrive/src/drive/ResourceTree.hh @@ -81,7 +81,7 @@ public : void Insert( Resource *coll ) ; void Erase( Resource *coll ) ; - void Update( Resource *coll, const Entry& e ) ; + void Update( Resource *coll, const Entry& e, const DateTime& last_sync ) ; Resource* Root() ; const Resource* Root() const ; @@ -89,12 +89,8 @@ public : iterator begin() ; iterator end() ; -// void Read( const Json& json ) ; -// Json Serialize() const ; - private : void Clear() ; -// void AddTree( Resource *node, const Json& json ) ; private : details::Folders m_set ; diff --git a/libgrive/src/drive/State.cc b/libgrive/src/drive/State.cc index d17bb99..3a8234e 100644 --- a/libgrive/src/drive/State.cc +++ b/libgrive/src/drive/State.cc @@ -128,7 +128,7 @@ bool State::Update( const Entry& e ) if ( Resource *res = m_res.FindByHref( e.SelfHref() ) ) { - m_res.Update( res, e ) ; + m_res.Update( res, e, m_last_sync ) ; return true ; } else if ( Resource *parent = m_res.FindByHref( e.ParentHref() ) ) @@ -141,31 +141,17 @@ bool State::Update( const Entry& e ) if ( child != 0 ) { // since we are updating the ID and Href, we need to remove it and re-add it. - m_res.Update( child, e ) ; + m_res.Update( child, e, m_last_sync ) ; } // folder entry exist in google drive, but not local. we should create // the directory else if ( e.Kind() == "folder" || !e.Filename().empty() ) { - // TODO: compare the last sync time to determine which one is newer - if ( e.MTime() > m_last_sync ) - { - child = new Resource( e ) ; - parent->AddChild( child ) ; - m_res.Insert( child ) ; - - fs::path child_path = child->Path() ; - if ( child->IsFolder() && !fs::is_directory( child_path ) ) - { - Log( "creating %1% directory", child_path, log::info ) ; - fs::create_directories( child_path ) ; - } - } - else - { - Trace( "should I delete the local %1%/%2%", parent->Path(), e.Filename() ) ; - } + child = new Resource( e ) ; + parent->AddChild( child ) ; + m_res.Insert( child ) ; + m_res.Update( child, e, m_last_sync ) ; } else {