diff --git a/README.md b/README.md index d6407c6..d79f223 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/libgrive/src/base/Resource.cc b/libgrive/src/base/Resource.cc index fecbe56..9d359a6 100644 --- a/libgrive/src/base/Resource.cc +++ b/libgrive/src/base/Resource.cc @@ -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 ) ; } diff --git a/libgrive/src/base/State.cc b/libgrive/src/base/State.cc index 44d8bf9..84b993e 100644 --- a/libgrive/src/base/State.cc +++ b/libgrive/src/base/State.cc @@ -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 ) ; diff --git a/libgrive/src/drive2/Entry2.cc b/libgrive/src/drive2/Entry2.cc index 75f7d96..1a91fd5 100644 --- a/libgrive/src/drive2/Entry2.cc +++ b/libgrive/src/drive2/Entry2.cc @@ -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