no need to check MD5 or mtime for folders

pull/40/head
Matchman Green 2012-05-27 22:49:49 +08:00
parent e09bdc5a8a
commit 729ec106f8
8 changed files with 59 additions and 22 deletions

View File

@ -121,7 +121,7 @@ int main( int argc, char **argv )
{
OAuth2 token( refresh_token, client_id, client_secret ) ;
Drive drive( token ) ;
drive.Update() ;
drive.SaveState() ;

View File

@ -98,14 +98,14 @@ Drive::Drive( OAuth2& auth ) :
{
Resource *parent = m_state.FindByHref( entry.ParentHref() ) ;
if ( entry.Filename().empty() )
Log( "file \"%1%\" is a google document, ignored", entry.Title(), log::info ) ;
Log( "file \"%1%\" is a google document, ignored", entry.Title(), log::verbose ) ;
else if ( parent == 0 || !parent->IsInRootTree() )
Log( "file \"%1%\" parent doesn't exist, ignored", entry.Title(), log::info ) ;
Log( "file \"%1%\" parent doesn't exist, ignored", entry.Title(), log::verbose ) ;
else if ( parent != 0 && !parent->IsFolder() )
Log( "entry %1% has parent %2% which is not a folder, ignored",
entry.Title(), parent->Name(), log::info ) ;
Log( "warning: entry %1% has parent %2% which is not a folder, ignored",
entry.Title(), parent->Name(), log::warning ) ;
else
m_state.FromRemote( entry ) ;
@ -131,7 +131,7 @@ void Drive::SaveState()
void Drive::ConstructDirTree( http::Agent *http )
{
http::XmlResponse xml ;
http->Get( feed_base + "/-/folder?max-results=10&showroot=true", &xml, m_http_hdr ) ;
http->Get( feed_base + "/-/folder?max-results=50&showroot=true", &xml, m_http_hdr ) ;
xml::Node resp = xml.Response() ;
@ -162,6 +162,9 @@ void Drive::ConstructDirTree( http::Agent *http )
}
m_state.ResolveEntry() ;
// print the state of the all folders
m_state.ShowFolders() ;
}
void Drive::Update()

View File

@ -93,12 +93,20 @@ Resource::Resource( const fs::path& path ) :
/// one is newer.
void Resource::FromRemote( const Entry& remote )
{
// sync folder is easy
if ( remote.Kind() == "folder" && IsFolder() )
{
Log( "folder %1% is in sync", Name(), log::verbose ) ;
m_state = sync ;
}
// if checksum is equal, no need to compare the mtime
if ( remote.MD5() == m_entry.MD5() )
else if ( remote.MD5() == m_entry.MD5() )
{
Log( "MD5 matches: %1% is already in sync", Name(), log::verbose ) ;
m_state = sync ;
}
// use mtime to check which one is more recent
else
{
@ -121,19 +129,24 @@ void Resource::FromLocal()
m_state = local_deleted ;
Log( "%1% in state but not exist on disk: %2%", Name(), m_state ) ;
}
else
{
m_state = local_new ;
// to save time, compare mtime before checksum
DateTime mtime = os::FileMTime( path ) ;
if ( mtime > m_entry.MTime() )
// no need to compare MD5 or mtime for directories
if ( !IsFolder() )
{
Log( "%1% mtime newer on disk: %2%", Name(), m_state ) ;
m_entry.Update( crypt::MD5( path ), mtime ) ;
// to save time, compare mtime before checksum
DateTime mtime = os::FileMTime( path ) ;
if ( mtime > m_entry.MTime() )
{
Log( "%1% mtime newer on disk: %2%", Name(), m_state ) ;
m_entry.Update( crypt::MD5( path ), mtime ) ;
}
else
Log( "%1% unchanged on disk: %2%", Name(), m_state ) ;
}
else
Log( "%1% unchanged on disk: %2%", Name(), m_state ) ;
}
}
@ -221,8 +234,8 @@ Resource* Resource::FindChild( const std::string& name )
void Resource::Sync( http::Agent *http, const http::Headers& auth )
{
// no need to update for folders
if ( IsFolder() )
return ;
// if ( IsFolder() )
// return ;
assert( m_parent != 0 ) ;
@ -231,6 +244,7 @@ void Resource::Sync( http::Agent *http, const http::Headers& auth )
case local_new :
Log( "sync %1% %2% doesn't exist in server. upload \"%3%\"?",
m_entry.Title(), m_entry.Filename(), m_parent->m_entry.CreateLink(), log::verbose ) ;
if ( Create( http, auth ) )
m_state = sync ;
break ;
@ -295,6 +309,8 @@ bool Resource::EditContent( http::Agent* http, const http::Headers& auth )
bool Resource::Create( http::Agent* http, const http::Headers& auth )
{
assert( m_parent != 0 ) ;
assert( !m_parent->m_entry.CreateLink().empty() ) ;
return Upload( http, m_parent->m_entry.CreateLink() + "?convert=false", auth, true ) ;
}

View File

@ -181,6 +181,8 @@ ResourceTree::iterator ResourceTree::end()
void ResourceTree::Read( const Json& json )
{
Clear() ;
assert( m_root == 0 ) ;
m_root = new Resource ;
AddTree( m_root, json ) ;
}

View File

@ -64,6 +64,9 @@ void State::FromLocal( const fs::path& p, gr::Resource* folder )
{
assert( folder != 0 ) ;
assert( folder->IsFolder() ) ;
// sync the folder itself
folder->FromLocal() ;
for ( fs::directory_iterator i( p ) ; i != fs::directory_iterator() ; ++i )
{
@ -91,6 +94,16 @@ void State::FromLocal( const fs::path& p, gr::Resource* folder )
}
}
void State::ShowFolders()
{
for ( ResourceTree::iterator i = m_res.begin() ; i != m_res.end() ; ++i )
{
Resource *r = *i ;
if ( r->IsFolder() )
Trace( "%1%: %2%", r->Name(), r->StateStr() ) ;
}
}
void State::FromRemote( const Entry& e )
{
if ( !Update( e ) )

View File

@ -54,6 +54,9 @@ public :
iterator begin() ;
iterator end() ;
// for debug
void ShowFolders() ;
private :
void FromLocal( const fs::path& p, Resource *folder ) ;

View File

@ -109,12 +109,12 @@ Json Json::ParseFile( const std::string& filename )
struct json_object *json = 0 ;
char buf[80] ;
char buf[1024] ;
std::size_t count = 0 ;
while ( (count = file.Read( buf, sizeof(buf) ) ) > 0 )
json = ::json_tokener_parse_ex( tok, buf, count ) ;
if ( json == 0 )
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( ::json_tokener_errors[tok->err] ) ) ;

View File

@ -29,6 +29,8 @@
namespace gr { namespace crypt {
const std::size_t read_size = 8 * 1024 ;
std::string MD5( const fs::path& file )
{
try
@ -44,16 +46,14 @@ std::string MD5( const fs::path& file )
std::string MD5( StdioFile& file )
{
char buf[64 * 1024] ;
char buf[read_size] ;
EVP_MD_CTX md ;
EVP_MD_CTX_init( &md );
EVP_DigestInit_ex( &md, EVP_md5(), 0 ) ;
std::size_t count = 0 ;
while ( (count = file.Read( buf, sizeof(buf) )) > 0 )
{
EVP_DigestUpdate( &md, buf, count ) ;
}
unsigned int md5_size = EVP_MAX_MD_SIZE ;
unsigned char md5[EVP_MAX_MD_SIZE] ;