SharingTranslator implements the callbacks for converting between items and records.
>>> from datetime import datetime, timedelta >>> from decimal import Decimal>>> from chandler.core import Item, Collection >>> from chandler.triage import Triage >>> from chandler.event import Event >>> from chandler.recurrence import Recurrence >>> from chandler.reminder import ReminderList >>> from chandler.time_services import TimeZone >>> TimeZone.default = TimeZone.pacific>>> from chandler.sharing import translator, legacy_model, eim, new_model >>> t = translator.SharingTranslator()
>>> t.startImport()>>> rec = legacy_model.ItemRecord( ... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89', ... title='Translator test', ... triage='200 -1167792143.00 1', ... createdOn=Decimal("1164803131"), ... hasBeenSent=0, ... needsReply=0, ... read=0, ... )>>> rs = eim.RecordSet([rec])>>> t.importRecords(rs) >>> t.finishImport()>>> item = eim.get_item_for_uuid('f230dcd4-7c32-4c3f-908b-d92081cc9a89') >>> item is not None True>>> item.title u'Translator test'>>> Triage(item).manual 200.0 >>> Triage(item).manual_timestamp 1167792143.0>>> item.created 1164803131.0
>>> t.startExport()
>>> records = list(t.exportItem(item))
>>> records
[ItemRecord('f230dcd4-7c32-4c3f-908b-d92081cc9a89', u'Translator test', '200 -1167792143.00 0', Decimal("1164803131"), NoChange, NoChange, NoChange), NoteRecord('f230dcd4-7c32-4c3f-908b-d92081cc9a89', u'', Inherit, Inherit, Inherit, Inherit), DisplayAlarmRecord('f230dcd4-7c32-4c3f-908b-d92081cc9a89', None, None, None, None)]
>>> rec = legacy_model.NoteRecord( ... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89', ... body='This is the body', ... icalUid='f230dcd4-7c32-4c3f-908b-d92081cc9a89', ... icalProperties=None, ... icalParameters=None, ... icalExtra=None, ... )>>> rs = eim.RecordSet([rec])>>> t.startImport() >>> t.importRecords(rs) >>> t.finishImport()>>> item.body u'This is the body' >>> eim.EIM(item).ical_extra is None True >>> eim.EIM(item).ical_uid u'f230dcd4-7c32-4c3f-908b-d92081cc9a89'
>>> t.startExport()
>>> records = list(t.exportItem(item))
>>> records
[ItemRecord('f230dcd4-7c32-4c3f-908b-d92081cc9a89', u'Translator test', '200 -1167792143.00 0', Decimal("1164803131"), NoChange, NoChange, NoChange), NoteRecord('f230dcd4-7c32-4c3f-908b-d92081cc9a89', u'This is the body', u'f230dcd4-7c32-4c3f-908b-d92081cc9a89', Inherit, Inherit, Inherit), DisplayAlarmRecord('f230dcd4-7c32-4c3f-908b-d92081cc9a89', None, None, None, None)]
>>> Event.installed_on(item) False>>> rec = legacy_model.EventRecord( ... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89', ... dtstart = ';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070201T140000', ... duration = 'PT1H', ... location = 'Nowhere', ... rrule = None, ... exrule = None, ... rdate = None, ... exdate = None, ... status = 'CANCELLED', ... lastPastOccurrence = None, ... )
Explain the record:
>>> for field in sorted(rec.explain()): ... print field[:2] ('Duration', '1:00:00 (hh:mm:ss)') ('Event status', u'FYI') ('Location', u'Nowhere') ('Start time', '2007-02-01 14:00:00-08:00') ('exdate', None) ('exrule', None) ('lastPastOccurrence', None) ('rdate', None) ('rrule', None)>>> rs = eim.RecordSet([rec])>>> t.startImport() >>> t.importRecords(rs) >>> t.finishImport()>>> Event.installed_on(item) True >>> event = Event(item) >>> event.transparency 'fyi' >>> event.location u'Nowhere' >>> event.start datetime.datetime(2007, 2, 1, 14, 0, tzinfo=<ICUtzinfo: America/Los_Angeles>) >>> event.duration datetime.timedelta(0, 3600)
>>> t.startExport() >>> records = [r for r in t.exportItem(item) if isinstance(r, legacy_model.EventRecord)] >>> records [EventRecord('f230dcd4-7c32-4c3f-908b-d92081cc9a89', u';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070201T140000', u'PT1H', u'Nowhere', None, None, None, None, u'CANCELLED', NoChange)]>>> item2 = Item(title="Item for export that wasn't imported") >>> dt = datetime(2008, 10, 1, 18, tzinfo = TimeZone.pacific) >>> event2 = Event(item2).add(base_start=dt, tzinfo=TimeZone.pacific) >>> eim.EIM.installed_on(item2) False >>> for r in t.exportItem(item2): ... print r ItemRecord(..., u"Item for export that wasn't imported", Inherit, ...) NoteRecord(..., u'', Inherit, Inherit, Inherit, Inherit) DisplayAlarmRecord('...', None, None, None, None) EventRecord('...', u';VALUE=DATE-TIME;TZID=US/Pacific:20081001T180000', u'PT1H', None, None, None, None, None, u'CONFIRMED', NoChange) >>> eim.EIM.installed_on(item2) True >>> eim.item_for_uuid(str(eim.EIM(item2).uuid)) is item2 True
>>> new_rec = legacy_model.EventRecord(
... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89',
... dtstart = rec.dtstart,
... duration = rec.duration,
... location = rec.location,
... rrule = 'FREQ=WEEKLY;COUNT=5;BYDAY=TU,TH',
... exrule = None,
... rdate = ';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070225T140000,20070223T140000',
... exdate = ';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070206T140000',
... status = rec.status,
... lastPastOccurrence = None,
... )
The rrule and rdate fields are order independent, so they’re sorted alphabetically:
>>> new_rec.rrule u'BYDAY=TU,TH;COUNT=5;FREQ=WEEKLY'>>> rs = eim.RecordSet([new_rec]) >>> t.startImport() >>> t.importRecords(rs) >>> t.finishImport()>>> recurrence = Recurrence(item) >>> [i.day for i in recurrence.rruleset] [1, 8, 13, 15, 23, 25]
>>> t.startExport()
>>> allRecords = list(t.exportItem(item))
>>> records = [r for r in allRecords if isinstance(r, legacy_model.EventRecord)]
>>> len(records) == 1
True
>>> record = records[0]
>>> record.rrule
u'BYDAY=TU,TH;COUNT=5;FREQ=WEEKLY'
>>> record.exrule is None
True
>>> record.rdate
u';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070223T140000,20070225T140000'
>>> record.exdate
u';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070206T140000'
Triage status isn’t meaningful for master events, so it should be NoChange for the recurrence master.
>>> itemRecords = [r for r in allRecords if isinstance(r, legacy_model.ItemRecord)]
>>> len(itemRecords) == 1
True
>>> itemRecord = itemRecords[0]
>>> itemRecord.triage
NoChange
>>> mod_rec = legacy_model.ItemRecord(
... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89:20070223T220000Z',
... title='Changed title',
... triage='100 -1167792143.00 1',
... createdOn=eim.Inherit,
... hasBeenSent=eim.Inherit,
... needsReply=eim.Inherit,
... read=eim.Inherit,
... )
The explain method should handle Inherit values:
>>> for field in sorted(mod_rec.explain()):
... print field[:2]
('Created on', Inherit)
('Has been read', Inherit)
('Has been sent', Inherit)
('Needs reply', Inherit)
('Title', u'Changed title')
('Triage status', u'Now')
>>> rs = eim.Diff([mod_rec])>>> t.startImport() >>> t.importRecords(rs) >>> t.finishImport()>>> mod = recurrence.get_occurrence(event.start + timedelta(22)) >>> mod.title u'Changed title'>>> Triage(mod).calculated 100.0
>>> t.startExport()
>>> records = list(t.exportItem(mod))
>>> event_records = [r for r in records if isinstance(r, legacy_model.EventRecord)]
>>> len(event_records) == 1
True
>>> event_record = event_records[0]
>>> event_record.dtstart
Inherit
>>> event_record.duration
Inherit
>>> item_records = [r for r in records if isinstance(r, legacy_model.ItemRecord)]
>>> len(item_records) == 1
True
>>> item_record = item_records[0]
>>> item_record.title
u'Changed title'
>>> item_record.triage
Inherit
>>> t.startImport()>>> item_rec = legacy_model.ItemRecord( ... uuid='a9b019a4-d995-11db-f269-0016cbca6aed', ... title='Item with reminder', ... triage='200 -1167792143.00 1', ... createdOn=Decimal("1164803131"), ... hasBeenSent=0, ... needsReply=0, ... read=0, ... ) >>> alarm_rec = legacy_model.DisplayAlarmRecord( ... uuid='a9b019a4-d995-11db-f269-0016cbca6aed', ... description="Don't forget!", ... trigger=';VALUE=DATE-TIME:20060304T220000Z', ... duration="PT1H", ... repeat=1, ... )>>> rs = eim.Diff([item_rec, alarm_rec])>>> t.importRecords(rs) >>> t.finishImport()>>> item = eim.get_item_for_uuid('a9b019a4-d995-11db-f269-0016cbca6aed') >>> reminders = ReminderList(item).reminders >>> len(reminders) 1 >>> reminders[0] <chandler.reminder.Reminder object at ...> >>> reminders[0].fixed_trigger.astimezone(TimeZone.pacific) datetime.datetime(2006, 3, 4, 14, 0, tzinfo=<ICUtzinfo: US/Pacific>) >>> reminders[0].description u"Don't forget!"
>>> t.startExport() >>> records = list(t.exportItem(item)) >>> len(records) 3 >>> records[0] ItemRecord('a9b019a4-d995-11db-f269-0016cbca6aed', u'Item with reminder', '200 -1167792143.00 0', Decimal("1164803131"), ...) >>> records[1] NoteRecord('a9b019a4-d995-11db-f269-0016cbca6aed', u'', Inherit, Inherit, Inherit, Inherit) >>> records[2] DisplayAlarmRecord('a9b019a4-d995-11db-f269-0016cbca6aed', u"Don't forget!", u';VALUE=DATE-TIME:20060304T220000Z', ...)>>> reminders[0].delta = timedelta(hours=-2) >>> reminders[0].fixed_trigger = None >>> t.startExport() >>> records = list(t.exportItem(item)) >>> records[2] DisplayAlarmRecord('a9b019a4-d995-11db-f269-0016cbca6aed', u"Don't forget!", u'-PT2H', ...)
>>> item_rec = legacy_model.ItemRecord( ... uuid='800644b6-dd73-11db-f79a-0016cbca6aed', ... title='Event Item with reminder', ... triage='200 -1167792996.00 1', ... createdOn=Decimal("1164805552"), ... hasBeenSent=0, ... needsReply=1, ... read=0, ... ) >>> note_rec = legacy_model.NoteRecord( ... uuid='800644b6-dd73-11db-f79a-0016cbca6aed', ... body='This is the body', ... icalUid=None, ... icalExtra=None, ... icalProperties=None, ... icalParameters=None, ... ) >>> event_rec = legacy_model.EventRecord( ... uuid='800644b6-dd73-11db-f79a-0016cbca6aed', ... dtstart = ';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070516T180000', ... duration = 'PT1H', ... location = 'Nowhere', ... rrule = None, ... exrule = None, ... rdate = None, ... exdate = None, ... status = 'CONFIRMED', ... lastPastOccurrence = None, ... ) >>> relative_alarm_rec = legacy_model.DisplayAlarmRecord( ... uuid='800644b6-dd73-11db-f79a-0016cbca6aed', ... description="Time to go!", ... trigger='-PT5M', ... duration=eim.Inherit, ... repeat=eim.Inherit, ... ) >>> rs = eim.Diff([item_rec, note_rec, event_rec, ... relative_alarm_rec])>>> t.importRecords(rs) >>> t.finishImport()>>> item = eim.get_item_for_uuid('800644b6-dd73-11db-f79a-0016cbca6aed') >>> Event.installed_on(item) True >>> len(ReminderList(item).reminders) 1 >>> reminder = ReminderList(item).reminders[0] >>> reminder <chandler.reminder.Reminder object at ...> >>> reminder.delta datetime.timedelta(-1, 86100) >>> reminder.description u'Time to go!'
>>> t.startExport()
>>> records = list(t.exportItem(item))
>>> len(records)
4
>>> records[0]
ItemRecord('800644b6-dd73-11db-f79a-0016cbca6aed', u'Event Item with reminder', '200 -1167792996.00 0', Decimal("1164805552"), ...)
>>> records[1]
NoteRecord('800644b6-dd73-11db-f79a-0016cbca6aed', ...)
>>> records[2]
DisplayAlarmRecord('800644b6-dd73-11db-f79a-0016cbca6aed', u'Time to go!', u'-PT5M', ...)
>>> records[3]
EventRecord('800644b6-dd73-11db-f79a-0016cbca6aed', u';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070516T180000', u'PT1H', u'Nowhere', None, None, None, None, u'CONFIRMED', ...)
>>> d = translator.DumpTranslator()>>> rec1 = legacy_model.ItemRecord( ... "d3ba7961-c9b4-4e73-a860-cc8cbb40acc7", ... "Interesting Collection Title", ... eim.NoChange, eim.NoChange, eim.NoChange, eim.NoChange, eim.NoChange ... ) >>> rec2 = legacy_model.CollectionRecord( ... "d3ba7961-c9b4-4e73-a860-cc8cbb40acc7", ... 0, ... 0, 0, 0, 0 ... )>>> rs = eim.Diff([rec1, rec2]) >>> d.startImport() >>> d.importRecords(rs) >>> d.finishImport() >>> collection = eim.collection_for_name("d3ba7961-c9b4-4e73-a860-cc8cbb40acc7") >>> collection <Collection: Interesting Collection Title>>>> d.startExport() >>> for record in eim.sort_records(d.exportItem(collection)): ... print record CollectionRecord('d3ba7961-c9b4-4e73-a860-cc8cbb40acc7', 0, 0, 0, 0, None, 0) ItemRecord('d3ba7961-c9b4-4e73-a860-cc8cbb40acc7', u'Interesting Collection Title', ...)
Keywords are imported and exported from the sidebar using KeywordRecord.
>>> d = translator.DumpTranslator()>>> rec1 = new_model.KeywordRecord( ... "@keyword:Stuff", ... 127, 127, 127, 0 ... )>>> rs = eim.Diff([rec1]) >>> d.startImport() >>> d.importRecords(rs) >>> d.finishImport() >>> keyword = eim.get_for_name_or_uuid("@keyword:Stuff") >>> keyword <Keyword: Stuff>>>> d.startExport() >>> for record in eim.sort_records(d.exportItem(keyword)): ... print record KeywordRecord(u'@keyword:Stuff', 127, 127, 127, None, 0)
Collections can be specified either by well-known name or UUID.
>>> note = Item() >>> rec = legacy_model.CollectionMembershipRecord( ... collectionID="@dashboard", ... itemUUID=eim.EIM(note).add().uuid, ... index=0, ... ) >>> rs = eim.Diff([rec]) >>> d.startImport() >>> d.importRecords(rs) >>> d.finishImport() >>> dashboard = eim.collection_for_name("@dashboard") >>> note in dashboard.items True>>> list(d.export_collection_memberships(dashboard)) [CollectionMembershipRecord(u'@dashboard', '...', NoChange)]
>>> collection = Collection()
>>> note = Item()
>>> rec = legacy_model.CollectionMembershipRecord(
... collectionID=eim.EIM(collection).add().uuid,
... itemUUID=eim.EIM(note).add().uuid,
... index=0,
... )
>>> rs = eim.Diff([rec])
>>> d.startImport()
>>> d.importRecords(rs)
>>> d.finishImport()
>>> note in collection.items
True
Verify the special converters we put in place for turning None to NoChange for event status, and empty string to NoChange for triage are working
>>> rec = legacy_model.ItemRecord( ... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89', ... title='triage test', ... triage='', ... createdOn=Decimal("1164803131"), ... hasBeenSent=0, ... needsReply=0, ... read=0, ... ) >>> rec.triage NoChange>>> rec = legacy_model.EventRecord( ... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89', ... dtstart = ';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070201T140000', ... duration = 'PT1H', ... location = 'Nowhere', ... rrule = None, ... exrule = None, ... rdate = None, ... exdate = None, ... status = None, ... lastPastOccurrence = None, ... ) >>> rec.status NoChange>>> rec = legacy_model.EventRecord( ... uuid='f230dcd4-7c32-4c3f-908b-d92081cc9a89', ... dtstart = ';VALUE=DATE-TIME;TZID=America/Los_Angeles:20070201T140000', ... duration = None, ... location = 'Nowhere', ... rrule = None, ... exrule = None, ... rdate = None, ... exdate = None, ... status = None, ... ) >>> rec.duration 'PT0S'