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 create_topic_route(request): """ Create a new topic. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401, 'WJ50hh2STw-5ujy62wyXew') # ## STEP 1) Create topic topic_data = request['params'] if not topic_data: return 400, { 'errors': [{ 'name': 'topic', 'message': 'Missing topic data.', 'ref': 'PmocSz4OQUGa2T7x98yVlg', }], } topic_data['user_id'] = current_user['id'] topic, errors = insert_topic(db_conn, topic_data) if errors: return 400, {'errors': errors, 'ref': 'UoyXf_vwSWee0tCWgxg4Zw'} # ## STEP 2) Add author as a follower insert_follow( db_conn, { 'user_id': current_user['id'], 'entity_id': topic['id'], 'entity_kind': 'topic', }) # TODO-2 also follow the entity automatically IF needed # ## STEP 3) Send out any needed notices send_notices(db_conn, entity_id=topic['entity_id'], entity_kind=topic['entity_kind'], notice_kind='create_topic', notice_data={ 'user_name': current_user['name'], 'topic_name': topic['name'], 'entity_kind': topic['entity_kind'], 'entity_name': convert_uuid_to_slug(topic['entity_id']), }) # ## STEP 4) Return response return 200, { 'topic': deliver_topic(topic), }
def test_send_notices(db_conn): create_test_follows(db_conn) notices, errors = send_notices(db_conn, entity_id=test_unit_uuid, entity_kind='unit', notice_kind='create_topic', notice_data={ 'user_name': 'Doris', 'topic_name': 'A new topic', 'entity_kind': 'unit', 'entity_name': 'Adding numbers', }) assert not errors assert len(notices) == 2
def update_entity_statuses(db_conn, proposal): """ Update the entity's status based on the vote power received. Move to accepted or blocked if qualified. """ from database.post import list_votes_by_proposal from modules.notices import send_notices for eev in proposal['entity_versions']: entity_kind, version_id = eev['kind'], eev['id'] entity_version = get_entity_version(db_conn, entity_kind, version_id) votes = list_votes_by_proposal(db_conn, proposal['id']) changed, status = get_entity_status(entity_version['status'], votes) if changed: entity_version['status'] = status user = get_user(db_conn, {'id': proposal['user_id']}) update_entity_status_by_kind( db_conn, kind=entity_kind, version_id=version_id, status=status ) send_notices( db_conn, entity_id=version_id, entity_kind=entity_kind, notice_kind=('block_proposal' if status == 'blocked' else 'accept_proposal'), notice_data={ 'user_name': user['name'], 'proposal_name': proposal['body'], 'entity_kind': entity_kind, 'entity_name': entity_version['name'], } )
def create_topic_route(request): """ Create a new topic. The first post (or proposal) must be provided. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401) # ## STEP 1) Create post and topic (and entity) instances topic_data = request['params'].get('topic') post_data = request['params'].get('post') if not topic_data: return 400, { 'errors': [{ 'name': 'topic', 'message': 'Missing topic data.' }], 'ref': 'zknSd46f2hRNjSjVHCg6YLwN' } if not post_data: return 400, { 'errors': [{ 'name': 'post', 'message': 'Missing post data.' }], 'ref': 'Qki4oWX4nTdNAjYI8z5iNawr' } topic_data = omit(topic_data, ('id', 'created', 'modified')) topic_data['user_id'] = current_user['id'] topic_data, topic_errors = validate_topic(topic_data, db_conn) post_data = omit(post_data, ( 'id', 'created', 'modified', )) post_data['user_id'] = current_user['id'] post_data['topic_id'] = topic_data['id'] post_ = instance_post_facade(post_data) post_kind = post_['kind'] if post_kind == 'proposal': entity = instance_new_entity(request['params']) entity_kind = get_kind(request['params']) post_['entity_version'] = { 'id': entity['id'], 'kind': entity_kind, } # ## STEP 2) Validate post and topic (and entity) instances errors = prefix_error_names('topic.', topic_errors) errors = errors + prefix_error_names('post.', post_.validate(db_conn)) if post_kind == 'proposal': errors = (errors + prefix_error_names('entity.', entity.validate(db_conn))) if len(errors): return 400, {'errors': errors, 'ref': 'TAY5pX3ghWBkSIVGTHzpQySa'} # ## STEP 3) Save post and topic (and entity) topic_data, topic_errors = insert_topic(topic_data, db_conn) post_['topic_id'] = topic_data['id'] post_.save(db_conn) if post_kind == 'proposal': entity.save(db_conn) # ## STEP 4) Add author as a follower insert_follow( { 'user_id': current_user['id'], 'entity': { 'id': topic_data['id'], 'kind': 'topic', } }, db_conn) # TODO-2 also follow the entity automatically IF needed # ## STEP 5) Send out any needed notices send_notices(db_conn, entity_id=topic_data['entity']['id'], entity_kind=topic_data['entity']['kind'], notice_kind='create_topic', notice_data={ 'user_name': current_user['name'], 'topic_name': topic_data['name'], 'entity_kind': topic_data['entity']['kind'], 'entity_name': topic_data['entity']['id'], }) if post_kind == 'proposal': send_notices(db_conn, entity_id=topic_data['entity']['id'], entity_kind=topic_data['entity']['kind'], notice_kind='create_proposal', notice_data={ 'user_name': current_user['name'], 'topic_name': topic_data['name'], 'entity_kind': topic_data['entity']['kind'], 'entity_name': topic_data['entity']['id'], }) # ## STEP 5) Return response return 200, {'topic': deliver_topic(topic_data), 'post': post_.deliver()}
def create_post_route(request, topic_id): """ Create a new post on a given topic. Proposal: must include entity (card, unit, or set) information. Vote: must refer to a valid proposal. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401) topic = get_topic({'id': topic_id}, db_conn) if not topic: return 404, { 'errors': [{ 'name': 'topic_id', 'message': c('no_topic'), }], 'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM', } # ## STEP 1) Create post (and entity) instances post_data = request['params'].get('post') if not post_data: return 400, { 'errors': [{ 'name': 'post', 'message': 'Missing post data.', }], 'ref': 'ykQpZwJKq54MTCxgkx0p6baW' } post_data = omit(post_data, ( 'id', 'created', 'modified', )) post_data['user_id'] = current_user['id'] post_data['topic_id'] = topic_id post_ = instance_post_facade(post_data) post_kind = post_['kind'] if post_kind == 'proposal': entity = instance_new_entity(request['params']) entity_kind = get_kind(request['params']) post_['entity_version'] = { 'id': entity['id'], 'kind': entity_kind, } # ## STEP 2) Validate post (and entity) instances errors = prefix_error_names('post.', post_.validate(db_conn)) if post_kind == 'proposal': errors = (errors + prefix_error_names('entity.', entity.validate(db_conn))) if len(errors): return 400, {'errors': errors, 'ref': 'tux33ztgFj9ittSpS7WKIkq7'} # ## STEP 3) Save post (and entity) post_.save(db_conn) if post_kind == 'proposal': entity.save(db_conn) # ## STEP 4) Add author as a follower insert_follow( { 'user_id': current_user['id'], 'entity': { 'id': topic['id'], 'kind': 'topic', } }, db_conn) # TODO-2 also follow the entity # ## STEP 5) Make updates based on proposal / vote status if post_kind == 'proposal': update_entity_status(db_conn, post_) if post_kind == 'vote': proposal = Proposal.get(db_conn, id=post_['replies_to_id']) update_entity_status(db_conn, proposal) # ## STEP 6) Send notices if post_kind == 'proposal': send_notices(db_conn, entity_id=topic['entity']['id'], entity_kind=topic['entity']['kind'], notice_kind='create_proposal', notice_data={ 'user_name': current_user['name'], 'topic_name': topic['name'], 'entity_kind': topic['entity']['kind'], 'entity_name': topic['entity']['id'], }) # ## STEP 7) Return response return 200, {'post': post_.deliver()}
def create_topic_route(request): """ Create a new topic. The first post (or proposal) must be provided. """ current_user = get_current_user(request) if not current_user: return abort(401) # ## STEP 1) Create post and topic (and entity) instances topic_data = request['params'].get('topic') post_data = request['params'].get('post') if not topic_data: return 400, { 'errors': [{ 'name': 'topic', 'message': 'Missing topic data.' }], 'ref': 'zknSd46f2hRNjSjVHCg6YLwN' } if not post_data: return 400, { 'errors': [{ 'name': 'post', 'message': 'Missing post data.' }], 'ref': 'Qki4oWX4nTdNAjYI8z5iNawr' } topic_data = omit(topic_data, ('id', 'created', 'modified')) topic_data['user_id'] = current_user['id'] topic = Topic(topic_data) post_data = omit(post_data, ('id', 'created', 'modified',)) post_data['user_id'] = current_user['id'] post_data['topic_id'] = topic['id'] post_ = instance_post_facade(post_data) post_kind = post_['kind'] if post_kind == 'proposal': entity = instance_new_entity(request['params']) entity_kind = get_kind(request['params']) post_['entity_version'] = { 'id': entity['id'], 'kind': entity_kind, } # ## STEP 2) Validate post and topic (and entity) instances errors = prefix_error_names('topic.', topic.validate()) errors = errors + prefix_error_names('post.', post_.validate()) if post_kind == 'proposal': errors = errors + prefix_error_names('entity.', entity.validate()) if len(errors): return 400, { 'errors': errors, 'ref': 'TAY5pX3ghWBkSIVGTHzpQySa' } # ## STEP 3) Save post and topic (and entity) topic.save() post_.save() if post_kind == 'proposal': entity.save() # ## STEP 4) Add author as a follower Follow.insert({ 'user_id': current_user['id'], 'entity': { 'id': topic['id'], 'kind': 'topic', } }) # TODO-2 also follow the entity automatically IF needed # ## STEP 5) Send out any needed notifications send_notices( entity_id=topic['entity']['id'], entity_kind=topic['entity']['kind'], notice_kind='create_topic', notice_data={ 'user_name': current_user['name'], 'topic_name': topic['name'], 'entity_kind': topic['entity']['kind'], 'entity_name': topic['entity']['id'], } ) # ## STEP 5) Return response return 200, {'topic': topic.deliver(), 'post': post_.deliver()}
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 create_post_route(request, topic_id): """ Create a new post on a given topic. Proposal: must include entity (card, unit, or set) information. Vote: must refer to a valid proposal. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401) topic = Topic.get(db_conn, id=topic_id) if not topic: return 404, { 'errors': [{ 'name': 'topic_id', 'message': c('no_topic'), }], 'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM', } # ## STEP 1) Create post (and entity) instances post_data = request['params'].get('post') if not post_data: return 400, { 'errors': [{ 'name': 'post', 'message': 'Missing post data.', }], 'ref': 'ykQpZwJKq54MTCxgkx0p6baW' } post_data = omit(post_data, ('id', 'created', 'modified',)) post_data['user_id'] = current_user['id'] post_data['topic_id'] = topic_id post_ = instance_post_facade(post_data) post_kind = post_['kind'] if post_kind == 'proposal': entity = instance_new_entity(request['params']) entity_kind = get_kind(request['params']) post_['entity_version'] = { 'id': entity['id'], 'kind': entity_kind, } # ## STEP 2) Validate post (and entity) instances errors = prefix_error_names('post.', post_.validate(db_conn)) if post_kind == 'proposal': errors = (errors + prefix_error_names('entity.', entity.validate(db_conn))) if len(errors): return 400, { 'errors': errors, 'ref': 'tux33ztgFj9ittSpS7WKIkq7' } # ## STEP 3) Save post (and entity) post_.save(db_conn) if post_kind == 'proposal': entity.save(db_conn) # ## STEP 4) Add author as a follower Follow.insert(db_conn, { 'user_id': current_user['id'], 'entity': { 'id': topic['id'], 'kind': 'topic', } }) # TODO-2 also follow the entity # ## STEP 5) Make updates based on proposal / vote status if post_kind == 'proposal': update_entity_status(db_conn, post_) if post_kind == 'vote': proposal = Proposal.get(db_conn, id=post_['replies_to_id']) update_entity_status(db_conn, proposal) # ## STEP 6) Send notices if post_kind == 'proposal': send_notices( db_conn, entity_id=topic['entity']['id'], entity_kind=topic['entity']['kind'], notice_kind='create_proposal', notice_data={ 'user_name': current_user['name'], 'topic_name': topic['name'], 'entity_kind': topic['entity']['kind'], 'entity_name': topic['entity']['id'], } ) # ## STEP 7) Return response return 200, {'post': post_.deliver()}