diff --git a/libgrive/src/drive/CommonUri.hh b/libgrive/src/drive/CommonUri.hh new file mode 100644 index 0000000..dd619d7 --- /dev/null +++ b/libgrive/src/drive/CommonUri.hh @@ -0,0 +1,27 @@ +/* + 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 + +namespace gr +{ + const std::string root_url = "https://docs.google.com/feeds/default/private/full" ; +} diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index 219e033..76a1501 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -19,6 +19,7 @@ #include "Drive.hh" +#include "CommonUri.hh" #include "File.hh" #include "http/HTTP.hh" @@ -44,8 +45,6 @@ namespace gr { -const std::string root_url = "https://docs.google.com/feeds/default/private/full" ; - Drive::Drive( OAuth2& auth ) : m_auth( auth ), m_root( ".", "https://docs.google.com/feeds/default/private/full/folder%3Aroot" ) diff --git a/libgrive/src/drive/File.cc b/libgrive/src/drive/File.cc index 71777b0..5154e46 100644 --- a/libgrive/src/drive/File.cc +++ b/libgrive/src/drive/File.cc @@ -19,6 +19,8 @@ #include "File.hh" +#include "CommonUri.hh" + #include "http/Download.hh" #include "http/StringResponse.hh" #include "http/XmlResponse.hh" @@ -47,12 +49,17 @@ File::File( const Json& entry ) void File::Update( const Json& entry ) { m_title = entry["title"]["$t"].Str() ; - m_filename = entry["docs$suggestedFilename"]["$t"].Str() ; + + m_filename = entry.Has("docs$suggestedFilename") ? + entry["docs$suggestedFilename"]["$t"].Str() : "" ; + m_href = entry["content"]["src"].Str() ; m_parent = Parent( entry ) ; m_server_modified = DateTime( entry["updated"]["$t"].Str() ) ; m_etag = entry["gd$etag"].Str() ; + m_resource_id = entry["gd$resourceId"]["$t"].Str() ; + m_server_md5 = entry.Has("docs$md5Checksum") ? entry["docs$md5Checksum"]["$t"].Str() : "" ; @@ -171,4 +178,25 @@ std::cout << xml.Response() << std::endl ; return true ; } +std::string File::ResourceID() const +{ + return m_resource_id ; +} + +std::string File::ETag() const +{ + return m_etag ; +} + +void File::Delete( http::Agent *http, const http::Headers& auth ) +{ + http::Headers hdr( auth ) ; + hdr.push_back( "If-Match: " + m_etag ) ; + +std::cout << root_url + "/" + m_resource_id + "?delete=true" << std::endl ; + + http::StringResponse str ; + http->Custom( "DELETE", root_url + "/" + m_resource_id + "?delete=true", &str, hdr ) ; +} + } // end of namespace diff --git a/libgrive/src/drive/File.hh b/libgrive/src/drive/File.hh index 6537ff6..f4b673f 100644 --- a/libgrive/src/drive/File.hh +++ b/libgrive/src/drive/File.hh @@ -44,12 +44,16 @@ public : std::string ServerMD5() const ; DateTime ServerModified() const ; + std::string ResourceID() const ; + std::string ETag() const ; + std::string Href() const ; std::string Parent() const ; void Download( const Path& file, const http::Headers& auth ) const ; bool Upload( std::streambuf *file, const http::Headers& auth ) ; - + void Delete( gr::http::Agent* http, const gr::http::Headers& auth ) ; + private : void Update( const Json& entry ) ; static std::string Parent( const Json& entry ) ; @@ -60,6 +64,7 @@ private : std::string m_kind ; std::string m_server_md5 ; std::string m_etag ; + std::string m_resource_id ; std::string m_href ; std::string m_parent ; diff --git a/libgrive/src/http/HTTP.cc b/libgrive/src/http/HTTP.cc index 179a62c..b1a2f9a 100644 --- a/libgrive/src/http/HTTP.cc +++ b/libgrive/src/http/HTTP.cc @@ -217,6 +217,37 @@ long Agent::Post( return http_code ; } +long Agent::Custom( + const std::string& method, + const std::string& url, + Receivable *dest, + const http::Headers& hdr ) +{ + CURL *curl = m_pimpl->curl ; + + ::curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, method.c_str() ); + ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Agent::Receive ) ; + ::curl_easy_setopt(curl, CURLOPT_WRITEDATA, dest ) ; + + SetHeader( hdr ) ; + + CURLcode curl_code = ::curl_easy_perform(curl); + + long http_code = 0; + ::curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + + if ( curl_code != CURLE_OK ) + throw Exception( curl_code, http_code, m_pimpl->error ) ; + else if (http_code >= 400 ) + { + std::cout << "http error " << http_code << std::endl ; + throw Exception( curl_code, http_code, m_pimpl->error ) ; + } + + return http_code ; +} + void Agent::SetHeader( const http::Headers& hdr ) { // set headers @@ -240,8 +271,6 @@ std::string Agent::Escape( const std::string& str ) std::string result = tmp ; curl_free( tmp ) ; - curl_easy_cleanup(curl); - return result ; } @@ -254,8 +283,6 @@ std::string Agent::Unescape( const std::string& str ) std::string result = tmp ; curl_free( tmp ) ; - curl_easy_cleanup(curl); - return result ; } diff --git a/libgrive/src/http/HTTP.hh b/libgrive/src/http/HTTP.hh index dc0c71b..a1e2f81 100644 --- a/libgrive/src/http/HTTP.hh +++ b/libgrive/src/http/HTTP.hh @@ -59,6 +59,12 @@ public : Receivable *dest, const http::Headers& hdr = http::Headers() ) ; + long Custom( + const std::string& method, + const std::string& url, + Receivable *dest, + const http::Headers& hdr = http::Headers() ) ; + std::string RedirLocation() const ; std::string Escape( const std::string& str ) ; diff --git a/libgrive/src/xml/Node.hh b/libgrive/src/xml/Node.hh index 77697b2..a3dd538 100644 --- a/libgrive/src/xml/Node.hh +++ b/libgrive/src/xml/Node.hh @@ -73,6 +73,11 @@ public : public : iterator( ImplVec::iterator *impl ) ; + typedef Node value_type ; + + value_type operator*() const ; +// value_type operator*() const ; + private : ImplVec::iterator *m_node ; } ;