def sync(self, db_conn): """ Pull the fields from the database. """ data = (self.table.get(self['id']).run(db_conn)) extend(self.data, data) return self
def update(self, data): """ Update the model in the database. Return model and errors if failed. """ assert isinstance(data, dict) data = omit(data, ('id', 'created', 'modified')) extend(self.data, data) return self.save()
def sync(self): """ Pull the fields from the database. """ data = (self.table .get(self['id']) .run(database.db_conn)) extend(self.data, data) return self
def test_update_document(db_conn): schema = vases_schema data1 = { 'name': 'celestial', 'plants': [ {'species': 'zzplant', 'quantity': 2}, {'species': 'rubbertree', 'quantity': 1}, ], 'soil': {'color': 'black'} } document1, errors1 = util.insert_document(schema, data1, db_conn) subdoc1 = pick(document1, ('name', 'plants', 'soil')) subdata1 = pick(data1, ('name', 'plants', 'soil')) data2 = { 'id': 'haxxor', 'name': 'zen', } document2, errors2 = util.update_document(schema, document1, data2, db_conn) subdoc2 = pick(document2, ('name', 'plants', 'soil')) subdata2 = pick(data2, ('name', 'plants', 'soil')) assert len(errors1) == 0 assert subdoc1 == subdata1 assert document1['id'] == document2['id'] assert len(errors2) == 0 assert subdoc2 == extend({}, subdata1, subdata2)
def test_update_document(db_conn): schema = vases_schema data1 = { 'name': 'celestial', 'plants': [ { 'species': 'zzplant', 'quantity': 2 }, { 'species': 'rubbertree', 'quantity': 1 }, ], 'soil': { 'color': 'black' } } document1, errors1 = util.insert_document(schema, data1, db_conn) subdoc1 = pick(document1, ('name', 'plants', 'soil')) subdata1 = pick(data1, ('name', 'plants', 'soil')) data2 = { 'id': 'haxxor', 'name': 'zen', } document2, errors2 = util.update_document(schema, document1, data2, db_conn) subdoc2 = pick(document2, ('name', 'plants', 'soil')) subdata2 = pick(data2, ('name', 'plants', 'soil')) assert len(errors1) == 0 assert subdoc1 == subdata1 assert document1['id'] == document2['id'] assert len(errors2) == 0 assert subdoc2 == extend({}, subdata1, subdata2)
def test_extend(): """ Expect to add properties of one object to another, recursively. """ a = { 'a': 0, 'q': 1, } b = { 'a': 1, 'b': 2, 'c': { 'c1': True, 'c2': False, } } c = { 'b': 3, 'c': { 'c2': True, } } assert util.extend(a, b, c) == { 'a': 1, 'b': 3, 'c': { 'c1': True, 'c2': True, }, 'q': 1 }
def update_document(schema, prev_data, data, db_conn): """ Update the document in the database. Return document and errors if failed. NOTICE: `prev_data` should be the _return_ of `insert_document`, not the originally provided data. """ data = omit(data, ('id', 'created', 'modified')) data = extend({}, prev_data, data) return save_document(schema, data, db_conn)
def list_notices_route(request): """ List notices for current user. Take parameters `limit`, `skip`, `tag`, and `read`. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401, '9oMIw3V8S3WeaLf9IgbmaQ') params = extend({}, request['params'], {'user_id': current_user['id']}) notices = list_notices(db_conn, params) output = {'notices': [deliver_notice(notice, access='private') for notice in notices]} return 200, output
def list_notices_route(request): """ List notices for current user. Take parameters `limit`, `skip`, `tag`, and `read`. """ db_conn = request['db_conn'] current_user = get_current_user(request) if not current_user: return abort(401) params = extend({}, request['params'], {'user_id': current_user['id']}) notices = list_notices(params, db_conn) output = {'notices': [deliver_notice(notice, access='private') for notice in notices]} return 200, output
def update_post(prev_data, data, db_conn): """ Update an existing post. """ schema = get_post_schema(data) data2 = omit(data, ('id', 'created', 'modified')) data2 = extend({}, prev_data, data2) data, errors = validate_post(data2, db_conn) if errors: return data, errors data, errors = update_document(schema, prev_data, data, db_conn) if not errors: add_post_to_es(data, db_conn) return data, errors
def update_row(db_conn, schema, query, prev_data, data): """ Validate changes, then update row. """ data = omit(data, ('id', 'created', 'modified')) data = extend({}, prev_data, data) # TODO-2 is it possible to have postgres do this work of # validating/preparing? data, errors = prepare_row(db_conn, schema, data) if errors: return None, errors data = bundle_fields(schema, data) data = convert_fields_to_pgjson(data) # TODO-1 fix this data, errors = save_row(db_conn, query, data) return data, errors
schema = extend({}, default, { 'tablename': 'users', 'fields': { 'modified': { 'default': r.now(), 'bundle': update_modified, 'access': ('private',), }, 'name': { 'validate': (is_required, is_string,), 'bundle': lowercase_and_strip, 'unique': True, }, 'email': { 'validate': (is_required, is_email,), 'bundle': lowercase_and_strip, 'unique': True, 'access': ('private',), }, 'password': { 'validate': (is_required, is_string, (has_min_length, 8)), 'access': ('PaSsWoRd',), 'bundle': encrypt_password, }, 'settings': { 'validate': (is_required,), 'default': {}, 'access': ('private',), 'embed': { 'email_frequency': { 'validate': (is_required, is_string, ( is_one_of, 'immediate', 'daily', 'weekly', 'never', )), 'access': ('private',), 'default': 'daily', }, 'view_sets': { 'validate': (is_required, is_string, ( is_one_of, 'public', 'private' )), 'access': ('private',), 'default': 'private', }, 'view_follows': { 'validate': (is_required, is_string, ( is_one_of, 'public', 'private' )), 'access': ('private',), 'default': 'private', }, } } }, 'validate': [], })
from modules.util import extend from modules.validations import is_required, is_string, is_one_of from schemas.card import schema as card_schema schema = extend({}, card_schema, { 'fields': { 'data': { 'embed': { 'site': { 'validate': ( is_required, is_string, (is_one_of, 'youtube', 'vimeo'), ), }, 'video_id': { 'validate': ( is_required, is_string, ), }, }, }, }, })
schema = extend({}, default, { 'tablename': 'notices', 'fields': { 'user_id': { # TODO-2 validate foreign 'validate': (is_required, is_string,) }, 'kind': { 'validate': (is_required, is_string, ( is_one_of, 'create_topic', 'create_proposal', 'block_proposal', 'decline_proposal', 'accept_proposal', 'create_post', 'come_back', )) }, 'data': { 'validate': (is_dict,), 'default': {}, }, 'read': { 'validate': (is_boolean,), 'default': False }, 'tags': { 'validate': (is_list, is_list_of_strings), 'default': [] } } })
schema = extend( {}, default, { 'tablename': 'follows', 'fields': { 'user_id': { # TODO-2 validate foreign 'validate': ( is_required, is_string, ) }, 'entity': { 'validate': (is_required, ), 'embed': { 'id': { 'validate': ( is_required, is_string, ), }, 'kind': { 'validate': (is_required, is_string, (is_one_of, 'card', 'unit', 'subject', 'topic')), } } } } })
from modules.validations import is_required, is_string, is_dict from schemas.index import schema as default from modules.util import extend schema = extend({}, default, { 'tablename': 'cards_parameters', 'fields': { 'entity_id': { # TODO-3 validate foreign 'validate': (is_required, is_string), }, 'guess_distribution': { 'validate': (is_required, is_dict,), }, 'slip_distribution': { 'validate': (is_required, is_dict,), }, }, })
from schemas.index import schema as default from modules.validations import is_required, is_string, is_one_of, \ has_min_length from modules.util import extend schema = extend({}, default, { 'tablename': 'topics', 'fields': { 'user_id': { # TODO-2 validate foreign 'validate': (is_required, is_string,) }, 'name': { 'validate': (is_required, is_string, (has_min_length, 1),) }, 'entity': { 'validate': (is_required,), 'embed': { 'id': { # TODO-1 validate foreign (circular) 'validate': (is_required, is_string,), }, 'kind': { 'validate': (is_required, is_string, ( is_one_of, 'card', 'unit', 'set' )), } } } } })
schema = extend({}, entity_schema, { 'tablename': 'subjects', 'fields': { 'body': { 'validate': ( is_required, is_string, ), }, 'members': { 'validate': ( is_required, is_list, ), 'embed_many': { 'id': { 'validate': ( is_required, is_string, ), }, 'kind': { 'validate': (is_required, is_string, (is_one_of, 'unit', 'subject')), } } } }, })
schema = extend({}, card_schema, { 'fields': { 'body': { # Question field 'validate': (is_required, is_string,) }, 'options': { # Available answers 'validate': (is_required, is_list, (has_min_length, 1)), 'embed_many': { 'value': { 'validate': (is_required, is_string,), }, 'correct': { 'validate': (is_required, is_boolean,), 'access': ('view',), }, 'feedback': { 'validate': (is_required, is_string,), 'access': ('view',), }, } }, 'default_incorrect_feedback': { 'validate': (is_required, is_string,), 'access': ('view',), }, 'case_sensitive': { 'validate': (is_boolean,), 'default': False, } } })
from schemas.index import schema as default from modules.util import extend from modules.validations import is_required, is_uuid schema = extend({}, default, { 'tablename': 'users_subjects', 'fields': { 'user_id': { 'validate': ( is_required, is_uuid, ), }, 'subject_id': { 'validate': ( is_required, is_uuid, ), }, }, })
schema = extend({}, default, { 'tablename': 'users', 'fields': { 'modified': { 'default': r.now(), 'bundle': update_modified, 'access': ('private', ), }, 'name': { 'validate': ( is_required, is_string, ), 'bundle': lowercase_and_strip, 'unique': True, }, 'email': { 'validate': ( is_required, is_email, ), 'bundle': lowercase_and_strip, 'unique': True, 'access': ('private', ), }, 'password': { 'validate': (is_required, is_string, (has_min_length, 8)), 'access': ('PaSsWoRd', ), 'bundle': encrypt_password, }, 'settings': { 'validate': (is_required, ), 'default': {}, 'access': ('private', ), 'embed': { 'email_frequency': { 'validate': (is_required, is_string, ( is_one_of, 'immediate', 'daily', 'weekly', 'never', )), 'access': ('private', ), 'default': 'daily', }, 'view_sets': { 'validate': (is_required, is_string, (is_one_of, 'public', 'private')), 'access': ('private', ), 'default': 'private', }, 'view_follows': { 'validate': (is_required, is_string, (is_one_of, 'public', 'private')), 'access': ('private', ), 'default': 'private', }, } } }, 'validate': [], })
schema = extend({}, card_schema, { 'fields': { 'data': { 'embed': { 'body': { # Question field 'validate': (is_required, is_string,), }, 'options': { # Available answers 'validate': (is_required, is_list, (has_min_length, 1), has_correct_options), 'embed_many': { 'id': { 'validate': (is_required, is_string,), 'default': create_uuid_b64, }, 'value': { 'validate': (is_required, is_string,), }, 'correct': { 'validate': (is_required, is_boolean,), 'access': ('view',), }, 'feedback': { 'validate': (is_required, is_string,), 'access': ('view',), }, } }, 'order': { 'validate': (is_string, (is_one_of, 'random', 'set')), 'default': 'random', 'access': ('view',), }, 'max_options_to_show': { 'validate': (is_integer,), 'default': 4, 'access': ('view',), }, }, }, }, })
from schemas.post import schema as post_schema from modules.util import extend from modules.validations import is_string, is_required, is_boolean, is_uuid schema = extend({}, post_schema, { 'fields': { 'response': { 'validate': ( is_required, is_boolean, ), } }, }) schema['fields']['body']['validate'] = (is_string, ) schema['fields']['replies_to_id']['validate'] = ( is_required, is_uuid, )
from modules.util import extend from modules.validations import is_required, is_string, is_url from schemas.card import schema as card_schema schema = extend({}, card_schema, { 'fields': { 'data': { 'url': { 'validate': ( is_required, is_string, is_url, ) }, }, } })
from schemas.index import schema as default from modules.util import extend from modules.validations import is_required, is_uuid, is_dict schema = extend({}, default, { 'tablename': 'cards_parameters', 'fields': { 'entity_id': { 'validate': (is_required, is_uuid,) }, 'guess_distribution': { 'validate': (is_required, is_dict,) }, 'slip_distribution': { 'validate': (is_required, is_dict,) }, }, })
schema = extend({}, default, { 'tablename': 'notices', 'fields': { 'user_id': { 'validate': ( is_required, is_uuid, ), }, 'kind': { 'validate': ( is_required, is_string, (is_one_of, 'create_topic', 'create_proposal', 'block_proposal', 'decline_proposal', 'accept_proposal', 'create_post', 'come_back'), ), }, 'data': { 'validate': ( is_required, is_dict, ), 'default': {}, }, 'read': { 'validate': (is_required, is_boolean), 'default': False, }, 'tags': { 'validate': (is_list, is_list_of_strings), 'default': [], }, } })
from schemas.entity_base import schema as entity_schema from modules.util import extend from modules.validations import is_required, is_string, is_list, \ is_list_of_uuids """ A unit is the medium size in the Sagefy data structure system. A unit represents a unit of learning activity. A unit is defined by a single goal (objective). See Bloom's Taxonomy. A unit should represent a goal that is as small as possible without becoming systemically redundant. An example of a unit is a small learning lesson, which may contain about five to eight minutes of information and 30-60 minutes of practice to gain proficiency. """ schema = extend({}, entity_schema, { 'tablename': 'units', 'fields': { 'body': { 'validate': ( is_required, is_string, ), }, 'require_ids': { 'validate': (is_required, is_list, is_list_of_uuids), 'default': [], }, }, })
schema = extend({}, default, { 'tablename': 'users', 'fields': { 'modified': { 'access': ('private', ), }, 'name': { 'validate': ( is_required, is_string, (has_min_length, 1), ), }, 'email': { 'validate': ( is_required, is_string, (has_min_length, 1), is_email, ), 'access': ('private', ), }, 'password': { 'validate': ( is_required, is_string, (has_min_length, 8), ), 'access': ('PaSsWoRd', ), 'bundle': encrypt_password, }, 'settings': { 'validate': (is_required, is_dict), 'default': {}, 'embed': { 'email_frequency': { 'validate': (is_required, is_string, ( is_one_of, 'immediate', 'daily', 'weekly', 'never', )), 'access': ('private', ), 'default': 'daily', }, 'view_subjects': { 'validate': (is_required, is_string, (is_one_of, 'public', 'private')), 'default': 'private', }, 'view_follows': { 'validate': (is_required, is_string, (is_one_of, 'public', 'private')), 'default': 'private', }, } } }, })
vases_schema = extend({}, default, { 'tablename': 'vases', 'fields': { 'name': { 'validate': (is_required, is_string,), 'bundle': lowercase_and_strip, 'unique': True, }, 'shape': { 'validate': ((is_one_of, 'round', 'square', 'triangle'),), 'default': 'round' }, 'plants': { 'validate': (is_required, (has_min_length, 1,),), 'default': [], 'embed_many': { 'species': { 'bundle': lowercase_and_strip, }, 'quantity': { 'default': 1, 'access': ('private',) } }, }, 'soil': { 'validate': (is_required,), 'default': {}, 'access': ('private',), 'embed': { 'color': { 'default': 'brown', 'bundle': lowercase_and_strip, 'validate': (is_required, (is_one_of, 'brown', 'black', 'gray', 'clay', )) } }, } }, })
schema = extend( {}, card_schema, { 'fields': { 'body': { # Question field 'validate': ( is_required, is_string, ) }, 'options': { # Available answers 'validate': (is_required, is_list, (has_min_length, 1)), 'embed_many': { 'value': { 'validate': ( is_required, is_string_or_number, ), }, 'correct': { 'validate': ( is_required, is_boolean, ), 'access': ('view', ), }, 'feedback': { 'validate': ( is_required, is_string, ), 'access': ('view', ), }, } }, 'variables': { 'validate': ( is_required, is_list, is_list_of_variables, ), }, 'range': { 'validate': ( is_required, is_number, ), 'default': 0.001, }, 'default_incorrect_feedback': { 'validate': ( is_required, is_string, ), 'access': ('view', ), }, } })
schema = extend( {}, default, { 'tablename': 'posts', 'fields': { 'user_id': { # TODO-2 validate foreign 'validate': ( is_required, is_string, ) }, 'topic_id': { 'validate': ( is_required, is_string, ) }, 'body': { 'validate': ( is_required, is_string, (has_min_length, 1), ) }, 'kind': { 'validate': (is_required, is_string, (is_one_of, 'post', 'proposal', 'vote')), 'default': 'post' }, 'replies_to_id': { 'validate': (is_string, ) } }, })
from schemas.index import schema as default from modules.validations import is_required, is_string, is_list_of_strings from modules.util import extend schema = extend({}, default, { 'tablename': 'users_sets', 'fields': { 'user_id': { # TODO-2 validate foreign 'validate': (is_required, is_string,), }, 'set_ids': { 'validate': (is_required, is_list_of_strings,), }, } })
vases_schema = extend({}, default, { 'tablename': 'vases', 'fields': { 'name': { 'validate': ( is_required, is_string, ), 'bundle': lowercase_and_strip, 'unique': True, }, 'shape': { 'validate': ((is_one_of, 'round', 'square', 'triangle'), ), 'default': 'round' }, 'plants': { 'validate': ( is_required, ( has_min_length, 1, ), ), 'default': [], 'embed_many': { 'species': { 'bundle': lowercase_and_strip, }, 'quantity': { 'default': 1, 'access': ('private', ) } }, }, 'soil': { 'validate': (is_required, ), 'default': {}, 'access': ('private', ), 'embed': { 'color': { 'default': 'brown', 'bundle': lowercase_and_strip, 'validate': (is_required, ( is_one_of, 'brown', 'black', 'gray', 'clay', )) } }, } }, })
from modules.util import extend from modules.validations import is_required, is_string, is_one_of card_schema = {} # TODO-3 import card_schema schema = extend({}, card_schema, { 'fields': { 'site': { 'validate': ( is_required, is_string, (is_one_of, 'slideshare'), ), }, 'slideshow_id': { 'validate': ( is_required, is_string, ), } } })
from schemas.post import schema as post_schema from modules.validations import is_required, is_string, is_one_of, is_list, \ has_min_length from modules.util import extend schema = extend({}, post_schema, { 'fields': { 'entity_versions': { 'validate': (is_required, is_list, (has_min_length, 1)), 'embed_many': { 'id': { 'validate': ( is_required, is_string, ), }, 'kind': { 'validate': (is_required, is_string, ( is_one_of, 'card', 'unit', 'subject', )), }, }, }, }, })
from modules.validations import is_required, is_string, is_one_of from schemas.index import schema as default from modules.util import extend schema = extend({}, default, { 'tablename': 'follows', 'fields': { 'user_id': { # TODO-2 validate foreign 'validate': (is_required, is_string,) }, 'entity': { 'validate': (is_required,), 'embed': { 'id': { 'validate': (is_required, is_string,), }, 'kind': { 'validate': (is_required, is_string, ( is_one_of, 'card', 'unit', 'set', 'topic' )), } } } } })
schema = extend({}, card_schema, { 'fields': { 'body': { # Question field 'validate': (is_required, is_string,) }, 'file_extensions': { 'validate': (is_required, is_list, is_list_of_strings,), }, # TODO-3 What extensions are allowed? For what kind of media? 'rubric': { 'validate': (is_required, is_list, (has_max_length, 5)), 'embed_many': { 'body': { 'validate': (is_required, is_string,), }, 'value': { 'validate': (is_required, is_integer,), 'default': 1, }, 'body_none': { # Incomplete (0%) 'validate': (is_required, is_string,), }, 'body_half': { # Needs Work (50%) 'validate': (is_required, is_string,), }, 'body_full': { # Good (100%) 'validate': (is_required, is_string,), }, }, }, } })