calendar additions for SyncEvent and UID

16 views
Skip to first unread message

Michael Ballbach

unread,
Nov 11, 2009, 10:20:51 AM11/11/09
to GData Python Client Library Contributors
I put together a python script that I run from mutt which takes ICS
files (we use outlook at work but I avoid it as much as possible) and
syncs them to my google calendar, sort of like the windows tool that
google provides. Anyway, to get this working, I had to add UID and
SyncEvent objects to the gdata API. I saw this issue as #215, it's
marked 'accepted', pardon my ignorance, I don't know if that means
someone has already supplied a patch or just that you've accepted it
as a valid issue.

I followed the examples and hope that I did it correctly. It works in
my program. I wasn't sure how to handle boolean values in the context
of the data model.

Additionally - is calendar awaiting the conversion to the new 2.0
style GDEntry/GDFeed data model? It appears so - but I wanted to
confirm that, because I couldn't find a related issue, so I thought
maybe it was not being done on purpose. I found issue 14, but the only
module I could see importing gdata.calendar is contacts, but I didn't
find a place in there where it used it.

Anyway, here's a patch.

--- /home/mballbach/src/gdata-2.0.4/src/gdata/calendar/__init__.py
2009-07-23 19:05:13.000000000 -0400
+++ ./gdata/calendar/__init__.py 2009-10-28 18:36:57.000000000 -0400
@@ -682,6 +682,33 @@
self.extension_elements = extension_elements or []
self.extension_attributes = extension_attributes or {}

+class SyncEvent(atom.AtomBase):
+ _tag = 'syncEvent'
+ _namespace = GCAL_NAMESPACE
+ _children = atom.AtomBase._children.copy()
+ _attributes = atom.AtomBase._attributes.copy()
+ _attributes['value'] = 'value'
+
+ def __init__(self, value='false', extension_elements=None,
+ extension_attributes=None, text=None):
+ self.value = value
+ self.text = text
+ self.extension_elements = extension_elements or []
+ self.extension_attributes = extension_attributes or {}
+
+class UID(atom.AtomBase):
+ _tag = 'uid'
+ _namespace = GCAL_NAMESPACE
+ _children = atom.AtomBase._children.copy()
+ _attributes = atom.AtomBase._attributes.copy()
+ _attributes['value'] = 'value'
+
+ def __init__(self, value=None, extension_elements=None,
+ extension_attributes=None, text=None):
+ self.value = value
+ self.text = text
+ self.extension_elements = extension_elements or []
+ self.extension_attributes = extension_attributes or {}

class WebContentGadgetPref(atom.AtomBase):

@@ -773,6 +800,8 @@

OriginalEvent)
_children['{%s}sequence' % GCAL_NAMESPACE] = ('sequence', Sequence)
_children['{%s}reminder' % gdata.GDATA_NAMESPACE] = ('reminder',
[Reminder])
+ _children['{%s}syncEvent' % GCAL_NAMESPACE] = ('sync_event',
SyncEvent)
+ _children['{%s}uid' % GCAL_NAMESPACE] = ('uid', UID)

def __init__(self, author=None, category=None, content=None,
atom_id=None, link=None, published=None,
@@ -783,7 +812,7 @@
where=None, when=None, who=None, quick_add=None,
extended_property=None, original_event=None,
batch_operation=None, batch_id=None, batch_status=None,
- sequence=None, reminder=None,
+ sequence=None, reminder=None, sync_event=None, uid=None,
extension_elements=None, extension_attributes=None, text=None):

gdata.BatchEntry.__init__(self, author=author,
category=category,
@@ -808,6 +837,8 @@
self.original_event = original_event
self.sequence = sequence
self.reminder = reminder or []
+ self.sync_event = sync_event
+ self.uid = uid
self.text = text
self.extension_elements = extension_elements or []
self.extension_attributes = extension_attributes or {}




I also added a unit test. The first chunk in the patch fixed the
testPostEntryWithCommentAndDelete test for me (otherwise the comment
can't be deleted because it thinks someone else added it). Two other
tests still fail consistently for me with or without my patch. One is
testPostUpdateAndDeleteSubscription which seems to have a hard-coded
feed ID in it, and I always get a 403. The other is
testCreateAndDeleteEventUsingBatch which complains about GetBatchLink
() returning None, but I haven't done any work with batch queries and
didn't look into it. Other than the occasional 302 problems noted
elsewhere on the list, the new test seems to successfully check the
new fields.

--- orig-service_test.py 2009-11-11 09:48:40.000000000 -0500
+++ service_test.py 2009-11-11 10:08:52.000000000 -0500
@@ -188,7 +188,7 @@
comments_entry.content = atom.Content(text='Comments content')
comments_entry.author.append(
atom.Author(name=atom.Name(text='GData Test user'),
- email=atom.Email(text='gdata.o...@gmail.com')))
+ email=atom.Email(text=username)))
new_comments_entry = self.cal_client.InsertEventComment
(comments_entry,
comments_feed.GetPostLink().href)

@@ -280,6 +280,78 @@
self.assertEquals(after_delete_query_result.entry
[0].event_status.value,
'CANCELED')

+ def testEventWithSyncEventAndUID(self):
+ """Test posting a new entry (with syncEvent and a UID) and
deleting it."""
+
+ # Get random data for creating event
+ r = random.Random()
+ r.seed()
+ random_event_number = str(r.randint(100000,1000000))
+ random_event_title = 'My Random Test Event %s' %
random_event_number
+
+ random_start_hour = (r.randint(1,1000000) % 23)
+ random_end_hour = random_start_hour + 1
+ non_random_start_minute = 0
+ non_random_end_minute = 0
+ random_month = (r.randint(1,1000000) % 12 + 1)
+ random_day_of_month = (r.randint(1,1000000) % 28 + 1)
+ non_random_year = 2008
+ start_time = '%04d-%02d-%02dT%02d:%02d:00.000-05:00' % (
+ non_random_year, random_month, random_day_of_month,
+ random_start_hour, non_random_start_minute,)
+ end_time = '%04d-%02d-%02dT%02d:%02d:00.000-05:00' % (
+ non_random_year, random_month, random_day_of_month,
+ random_end_hour, non_random_end_minute,)
+
+ # create a random event ID. I'm mimicing an example from outlook
here,
+ # the format doesn't seem to be important per the RFC except for
being
+ # globally unique.
+ uid_string = ''
+ for i in xrange(121):
+ uid_string += "%X" % r.randint(0, 0xf)
+
+ # Set event data
+ event = gdata.calendar.CalendarEventEntry()
+ event.author.append(atom.Author(name=atom.Name(text='GData Test
user')))
+ event.title = atom.Title(text=random_event_title)
+ event.content = atom.Content(text='Picnic with some lunch')
+ event.where.append(gdata.calendar.Where(value_string='Down by the
river'))
+ event.when.append(gdata.calendar.When
(start_time=start_time,end_time=end_time))
+ event.sync_event = gdata.calendar.SyncEvent('true')
+ event.uid = gdata.calendar.UID(value=uid_string)
+
+ # Insert event
+ self.cal_client.ProgrammaticLogin()
+ new_event = self.cal_client.InsertEvent(event,
+ '/calendar/feeds/default/private/full')
+
+ # Inserting it a second time should fail, as it'll have the same
UID
+ try:
+ bad_event = self.cal_client.InsertEvent(event,
+ '/calendar/feeds/default/private/full')
+ self.fail('Was able to insert an event with a duplicate UID')
+ except gdata.service.RequestError, error:
+ # for the current problem with redirects, just re-raise so the
+ # failure doesn't seem to be because of the duplicate UIDs.
+ status = error[0]['status']
+ if status == 302:
+ raise
+
+ # otherwise, make sure it was the right error
+ self.assertEquals(error[0]['status'], 409)
+ self.assertEquals(error[0]['reason'], 'Conflict')
+
+ # Ensure that atom data returned from calendar server equals atom
data sent
+ self.assertEquals(event.title.text, new_event.title.text)
+ self.assertEquals(event.content.text, new_event.content.text)
+
+ # Ensure that gd:where data returned from calendar equals value
sent
+ self.assertEquals(event.where[0].value_string,
+ new_event.where[0].value_string)
+
+ # Delete the event
+ self.cal_client.DeleteEvent(new_event.GetEditLink().href)
+
def testCreateAndDeleteEventUsingBatch(self):
# Get random data for creating event
r = random.Random()




Thanks!

Jeff S

unread,
Nov 11, 2009, 1:12:53 PM11/11/09
to GData Python Client Library Contributors
Hi Michael,

Thanks for writing this up! There is just one piece of red tape that
we need to get thought before I can accept your patch, we need a
signed Contributor License Agreement:

http://code.google.com/legal/individual-cla-v1.0.html

Please ping me when you've filled this out. In regards to the v2
codebase, we do have plans to create gdata.calendar.data and
gdata.calendar.client though it hasn't been a high priority so far
because the v1 code continues to work for most cases. I have a few
small changes requested for the current calendar/__init__.py file and
I'll keep you in the loop on those, I don't anticipate any conflicts.

Thank you,

Jeff
> -            email=atom.Email(text='gdata.ops.d...@gmail.com')))

Michael Ballbach

unread,
Nov 11, 2009, 1:59:05 PM11/11/09
to GData Python Client Library Contributors
I did that when I submitted the last patch, though foolishly, I
suppose, used my regular email address instead of my gmail one.

This is the thread:

http://groups.google.com/group/gdata-python-client-library-contributors/browse_thread/thread/48254170a6f6818a/a2d1ecd15a37736a

Thanks!

On Nov 11, 1:12 pm, Jeff S <j...@google.com> wrote:
> Hi Michael,
>
> Thanks for writing this up! There is just one piece of red tape that
> we need to get thought before I can accept your patch, we need a
> signed Contributor License Agreement:
>
> http://code.google.com/legal/individual-cla-v1.0.html
>
> Please ping me when you've filled this out. In regards to the v2
> codebase, we do have plans to create gdata.calendar.data and
> gdata.calendar.client though it hasn't been a high priority so far
> because the v1 code continues to work for most cases. I have a few
> small changes requested for the current calendar/__init__.py file and
> I'll keep you in the loop on those, I don't anticipate any conflicts.
>
> Thank you,
>
> Jeff
>

Jeff S

unread,
Nov 11, 2009, 8:19:29 PM11/11/09
to GData Python Client Library Contributors
Ha, good stuff. My mistake.

On Nov 11, 10:59 am, Michael Ballbach <ballb...@gmail.com> wrote:
> I did that when I submitted the last patch, though foolishly, I
> suppose, used my regular email address instead of my gmail one.
>
> This is the thread:
>
> http://groups.google.com/group/gdata-python-client-library-contributo...
> ...
>
> read more »

Jeff S

unread,
Nov 12, 2009, 2:02:22 PM11/12/09
to GData Python Client Library Contributors
Hi Michael,

Your patch looks great. I've integrated it and run the new tests so
I'm checking this in now along with a few other classes for new
elements which had been added since the last time the calendar module
was updated.

Thank you!

Jeff
> ...
>
> read more »
Reply all
Reply to author
Forward
0 new messages