Example #1
0
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