def update_index(obj, batch=False): """Updates SearchIndex and GeoIndex tables with obj-related keywords and locations for the contact to which obj belongs. If obj indices are already in the SearchIndex, their content is updated. If obj is new, it is added. Index keywords are: - name (name: Contact) - nickname (nickname: Person) - last name (lastname: Person) - place (adr_zoom: Address) """ # # generate the keys and find the contact reference # new_keys = None new_location = None contact_ref = None attic = False res = [] try: obj_class = obj.class_name() except AttributeError: # for non poly model objects obj_class = obj.key().kind() if obj_class in ['Person','Contact','Company']: contact = obj new_keys = plainify(contact.name) if contact.class_name() == "Person": if contact.lastname: new_keys.extend(plainify(contact.lastname)) if contact.nickname: new_keys.extend(plainify(contact.nickname)) attic = obj.attic or contact.attic elif obj_class in ['Address']: try: contact = obj.contact_ref except db.ReferencePropertyResolveError: logging.warning("Address has invalid reference to contact %s" % (str(obj.key()))) return None # use the elements as search keys (should be town and neighborhood or similar) new_keys = plainify(" ".join(obj.adr_zoom[:2])) if obj.location: new_location = obj.location attic = obj.attic or contact.attic elif obj_class in ['LoginUser']: try: contact = obj.me except db.ReferencePropertyResolveError: logging.warning("Address has invalid reference to contact %s" % (str(obj.key()))) return None if obj.location: new_location = obj.location else: logging.debug("update_index(): class %s is not considered here" % (obj_class)) return None if new_location: logging.debug("Update %s class %s with location: %f %f" % (contact.name,obj_class,new_location.lat,new_location.lon)) if new_keys: logging.debug("Update %s class %s with keys: %s" % (contact.name,obj_class,new_keys)) if new_keys: # read SearchIndex dataset with reference to obj data = SearchIndex.all().filter("data_ref =", obj).get() if data: # update existing dataset data.keys = new_keys data.attic = attic else: if batch: logging.warning("A new search index was created in batch for dataset: %d" % (obj.key().id())) data = SearchIndex(keys=new_keys, attic=attic, data_ref=obj, contact_ref=contact) if batch: res.append(data) else: data.put() if new_location: # read GeoIndex dataset with reference to obj geo = GeoIndex.all().filter("data_ref =", obj).get() if geo: # update existing dataset geo.location = new_location geo.attic = attic # update geo reference field geo.update_location() else: if batch: logging.warning("A new geo index was created in batch for dataset: %d" % (obj.key().id())) geo = GeoIndex(location=new_location, attic=attic, data_ref=obj, contact_ref=contact) geo.update_location() if batch: res.append(geo) else: geo.put() return res