示例#1
0
    def get(self):
        """Function is called by cron to build a contact index

        Call with a key to build index for this entity.
        """
        if not users.is_current_user_admin():
            logging.critical("UpdateIndex called by non-admin")
            self.error(500)
            return

        key = self.request.get("key", None)

        logging.info("Update index tables.")

        if key:
            con = Contact.get(Key(key))
            if con:
                update_index(con)
                # update dependant take2 entries
                for t2 in Take2.all().filter("contact_ref =", con):
                    update_index(t2)
                # update parent login_user
                user = LoginUser.all().filter("me =", con).get()
                if user:
                    update_index(user)
                return
            else:
                t2 = Take2.get(Key(key))
                if t2:
                    update_index(t2)
                    return
            logging.info("Could not find key: %s" % (key))
            return

        # Go through the tables which contribute to the index
        for table in [LoginUser,Contact,Address]:
            batch = []
            for obj in table.all():
                res = update_index(obj, batch=True)
                if res:
                    batch.extend(res)

            # bulk db operation
            db.put(batch)
            logging.info("%d updates." % (len(batch)))

        self.response.headers['Content-Type'] = "text/plain"
        self.response.out.write("/index done.")
示例#2
0
def encode_take2(contact, include_attic=False):
    """Encodes the contact's take2 property objects

    Returns a dictionary with the property's name
    as the key and a list of properties as values.
    """
    restypes = {}
    for take2 in [Email,Web,Address,Mobile,Other]:
        restypes[take2.class_name().lower()] = []

    q_obj = Take2.all()
    q_obj.filter("contact_ref =", contact)
    q_obj.order('-timestamp')
    for obj in q_obj:
        # do only enclose non-attic take2 properties unless attic parameter is set
        if obj.attic and not include_attic:
            continue
        res = {}
        res['key'] = str(obj.key())
        res['type'] = obj.class_name().lower()
        res['timestamp'] = obj.timestamp.isoformat()
        res['attic'] = obj.attic
        if obj.class_name() == "Email":
            res['email'] = obj.email
        elif obj.class_name() == "Web":
            res['web'] = obj.web
        elif obj.class_name() == "Address":
            if obj.location:
                res['location_lat'] = obj.location.lat
                res['location_lon'] = obj.location.lon
            res['adr'] = obj.adr
            if obj.landline_phone:
                res['landline_phone'] = obj.landline_phone
            if obj.country:
                res['country'] = obj.country.country
            if obj.adr_zoom:
                res['adr_zoom'] = obj.adr_zoom
        elif obj.class_name() == "Mobile":
            res['mobile'] = obj.mobile
        elif obj.class_name() == "Other":
            res['tag'] = obj.tag.tag
            res['text'] = obj.text
        else:
            assert True, "Invalid class name: %s" % obj.class_name()
        restypes[obj.class_name().lower()].append(res)

    return restypes
示例#3
0
def encode_contact(contact, login_user, include_attic=False, include_privacy=False):
    """Factory to encode data into view classes which can easily be rendered

    The function takes into account the access rights and encodes only elements
    which the user is allowed to see.
    signed_in is set to True if the user is signed in
    If include_attic=True, data will include the complete history and also archived data.
    If include_privacy is set, it will include the privacy setting for contacts
    this user owns: private, restricted or public
    """
    result = None
    # do only enclose non-attic contacts unless attic parameter is set
    if contact.attic and not include_attic:
        return None

    result = ContactView(contact)

    if contact.class_name() == "Person":
        if contact.lastname:
            result.lastname = contact.lastname

    if login_user:
        # Birthday
        if contact.class_name() == "Person":
            if contact.birthday.has_year():
                result.birthyear = contact.birthday.year
            if contact.birthday.has_month():
                result.birthmonth = calendar.month_name[contact.birthday.month]
            if contact.birthday.has_day():
                result.birthday = contact.birthday.day

        # nickname
        if contact.nickname:
            result.nickname = contact.nickname

    # A user can see their own data, obviously
    if login_user and login_user.key() == contact.owned_by.key():
        # introduction/relation to this person
        result.relation = contact.introduction if contact.introduction else ""
        # Relation back to the middleman
        if contact.middleman_ref:
            result.middleman = contact.middleman_ref.name
            result.middleman_ref = str(contact.middleman_ref.key())

        # Relation(s) going out from this person towards others
        result.contacts = []
        # for con in Contact.all().filter("middleman_ref =", contact):
        for con in contact.affix:
            if not con.attic or include_attic:
                result.append_take2(con)

        # can I edit the contact data?
        if login_user:
            if contact.owned_by.key() == login_user.key():
                result.can_edit = True

        # Is this the contact data for the logged in user (myself)?
        if login_user and login_user.me:
            if contact.key() == login_user.me.key():
                result.is_myself = True

        #
        # encode contact's data
        #
        q_obj = Take2.all()
        q_obj.filter("contact_ref =", contact)
        q_obj.order('-timestamp')
        for obj in q_obj:
            # do only enclose non-attic take2 properties unless attic parameter is set
            if obj.attic and not include_attic:
                continue
            if include_privacy:
                # look for an entry in the SharedTake2 table
                priv = SharedTake2.all().filter("contact_ref =", contact).filter("take2_ref =", obj).get()
                if priv:
                    if priv.class_name() == "PublicTake2":
                        # add privacy property to obj on the fly
                        obj.privacy = 'public'
                    elif priv.class_name() == "RestrictedTake2":
                        obj.privacy = 'restricted'
            result.append_take2(obj)
    else:
        result.relation = "(You cannot see this person's data.)"
        # user does not own the contact, but let's check whether the privacy settings
        # allow us to see something
        q_priv = SharedTake2.all().filter("contact_ref =", contact)
        for priv in q_priv:
            # public objects
            if priv.class_name() == 'PublicTake2':
                obj = priv.take2_ref
                # do only enclose non-attic take2 properties unless attic parameter is set
                if obj.attic and not include_attic:
                    continue
                result.append_take2(obj)
                result.relation = "(This person shares some data.)"


    return result
示例#4
0
    def get(self):
        if not users.is_current_user_admin():
            logging.critical("UpdateIndex called by non-admin")
            self.error(500)
            return

        fix = True if self.request.get("fix", "False") == "True" else False

        # look for LoginUser with invalid Person attached
        logging.info("Check LoginUser")
        err = False
        for obj in LoginUser.all():
            try:
                if not obj.me:
                    logging.critical("LoginUser %d has no Person attached" % ((obj.key().id())))
                    err = True
            except db.ReferencePropertyResolveError:
                logging.critical("LoginUser %d has invalid Person reference" % ((obj.key().id())))
                err = True
            if err:
                # check for dependent datasets
                count = Contact.all().filter("owned_by =", obj).count()
                logging.critical("LoginUser %d has %d dependant datasets" % (obj.key().id(),count))
                if fix:
                    obj.delete()
                    logging.info("%d deleted" % obj.key().id())
            err = False


        logging.info("Check Contact")
        err = False
        for obj in Contact.all():
            try:
                if not obj.owned_by:
                    logging.critical("Contact '%s' %d has no reference to owner" % (obj.name,obj.key().id()))
                    err = True
            except db.ReferencePropertyResolveError:
                logging.critical("Contact '%s' %d has invalid reference to owner" % (obj.name,obj.key().id()))
                count = LoginUser.all().filter("me =", obj).count()
                if count:
                    logging.critical("... but owner has reference!")
                err = True
            if err:
                # check for dependent datasets
                count = Take2.all().filter("contact_ref =", obj).count()
                logging.critical("Contact '%s' has %d dependent datasets" % (obj.name, count))
                if fix:
                    obj.delete()
                    logging.info("%d deleted" % obj.key().id())
            err = False

        logging.info("Check Take2")
        err = False
        for obj in Take2.all():
            try:
                if not obj.contact_ref:
                    logging.critical("Take2 has no reference to owner %s" % (obj.key().id()))
                    err = True
            except db.ReferencePropertyResolveError:
                logging.critical("Take2 has invalid reference to owner %s" % (obj.key().id()))
                err = True
            if err:
                if fix:
                    obj.delete()
                    logging.info("%d deleted" % obj.key().id())
            # location in address shall be set to default
            if obj.class_name() == 'Address' and not obj.location:
                logging.error("Address has null location %s. Fixed." % (obj.key().id()))
                obj.location=db.GeoPt(lon=0.0, lat=0.0)
                obj.put()
            err = False

        logging.info("Check SearchIndex")
        err = False
        for obj in SearchIndex.all():
            try:
                if not obj.contact_ref:
                    logging.critical("SearchIndex %d has no reference to owner" % (obj.key().id()))
                    err = True
            except db.ReferencePropertyResolveError:
                logging.critical("SearchIndex %d has invalid reference to owner" % (obj.key().id()))
                err = True
            if err:
                if fix:
                    obj.delete()
                    logging.info("%d deleted" % obj.key().id())
            err = False

        logging.info("Check GeoIndex")
        err = False
        for obj in GeoIndex.all():
            try:
                if not obj.contact_ref:
                    logging.critical("GeoIndex %d has no reference to owner" % (obj.key().id()))
                    err = True
            except db.ReferencePropertyResolveError:
                logging.critical("GeoIndex %d has invalid reference to owner" % (obj.key().id()))
                err = True
            if err:
                if fix:
                    obj.delete()
                    logging.info("%d deleted" % obj.key().id())
            err = False

        self.response.headers['Content-Type'] = "text/plain"
        self.response.out.write("/fix done.")