mirror of https://github.com/vitalif/grive2
should be able to detect new and deleted files correctly now
parent
8b1b388713
commit
7e5b7e0b7d
|
@ -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] ;
|
||||
|
|
|
@ -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 ) ;
|
||||
|
|
|
@ -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<ByIdentity>().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<Json> array = json["child"].AsArray() ;
|
||||
for ( std::vector<Json>::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
|
||||
|
|
|
@ -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 ;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue