Experimental support for syncing Google Documents (issue #46)

FIXME:
- Files are "remote changed" and re-downloaded after being uploaded, which is
  indeed correct because they really differ after re-downloading, but should be fixed
- Extension is added to filename after uploading
googledocs
Vitaliy Filippov 2016-05-17 00:17:59 +03:00
parent 1bd86307c6
commit 6670ae2d24
4 changed files with 46 additions and 12 deletions

View File

@ -76,6 +76,7 @@ Enjoy!
- ignore regexp does not persist anymore (note that Grive will still track it to not
accidentally delete remote files when changing ignore regexp)
- added options to limit upload and download speed
- added ability to sync google documents
### Grive2 v0.5

View File

@ -169,7 +169,9 @@ void Resource::FromRemoteFile( const Entry& remote )
{
Trace( "file %1% change stamp = %2%", Path(), remote.ChangeStamp() ) ;
if ( remote.MTime().Sec() > m_mtime.Sec() || remote.MD5() != m_md5 || remote.ChangeStamp() > 0 )
if ( remote.MTime().Sec() > m_mtime.Sec() ||
( !remote.MD5().empty() && remote.MD5() != m_md5 ) ||
remote.ChangeStamp() > 0 )
{
Log( "file %1% is created in remote (change %2%)", path,
remote.ChangeStamp(), log::verbose ) ;
@ -182,17 +184,17 @@ void Resource::FromRemoteFile( const Entry& remote )
m_state = local_deleted ;
}
}
// remote checksum unknown, assume the file is not changed in remote
else if ( remote.MD5().empty() )
// remote download URL unknown, skip file
else if ( remote.ContentSrc().empty() )
{
Log( "file %1% has unknown checksum in remote. assumed in sync",
Log( "file %1% has unknown download URL. assumed in sync",
Path(), log::verbose ) ;
m_state = sync ;
}
// if checksum is equal, no need to compare the mtime
else if ( remote.MD5() == m_md5 )
else if ( !remote.MD5().empty() && remote.MD5() == m_md5 )
{
Log( "file %1% is already in sync", Path(), log::verbose ) ;
m_state = sync ;
@ -209,13 +211,21 @@ void Resource::FromRemoteFile( const Entry& remote )
Log( "file %1% is changed in remote", path, log::verbose ) ;
m_state = remote_changed ;
}
// google document
else if ( remote.MD5().empty() && m_state == remote_deleted )
{
Log( "file %1% has no MD5 and is in sync", path, log::verbose ) ;
m_state = sync ;
}
// remote also has the file, so it's not new in local
else if ( m_state == local_new || m_state == remote_deleted )
{
Log( "file %1% is changed in local", path, log::verbose ) ;
m_state = local_changed ;
}
else
Trace( "file %1% state is %2%", m_name, m_state ) ;
}

View File

@ -151,7 +151,7 @@ void State::FromRemote( const Entry& e )
// common checkings
if ( !e.IsDir() && ( fn.empty() || e.ContentSrc().empty() ) )
Log( "%1% \"%2%\" is a google document, ignored", k, e.Name(), log::verbose ) ;
Log( "%1% \"%2%\" has no download link or filename, ignored", k, e.Name(), log::verbose ) ;
else if ( fn.find('/') != fn.npos )
Log( "%1% \"%2%\" contains a slash in its name, ignored", k, e.Name(), log::verbose ) ;

View File

@ -66,10 +66,33 @@ void Entry2::Update( const Val& item )
m_is_removed = file["labels"]["trashed"].Bool() ;
if ( !m_is_dir )
{
if ( !file.Has( "md5Checksum" ) || !file.Has("downloadUrl") )
if ( !file.Has( "md5Checksum" ) && file.Has( "exportLinks" ) )
{
// This is either a google docs document or a not-yet-uploaded file. Ignore it.
// FIXME: We'll need to compare timestamps to support google docs.
// This is a google docs document.
const Val::Object& obj = file["exportLinks"].AsObject() ;
const char ooxml[] = "application/vnd.openxmlformats-officedocument";
for ( Val::Object::const_iterator i = obj.begin() ; i != obj.end() ; ++i )
if ( i->first.substr( 0, sizeof( ooxml ) - 1 ) == ooxml )
m_content_src = i->second.Str();
if ( m_content_src.empty() )
m_content_src = obj.begin()->second.Str();
if ( !m_content_src.empty() )
{
size_t pos = m_content_src.find( "exportFormat=" );
if ( pos != std::string::npos )
{
size_t end = m_content_src.find( '&', pos+13 );
if ( end == std::string::npos )
end = m_content_src.length();
std::string fmt = m_content_src.substr( pos+13, end-pos-13 );
if ( m_filename.substr( m_filename.length() - fmt.length() - 1 ) != "."+fmt )
m_filename += "."+fmt;
}
}
}
else if ( !file.Has( "md5Checksum" ) || !file.Has("downloadUrl") )
{
// This is a not-yet-uploaded file. Ignore it.
m_is_removed = true;
}
else