iwonbigbro/gsync

Datetime format not in ISO8601

Closed this issue · 2 comments

xsbr commented

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)

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"">

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...