diff --git a/README.md b/README.md index 756873b..2b0f69e 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ Enjoy! - Much faster and more correct synchronisation using local modification time and checksum cache (similar to git index) - Automatic move/rename detection, -m option removed - force option works again +- Instead of crashing on sync exceptions Grive will give a warning and attempt to sync failed files again during the next run. ### Grive2 v0.4.2 diff --git a/libgrive/src/base/Drive.cc b/libgrive/src/base/Drive.cc index 9dd8089..5e3eaaf 100644 --- a/libgrive/src/base/Drive.cc +++ b/libgrive/src/base/Drive.cc @@ -35,7 +35,6 @@ #include #include #include -#include // for debugging only #include diff --git a/libgrive/src/base/Resource.cc b/libgrive/src/base/Resource.cc index 66a4ac3..a0d571b 100644 --- a/libgrive/src/base/Resource.cc +++ b/libgrive/src/base/Resource.cc @@ -28,6 +28,7 @@ #include "util/log/Log.hh" #include "util/OS.hh" #include "util/File.hh" +#include "http/Error.hh" #include #include @@ -264,18 +265,12 @@ void Resource::FromLocal( Val& state ) m_md5 = crypt::MD5::Get( path ); // File is changed locally. TODO: Detect conflicts is_changed = !state.Has( "md5" ) || m_md5 != state["md5"].Str(); - state.Set( "md5", Val( m_md5 ) ); } else is_changed = true; - state.Set( "ctime", Val( m_ctime.Sec() ) ); } if ( state.Has( "srv_time" ) ) m_mtime.Assign( state[ "srv_time" ].U64(), 0 ) ; - if ( is_dir ) - state.Del( "md5" ); - else - state.Del( "tree" ); // follow parent recursively if ( m_parent->m_state == local_new || m_parent->m_state == remote_deleted ) @@ -418,6 +413,32 @@ void Resource::Sync( Syncer *syncer, ResourceTree *res_tree, const Val& options Log( "Error syncing %1%: %2%", Path(), e.what(), log::error ); return; } + catch ( http::Error &e ) + { + int *curlcode = boost::get_error_info< http::CurlCode > ( e ) ; + int *httpcode = boost::get_error_info< http::HttpResponseCode > ( e ) ; + std::string msg; + if ( curlcode ) + msg = *( boost::get_error_info< http::CurlErrMsg > ( e ) ); + else if ( httpcode ) + msg = "HTTP " + boost::to_string( *httpcode ); + else + msg = e.what(); + Log( "Error syncing %1%: %2%", Path(), msg, log::error ); + std::string *url = boost::get_error_info< http::Url > ( e ); + std::string *resp_hdr = boost::get_error_info< http::HttpResponseHeaders > ( e ); + std::string *resp_txt = boost::get_error_info< http::HttpResponseText > ( e ); + http::Header *req_hdr = boost::get_error_info< http::HttpRequestHeaders > ( e ); + if ( url ) + Log( "Request URL: %1%", *url, log::verbose ); + if ( req_hdr ) + Log( "Request headers: %1%", req_hdr->Str(), log::verbose ); + if ( resp_hdr ) + Log( "Response headers: %1%", *resp_hdr, log::verbose ); + if ( resp_txt ) + Log( "Response text: %1%", *resp_txt, log::verbose ); + return; + } // if myself is deleted, no need to do the childrens if ( m_state != local_deleted && m_state != remote_deleted ) @@ -463,11 +484,14 @@ void Resource::SyncSelf( Syncer* syncer, ResourceTree *res_tree, const Val& opti if ( syncer ) { if ( is_local ) + { syncer->Move( from, to->Parent(), to->Name() ); + to->SetIndex( false ); + } else { fs::rename( from->Path(), to->Path() ); - to->SetIndex(); + to->SetIndex( true ); } to->m_mtime = from->m_mtime; to->m_json->Set( "srv_time", Val( from->m_mtime.Sec() ) ); @@ -485,9 +509,11 @@ void Resource::SyncSelf( Syncer* syncer, ResourceTree *res_tree, const Val& opti case local_new : Log( "sync %1% doesn't exist in server, uploading", path, log::info ) ; - // FIXME: (?) do not write new timestamp on failed upload if ( syncer && syncer->Create( this ) ) + { m_state = sync ; + SetIndex( false ); + } break ; case local_deleted : @@ -502,7 +528,10 @@ void Resource::SyncSelf( Syncer* syncer, ResourceTree *res_tree, const Val& opti case local_changed : Log( "sync %1% changed in local. uploading", path, log::info ) ; if ( syncer && syncer->EditContent( this, options["new-rev"].Bool() ) ) + { m_state = sync ; + SetIndex( false ); + } break ; case remote_new : @@ -513,7 +542,7 @@ void Resource::SyncSelf( Syncer* syncer, ResourceTree *res_tree, const Val& opti fs::create_directories( path ) ; else syncer->Download( this, path ) ; - SetIndex() ; + SetIndex( true ) ; m_state = sync ; } break ; @@ -524,7 +553,7 @@ void Resource::SyncSelf( Syncer* syncer, ResourceTree *res_tree, const Val& opti if ( syncer ) { syncer->Download( this, path ) ; - SetIndex() ; + SetIndex( true ) ; m_state = sync ; } break ; @@ -604,21 +633,26 @@ void Resource::DeleteIndex() m_json = NULL; } -void Resource::SetIndex() +void Resource::SetIndex( bool re_stat ) { assert( m_parent->m_json != NULL ); if ( !m_json ) m_json = &((*m_parent->m_json)["tree"]).Item( Name() ); bool is_dir; - os::Stat( Path(), &m_ctime, NULL, &is_dir ); + if ( re_stat ) + os::Stat( Path(), &m_ctime, NULL, &is_dir ); if ( !is_dir ) { m_json->Set( "ctime", Val( m_ctime.Sec() ) ); m_json->Set( "md5", Val( m_md5 ) ); m_json->Del( "tree" ); } - else // check if tree item exists + else + { + // add tree item if it does not exist m_json->Item( "tree" ); + m_json->Del( "md5" ); + } } Resource::iterator Resource::begin() const diff --git a/libgrive/src/base/Resource.hh b/libgrive/src/base/Resource.hh index 354369f..531b78d 100644 --- a/libgrive/src/base/Resource.hh +++ b/libgrive/src/base/Resource.hh @@ -139,7 +139,7 @@ private : void DeleteLocal() ; void DeleteIndex() ; - void SetIndex() ; + void SetIndex( bool ) ; void SyncSelf( Syncer* syncer, ResourceTree *res_tree, const Val& options ) ; diff --git a/libgrive/src/http/CurlAgent.cc b/libgrive/src/http/CurlAgent.cc index a527d51..4b23067 100644 --- a/libgrive/src/http/CurlAgent.cc +++ b/libgrive/src/http/CurlAgent.cc @@ -35,7 +35,6 @@ #include #include #include -#include #include #include diff --git a/libgrive/src/http/Download.cc b/libgrive/src/http/Download.cc index 885187e..26804e6 100644 --- a/libgrive/src/http/Download.cc +++ b/libgrive/src/http/Download.cc @@ -20,7 +20,6 @@ #include "Download.hh" // #include "util/SignalHandler.hh" -#include "Error.hh" #include "util/Crypt.hh" // boost headers diff --git a/libgrive/src/http/Header.cc b/libgrive/src/http/Header.cc index 9f0bdd3..6d875f9 100644 --- a/libgrive/src/http/Header.cc +++ b/libgrive/src/http/Header.cc @@ -22,6 +22,7 @@ #include #include #include +#include namespace gr { namespace http { @@ -34,6 +35,13 @@ void Header::Add( const std::string& str ) m_vec.push_back( str ) ; } +std::string Header::Str() const +{ + std::ostringstream s ; + s << *this ; + return s.str() ; +} + Header::iterator Header::begin() const { return m_vec.begin() ; diff --git a/libgrive/src/http/Header.hh b/libgrive/src/http/Header.hh index 2486cd0..844b6e6 100644 --- a/libgrive/src/http/Header.hh +++ b/libgrive/src/http/Header.hh @@ -37,6 +37,7 @@ public : Header() ; void Add( const std::string& str ) ; + std::string Str() const ; iterator begin() const ; iterator end() const ; diff --git a/libgrive/src/util/Crypt.cc b/libgrive/src/util/Crypt.cc index 5fb8ebe..b34494f 100644 --- a/libgrive/src/util/Crypt.cc +++ b/libgrive/src/util/Crypt.cc @@ -24,7 +24,6 @@ #include "MemMap.hh" #include -#include // dependent libraries #include diff --git a/libgrive/src/util/DateTime.cc b/libgrive/src/util/DateTime.cc index ffb4ec5..2fe7989 100644 --- a/libgrive/src/util/DateTime.cc +++ b/libgrive/src/util/DateTime.cc @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/libgrive/src/util/Exception.cc b/libgrive/src/util/Exception.cc index 9cf6681..a4652f6 100644 --- a/libgrive/src/util/Exception.cc +++ b/libgrive/src/util/Exception.cc @@ -26,7 +26,6 @@ #include #include -#include namespace gr {