Hi, I've been missing reminder sync from Erminig, so today, finally, I opened my toolbox called vim ;-). erminig-0.2.11.patch adds support for alarm/reminder sync. You can uncompress erminig-0.2.11.patched.tgz under /: tar zxvf erminig-0.2.11.patched.tgz. This tarball replaces: /usr/share/erminig/Event.py /usr/share/erminig/cwrapper.py /usr/share/erminig/erminig_core.py /usr/share/erminig/libcalaccess.so Note that Python Google Calendar API supports reminders only in the primary calendar. One workaround for this limitation is to add reminders from non-primary Google calendars and sync them to N900. Thanks.
Traceback (most recent call last): File "/usr/bin/erminig", line 153, sync_all_profiles(widget=<gtk.ToolButton object at 0x41f79aa8 (GtkToolButton at 0x4c79f0)>, data=<hildon.StackableWindow object at 0x41f791e8 (HildonStackableWindow at 0x458060)>) id = i[0] do_profile_sync(id, data) variables: {'data': ('local', <hildon.StackableWindow object at 0x41f791e8 (HildonStackableWindow at 0x458060)>), 'id': ('local', 1), 'do_profile_sync': ('global', <function do_profile_sync at 0x41fa3330>)} File "/usr/bin/erminig", line 139, do_profile_sync(id=1, data=<hildon.StackableWindow object at 0x41f791e8 (HildonStackableWindow at 0x458060)>) profile['remoteSource'], \ profile['lastLocalUpdate'], currentTime, progress) variables: {'profile': ('local', {'lastUpdate': 1291754673, 'direction': 0, 'lastLocalUpdate': 1291754673, 'remoteSourceTitle': u'Gabriel Devenyi', 'remoteAccountId': 1, 'enabled': 1, 'localSource': u'1', 'remoteSource': u'myemail@gmail.com', 'localSourceTitle': u'N900', 'id': 1}), 'progress': ('local', <gtk.ProgressBar object at 0x41f7c8f0 (GtkProgressBar at 0x4dd8d0)>), 'currentTime': ('local', 1291942054)} File "/usr/share/erminig/erminig_core.py", line 552, local_sync(pid=1, localSource=u'1', remoteSource=u'myemail@gmail.com', lastSync=1291754673, stime=1291942054, progress=<gtk.ProgressBar object at 0x41f7c8f0 (GtkProgressBar at 0x4dd8d0)>) getNewEventsFromLocal(pid, int(localSource), remoteSource, lastSync, progress) getUpdatedEventsFromLocal(pid, int(localSource), remoteSource, lastSync, progress) getDeletedEventsFromLocal(pid, int(localSource), remoteSource, lastSync, progress) variables: {'lastSync': ('local', 1291754673), 'getUpdatedEventsFromLocal': ('global', <function getUpdatedEventsFromLocal at 0x4107df30>), 'int': ('builtin', <type 'int'>), 'pid': ('local', 1), 'localSource': ('local', u'1'), 'remoteSource': ('local', u'myemail@gmail.com'), 'progress': ('local', <gtk.ProgressBar object at 0x41f7c8f0 (GtkProgressBar at 0x4dd8d0)>)} File "/usr/share/erminig/erminig_core.py", line 511, getUpdatedEventsFromLocal(pid=1, localSource=1, remoteSource=u'myemail@gmail.com', lastSync=1291754673, progress=<gtk.ProgressBar object at 0x41f7c8f0 (GtkProgressBar at 0x4dd8d0)>) event.set_tzOffset(e[7]) gid = updateGoogleEvent(event, remoteSource, pid) variables: {'updateGoogleEvent': ('global', <function updateGoogleEvent at 0x4107def0>), 'gid': (None, None), 'pid': ('local', 1), 'event': ('local', <Event.Event instance at 0x41eeff08>), 'remoteSource': ('local', u'myemail@gmail.com')} File "/usr/share/erminig/erminig_core.py", line 490, updateGoogleEvent(evt=<Event.Event instance at 0x41eeff08>, googleid=u'myemail@gmail.com', pid=1) try: google_api.run_google_action(google_api.gd_client.UpdateEvent, event.GetEditLink().href, event) except ErminigGoogleError, e: variables: {'href': (None, None), 'google_api.gd_client.UpdateEvent': ('global', <bound method CalendarService.UpdateEvent of <gdata.calendar.service.CalendarService object at 0x41fad9f0>>), 'event': ('local', <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>), 'google_api.run_google_action': ('global', <function run_google_action at 0x41076db0>), 'event.GetEditLink': ('local', <bound method CalendarEventEntry.GetEditLink of <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>>)} File "/usr/share/erminig/google_api.py", line 26, run_google_action(func=<bound method CalendarService.UpdateEvent of <gd...ar.service.CalendarService object at 0x41fad9f0>>, *args=('http://www.google.com/calendar/feeds/myemaillink', <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>), **kwargs={}) try: res = func(*args, **kwargs) break variables: {'res': ('local', None), 'args': ('local', ('http://www.google.com/calendar/feeds/myemaillink', <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>)), 'func': ('local', <bound method CalendarService.UpdateEvent of <gdata.calendar.service.CalendarService object at 0x41fad9f0>>), 'kwargs': ('local', None)} File "/usr/lib/python2.5/site-packages/gdata/calendar/service.py", line 390, UpdateEvent(self=<gdata.calendar.service.CalendarService object at 0x41fad9f0>, edit_uri='calendar/feeds/myemaillink', updated_event=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>, url_params=None, escape_params=True) escape_params=escape_params, converter=gdata.calendar.CalendarEventEntryFromString) variables: {'converter': (None, None), 'gdata.calendar.CalendarEventEntryFromString': ('global', <function CalendarEventEntryFromString at 0x4118a230>)} File "/usr/lib/python2.5/site-packages/gdata/service.py", line 1335, Put(self=<gdata.calendar.service.CalendarService object at 0x41fad9f0>, data=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>, uri='/calendar/feeds/myemaillink', extra_headers=None, url_params=None, escape_params=True, redirects_remaining=3, media_source=None, converter=<function CalendarEventEntryFromString at 0x4118a230>) escape_params=escape_params, redirects_remaining=redirects_remaining, media_source=media_source, converter=converter) variables: {'media_source': ('local', None), 'converter': ('local', <function CalendarEventEntryFromString at 0x4118a230>)} File "/usr/lib/python2.5/site-packages/gdata/service.py", line 1263, PostOrPut(self=<gdata.calendar.service.CalendarService object at 0x41fad9f0>, verb='PUT', data=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>, uri='/calendar/feeds/myemaillink', extra_headers={'Content-Type': 'application/atom+xml'}, url_params={'gsessionid': 'erEgWvFkWpBRHc9ePExyVA'}, escape_params=True, redirects_remaining=3, media_source=None, converter=<function CalendarEventEntryFromString at 0x4118a230>) server_response = self.request(verb, uri, data=http_data, headers=extra_headers, url_params=url_params) result_body = server_response.read() variables: {'headers': (None, None), 'url_params': ('local', {'gsessionid': 'erEgWvFkWpBRHc9ePExyVA'}), 'extra_headers': ('local', {'Content-Type': 'application/atom+xml'})} File "/usr/lib/python2.5/site-packages/atom/__init__.py", line 93, optional_warn_function(*args=(<gdata.calendar.service.CalendarService object at 0x41fad9f0>, 'PUT', '/calendar/feeds/myemaillink'), **kwargs={'data': <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>, 'headers': {'Content-Type': 'application/atom+xml'}, 'url_params': {'gsessionid': 'erEgWvFkWpBRHc9ePExyVA'}}) warnings.warn(warning, DeprecationWarning, stacklevel=2) return f(*args, **kwargs) # Preserve the original name to avoid masking all decorated functions as variables: {'kwargs': ('local', {'headers': {'Content-Type': 'application/atom+xml'}, 'url_params': {'gsessionid': 'erEgWvFkWpBRHc9ePExyVA'}, 'data': <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>}), 'args': ('local', (<gdata.calendar.service.CalendarService object at 0x41fad9f0>, 'PUT', '/calendar/feeds/myemaillink')), 'f': ('local', <function request at 0x41806cb0>)} File "/usr/lib/python2.5/site-packages/atom/service.py", line 172, request(self=<gdata.calendar.service.CalendarService object at 0x41fad9f0>, operation='PUT', url=<atom.url.Url object at 0x41ef0250>, data=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>, headers={'Content-Type': 'application/atom+xml'}, url_params={'gsessionid': 'erEgWvFkWpBRHc9ePExyVA'}) if data and 'Content-Length' not in all_headers: content_length = CalculateDataLength(data) if content_length: variables: {'content_length': (None, None), 'CalculateDataLength': ('global', <function CalculateDataLength at 0x418080b0>), 'data': ('local', <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>)} File "/usr/lib/python2.5/site-packages/atom/service.py", line 728, CalculateDataLength(data=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>) else: return len(str(data)) variables: {'data': ('local', <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>), 'str': ('builtin', <type 'str'>), 'len': ('builtin', <built-in function len>)} File "/usr/lib/python2.5/site-packages/atom/__init__.py", line 364, __str__(self=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>) def __str__(self): return self.ToString() variables: {'self.ToString': ('local', <bound method CalendarEventEntry.ToString of <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>>)} File "/usr/lib/python2.5/site-packages/atom/__init__.py", line 361, ToString(self=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>, string_encoding='UTF-8') """Converts the Atom object to a string containing XML.""" return ElementTree.tostring(self._ToElementTree(), encoding=string_encoding) variables: {'ElementTree.tostring': ('global', <function tostring at 0x411772f0>), 'self._ToElementTree': ('local', <bound method CalendarEventEntry._ToElementTree of <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>>), 'string_encoding': ('local', 'UTF-8'), 'encoding': (None, None)} File "/usr/lib/python2.5/site-packages/atom/__init__.py", line 356, _ToElementTree(self=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>) self.__class__._tag)) self._AddMembersToElementTree(new_tree) return new_tree variables: {'self._AddMembersToElementTree': ('local', <bound method CalendarEventEntry._AddMembersToElementTree of <gdata.calendar.CalendarEventEntry object at 0x41ef0d50>>), 'new_tree': ('local', <Element '{http://www.w3.org/2005/Atom}entry' at 0x4020cef0>)} File "/usr/lib/python2.5/site-packages/atom/__init__.py", line 316, _AddMembersToElementTree(self=<gdata.calendar.CalendarEventEntry object at 0x41ef0d50>, tree=<Element '{http://www.w3.org/2005/Atom}entry' at 0x4020cef0>) for instance in member: instance._BecomeChildElement(tree) else: variables: {'instance._BecomeChildElement': ('local', <bound method Reminder._BecomeChildElement of <gdata.calendar.Reminder object at 0x41ef02d0>>), 'tree': ('local', <Element '{http://www.w3.org/2005/Atom}entry' at 0x4020cef0>)} File "/usr/lib/python2.5/site-packages/atom/__init__.py", line 344, _BecomeChildElement(self=<gdata.calendar.Reminder object at 0x41ef02d0>, tree=<Element '{http://www.w3.org/2005/Atom}entry' at 0x4020cef0>) self.__class__._tag) self._AddMembersToElementTree(new_child) variables: {'new_child': ('local', None), 'self._AddMembersToElementTree': ('local', <bound method Reminder._AddMembersToElementTree of <gdata.calendar.Reminder object at 0x41ef02d0>>)} File "/usr/lib/python2.5/site-packages/atom/__init__.py", line 326, _AddMembersToElementTree(self=<gdata.calendar.Reminder object at 0x41ef02d0>, tree=<Element '{http://schemas.google.com/g/2005}reminder' at 0x41fb1410>) else: tree.attrib[xml_attribute] = member.decode(MEMBER_STRING_ENCODING) # Lastly, call the ExtensionContainers's _AddMembersToElementTree to variables: {'tree': ('local', None), 'xml_attribute': ('local', 'minutes')} AttributeError: 'int' object has no attribute 'decode'