iwonbigbro / gsync

RSync for Google Drive - GSync
Other
238 stars 50 forks source link

Datetime format not in ISO8601 #73

Closed xsbr closed 9 years ago

xsbr commented 10 years ago

Running gsync received this error about an invalid datetime format:

Error: <HttpError 400 when requesting https://www.googleapis.com/drive/v2/files/xxxx?alt=json&setModifiedDate=true&newRevision=true
returned "Invalid value for: Invalid format: "2014-07-27T18:23:25.330175" is too short">

According Google Drive API Documentation, DateTime needs to be in ISO8601 format and timezone is required https://developers.google.com/resources/api-libraries/documentation/drive/v2/java/latest/com/google/api/services/drive/model/File.html http://en.wikipedia.org/wiki/ISO_8601

isoformat() in python doesn't include TimeZone unless be defined, so I put tzinfo in all isoformat() calls

diff -Naur iwonbigbro/gsync/libgsync/drive/__init__.py xsbr/gsync/libgsync/drive/__init__.py
--- iwonbigbro/gsync/libgsync/drive/__init__.py 2014-07-27 18:54:53.000000000 -0300
+++ xsbr/gsync/libgsync/drive/__init__.py       2014-07-27 23:27:21.000000000 -0300
@@ -6,7 +6,7 @@
 """The GSync Drive module that provides an interface to the Google Drive"""

 import os, sys, re, datetime, shelve, time, retrying
-
+from dateutil.tz import tzutc
 from contextlib import contextmanager

 # Setup default retryer.
@@ -64,7 +64,8 @@
         # Public
         self.closed = False
         self.description = ""
-        self.modified_date = datetime.datetime.now().isoformat()
+        self.modified_date = datetime.datetime.now().replace(
+            tzinfo=tzutc()).isoformat()

         # Private
         drive = Drive()
diff -Naur iwonbigbro/gsync/libgsync/sync/file/remote/__init__.py xsbr/gsync/libgsync/sync/file/remote/__init__.py
--- iwonbigbro/gsync/libgsync/sync/file/remote/__init__.py      2014-07-27 18:54:53.000000000 -0300
+++ xsbr/gsync/libgsync/sync/file/remote/__init__.py    2014-07-27 23:40:53.000000000 -0300
@@ -12,6 +12,7 @@
 from libgsync.options import GsyncOptions
 from apiclient.http import MediaIoBaseUpload, MediaUploadProgress
 from libgsync.drive import Drive
+from dateutil.tz import tzutc

 class SyncFileRemote(SyncFile):
@@ -186,7 +187,7 @@
         info.set_stat_info(st_info)

         mtime_utc = datetime.datetime.utcfromtimestamp(
-            attrs.mtime).isoformat()
+            attrs.mtime).replace(tzinfo=tzutc()).isoformat()

         Drive().update(path, properties = {
             'description': info.description,
diff -Naur iwonbigbro/gsync/libgsync/sync/file/local/__init__.py xsbr/gsync/libgsync/sync/file/local/__init__.py
--- iwonbigbro/gsync/libgsync/sync/file/local/__init__.py       2014-07-27 18:54:53.000000000 -0300
+++ xsbr/gsync/libgsync/sync/file/local/__init__.py     2014-07-27 23:40:39.000000000 -0300
@@ -13,6 +13,7 @@
 from libgsync.sync.file import SyncFile, SyncFileInfo
 from libgsync.options import GsyncOptions
 from apiclient.http import MediaFileUpload, MediaUploadProgress
+from dateutil.tz import tzutc

 class SyncFileLocal(SyncFile):
@@ -62,7 +63,7 @@
                 title=filename,
                 modifiedDate=datetime.datetime.utcfromtimestamp(
                     st_info.st_mtime
-                ).isoformat(),
+                ).replace(tzinfo=tzutc()).isoformat(),
                 mimeType=mimetype,
                 description=st_info,
                 fileSize=st_info.st_size,

I found another bizarre error:

Error: <HttpError 400 when requesting https://www.googleapis.com/drive/v2/files/xxxx?alt=json&setModifiedDate=true&newRevision=true
returned "Invalid value for: Invalid format: "2014-07-27T15:53:23.280423d+00:00" is malformed at 'd+00:00'">

There is a "d" character in strftime

diff -Naur iwonbigbro/gsync/libgsync/sync/file/__init__.py xsbr/gsync/libgsync/sync/file/__init__.py
--- iwonbigbro/gsync/libgsync/sync/file/__init__.py     2014-07-27 18:54:53.000000000 -0300
+++ xsbr/gsync/libgsync/sync/file/__init__.py   2014-07-27 23:30:11.000000000 -0300
@@ -80,7 +80,7 @@
         return "SyncFileInfoDatetime(%s)" % repr(self.__value)

     def __str__(self):
-        return self.__value.strftime("%Y-%m-%dT%H:%M:%S.%fd+00:00")
+        return self.__value.strftime("%Y-%m-%dT%H:%M:%S.%f+00:00")

     def __secs(self):
         delta = (self.__value - self.__epoch)
nwagner commented 9 years ago

I'm still seeing an error: Error: <HttpError 400 when requesting https://www.googleapis.com/drive/v2/files/0Bxz1GwrmCSg4T2MzQVR6amJtR00?alt=json&setModifiedDate=true&newRevision=true returned "Invalid value for: Invalid format: "2014-05-31T15:39:29+00:00" is malformed at "+00:00"">

benfry commented 9 years ago

Was able to fix(?) this by using strftime("%Y-%m-%dT%H:%M:%S.%f%z") instead of isoformat(). It seems that microseconds are required in the RFC 3339 spec, or at least that's what the Drive API requires here.

Still trying to sort out whether it's all working properly, but the HttpError 400 is gone. Thanks @xsbr for pointing the way...