diff --git a/libgrive/CMakeLists.txt b/libgrive/CMakeLists.txt index 39d64f7..54776bd 100644 --- a/libgrive/CMakeLists.txt +++ b/libgrive/CMakeLists.txt @@ -49,10 +49,6 @@ include_directories( ${YAJL_INCLUDE_DIRS} ) -file(GLOB DRIVE_HEADERS - ${libgrive_SOURCE_DIR}/src/drive/*.hh -) - file (GLOB PROTOCOL_HEADERS ${libgrive_SOURCE_DIR}/src/protocol/*.hh ) @@ -67,14 +63,12 @@ file (GLOB XML_HEADERS file (GLOB LIBGRIVE_SRC src/base/*.cc - src/drive/*.cc src/drive2/*.cc src/http/*.cc src/protocol/*.cc src/json/*.cc src/util/*.cc src/util/log/*.cc - src/xml/*.cc ) add_definitions( @@ -121,9 +115,7 @@ IF ( CPPUNIT_FOUND ) # list of test source files here file(GLOB TEST_SRC test/base/*.cc - test/drive/*.cc test/util/*.cc - test/xml/*.cc ) add_executable( unittest diff --git a/libgrive/src/drive/CommonUri.hh b/libgrive/src/drive/CommonUri.hh deleted file mode 100644 index bbc3b0b..0000000 --- a/libgrive/src/drive/CommonUri.hh +++ /dev/null @@ -1,34 +0,0 @@ -/* - Common URIs for the old "Document List" Google Docs API - 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 { namespace v1 -{ - const std::string feed_base = "https://docs.google.com/feeds/default/private/full" ; - const std::string feed_changes = "https://docs.google.com/feeds/default/private/changes" ; - const std::string feed_metadata = "https://docs.google.com/feeds/metadata/default" ; - - const std::string root_href = - "https://docs.google.com/feeds/default/private/full/folder%3Aroot" ; - const std::string root_create = - "https://docs.google.com/feeds/upload/create-session/default/private/full" ; -} } diff --git a/libgrive/src/drive/Entry1.cc b/libgrive/src/drive/Entry1.cc deleted file mode 100644 index 9f75138..0000000 --- a/libgrive/src/drive/Entry1.cc +++ /dev/null @@ -1,86 +0,0 @@ -/* - Item class implementation for the old "Document List" Google Docs API - Copyright (C) 2012 Wan Wai Ho, (C) 2015 Vitaliy Filippov - - 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 "Entry1.hh" -#include "CommonUri.hh" - -#include "util/Crypt.hh" -#include "util/log/Log.hh" -#include "util/OS.hh" -#include "xml/Node.hh" -#include "xml/NodeSet.hh" - -#include -#include - -namespace gr { namespace v1 { - -Entry1::Entry1(): - Entry () -{ - m_self_href = root_href; -} - -/// construct an entry for remote - Doclist API v3 -Entry1::Entry1( const xml::Node& n ) -{ - Update( n ) ; -} - -void Entry1::Update( const xml::Node& n ) -{ - m_title = n["title"] ; - m_etag = n["@gd:etag"] ; - m_filename = n["docs:suggestedFilename"] ; - m_content_src = n["content"]["@src"] ; - m_self_href = n["link"].Find( "@rel", "self" )["@href"] ; - m_mtime = DateTime( n["updated"] ) ; - - m_resource_id = n["gd:resourceId"] ; - m_md5 = n["docs:md5Checksum"] ; - m_is_dir = n["category"].Find( "@scheme", "http://schemas.google.com/g/2005#kind" )["@label"] == "folder" ; - m_is_editable = !n["link"].Find( "@rel", m_is_dir - ? "http://schemas.google.com/g/2005#resumable-create-media" : "http://schemas.google.com/g/2005#resumable-edit-media" ) - ["@href"].empty() ; - - // changestamp only appear in change feed entries - xml::NodeSet cs = n["docs:changestamp"]["@value"] ; - m_change_stamp = cs.empty() ? -1 : std::atoi( cs.front().Value().c_str() ) ; - if ( m_change_stamp != -1 ) - { - m_self_href = n["link"].Find( "@rel", "http://schemas.google.com/docs/2007#alt-self" )["@href"] ; - } - - m_parent_hrefs.clear( ) ; - xml::NodeSet parents = n["link"].Find( "@rel", "http://schemas.google.com/docs/2007#parent" ) ; - for ( xml::NodeSet::iterator i = parents.begin() ; i != parents.end() ; ++i ) - { - std::string href = (*i)["@href"]; - if ( href == root_href ) - href = "root"; // API-independent root href - m_parent_hrefs.push_back( href ) ; - } - - // convert to lower case for easy comparison - std::transform( m_md5.begin(), m_md5.end(), m_md5.begin(), tolower ) ; - - m_is_removed = !n["gd:deleted"].empty() || !n["docs:removed"].empty() ; -} - -} } // end of namespace gr::v1 diff --git a/libgrive/src/drive/Entry1.hh b/libgrive/src/drive/Entry1.hh deleted file mode 100644 index 6fff374..0000000 --- a/libgrive/src/drive/Entry1.hh +++ /dev/null @@ -1,42 +0,0 @@ -/* - Item class implementation for the old "Document List" Google Docs API - Copyright (C) 2012 Wan Wai Ho, (C) 2015 Vitaliy Filippov - - 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 "base/Entry.hh" - -namespace gr { - -namespace xml -{ - class Node ; -} - -namespace v1 { - -class Entry1: public Entry -{ -public : - Entry1( ) ; - explicit Entry1( const xml::Node& n ) ; -private : - void Update( const xml::Node& entry ) ; -} ; - -} } // end of namespace gr::v1 diff --git a/libgrive/src/drive/Feed1.cc b/libgrive/src/drive/Feed1.cc deleted file mode 100644 index 86d59bd..0000000 --- a/libgrive/src/drive/Feed1.cc +++ /dev/null @@ -1,64 +0,0 @@ -/* - Item list ("Feed") implementation for the old "Document List" Google Docs API - Copyright (C) 2012 Wan Wai Ho, (C) 2015 Vitaliy Filippov - - 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 "CommonUri.hh" -#include "Feed1.hh" - -#include "Entry1.hh" - -#include "http/Agent.hh" -#include "http/Header.hh" -#include "http/XmlResponse.hh" -#include "xml/NodeSet.hh" - -#include - -#include - -namespace gr { namespace v1 { - -Feed1::Feed1( const std::string &url ): - Feed( url ) -{ -} - -bool Feed1::GetNext( http::Agent *http ) -{ - http::XmlResponse xrsp ; - - if ( m_next.empty() ) - return false; - - http->Get( m_next, &xrsp, http::Header() ) ; - - xml::Node m_root = xrsp.Response() ; - xml::NodeSet xe = m_root["entry"] ; - m_entries.clear() ; - for ( xml::NodeSet::iterator i = xe.begin() ; i != xe.end() ; ++i ) - { - m_entries.push_back( Entry1( *i ) ); - } - - xml::NodeSet nss = m_root["link"].Find( "@rel", "next" ) ; - m_next = nss.empty() ? std::string( "" ) : nss["@href"]; - - return true; -} - -} } // end of namespace gr::v1 diff --git a/libgrive/src/drive/Feed1.hh b/libgrive/src/drive/Feed1.hh deleted file mode 100644 index 40f88a8..0000000 --- a/libgrive/src/drive/Feed1.hh +++ /dev/null @@ -1,40 +0,0 @@ -/* - Item list ("Feed") implementation for the old "Document List" Google Docs API - Copyright (C) 2012 Wan Wai Ho, (C) 2015 Vitaliy Filippov - - 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 "base/Feed.hh" - -#include "xml/Node.hh" -#include "xml/NodeSet.hh" - -#include - -#include - -namespace gr { namespace v1 { - -class Feed1: public Feed -{ -public : - Feed1( const std::string& url ) ; - bool GetNext( http::Agent *http ) ; -} ; - -} } // end of namespace gr::v1 diff --git a/libgrive/src/drive/Syncer1.cc b/libgrive/src/drive/Syncer1.cc deleted file mode 100644 index 94997e7..0000000 --- a/libgrive/src/drive/Syncer1.cc +++ /dev/null @@ -1,271 +0,0 @@ -/* - Syncer implementation for the old "Document List" Google Docs API - Copyright (C) 2012 Wan Wai Ho, (C) 2015 Vitaliy Filippov - - 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 "base/Resource.hh" -#include "CommonUri.hh" -#include "Entry1.hh" -#include "Feed1.hh" -#include "Syncer1.hh" - -#include "http/Agent.hh" -#include "http/Header.hh" -#include "http/StringResponse.hh" -#include "http/XmlResponse.hh" - -#include "xml/Node.hh" -#include "xml/NodeSet.hh" -#include "xml/String.hh" -#include "xml/TreeBuilder.hh" - -#include "util/File.hh" -#include "util/OS.hh" -#include "util/log/Log.hh" - -#include - -#include - -// for debugging -#include - -namespace gr { namespace v1 { - -// hard coded XML file -const std::string xml_meta = - "\n" - "" - "" - "%2%" - "" ; - -Syncer1::Syncer1( http::Agent *http ): - Syncer( http ) -{ - assert( http != 0 ) ; -} - -void Syncer1::DeleteRemote( Resource *res ) -{ - http::StringResponse str ; - - try - { - http::Header hdr ; - hdr.Add( "If-Match: " + res->ETag() ) ; - - // don't know why, but an update before deleting seems to work always - http::XmlResponse xml ; - m_http->Get( res->SelfHref(), &xml, hdr ) ; - AssignIDs( res, Entry1( xml.Response() ) ) ; - - m_http->Request( "DELETE", res->SelfHref(), NULL, &str, hdr ) ; - } - catch ( Exception& e ) - { - // don't rethrow here. there are some cases that I don't know why - // the delete will fail. - Trace( "Exception %1% %2%", - boost::diagnostic_information(e), - str.Response() ) ; - } -} - -bool Syncer1::EditContent( Resource *res, bool new_rev ) -{ - assert( res->Parent() ) ; - assert( res->Parent()->GetState() == Resource::sync ) ; - - if ( !res->IsEditable() ) - { - Log( "Cannot upload %1%: file read-only. %2%", res->Name(), res->StateStr(), log::warning ) ; - return false ; - } - - return Upload( res, feed_base + "/" + res->ResourceID() + ( new_rev ? "?new-revision=true" : "" ), false ) ; -} - -bool Syncer1::Create( Resource *res ) -{ - assert( res->Parent() ) ; - assert( res->Parent()->IsFolder() ) ; - assert( res->Parent()->GetState() == Resource::sync ) ; - - if ( res->IsFolder() ) - { - std::string uri = feed_base ; - if ( !res->Parent()->IsRoot() ) - uri += ( "/" + m_http->Escape( res->Parent()->ResourceID() ) + "/contents" ) ; - - std::string meta = (boost::format( xml_meta ) - % "folder" - % xml::Escape( res->Name() ) - ).str() ; - - http::Header hdr ; - hdr.Add( "Content-Type: application/atom+xml" ) ; - - http::XmlResponse xml ; - m_http->Post( uri, meta, &xml, hdr ) ; - AssignIDs( res, Entry1( xml.Response() ) ) ; - - return true ; - } - else if ( res->Parent()->IsEditable() ) - { - return Upload( res, root_create + (res->Parent()->ResourceID() == "folder:root" - ? "" : "/" + res->Parent()->ResourceID() + "/contents") + "?convert=false", true ) ; - } - else - { - Log( "parent of %1% does not exist: cannot upload", res->Name(), log::warning ) ; - return false ; - } -} - -bool Syncer1::Upload( Resource *res, - const std::string& link, - bool post ) -{ - File file( res->Path() ) ; - std::ostringstream xcontent_len ; - xcontent_len << "X-Upload-Content-Length: " << file.Size() ; - - http::Header hdr ; - hdr.Add( "Content-Type: application/atom+xml" ) ; - hdr.Add( "X-Upload-Content-Type: application/octet-stream" ) ; - hdr.Add( xcontent_len.str() ) ; - hdr.Add( "If-Match: " + res->ETag() ) ; - hdr.Add( "Expect:" ) ; - - std::string meta = (boost::format( xml_meta ) - % res->Kind() - % xml::Escape( res->Name() ) - ).str() ; - - bool retrying = false; - while ( true ) - { - if ( retrying ) - { - file.Seek( 0, SEEK_SET ); - os::Sleep( 5 ); - } - - try - { - http::StringResponse str ; - if ( post ) - m_http->Post( link, meta, &str, hdr ) ; - else - m_http->Put( link, meta, &str, hdr ) ; - } - catch ( Exception &e ) - { - std::string const *info = boost::get_error_info(e); - if ( info && (*info == "XML_Parse") ) - { - Log( "Error parsing pre-upload response XML, retrying whole upload in 5s", - log::warning ); - retrying = true; - continue; - } - else - { - throw e; - } - } - - http::Header uphdr ; - uphdr.Add( "Expect:" ) ; - uphdr.Add( "Accept:" ) ; - - // the content upload URL is in the "Location" HTTP header - std::string uplink = m_http->RedirLocation() ; - http::XmlResponse xml ; - - long http_code = 0; - try - { - http_code = m_http->Put( uplink, &file, &xml, uphdr ) ; - } - catch ( Exception &e ) - { - std::string const *info = boost::get_error_info(e); - if ( info && (*info == "XML_Parse") ) - { - Log( "Error parsing response XML, retrying whole upload in 5s", - log::warning ); - retrying = true; - continue; - } - else - { - throw e; - } - } - - if ( http_code == 410 || http_code == 412 ) - { - Log( "request failed with %1%, body: %2%, retrying whole upload in 5s", http_code, m_http->LastError(), log::warning ) ; - retrying = true; - continue; - } - - if ( retrying ) - Log( "upload succeeded on retry", log::warning ); - Entry1 responseEntry = Entry1( xml.Response() ); - AssignIDs( res, responseEntry ) ; - res->SetServerTime( responseEntry.MTime() ); - break; - } - - return true ; -} - -std::unique_ptr Syncer1::GetFolders() -{ - return std::unique_ptr( new Feed1( feed_base + "/-/folder?max-results=50&showroot=true" ) ); -} - -std::unique_ptr Syncer1::GetAll() -{ - return std::unique_ptr( new Feed1( feed_base + "?showfolders=true&showroot=true" ) ); -} - -std::string ChangesFeed( int changestamp ) -{ - boost::format feed( feed_changes + "?start-index=%1%" ) ; - return changestamp > 0 ? ( feed % changestamp ).str() : feed_changes ; -} - -std::unique_ptr Syncer1::GetChanges( long min_cstamp ) -{ - return std::unique_ptr( new Feed1( ChangesFeed( min_cstamp ) ) ); -} - -long Syncer1::GetChangeStamp( long min_cstamp ) -{ - http::XmlResponse xrsp ; - m_http->Get( ChangesFeed( min_cstamp ), &xrsp, http::Header() ) ; - - return std::atoi( xrsp.Response()["docs:largestChangestamp"]["@value"].front().Value().c_str() ); -} - -} } // end of namespace gr::v1 diff --git a/libgrive/src/drive/Syncer1.hh b/libgrive/src/drive/Syncer1.hh deleted file mode 100644 index 8c6580d..0000000 --- a/libgrive/src/drive/Syncer1.hh +++ /dev/null @@ -1,52 +0,0 @@ -/* - Syncer implementation for the old "Document List" Google Docs API - Copyright (C) 2012 Wan Wai Ho, (C) 2015 Vitaliy Filippov - - 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 "base/Syncer.hh" - -namespace gr { - -class Feed; - -namespace v1 { - -class Syncer1: public Syncer -{ - -public : - - Syncer1( http::Agent *http ); - - void DeleteRemote( Resource *res ); - bool EditContent( Resource *res, bool new_rev ); - bool Create( Resource *res ); - - std::unique_ptr GetFolders(); - std::unique_ptr GetAll(); - std::unique_ptr GetChanges( long min_cstamp ); - long GetChangeStamp( long min_cstamp ); - -private : - - bool Upload( Resource *res, const std::string& link, bool post); - -} ; - -} } // end of namespace gr::v1 diff --git a/libgrive/test/drive/EntryTest.cc b/libgrive/test/drive/EntryTest.cc deleted file mode 100644 index a78516d..0000000 --- a/libgrive/test/drive/EntryTest.cc +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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 "EntryTest.hh" - -#include "Assert.hh" - -#include "drive/Entry1.hh" -#include "xml/Node.hh" -#include "xml/NodeSet.hh" -#include "xml/TreeBuilder.hh" - -#include - -namespace grut { - -using namespace gr ; -using namespace gr::v1 ; - -Entry1Test::Entry1Test( ) -{ -} - -void Entry1Test::TestXml( ) -{ - xml::Node root = xml::TreeBuilder::ParseFile( TEST_DATA "entry.xml" ) ; - - CPPUNIT_ASSERT( !root["entry"].empty() ) ; - - Entry1 subject( root["entry"].front() ) ; - GRUT_ASSERT_EQUAL( "snes", subject.Title() ) ; - GRUT_ASSERT_EQUAL( "\"WxYPGE8CDyt7ImBk\"", subject.ETag() ) ; - GRUT_ASSERT_EQUAL( "https://docs.google.com/feeds/default/private/full/folder%3A0B5KhdsbryVeGMl83OEV1ZVc3cUE", - subject.SelfHref() ) ; - - GRUT_ASSERT_EQUAL( 1U, subject.ParentHrefs().size() ) ; - GRUT_ASSERT_EQUAL( "https://docs.google.com/feeds/default/private/full/folder%3A0B5KhdsbryVeGNEZjdUxzZHl3Sjg", - subject.ParentHrefs().front() ) ; - - GRUT_ASSERT_EQUAL( true, subject.IsDir() ) ; -} - -} // end of namespace grut diff --git a/libgrive/test/drive/EntryTest.hh b/libgrive/test/drive/EntryTest.hh deleted file mode 100644 index f7bc8f5..0000000 --- a/libgrive/test/drive/EntryTest.hh +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 -#include - -namespace grut { - -class Entry1Test : public CppUnit::TestFixture -{ -public : - Entry1Test( ) ; - - // declare suit function - CPPUNIT_TEST_SUITE( Entry1Test ) ; - CPPUNIT_TEST( TestXml ) ; - CPPUNIT_TEST_SUITE_END(); - -private : - void TestXml( ) ; -} ; - -} // end of namespace