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'], })
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 []
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 []
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
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'], } )
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