Ejemplo n.º 1
0
def update_entity_status(db_conn, proposal):
    """
    Update the entity's status based on the vote power received.
    Move to accepted or blocked if qualified.
    TODO-2 Update this to work as described in:
        https://github.com/heiskr/sagefy/wiki/Planning%3A-Contributor-Ratings
        This requires knowing two things:
        - Number of learners the entity impacts
        - The vote and proposal history of the contributor
    """

    # Get the entity version
    entity_version = get_version(db_conn, proposal['entity_version']['kind'],
                                 proposal['entity_version']['id'])

    votes = Vote.list(db_conn, replies_to_id=proposal['id'])
    changed, status = get_entity_status(entity_version['status'], votes)

    if changed:
        entity_version['status'] = status
        entity_version.save(db_conn)
        send_notices(
            db_conn,
            entity_id=proposal['entity_version']['id'],
            entity_kind=proposal['entity_version']['kind'],
            notice_kind=('block_proposal'
                         if status == 'blocked' else 'accept_proposal'),
            notice_data={
                'user_name': '???',  # TODO-2
                'proposal_name': proposal['name'],
                'entity_kind': proposal['entity_version']['kind'],
                'entity_name': entity_version['name'],
            })
Ejemplo n.º 2
0
def is_valid_reply_kind(data, db_conn):
    """
    A vote can reply to a proposal.
    A vote cannot reply to a proposal that is accepted or declined.
    A user cannot vote on their own proposal.
    """

    query = (r.table(post_schema['tablename']).get(data['replies_to_id']))
    proposal_data = query.run(db_conn)
    if not proposal_data:
        return [{'message': 'No proposal found.'}]
    if proposal_data['kind'] != 'proposal':
        return [{'message': 'A vote must reply to a proposal.'}]
    if proposal_data['user_id'] == data['user_id']:
        return [{'message': 'You cannot vote on your own proposal.'}]
    entity_version = get_version(db_conn,
                                 proposal_data['entity_versions'][0]['kind'],
                                 proposal_data['entity_versions'][0]['id'])
    if not entity_version:
        return [{'message': 'No entity version for proposal.'}]
    if entity_version['status'] in ('accepted', 'declined'):
        return [{'message': 'Proposal is already complete.'}]
    return []
Ejemplo n.º 3
0
    def is_valid_reply_kind(self, db_conn):
        """
        A vote can reply to a proposal.
        A vote cannot reply to a proposal that is accepted or declined.
        A user cannot vote on their own proposal.
        """

        query = (self.table
                     .get(self['replies_to_id']))
        proposal_data = query.run(db_conn)
        if not proposal_data:
            return [{'message': 'No proposal found.'}]
        if proposal_data['kind'] != 'proposal':
            return [{'message': 'A vote must reply to a proposal.'}]
        if proposal_data['user_id'] == self['user_id']:
            return [{'message': 'You cannot vote on your own proposal.'}]
        entity_version = get_version(db_conn,
                                     proposal_data['entity_version']['kind'],
                                     proposal_data['entity_version']['id'])
        if not entity_version:
            return [{'message': 'No entity version for proposal.'}]
        if entity_version['status'] in ('accepted', 'declined'):
            return [{'message': 'Proposal is already complete.'}]
        return []
Ejemplo n.º 4
0
def get_posts_route(request, topic_id):
    """
    Get a reverse chronological listing of posts for given topic.
    Includes topic meta data and posts (or proposals or votes).
    Paginates.
    """

    db_conn = request['db_conn']

    # Is the topic valid?
    topic = get_topic({'id': topic_id}, db_conn)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'pgnNbqSP1VUWkOYq8MVGPrSS',
        }

    # Pull the entity
    entity_kind = topic['entity']['kind']
    entity = get_latest_accepted(db_conn, entity_kind, topic['entity']['id'])

    # Pull all kinds of posts
    posts = get_posts_facade(db_conn,
                             limit=request['params'].get('limit') or 10,
                             skip=request['params'].get('skip') or 0,
                             topic_id=topic_id)

    # For proposals, pull up the proposal entity version
    # ...then pull up the previous version
    # ...make a diff between the previous and the proposal entity version
    diffs = {}
    entity_versions = {}
    for post_ in posts:
        if post_['kind'] == 'proposal':
            entity_version = entity_versions[post_['id']] = get_version(
                db_conn, post_['entity_version']['kind'],
                post_['entity_version']['id'])
            previous_version = get_version(db_conn,
                                           post_['entity_version']['kind'],
                                           entity_version['previous_id'])
            if previous_version:
                diffs[post_['id']] = object_diff(previous_version.deliver(),
                                                 entity_version.deliver())

    # TODO-2 SPLITUP create new endpoint for this instead
    users = {}
    for post_ in posts:
        user_id = post_['user_id']
        if user_id not in users:
            user = get_user({'id': user_id}, db_conn)
            if user:
                users[user_id] = {
                    'name': user['name'],
                    'avatar': get_avatar(user['email'], 48),
                }

    # TODO-2 SPLITUP create new endpoints for these instead
    output = {
        'topic': deliver_topic(topic),
        'posts': [p.deliver() for p in posts],
        'entity_versions':
        {p: ev.deliver('view')
         for p, ev in entity_versions.items()},
        # 'diffs': diffs,  TODO-2 this causes a circular dependency
        'users': users,
    }
    if entity:
        output[entity_kind] = entity.deliver()
    return 200, output
Ejemplo n.º 5
0
def update_entity_status(proposal):
    """
    Update the entity's status based on the vote power received.
    Move to accepted or blocked if qualified.
    TODO-2 Update this to work as described in:
        https://github.com/heiskr/sagefy/wiki/Planning%3A-Contributor-Ratings
        This requires knowing two things:
        - Number of learners the entity impacts
        - The vote and proposal history of the contributor
    """

    # Get the entity version
    entity_version = get_version(proposal['entity_version']['kind'],
                                 proposal['entity_version']['id'])

    # Make sure the entity version status is not declined or accepted
    if entity_version['status'] in ('accepted', 'declined'):
        return

    # Count the "no" and "yes" vote power
    no_vote_power = 0
    yes_vote_power = 1
    # For now, we will assume the proposer is one "yes" vote until
    # contributor vote power is calculated
    votes = Vote.list(replies_to_id=proposal['id'])
    for vote in votes:
        if vote['response']:
            yes_vote_power = yes_vote_power + 1
        else:
            no_vote_power = no_vote_power + 1

    # If no power is great enough, then block the version
    if no_vote_power >= 1:
        entity_version['status'] = 'blocked'
        entity_version.save()
        send_notices(
            entity_id=proposal['entity_version']['id'],
            entity_kind=proposal['entity_version']['kind'],
            notice_kind='block_proposal',
            notice_data={
                'user_name': '???',  # TODO-2
                'proposal_name': proposal['name'],
                'entity_kind': proposal['entity_version']['kind'],
                'entity_name': entity_version['name'],
            }
        )

    # If yes power is great enough, then accept the version
    if yes_vote_power >= 3:
        entity_version['status'] = 'accepted'
        entity_version.save()
        send_notices(
            entity_id=proposal['entity_version']['id'],
            entity_kind=proposal['entity_version']['kind'],
            notice_kind='accept_proposal',
            notice_data={
                'proposal_name': proposal['name'],
                'entity_kind': proposal['entity_version']['kind'],
                'entity_name': entity_version['name'],
            }
        )
Ejemplo n.º 6
0
def get_posts_route(request, topic_id):
    """
    Get a reverse chronological listing of posts for given topic.
    Includes topic meta data and posts (or proposals or votes).
    Paginates.
    """

    # Is the topic valid?
    topic = Topic.get(id=topic_id)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'pgnNbqSP1VUWkOYq8MVGPrSS',
        }

    # Pull the entity
    entity_kind = topic['entity']['kind']
    entity = get_latest_accepted(entity_kind,
                                 topic['entity']['id'])

    # Pull all kinds of posts
    posts = get_posts_facade(
        limit=request['params'].get('limit') or 10,
        skip=request['params'].get('skip') or 0,
        topic_id=topic_id
    )

    # For proposals, pull up the proposal entity version
    # ...then pull up the previous version
    # ...make a diff between the previous and the proposal entity version
    diffs = {}
    entity_versions = {}
    for post_ in posts:
        if post_['kind'] == 'proposal':
            entity_version = entity_versions[post_['id']] = get_version(
                post_['entity_version']['kind'],
                post_['entity_version']['id']
            )
            previous_version = get_version(
                post_['entity_version']['kind'],
                entity_version['previous_id']
            )
            if previous_version:
                diffs[post_['id']] = object_diff(previous_version.deliver(),
                                                 entity_version.deliver())

    # TODO-2 SPLITUP create new endpoint for this instead
    users = {}
    for post_ in posts:
        user_id = post_['user_id']
        if user_id not in users:
            user = User.get(id=user_id)
            if user:
                users[user_id] = {
                    'name': user['name'],
                    'avatar': user.get_avatar(48)
                }

    # TODO-2 SPLITUP create new endpoints for these instead
    output = {
        'topic': topic.deliver(),
        'posts': [p.deliver() for p in posts],
        'entity_versions': {
            p: ev.deliver()
            for p, ev in entity_versions.items()
        },
        # 'diffs': diffs,  TODO-2 this causes a circular dependency
        'users': users,
    }
    if entity:
        output[entity_kind] = entity.deliver()
    return 200, output