support creating revisions with --new-rev (#87)

pull/40/head
Nestal Wan 2012-07-27 00:45:53 +08:00
parent fd81cc1fe4
commit d831b8d59f
8 changed files with 35 additions and 28 deletions

View File

@ -83,6 +83,7 @@ int Main( int argc, char **argv )
( "auth,a", "Request authorization token" )
( "verbose,V", "Verbose mode. Enable more messages than normal.")
( "log-xml", "Log more HTTP responses as XML for debugging.")
( "new-rev", "Create new revisions in server for updated files.")
( "debug,d", "Enable debug level messages. Implies -v.")
( "log,l", po::value<std::string>(), "Set log output filename." )
( "force,f", "Force grive to always download a file from Google Drive "
@ -149,6 +150,7 @@ int Main( int argc, char **argv )
}
options.Add( "log-xml", Json(vm.count("log-xml") > 0) ) ;
options.Add( "new-rev", Json(vm.count("new-rev") > 0) ) ;
if ( vm.count( "debug" ) )
{

View File

@ -26,7 +26,6 @@
#include "http/Agent.hh"
#include "http/ResponseLog.hh"
#include "http/XmlResponse.hh"
#include "protocol/Json.hh"
#include "util/Destroy.hh"
#include "util/log/Log.hh"
#include "xml/Node.hh"
@ -55,7 +54,7 @@ namespace
Drive::Drive( http::Agent *http, const Json& options ) :
m_http ( http ),
m_state ( state_file, options ),
m_log_xml ( options["log-xml"].Bool() )
m_options ( options )
{
assert( m_http != 0 ) ;
}
@ -137,7 +136,7 @@ void Drive::DetectChanges()
Log( "Reading remote server file list", log::info ) ;
Feed feed ;
if ( m_log_xml )
if ( m_options["log-xml"].Bool() )
feed.EnableLog( "/tmp/file", ".xml" ) ;
feed.Start( m_http, http::Header(), feed_base + "?showfolders=true&showroot=true" ) ;
@ -158,7 +157,7 @@ void Drive::DetectChanges()
{
Log( "Detecting changes from last sync", log::info ) ;
Feed changes ;
if ( m_log_xml )
if ( m_options["log-xml"].Bool() )
feed.EnableLog( "/tmp/changes", ".xml" ) ;
feed.Start( m_http, http::Header(), ChangesFeed(prev_stamp+1) ) ;
@ -172,7 +171,7 @@ void Drive::DetectChanges()
void Drive::Update()
{
Log( "Synchronizing files", log::info ) ;
m_state.Sync( m_http ) ;
m_state.Sync( m_http, m_options ) ;
UpdateChangeStamp( ) ;
}
@ -180,7 +179,7 @@ void Drive::Update()
void Drive::DryRun()
{
Log( "Synchronizing files (dry-run)", log::info ) ;
m_state.Sync( 0 ) ;
m_state.Sync( 0, m_options ) ;
}
void Drive::UpdateChangeStamp( )

View File

@ -22,6 +22,7 @@
#include "State.hh"
#include "http/Header.hh"
#include "protocol/Json.hh"
#include "util/Exception.hh"
#include <string>
@ -35,7 +36,6 @@ namespace http
}
class Entry ;
class Json ;
class Drive
{
@ -61,7 +61,7 @@ private :
std::string m_resume_link ;
State m_state ;
bool m_log_xml ;
Json m_options ;
} ;
} // end of namespace

View File

@ -365,23 +365,24 @@ Resource* Resource::FindChild( const std::string& name )
}
// try to change the state to "sync"
void Resource::Sync( http::Agent *http, DateTime& sync_time )
void Resource::Sync( http::Agent *http, DateTime& sync_time, const Json& options )
{
assert( m_state != unknown ) ;
assert( !IsRoot() || m_state == sync ) ; // root folder is already synced
SyncSelf( http ) ;
// we want the server sync time, so we will take the server time of the last file uploaded to store as the sync time
// m_mtime is updated to server modified time when the file is uploaded
sync_time = std::max(sync_time, m_mtime);
SyncSelf( http, options ) ;
// we want the server sync time, so we will take the server time of the last file uploaded to store as the sync time
// m_mtime is updated to server modified time when the file is uploaded
sync_time = std::max(sync_time, m_mtime);
// if myself is deleted, no need to do the childrens
if ( m_state != local_deleted && m_state != remote_deleted )
std::for_each( m_child.begin(), m_child.end(),
boost::bind( &Resource::Sync, _1, http, boost::ref(sync_time) ) ) ;
boost::bind( &Resource::Sync, _1, http, boost::ref(sync_time), options ) ) ;
}
void Resource::SyncSelf( http::Agent* http )
void Resource::SyncSelf( http::Agent* http, const Json& options )
{
assert( !IsRoot() || m_state == sync ) ; // root is always sync
assert( IsRoot() || http == 0 || fs::is_directory( m_parent->Path() ) ) ;
@ -407,7 +408,7 @@ void Resource::SyncSelf( http::Agent* http )
case local_changed :
Log( "sync %1% changed in local. uploading", path, log::info ) ;
if ( http != 0 && EditContent( http ) )
if ( http != 0 && EditContent( http, options["new-rev"].Bool() ) )
m_state = sync ;
break ;
@ -520,7 +521,7 @@ void Resource::Download( http::Agent* http, const fs::path& file ) const
}
}
bool Resource::EditContent( http::Agent* http )
bool Resource::EditContent( http::Agent* http, bool new_rev )
{
assert( http != 0 ) ;
assert( m_parent != 0 ) ;
@ -533,10 +534,10 @@ bool Resource::EditContent( http::Agent* http )
return false ;
}
return Upload( http, m_edit, false ) ;
return Upload( http, m_edit + (new_rev ? "?new-revision=true" : ""), false ) ;
}
bool Resource::Create( http::Agent* http)
bool Resource::Create( http::Agent* http )
{
assert( http != 0 ) ;
assert( m_parent != 0 ) ;

View File

@ -35,6 +35,7 @@ namespace http
}
class Entry ;
class Json ;
/*! \brief A resource can be a file or a folder in the google drive
@ -76,7 +77,7 @@ public :
void FromRemote( const Entry& remote, const DateTime& last_sync ) ;
void FromLocal( const DateTime& last_sync ) ;
void Sync( http::Agent* http, DateTime& sync_time ) ;
void Sync( http::Agent* http, DateTime& sync_time, const Json& options ) ;
// children access
iterator begin() const ;
@ -124,7 +125,7 @@ private :
void SetState( State new_state ) ;
void Download( http::Agent* http, const fs::path& file ) const ;
bool EditContent( http::Agent* http ) ;
bool EditContent( http::Agent* http, bool new_rev ) ;
bool Create( http::Agent* http ) ;
bool Upload( http::Agent* http, const std::string& link, bool post ) ;
@ -135,7 +136,7 @@ private :
void DeleteRemote( http::Agent* http ) ;
void AssignIDs( const Entry& remote ) ;
void SyncSelf( http::Agent* http ) ;
void SyncSelf( http::Agent* http, const Json& options ) ;
private :
std::string m_name ;

View File

@ -261,7 +261,7 @@ void State::Write( const fs::path& filename ) const
fs << result ;
}
void State::Sync( http::Agent *http )
void State::Sync( http::Agent *http, const Json& options )
{
// set the last sync time from the time returned by the server for the last file synced
// if the sync time hasn't changed (i.e. now files have been uploaded)
@ -271,7 +271,8 @@ void State::Sync( http::Agent *http )
// TODO - WARNING - do we use the last sync time to compare to client file times
// need to check if this introduces a new problem
DateTime last_sync_time = m_last_sync;
m_res.Root()->Sync( http, last_sync_time ) ;
m_res.Root()->Sync( http, last_sync_time, options ) ;
if ( last_sync_time == m_last_sync )
{
Trace( "nothing changed? %1%", m_last_sync ) ;

View File

@ -57,7 +57,7 @@ public :
Resource* FindByID( const std::string& id ) ;
Resource* Find( const fs::path& path ) ;
void Sync( http::Agent *http ) ;
void Sync( http::Agent *http, const Json& options ) ;
iterator begin() ;
iterator end() ;

View File

@ -150,12 +150,15 @@ long CurlAgent::ExecCurl(
dest->Clear() ;
CURLcode curl_code = ::curl_easy_perform(curl);
// get the HTTTP response code
long http_code = 0;
::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
Trace( "HTTP response %1%", http_code ) ;
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, 0 ) ;
// reset the curl buffer to prevent it from touch our "error" buffer
::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, 0 ) ;
// only throw for libcurl errors
if ( curl_code != CURLE_OK )
{
BOOST_THROW_EXCEPTION(