mirror of https://github.com/vitalif/grive2
added AuthAgent, a wrapper around http agent
parent
57c431dd83
commit
28e8012ca5
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
#include "drive/Drive.hh"
|
#include "drive/Drive.hh"
|
||||||
|
|
||||||
|
#include "http/CurlAgent.hh"
|
||||||
|
#include "protocol/AuthAgent.hh"
|
||||||
#include "protocol/OAuth2.hh"
|
#include "protocol/OAuth2.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "protocol/Json.hh"
|
||||||
|
|
||||||
|
@ -172,7 +174,8 @@ int Main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
|
|
||||||
OAuth2 token( refresh_token, client_id, client_secret ) ;
|
OAuth2 token( refresh_token, client_id, client_secret ) ;
|
||||||
Drive drive( token, options ) ;
|
AuthAgent agent( token, std::auto_ptr<http::Agent>( new http::CurlAgent ) ) ;
|
||||||
|
Drive drive( &agent, options ) ;
|
||||||
drive.DetectChanges() ;
|
drive.DetectChanges() ;
|
||||||
|
|
||||||
if ( vm.count( "dry-run" ) == 0 )
|
if ( vm.count( "dry-run" ) == 0 )
|
||||||
|
|
|
@ -23,11 +23,11 @@
|
||||||
#include "Entry.hh"
|
#include "Entry.hh"
|
||||||
#include "Feed.hh"
|
#include "Feed.hh"
|
||||||
|
|
||||||
#include "http/CurlAgent.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 "protocol/Json.hh"
|
||||||
#include "protocol/OAuth2.hh"
|
// #include "protocol/OAuth2.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"
|
||||||
|
@ -53,12 +53,11 @@ namespace
|
||||||
const std::string state_file = ".grive_state" ;
|
const std::string state_file = ".grive_state" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Drive::Drive( OAuth2& auth, const Json& options ) :
|
Drive::Drive( http::Agent *http, const Json& options ) :
|
||||||
m_auth( auth ),
|
m_http( http ),
|
||||||
m_state( state_file, options )
|
m_state( state_file, options )
|
||||||
{
|
{
|
||||||
m_http_hdr.Add( "Authorization: Bearer " + m_auth.AccessToken() ) ;
|
assert( m_http != 0 ) ;
|
||||||
m_http_hdr.Add( "GData-Version: 3.0" ) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drive::FromRemote( const Entry& entry )
|
void Drive::FromRemote( const Entry& entry )
|
||||||
|
@ -93,14 +92,14 @@ void Drive::SaveState()
|
||||||
m_state.Write( state_file ) ;
|
m_state.Write( state_file ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drive::SyncFolders( http::Agent *http )
|
void Drive::SyncFolders( )
|
||||||
{
|
{
|
||||||
assert( http != 0 ) ;
|
assert( m_http != 0 ) ;
|
||||||
|
|
||||||
Log( "Synchronizing folders", log::info ) ;
|
Log( "Synchronizing folders", log::info ) ;
|
||||||
|
|
||||||
http::XmlResponse xml ;
|
http::XmlResponse xml ;
|
||||||
http->Get( feed_base + "/-/folder?max-results=50&showroot=true", &xml, m_http_hdr ) ;
|
m_http->Get( feed_base + "/-/folder?max-results=50&showroot=true", &xml, http::Header() ) ;
|
||||||
|
|
||||||
Feed feed( xml.Response() ) ;
|
Feed feed( xml.Response() ) ;
|
||||||
do
|
do
|
||||||
|
@ -121,7 +120,7 @@ void Drive::SyncFolders( http::Agent *http )
|
||||||
m_state.FromRemote( e ) ;
|
m_state.FromRemote( e ) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ( feed.GetNext( http, m_http_hdr ) ) ;
|
} while ( feed.GetNext( m_http, http::Header() ) ) ;
|
||||||
|
|
||||||
m_state.ResolveEntry() ;
|
m_state.ResolveEntry() ;
|
||||||
}
|
}
|
||||||
|
@ -131,17 +130,15 @@ void Drive::DetectChanges()
|
||||||
Log( "Reading local directories", log::info ) ;
|
Log( "Reading local directories", log::info ) ;
|
||||||
m_state.FromLocal( "." ) ;
|
m_state.FromLocal( "." ) ;
|
||||||
|
|
||||||
http::CurlAgent http ;
|
|
||||||
|
|
||||||
long prev_stamp = m_state.ChangeStamp() ;
|
long prev_stamp = m_state.ChangeStamp() ;
|
||||||
Trace( "previous change stamp is %1%", prev_stamp ) ;
|
Trace( "previous change stamp is %1%", prev_stamp ) ;
|
||||||
|
|
||||||
SyncFolders( &http ) ;
|
SyncFolders( ) ;
|
||||||
|
|
||||||
Log( "Reading remote server file list", log::info ) ;
|
Log( "Reading remote server file list", log::info ) ;
|
||||||
Feed feed ;
|
Feed feed ;
|
||||||
// feed.EnableLog( "/tmp/file", ".xml" ) ;
|
// feed.EnableLog( "/tmp/file", ".xml" ) ;
|
||||||
feed.Start( &http, m_http_hdr, feed_base + "?showfolders=true&showroot=true" ) ;
|
feed.Start( m_http, http::Header(), feed_base + "?showfolders=true&showroot=true" ) ;
|
||||||
|
|
||||||
m_resume_link = feed.Root()["link"].
|
m_resume_link = feed.Root()["link"].
|
||||||
Find( "@rel", "http://schemas.google.com/g/2005#resumable-create-media" )["@href"] ;
|
Find( "@rel", "http://schemas.google.com/g/2005#resumable-create-media" )["@href"] ;
|
||||||
|
@ -152,7 +149,7 @@ void Drive::DetectChanges()
|
||||||
feed.begin(), feed.end(),
|
feed.begin(), feed.end(),
|
||||||
boost::bind( &Drive::FromRemote, this, _1 ) ) ;
|
boost::bind( &Drive::FromRemote, this, _1 ) ) ;
|
||||||
|
|
||||||
} while ( feed.GetNext( &http, m_http_hdr ) ) ;
|
} while ( feed.GetNext( m_http, http::Header() ) ) ;
|
||||||
|
|
||||||
// pull the changes feed
|
// pull the changes feed
|
||||||
if ( prev_stamp != -1 )
|
if ( prev_stamp != -1 )
|
||||||
|
@ -160,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 ;
|
||||||
// feed.EnableLog( "/tmp/changes", ".xml" ) ;
|
// feed.EnableLog( "/tmp/changes", ".xml" ) ;
|
||||||
feed.Start( &http, m_http_hdr, ChangesFeed(prev_stamp+1) ) ;
|
feed.Start( m_http, http::Header(), ChangesFeed(prev_stamp+1) ) ;
|
||||||
|
|
||||||
std::for_each(
|
std::for_each(
|
||||||
changes.begin(), changes.end(),
|
changes.begin(), changes.end(),
|
||||||
|
@ -171,25 +168,24 @@ void Drive::DetectChanges()
|
||||||
void Drive::Update()
|
void Drive::Update()
|
||||||
{
|
{
|
||||||
Log( "Synchronizing files", log::info ) ;
|
Log( "Synchronizing files", log::info ) ;
|
||||||
http::CurlAgent http ;
|
m_state.Sync( m_http ) ;
|
||||||
m_state.Sync( &http, m_http_hdr ) ;
|
|
||||||
|
|
||||||
UpdateChangeStamp( &http ) ;
|
UpdateChangeStamp( ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
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_http_hdr ) ;
|
m_state.Sync( 0 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drive::UpdateChangeStamp( http::Agent *http )
|
void Drive::UpdateChangeStamp( )
|
||||||
{
|
{
|
||||||
assert( http != 0 ) ;
|
assert( m_http != 0 ) ;
|
||||||
|
|
||||||
// get changed feed
|
// get changed feed
|
||||||
http::XmlResponse xrsp ;
|
http::XmlResponse xrsp ;
|
||||||
http->Get( ChangesFeed(m_state.ChangeStamp()+1), &xrsp, m_http_hdr ) ;
|
m_http->Get( ChangesFeed(m_state.ChangeStamp()+1), &xrsp, http::Header() ) ;
|
||||||
|
|
||||||
// we should go through the changes to see if it was really Grive to made that change
|
// we should go through the changes to see if it was really Grive to made that change
|
||||||
// maybe by recording the updated timestamp and compare it?
|
// maybe by recording the updated timestamp and compare it?
|
||||||
|
|
|
@ -35,13 +35,12 @@ namespace http
|
||||||
}
|
}
|
||||||
|
|
||||||
class Entry ;
|
class Entry ;
|
||||||
class OAuth2 ;
|
|
||||||
class Json ;
|
class Json ;
|
||||||
|
|
||||||
class Drive
|
class Drive
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
Drive( OAuth2& auth, const Json& options ) ;
|
Drive( http::Agent *http, const Json& options ) ;
|
||||||
|
|
||||||
void DetectChanges() ;
|
void DetectChanges() ;
|
||||||
void Update() ;
|
void Update() ;
|
||||||
|
@ -51,15 +50,16 @@ public :
|
||||||
struct Error : virtual Exception {} ;
|
struct Error : virtual Exception {} ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
void SyncFolders( http::Agent *http ) ;
|
void SyncFolders( ) ;
|
||||||
void file();
|
void file();
|
||||||
void FromRemote( const Entry& entry ) ;
|
void FromRemote( const Entry& entry ) ;
|
||||||
void FromChange( const Entry& entry ) ;
|
void FromChange( const Entry& entry ) ;
|
||||||
void UpdateChangeStamp( http::Agent *http ) ;
|
void UpdateChangeStamp( ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
OAuth2& m_auth ;
|
http::Agent *m_http ;
|
||||||
http::Header m_http_hdr ;
|
// OAuth2& m_auth ;
|
||||||
|
// http::Header m_http_hdr ;
|
||||||
|
|
||||||
std::string m_resume_link ;
|
std::string m_resume_link ;
|
||||||
State m_state ;
|
State m_state ;
|
||||||
|
|
|
@ -365,20 +365,20 @@ 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, const http::Header& auth, DateTime& sync_time )
|
void Resource::Sync( http::Agent *http, DateTime& sync_time )
|
||||||
{
|
{
|
||||||
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, auth, sync_time ) ;
|
SyncSelf( http, sync_time ) ;
|
||||||
|
|
||||||
// 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, auth, boost::ref(sync_time) ) ) ;
|
boost::bind( &Resource::Sync, _1, http, boost::ref(sync_time) ) ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::SyncSelf( http::Agent* http, const http::Header& auth, DateTime& sync_time )
|
void Resource::SyncSelf( http::Agent* http, DateTime& sync_time )
|
||||||
{
|
{
|
||||||
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() ) ) ;
|
||||||
|
@ -392,19 +392,19 @@ void Resource::SyncSelf( http::Agent* http, const http::Header& auth, DateTime&
|
||||||
case local_new :
|
case local_new :
|
||||||
Log( "sync %1% doesn't exist in server, uploading", path, log::info ) ;
|
Log( "sync %1% doesn't exist in server, uploading", path, log::info ) ;
|
||||||
|
|
||||||
if ( http != 0 && Create( http, auth, sync_time ) )
|
if ( http != 0 && Create( http, sync_time ) )
|
||||||
m_state = sync ;
|
m_state = sync ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case local_deleted :
|
case local_deleted :
|
||||||
Log( "sync %1% deleted in local. deleting remote", path, log::info ) ;
|
Log( "sync %1% deleted in local. deleting remote", path, log::info ) ;
|
||||||
if ( http != 0 )
|
if ( http != 0 )
|
||||||
DeleteRemote( http, auth ) ;
|
DeleteRemote( http ) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
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, auth, sync_time ) )
|
if ( http != 0 && EditContent( http, sync_time ) )
|
||||||
m_state = sync ;
|
m_state = sync ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
|
@ -415,7 +415,7 @@ void Resource::SyncSelf( http::Agent* http, const http::Header& auth, DateTime&
|
||||||
if ( IsFolder() )
|
if ( IsFolder() )
|
||||||
fs::create_directories( path ) ;
|
fs::create_directories( path ) ;
|
||||||
else
|
else
|
||||||
Download( http, path, auth ) ;
|
Download( http, path ) ;
|
||||||
|
|
||||||
m_state = sync ;
|
m_state = sync ;
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ void Resource::SyncSelf( http::Agent* http, const http::Header& auth, DateTime&
|
||||||
Log( "sync %1% changed in remote. downloading", path, log::info ) ;
|
Log( "sync %1% changed in remote. downloading", path, log::info ) ;
|
||||||
if ( http != 0 )
|
if ( http != 0 )
|
||||||
{
|
{
|
||||||
Download( http, path, auth ) ;
|
Download( http, path ) ;
|
||||||
m_state = sync ;
|
m_state = sync ;
|
||||||
}
|
}
|
||||||
break ;
|
break ;
|
||||||
|
@ -474,14 +474,14 @@ void Resource::DeleteLocal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Resource::DeleteRemote( http::Agent *http, const http::Header& auth )
|
void Resource::DeleteRemote( http::Agent *http )
|
||||||
{
|
{
|
||||||
assert( http != 0 ) ;
|
assert( http != 0 ) ;
|
||||||
http::StringResponse str ;
|
http::StringResponse str ;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
http::Header hdr( auth ) ;
|
http::Header hdr ;
|
||||||
hdr.Add( "If-Match: " + m_etag ) ;
|
hdr.Add( "If-Match: " + m_etag ) ;
|
||||||
|
|
||||||
// doesn't know why, but an update before deleting seems to work always
|
// doesn't know why, but an update before deleting seems to work always
|
||||||
|
@ -502,12 +502,12 @@ void Resource::DeleteRemote( http::Agent *http, const http::Header& auth )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Resource::Download( http::Agent* http, const fs::path& file, const http::Header& auth ) const
|
void Resource::Download( http::Agent* http, const fs::path& file ) const
|
||||||
{
|
{
|
||||||
assert( http != 0 ) ;
|
assert( http != 0 ) ;
|
||||||
|
|
||||||
http::Download dl( file.string(), http::Download::NoChecksum() ) ;
|
http::Download dl( file.string(), http::Download::NoChecksum() ) ;
|
||||||
long r = http->Get( m_content, &dl, auth ) ;
|
long r = http->Get( m_content, &dl, http::Header() ) ;
|
||||||
if ( r <= 400 )
|
if ( r <= 400 )
|
||||||
{
|
{
|
||||||
if ( m_mtime != DateTime() )
|
if ( m_mtime != DateTime() )
|
||||||
|
@ -517,7 +517,7 @@ void Resource::Download( http::Agent* http, const fs::path& file, const http::He
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resource::EditContent( http::Agent* http, const http::Header& auth, DateTime& sync_time )
|
bool Resource::EditContent( http::Agent* http, DateTime& sync_time )
|
||||||
{
|
{
|
||||||
assert( http != 0 ) ;
|
assert( http != 0 ) ;
|
||||||
assert( m_parent != 0 ) ;
|
assert( m_parent != 0 ) ;
|
||||||
|
@ -530,10 +530,10 @@ bool Resource::EditContent( http::Agent* http, const http::Header& auth, DateTim
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Upload( http, m_edit, auth, false, sync_time ) ;
|
return Upload( http, m_edit, false, sync_time ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Resource::Create( http::Agent* http, const http::Header& auth, DateTime& sync_time )
|
bool Resource::Create( http::Agent* http, DateTime& sync_time )
|
||||||
{
|
{
|
||||||
assert( http != 0 ) ;
|
assert( http != 0 ) ;
|
||||||
assert( m_parent != 0 ) ;
|
assert( m_parent != 0 ) ;
|
||||||
|
@ -551,7 +551,7 @@ bool Resource::Create( http::Agent* http, const http::Header& auth, DateTime& sy
|
||||||
% xml::Escape(m_name)
|
% xml::Escape(m_name)
|
||||||
).str() ;
|
).str() ;
|
||||||
|
|
||||||
http::Header hdr( auth ) ;
|
http::Header hdr ;
|
||||||
hdr.Add( "Content-Type: application/atom+xml" ) ;
|
hdr.Add( "Content-Type: application/atom+xml" ) ;
|
||||||
|
|
||||||
http::XmlResponse xml ;
|
http::XmlResponse xml ;
|
||||||
|
@ -563,7 +563,7 @@ bool Resource::Create( http::Agent* http, const http::Header& auth, DateTime& sy
|
||||||
}
|
}
|
||||||
else if ( !m_parent->m_create.empty() )
|
else if ( !m_parent->m_create.empty() )
|
||||||
{
|
{
|
||||||
return Upload( http, m_parent->m_create + "?convert=false", auth, true, sync_time ) ;
|
return Upload( http, m_parent->m_create + "?convert=false", true, sync_time ) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -575,7 +575,6 @@ bool Resource::Create( http::Agent* http, const http::Header& auth, DateTime& sy
|
||||||
bool Resource::Upload(
|
bool Resource::Upload(
|
||||||
http::Agent* http,
|
http::Agent* http,
|
||||||
const std::string& link,
|
const std::string& link,
|
||||||
const http::Header& auth,
|
|
||||||
bool post,
|
bool post,
|
||||||
DateTime& sync_time )
|
DateTime& sync_time )
|
||||||
{
|
{
|
||||||
|
@ -585,7 +584,7 @@ bool Resource::Upload(
|
||||||
std::ostringstream xcontent_len ;
|
std::ostringstream xcontent_len ;
|
||||||
xcontent_len << "X-Upload-Content-Length: " << file.Size() ;
|
xcontent_len << "X-Upload-Content-Length: " << file.Size() ;
|
||||||
|
|
||||||
http::Header hdr( auth ) ;
|
http::Header hdr ;
|
||||||
hdr.Add( "Content-Type: application/atom+xml" ) ;
|
hdr.Add( "Content-Type: application/atom+xml" ) ;
|
||||||
hdr.Add( "X-Upload-Content-Type: application/octet-stream" ) ;
|
hdr.Add( "X-Upload-Content-Type: application/octet-stream" ) ;
|
||||||
hdr.Add( xcontent_len.str() ) ;
|
hdr.Add( xcontent_len.str() ) ;
|
||||||
|
|
|
@ -32,7 +32,6 @@ namespace gr {
|
||||||
namespace http
|
namespace http
|
||||||
{
|
{
|
||||||
class Agent ;
|
class Agent ;
|
||||||
class Header ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Entry ;
|
class Entry ;
|
||||||
|
@ -77,7 +76,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, const http::Header& auth, DateTime& sync_time ) ;
|
void Sync( http::Agent* http, DateTime& sync_time ) ;
|
||||||
|
|
||||||
// children access
|
// children access
|
||||||
iterator begin() const ;
|
iterator begin() const ;
|
||||||
|
@ -124,19 +123,19 @@ private :
|
||||||
private :
|
private :
|
||||||
void SetState( State new_state ) ;
|
void SetState( State new_state ) ;
|
||||||
|
|
||||||
void Download( http::Agent* http, const fs::path& file, const http::Header& auth ) const ;
|
void Download( http::Agent* http, const fs::path& file ) const ;
|
||||||
bool EditContent( http::Agent* http, const http::Header& auth, DateTime& sync_time ) ;
|
bool EditContent( http::Agent* http, DateTime& sync_time ) ;
|
||||||
bool Create( http::Agent* http, const http::Header& auth, DateTime& sync_time ) ;
|
bool Create( http::Agent* http, DateTime& sync_time ) ;
|
||||||
bool Upload( http::Agent* http, const std::string& link, const http::Header& auth, bool post, DateTime& sync_time ) ;
|
bool Upload( http::Agent* http, const std::string& link, bool post, DateTime& sync_time ) ;
|
||||||
|
|
||||||
void FromRemoteFolder( const Entry& remote, const DateTime& last_sync ) ;
|
void FromRemoteFolder( const Entry& remote, const DateTime& last_sync ) ;
|
||||||
void FromRemoteFile( const Entry& remote, const DateTime& last_sync ) ;
|
void FromRemoteFile( const Entry& remote, const DateTime& last_sync ) ;
|
||||||
|
|
||||||
void DeleteLocal() ;
|
void DeleteLocal() ;
|
||||||
void DeleteRemote( http::Agent* http, const http::Header& auth ) ;
|
void DeleteRemote( http::Agent* http ) ;
|
||||||
|
|
||||||
void AssignIDs( const Entry& remote ) ;
|
void AssignIDs( const Entry& remote ) ;
|
||||||
void SyncSelf( http::Agent* http, const http::Header& auth, DateTime& sync_time ) ;
|
void SyncSelf( http::Agent* http, DateTime& sync_time ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
std::string m_name ;
|
std::string m_name ;
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "CommonUri.hh"
|
#include "CommonUri.hh"
|
||||||
|
|
||||||
#include "http/Agent.hh"
|
#include "http/Agent.hh"
|
||||||
#include "http/Header.hh"
|
|
||||||
#include "util/Crypt.hh"
|
#include "util/Crypt.hh"
|
||||||
#include "util/log/Log.hh"
|
#include "util/log/Log.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "protocol/Json.hh"
|
||||||
|
@ -262,7 +261,7 @@ void State::Write( const fs::path& filename ) const
|
||||||
fs << result ;
|
fs << result ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void State::Sync( http::Agent *http, const http::Header& auth )
|
void State::Sync( http::Agent *http )
|
||||||
{
|
{
|
||||||
// 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)
|
||||||
|
@ -272,7 +271,7 @@ void State::Sync( http::Agent *http, const http::Header& auth )
|
||||||
// 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, auth, last_sync_time ) ;
|
m_res.Root()->Sync( http, last_sync_time ) ;
|
||||||
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 ) ;
|
||||||
|
|
|
@ -31,7 +31,6 @@ namespace gr {
|
||||||
namespace http
|
namespace http
|
||||||
{
|
{
|
||||||
class Agent ;
|
class Agent ;
|
||||||
class Header ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Json ;
|
class Json ;
|
||||||
|
@ -58,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, const http::Header& auth ) ;
|
void Sync( http::Agent *http ) ;
|
||||||
|
|
||||||
iterator begin() ;
|
iterator begin() ;
|
||||||
iterator end() ;
|
iterator end() ;
|
||||||
|
|
|
@ -50,4 +50,11 @@ std::ostream& operator<<( std::ostream& os, const Header& h )
|
||||||
return os ;
|
return os ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Header operator+( const Header& header, const std::string& str )
|
||||||
|
{
|
||||||
|
Header h( header ) ;
|
||||||
|
h.Add( str ) ;
|
||||||
|
return h ;
|
||||||
|
}
|
||||||
|
|
||||||
} } // end of namespace
|
} } // end of namespace
|
||||||
|
|
|
@ -46,5 +46,6 @@ private :
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
std::ostream& operator<<( std::ostream& os, const Header& h ) ;
|
std::ostream& operator<<( std::ostream& os, const Header& h ) ;
|
||||||
|
Header operator+( const Header& header, const std::string& str ) ;
|
||||||
|
|
||||||
}} // end of namespace
|
}} // end of namespace
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
grive: an GPL program to sync a local directory with Google Drive
|
||||||
|
Copyright (C) 2012 Wan Wai Ho
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation version 2
|
||||||
|
of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AuthAgent.hh"
|
||||||
|
#include "http/Header.hh"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
|
||||||
|
using namespace http ;
|
||||||
|
|
||||||
|
AuthAgent::AuthAgent( const OAuth2& auth, std::auto_ptr<Agent> real_agent ) :
|
||||||
|
m_auth ( auth ),
|
||||||
|
m_agent ( real_agent )
|
||||||
|
{
|
||||||
|
assert( m_agent.get() != 0 ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Header AuthAgent::AppendHeader( const Header& hdr ) const
|
||||||
|
{
|
||||||
|
Header h(hdr) ;
|
||||||
|
h.Add( "Authorization: Bearer " + m_auth.AccessToken() ) ;
|
||||||
|
h.Add( "GData-Version: 3.0" ) ;
|
||||||
|
return h ;
|
||||||
|
}
|
||||||
|
|
||||||
|
long AuthAgent::Put(
|
||||||
|
const std::string& url,
|
||||||
|
const std::string& data,
|
||||||
|
Receivable *dest,
|
||||||
|
const Header& hdr )
|
||||||
|
{
|
||||||
|
return m_agent->Put( url, data, dest, AppendHeader(hdr) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
long AuthAgent::Put(
|
||||||
|
const std::string& url,
|
||||||
|
StdioFile& file,
|
||||||
|
Receivable *dest,
|
||||||
|
const Header& hdr )
|
||||||
|
{
|
||||||
|
return m_agent->Put( url, file, dest, AppendHeader(hdr) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
long AuthAgent::Get(
|
||||||
|
const std::string& url,
|
||||||
|
Receivable *dest,
|
||||||
|
const Header& hdr )
|
||||||
|
{
|
||||||
|
return m_agent->Get( url, dest, AppendHeader(hdr) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
long AuthAgent::Post(
|
||||||
|
const std::string& url,
|
||||||
|
const std::string& data,
|
||||||
|
Receivable *dest,
|
||||||
|
const Header& hdr )
|
||||||
|
{
|
||||||
|
return m_agent->Post( url, data, dest, AppendHeader(hdr) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
long AuthAgent::Custom(
|
||||||
|
const std::string& method,
|
||||||
|
const std::string& url,
|
||||||
|
Receivable *dest,
|
||||||
|
const Header& hdr )
|
||||||
|
{
|
||||||
|
return m_agent->Custom( method, url, dest, AppendHeader(hdr) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AuthAgent::RedirLocation() const
|
||||||
|
{
|
||||||
|
return m_agent->RedirLocation() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AuthAgent::Escape( const std::string& str )
|
||||||
|
{
|
||||||
|
return m_agent->Escape( str ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AuthAgent::Unescape( const std::string& str )
|
||||||
|
{
|
||||||
|
return m_agent->Unescape( str ) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
grive: an GPL program to sync a local directory with Google Drive
|
||||||
|
Copyright (C) 2012 Wan Wai Ho
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation version 2
|
||||||
|
of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "http/Agent.hh"
|
||||||
|
#include "OAuth2.hh"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace gr {
|
||||||
|
|
||||||
|
/*! \brief An HTTP agent with support OAuth2
|
||||||
|
|
||||||
|
This is a HTTP agent that provide support for OAuth2. It will also perform retries on
|
||||||
|
certain HTTP errors.
|
||||||
|
*/
|
||||||
|
class AuthAgent : public http::Agent
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
AuthAgent( const OAuth2& auth, std::auto_ptr<http::Agent> real_agent ) ;
|
||||||
|
|
||||||
|
long Put(
|
||||||
|
const std::string& url,
|
||||||
|
const std::string& data,
|
||||||
|
http::Receivable *dest,
|
||||||
|
const http::Header& hdr ) ;
|
||||||
|
|
||||||
|
long Put(
|
||||||
|
const std::string& url,
|
||||||
|
StdioFile& file,
|
||||||
|
http::Receivable *dest,
|
||||||
|
const http::Header& hdr ) ;
|
||||||
|
|
||||||
|
long Get(
|
||||||
|
const std::string& url,
|
||||||
|
http::Receivable *dest,
|
||||||
|
const http::Header& hdr ) ;
|
||||||
|
|
||||||
|
long Post(
|
||||||
|
const std::string& url,
|
||||||
|
const std::string& data,
|
||||||
|
http::Receivable *dest,
|
||||||
|
const http::Header& hdr ) ;
|
||||||
|
|
||||||
|
long Custom(
|
||||||
|
const std::string& method,
|
||||||
|
const std::string& url,
|
||||||
|
http::Receivable *dest,
|
||||||
|
const http::Header& hdr ) ;
|
||||||
|
|
||||||
|
std::string RedirLocation() const ;
|
||||||
|
|
||||||
|
std::string Escape( const std::string& str ) ;
|
||||||
|
std::string Unescape( const std::string& str ) ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
http::Header AppendHeader( const http::Header& hdr ) const ;
|
||||||
|
|
||||||
|
private :
|
||||||
|
OAuth2 m_auth ;
|
||||||
|
const std::auto_ptr<http::Agent> m_agent ;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
} // end of namespace
|
Loading…
Reference in New Issue