def get_card_route(request, card_id): """ Get a specific card given an ID. Show all relevant data, but not used for the learning interface. """ db_conn = request['db_conn'] card = get_latest_accepted_card(db_conn, card_id) if not card: return abort(404, 'fPebfwqfRNmOiSWqWISeaA') unit = get_latest_accepted_unit(db_conn, card['unit_id']) if not unit: return abort(404, 'IKSqfvHvRK6hbSAIOkQuLg') # TODO-2 SPLITUP create new endpoints for these instead requires = list_required_cards(db_conn, card_id) required_by = list_required_by_cards(db_conn, card_id) params = get_card_parameters(db_conn, {'entity_id': card_id}) return 200, { 'card': deliver_card(card, access='view'), 'card_parameters': (get_card_parameters_values(params) if params else None), 'unit': deliver_unit(unit), 'requires': [deliver_card(require) for require in requires], 'required_by': [deliver_card(require) for require in required_by], }
def test_update_card_parameters(db_conn): create_card_test_data(db_conn) prev_data = get_latest_accepted_card(db_conn, entity_id=card_b_uuid) data = { 'guess_distribution': {}, 'slip_distribution': {}, } cp, errors = update_card_parameters(db_conn, prev_data, data) assert not errors assert cp
def test_deliver_card(db_conn): create_card_test_data(db_conn) card = get_latest_accepted_card(db_conn, entity_id=card_a_uuid) # a bad kind card['kind'] = 'eraser' assert deliver_card(card, access=None) card['kind'] = 'video' # for real assert deliver_card(card, access=None) # access = learn, kind = choice, order = random # ... and max_options_to_show < total options card = get_latest_accepted_card(db_conn, entity_id=card_b_uuid) card['data']['order'] = 'random' card['data']['max_options_to_show'] = 1 result = deliver_card(card, access='learn') assert result assert result['kind'] == 'choice' assert result['data']['options'][0].get('feedback') is None assert result['data']['options'][0].get('correct') is None assert len(result['data']['options']) == 1
def learn_card_route(request, card_id): """ Render the card's data, ready for learning. NEXT STATE GET Learn Card -> POST Respond Card """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401, 'WBv3UeikTLu5AAwG9A0QZg') card = get_latest_accepted_card(db_conn, card_id) if not card: return abort(404, 'UgQHXzx4SSaHgJzHpRaL9g') # Make sure the current unit id matches the card context = get_learning_context(current_user) context_unit_id = context.get('unit', {}).get('entity_id') if context_unit_id != convert_uuid_to_slug(card['unit_id']): return 400, { 'errors': [{ 'name': 'unit_id', 'message': 'card not in current unit.', 'ref': 'd6rhaoCuRdW0f9j8AlMXBQ', }], } next_ = { 'method': 'POST', 'path': '/s/cards/{card_id}/responses'.format( card_id=convert_uuid_to_slug(card['entity_id'])) } set_learning_context(current_user, card=card, next=next_) return 200, { 'card': deliver_card(card, access='learn'), 'subject': context.get('subject'), 'unit': context.get('unit'), 'next': next_, }
def create_existing_card_version_route(request, card_id): """ Create a new card version for an existing card. """ current_user = get_current_user(request) if not current_user: return abort(401, 'a3vXGVFCRpWwf8WEkqtBgQ') db_conn = request['db_conn'] next_data = deepcopy(request['params']) next_data['entity_id'] = card_id next_data['user_id'] = current_user['id'] current_data = get_latest_accepted_card(db_conn, card_id) if not current_data: return abort(404, 'dQvoI_OjQY2U-GeyP8fsTA') card, errors = insert_card_version(db_conn, current_data, next_data) if errors: return 400, { 'errors': errors, 'ref': 'DyKLB28gT6CYGdyQ9smOKQ', } return 200, {'version': deliver_card(card, 'view')}
def test_get_latest_accepted_card(db_conn): create_card_test_data(db_conn) card = get_latest_accepted_card(db_conn, entity_id=card_a_uuid) assert card assert card['entity_id'] == card_a_uuid
def respond_to_card_route(request, card_id): """ Record and process a learner's response to a card. NEXT STATE POST Respond Card -> GET Learn Card ...when not ready -> GET Choose Unit ...when ready, but still units -> GET View Subject Tree ...when ready and done """ # TODO-3 simplify this method. # perhaps smaller methods or move to model layer? db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401, 'XDVEHHLRSZqQNJW4Zi_iqw') card = get_latest_accepted_card(db_conn, card_id) if not card: return abort(404, 'TQZ3SmAhS1qBd274C9DG0w') # Make sure the card is the current one context = get_learning_context(current_user) context_card_id = context.get('card', {}).get('entity_id') if context_card_id != convert_uuid_to_slug(card['entity_id']): return 400, { 'errors': [{ 'message': 'Not the current card.', 'ref': 'XfmF52NmQnK_bbaxx-p8dg', }] } result = seq_update(db_conn, current_user, card, request['params'].get('response')) errors, response, feedback = (result.get('errors'), result.get('response'), result.get('feedback')) if errors: return 400, { 'errors': errors, 'ref': 'HfuW7_B-TByy8yh4FwgdrA', } subject = context.get('subject') unit = context.get('unit') status = judge(db_conn, unit, current_user) # If we are done with this current unit... if status == "done": buckets = traverse(db_conn, current_user, subject) # If there are units to be diagnosed... if buckets.get('diagnose'): unit = buckets['diagnose'][0] next_card = choose_card(db_conn, current_user, unit) next_ = { 'method': 'GET', 'path': '/s/cards/{card_id}/learn'.format( card_id=convert_uuid_to_slug(next_card['entity_id'])), } set_learning_context(current_user, card=next_card.data, unit=unit, next=next_) # If there are units to be learned or reviewed... elif buckets.get('learn') or buckets.get('review'): next_ = { 'method': 'GET', 'path': '/s/subjects/{subject_id}/units'.format( subject_id=convert_uuid_to_slug(subject['entity_id'])), } set_learning_context(current_user, card=None, unit=None, next=next_) # If we are out of units... else: next_ = { 'method': 'GET', 'path': '/s/subjects/{subject_id}/tree'.format( subject_id=convert_uuid_to_slug(subject['entity_id'])), } set_learning_context(current_user, card=None, unit=None, next=next_) # If we are still reviewing, learning or diagnosing this unit... else: next_card = choose_card(db_conn, current_user, unit) if next_card: next_ = { 'method': 'GET', 'path': '/s/cards/{card_id}/learn'.format( card_id=convert_uuid_to_slug(next_card['entity_id'])), } set_learning_context(current_user, card=next_card, next=next_) else: next_ = {} set_learning_context(current_user, next=next_) return 200, { 'response': deliver_response(response), 'feedback': feedback, 'next': next_, }