importMappings = {} # parameterized decorators need triply nested functions, ugh, we should use the # decorator package someday, instead def import_mapper(attr, passVal=True): """ Parameterized decorator, takes a function that takes a record attribute, returns a staticmethod that takes a record as an argument and returns eim.NoChange if record.attr is eim.NoChange, otherwise returns the function applied to record.attr. Also adds the mapping to the importMappings dictionary. If passVal is False, pass the record in to the original function, not record.attr """ def actual_decorator(func): def guardedFunction(record): if not passVal: return func(record) val = getattr(record, attr) if val is eim.NoChange: return eim.NoChange else: return func(val) importMappings[attr] = guardedFunction return staticmethod(guardedFunction) return actual_decorator utc = ICUtzinfo.getInstance('UTC') def import_fields(record, fields): """ Take a record and an iterable of fields, return a dictionary mapping field -> imported value, using the import functions in importMappings. """ return dict( (key, importMappings[key](record)) for key in fields) class PIMTranslator(eim.Translator): URI = "cid:pim-translator@osaf.us" version = 1 description = u"Translator for Chandler PIM items" handled_fields = ('displayName', 'triageStatus', 'triageStatusChanged', 'createdOn') # ItemRecord ------------- # TODO: lastModifiedBy @model.ItemRecord.importer def import_item(self, record): if COSMO_MODE: self.loadItemByUUID( record.uuid, pim.ContentItem, displayName=record.title, ) # incomplete return else: kwds = import_fields(record, self.handled_fields) self.loadItemByUUID(record.uuid, pim.ContentItem, **kwds)# incomplete @import_mapper('createdOn') def import_createdOn(val): # createdOn is a Decimal we need to change to datetime naive = datetime.utcfromtimestamp(float(val)) inUTC = naive.replace(tzinfo=utc) # Convert to user's tz: return inUTC.astimezone(ICUtzinfo.default) @import_mapper('triageStatus') def import_triageStatus(val): return getattr(pim.TriageEnum, val) @import_mapper('triageStatusChanged') def import_triageStatusChanged(val): return float(val) @import_mapper('displayName', False) def import_displayName(record): return record.title @eim.exporter(pim.ContentItem) def export_item(self, item): utc = ICUtzinfo.getInstance('UTC') yield model.ItemRecord( item.itsUUID, # uuid item.displayName, # title str(item.triageStatus), # triageStatus Decimal("%.2f" % item.triageStatusChanged), # t_s_changed None, # lastModifiedBy Decimal(int(time.mktime(item.createdOn.timetuple()))) # createdOn )