mirror of https://github.com/vitalif/grive2
support creating revisions with --new-rev (#87)
parent
fd81cc1fe4
commit
d831b8d59f
|
@ -83,6 +83,7 @@ int Main( int argc, char **argv )
|
||||||
( "auth,a", "Request authorization token" )
|
( "auth,a", "Request authorization token" )
|
||||||
( "verbose,V", "Verbose mode. Enable more messages than normal.")
|
( "verbose,V", "Verbose mode. Enable more messages than normal.")
|
||||||
( "log-xml", "Log more HTTP responses as XML for debugging.")
|
( "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.")
|
( "debug,d", "Enable debug level messages. Implies -v.")
|
||||||
( "log,l", po::value<std::string>(), "Set log output filename." )
|
( "log,l", po::value<std::string>(), "Set log output filename." )
|
||||||
( "force,f", "Force grive to always download a file from Google Drive "
|
( "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( "log-xml", Json(vm.count("log-xml") > 0) ) ;
|
||||||
|
options.Add( "new-rev", Json(vm.count("new-rev") > 0) ) ;
|
||||||
|
|
||||||
if ( vm.count( "debug" ) )
|
if ( vm.count( "debug" ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "http/Agent.hh"
|
#include "http/Agent.hh"
|
||||||
#include "http/ResponseLog.hh"
|
#include "http/ResponseLog.hh"
|
||||||
#include "http/XmlResponse.hh"
|
#include "http/XmlResponse.hh"
|
||||||
#include "protocol/Json.hh"
|
|
||||||
#include "util/Destroy.hh"
|
#include "util/Destroy.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
#include "xml/Node.hh"
|
#include "xml/Node.hh"
|
||||||
|
@ -55,7 +54,7 @@ namespace
|
||||||
Drive::Drive( http::Agent *http, const Json& options ) :
|
Drive::Drive( http::Agent *http, const Json& options ) :
|
||||||
m_http ( http ),
|
m_http ( http ),
|
||||||
m_state ( state_file, options ),
|
m_state ( state_file, options ),
|
||||||
m_log_xml ( options["log-xml"].Bool() )
|
m_options ( options )
|
||||||
{
|
{
|
||||||
assert( m_http != 0 ) ;
|
assert( m_http != 0 ) ;
|
||||||
}
|
}
|
||||||
|
@ -137,7 +136,7 @@ void Drive::DetectChanges()
|
||||||
|
|
||||||
Log( "Reading remote server file list", log::info ) ;
|
Log( "Reading remote server file list", log::info ) ;
|
||||||
Feed feed ;
|
Feed feed ;
|
||||||
if ( m_log_xml )
|
if ( m_options["log-xml"].Bool() )
|
||||||
feed.EnableLog( "/tmp/file", ".xml" ) ;
|
feed.EnableLog( "/tmp/file", ".xml" ) ;
|
||||||
|
|
||||||
feed.Start( m_http, http::Header(), feed_base + "?showfolders=true&showroot=true" ) ;
|
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 ) ;
|
Log( "Detecting changes from last sync", log::info ) ;
|
||||||
Feed changes ;
|
Feed changes ;
|
||||||
if ( m_log_xml )
|
if ( m_options["log-xml"].Bool() )
|
||||||
feed.EnableLog( "/tmp/changes", ".xml" ) ;
|
feed.EnableLog( "/tmp/changes", ".xml" ) ;
|
||||||
|
|
||||||
feed.Start( m_http, http::Header(), ChangesFeed(prev_stamp+1) ) ;
|
feed.Start( m_http, http::Header(), ChangesFeed(prev_stamp+1) ) ;
|
||||||
|
@ -172,7 +171,7 @@ void Drive::DetectChanges()
|
||||||
void Drive::Update()
|
void Drive::Update()
|
||||||
{
|
{
|
||||||
Log( "Synchronizing files", log::info ) ;
|
Log( "Synchronizing files", log::info ) ;
|
||||||
m_state.Sync( m_http ) ;
|
m_state.Sync( m_http, m_options ) ;
|
||||||
|
|
||||||
UpdateChangeStamp( ) ;
|
UpdateChangeStamp( ) ;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +179,7 @@ void Drive::Update()
|
||||||
void Drive::DryRun()
|
void Drive::DryRun()
|
||||||
{
|
{
|
||||||
Log( "Synchronizing files (dry-run)", log::info ) ;
|
Log( "Synchronizing files (dry-run)", log::info ) ;
|
||||||
m_state.Sync( 0 ) ;
|
m_state.Sync( 0, m_options ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drive::UpdateChangeStamp( )
|
void Drive::UpdateChangeStamp( )
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "State.hh"
|
#include "State.hh"
|
||||||
|
|
||||||
#include "http/Header.hh"
|
#include "http/Header.hh"
|
||||||
|
#include "protocol/Json.hh"
|
||||||
#include "util/Exception.hh"
|
#include "util/Exception.hh"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -35,7 +36,6 @@ namespace http
|
||||||
}
|
}
|
||||||
|
|
||||||
class Entry ;
|
class Entry ;
|
||||||
class Json ;
|
|
||||||
|
|
||||||
class Drive
|
class Drive
|
||||||
{
|
{
|
||||||
|
@ -61,7 +61,7 @@ private :
|
||||||
std::string m_resume_link ;
|
std::string m_resume_link ;
|
||||||
State m_state ;
|
State m_state ;
|
||||||
|
|
||||||
bool m_log_xml ;
|
Json m_options ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|
|
@ -365,23 +365,24 @@ Resource* Resource::FindChild( const std::string& name )
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to change the state to "sync"
|
// 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( m_state != unknown ) ;
|
||||||
assert( !IsRoot() || m_state == sync ) ; // root folder is already synced
|
assert( !IsRoot() || m_state == sync ) ; // root folder is already synced
|
||||||
|
|
||||||
SyncSelf( http ) ;
|
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
|
// we want the server sync time, so we will take the server time of the last file uploaded to store as the sync time
|
||||||
sync_time = std::max(sync_time, m_mtime);
|
// 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 myself is deleted, no need to do the childrens
|
||||||
if ( m_state != local_deleted && m_state != remote_deleted )
|
if ( m_state != local_deleted && m_state != remote_deleted )
|
||||||
std::for_each( m_child.begin(), m_child.end(),
|
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() || m_state == sync ) ; // root is always sync
|
||||||
assert( IsRoot() || http == 0 || fs::is_directory( m_parent->Path() ) ) ;
|
assert( IsRoot() || http == 0 || fs::is_directory( m_parent->Path() ) ) ;
|
||||||
|
@ -407,7 +408,7 @@ void Resource::SyncSelf( http::Agent* http )
|
||||||
|
|
||||||
case local_changed :
|
case local_changed :
|
||||||
Log( "sync %1% changed in local. uploading", path, log::info ) ;
|
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 ;
|
m_state = sync ;
|
||||||
break ;
|
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( http != 0 ) ;
|
||||||
assert( m_parent != 0 ) ;
|
assert( m_parent != 0 ) ;
|
||||||
|
@ -533,10 +534,10 @@ bool Resource::EditContent( http::Agent* http )
|
||||||
return false ;
|
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( http != 0 ) ;
|
||||||
assert( m_parent != 0 ) ;
|
assert( m_parent != 0 ) ;
|
||||||
|
|
|
@ -35,6 +35,7 @@ namespace http
|
||||||
}
|
}
|
||||||
|
|
||||||
class Entry ;
|
class Entry ;
|
||||||
|
class Json ;
|
||||||
|
|
||||||
/*! \brief A resource can be a file or a folder in the google drive
|
/*! \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 FromRemote( const Entry& remote, const DateTime& last_sync ) ;
|
||||||
void FromLocal( 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
|
// children access
|
||||||
iterator begin() const ;
|
iterator begin() const ;
|
||||||
|
@ -124,7 +125,7 @@ private :
|
||||||
void SetState( State new_state ) ;
|
void SetState( State new_state ) ;
|
||||||
|
|
||||||
void Download( http::Agent* http, const fs::path& file ) const ;
|
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 Create( http::Agent* http ) ;
|
||||||
bool Upload( http::Agent* http, const std::string& link, bool post ) ;
|
bool Upload( http::Agent* http, const std::string& link, bool post ) ;
|
||||||
|
|
||||||
|
@ -135,7 +136,7 @@ private :
|
||||||
void DeleteRemote( http::Agent* http ) ;
|
void DeleteRemote( http::Agent* http ) ;
|
||||||
|
|
||||||
void AssignIDs( const Entry& remote ) ;
|
void AssignIDs( const Entry& remote ) ;
|
||||||
void SyncSelf( http::Agent* http ) ;
|
void SyncSelf( http::Agent* http, const Json& options ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
std::string m_name ;
|
std::string m_name ;
|
||||||
|
|
|
@ -261,7 +261,7 @@ void State::Write( const fs::path& filename ) const
|
||||||
fs << result ;
|
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
|
// 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)
|
// 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
|
// TODO - WARNING - do we use the last sync time to compare to client file times
|
||||||
// need to check if this introduces a new problem
|
// need to check if this introduces a new problem
|
||||||
DateTime last_sync_time = m_last_sync;
|
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 )
|
if ( last_sync_time == m_last_sync )
|
||||||
{
|
{
|
||||||
Trace( "nothing changed? %1%", m_last_sync ) ;
|
Trace( "nothing changed? %1%", m_last_sync ) ;
|
||||||
|
|
|
@ -57,7 +57,7 @@ public :
|
||||||
Resource* FindByID( const std::string& id ) ;
|
Resource* FindByID( const std::string& id ) ;
|
||||||
Resource* Find( const fs::path& path ) ;
|
Resource* Find( const fs::path& path ) ;
|
||||||
|
|
||||||
void Sync( http::Agent *http ) ;
|
void Sync( http::Agent *http, const Json& options ) ;
|
||||||
|
|
||||||
iterator begin() ;
|
iterator begin() ;
|
||||||
iterator end() ;
|
iterator end() ;
|
||||||
|
|
|
@ -150,12 +150,15 @@ long CurlAgent::ExecCurl(
|
||||||
dest->Clear() ;
|
dest->Clear() ;
|
||||||
CURLcode curl_code = ::curl_easy_perform(curl);
|
CURLcode curl_code = ::curl_easy_perform(curl);
|
||||||
|
|
||||||
|
// get the HTTTP response code
|
||||||
long http_code = 0;
|
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 ) ;
|
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 )
|
if ( curl_code != CURLE_OK )
|
||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(
|
BOOST_THROW_EXCEPTION(
|
||||||
|
|
Loading…
Reference in New Issue