drive: work around drive bug which didn't set modtime of copied docs

Google drive appears to no longer be copying the modification time of
google docs.

Setting the mod time immediately after the copy doesn't work either,
so this patch copies the object, waits for 1 second and then sets the
modtime.

Fixes #4517
This commit is contained in:
Nick Craig-Wood 2020-08-18 19:36:50 +01:00
parent 0931b84940
commit b5ba077a2f

View file

@ -2258,13 +2258,13 @@ func (f *Fs) Precision() time.Duration {
func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) { func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object, error) {
var srcObj *baseObject var srcObj *baseObject
ext := "" ext := ""
readDescription := false isDoc := false
switch src := src.(type) { switch src := src.(type) {
case *Object: case *Object:
srcObj = &src.baseObject srcObj = &src.baseObject
case *documentObject: case *documentObject:
srcObj, ext = &src.baseObject, src.ext() srcObj, ext = &src.baseObject, src.ext()
readDescription = true isDoc = true
case *linkObject: case *linkObject:
srcObj, ext = &src.baseObject, src.ext() srcObj, ext = &src.baseObject, src.ext()
default: default:
@ -2288,7 +2288,7 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object,
return nil, err return nil, err
} }
if readDescription { if isDoc {
// preserve the description on copy for docs // preserve the description on copy for docs
info, err := f.getFile(actualID(srcObj.id), "description") info, err := f.getFile(actualID(srcObj.id), "description")
if err != nil { if err != nil {
@ -2320,6 +2320,22 @@ func (f *Fs) Copy(ctx context.Context, src fs.Object, remote string) (fs.Object,
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Google docs aren't preserving their mod time after copy, so set them explicitly
// See: https://github.com/rclone/rclone/issues/4517
//
// FIXME remove this when google fixes the problem!
if isDoc {
// A short sleep is needed here in order to make the
// change effective, without it is is ignored. This is
// probably some eventual consistency nastiness.
sleepTime := 2 * time.Second
fs.Debugf(f, "Sleeping for %v before setting the modtime to work around drive bug - see #4517")
time.Sleep(sleepTime)
err = newObject.SetModTime(ctx, src.ModTime(ctx))
if err != nil {
return nil, err
}
}
if existingObject != nil { if existingObject != nil {
err = existingObject.Remove(ctx) err = existingObject.Remove(ctx)
if err != nil { if err != nil {