def add_new_rubric_row( assig: models.Assignment, header: str, description: str, items: t.Sequence[JSONType] ) -> int: """Add new rubric row to the assignment. :param assig: The assignment to add the rubric row to :param header: The name of the new rubric row. :param description: The description of the new rubric row. :param items: The items (:py:class:`.models.RubricItem`) that should be added to the new rubric row, the JSONType should be a dictionary with the keys ``description`` (:py:class:`str`), ``header`` (:py:class:`str`) and ``points`` (:py:class:`float`). :returns: The amount of items in this row. :raises APIException: If `description` or `points` fields are not in `item`. (INVALID_PARAM) """ rubric_row = models.RubricRow( assignment_id=assig.id, header=header, description=description ) for item in items: item = ensure_json_dict(item) ensure_keys_in_dict( item, [('description', str), ('header', str), ('points', numbers.Real)] ) description = t.cast(str, item['description']) header = t.cast(str, item['header']) points = t.cast(numbers.Real, item['points']) rubric_item = models.RubricItem( rubricrow_id=rubric_row.id, header=header, description=description, points=points ) db.session.add(rubric_item) rubric_row.items.append(rubric_item) db.session.add(rubric_row) return len(items)
def test_data(db=None): db = db or psef.models.db if not app.config['DEBUG']: print('You can not add test data in production mode', file=sys.stderr) return 1 seed() db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/courses.json', 'r' ) as c: cs = json.load(c) for c in cs: if m.Course.query.filter_by(name=c['name']).first() is None: db.session.add(m.Course(name=c['name'])) db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/assignments.json', 'r' ) as c: cs = json.load(c) for c in cs: assig = m.Assignment.query.filter_by(name=c['name']).first() if assig is None: db.session.add( m.Assignment( name=c['name'], deadline=datetime.datetime.utcnow() + datetime.timedelta(days=c['deadline']), state=c['state'], description=c['description'], course=m.Course.query.filter_by(name=c['course'] ).first() ) ) else: assig.description = c['description'] assig.state = c['state'] assig.course = m.Course.query.filter_by(name=c['course'] ).first() db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/users.json', 'r' ) as c: cs = json.load(c) for c in cs: u = m.User.query.filter_by(name=c['name']).first() courses = { m.Course.query.filter_by(name=name).first(): role for name, role in c['courses'].items() } perms = { course.id: m.CourseRole.query.filter_by(name=name, course_id=course.id).first() for course, name in courses.items() } username = c['name'].split(' ')[0].lower() if u is not None: u.name = c['name'] u.courses = perms u.email = c['name'].replace(' ', '_').lower() + '@example.com' u.password = c['name'] u.username = username u.role = m.Role.query.filter_by(name=c['role']).first() else: u = m.User( name=c['name'], courses=perms, email=c['name'].replace(' ', '_').lower() + '@example.com', password=c['name'], username=username, role=m.Role.query.filter_by(name=c['role']).first() ) db.session.add(u) for course, role in courses.items(): if role == 'Student': for assig in course.assignments: work = m.Work(assignment=assig, user=u) db.session.add( m.File( work=work, name='Top stub dir', is_directory=True ) ) db.session.add(work) db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/rubrics.json', 'r' ) as c: cs = json.load(c) for c in cs: for row in c['rows']: assignment = m.Assignment.query.filter_by( name=c['assignment'] ).first() if assignment is not None: rubric_row = m.RubricRow.query.filter_by( header=row['header'], description=row['description'], assignment_id=assignment.id ).first() if rubric_row is None: rubric_row = m.RubricRow( header=row['header'], description=row['description'], assignment=assignment ) db.session.add(rubric_row) for item in row['items']: if not db.session.query( m.RubricItem.query.filter_by( rubricrow_id=rubric_row.id, **item, ).exists() ).scalar(): rubric_item = m.RubricItem( description=item['description'] * 5, header=item['header'], points=item['points'], rubricrow=rubric_row ) db.session.add(rubric_item) db.session.commit()
def test_data(db=None): db = psef.models.db if db is None else db if not app.config['DEBUG']: print('You can not add test data in production mode', file=sys.stderr) return 1 if not os.path.isdir(app.config['UPLOAD_DIR']): os.mkdir(app.config['UPLOAD_DIR']) seed() db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/courses.json', 'r') as c: cs = json.load(c) for c in cs: if m.Course.query.filter_by(name=c['name']).first() is None: db.session.add(m.Course.create_and_add(name=c['name'])) db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/assignments.json', 'r') as c: cs = json.load(c) for c in cs: assig = m.Assignment.query.filter_by(name=c['name']).first() if assig is None: db.session.add( m.Assignment( name=c['name'], deadline=cg_dt_utils.now() + datetime.timedelta(days=c['deadline']), state=c['state'], description=c['description'], course=m.Course.query.filter_by( name=c['course']).first(), is_lti=False, )) else: assig.description = c['description'] assig.state = c['state'] assig.course = m.Course.query.filter_by( name=c['course']).first() db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/users.json', 'r') as c: cs = json.load(c) for c in cs: u = m.User.query.filter_by(name=c['name']).first() courses = { m.Course.query.filter_by(name=name).first(): role for name, role in c['courses'].items() } perms = { course.id: m.CourseRole.query.filter_by(name=name, course_id=course.id).first() for course, name in courses.items() } username = c['name'].split(' ')[0].lower() if u is not None: u.name = c['name'] u.courses = perms u.email = c['name'].replace(' ', '_').lower() + '@example.com' u.password = c['name'] u.username = username u.role = m.Role.query.filter_by(name=c['role']).first() else: u = m.User(name=c['name'], courses=perms, email=c['name'].replace(' ', '_').lower() + '@example.com', password=c['name'], username=username, role=m.Role.query.filter_by(name=c['role']).first()) db.session.add(u) for course, role in courses.items(): if role == 'Student': for assig in course.assignments: work = m.Work(assignment=assig, user=u) f = m.File(work=work, name='Top stub dir ({})'.format(u.name), is_directory=True) filename = str(uuid.uuid4()) shutil.copyfile( __file__, os.path.join(app.config['UPLOAD_DIR'], filename)) f.children = [ m.File(work=work, name='manage.py', is_directory=False, filename=filename) ] db.session.add(f) db.session.add(work) db.session.commit() with open( f'{os.path.dirname(os.path.abspath(__file__))}/test_data/rubrics.json', 'r') as c: cs = json.load(c) for c in cs: for row in c['rows']: assignment = m.Assignment.query.filter_by( name=c['assignment']).first() if assignment is not None: rubric_row = m.RubricRow.query.filter_by( header=row['header'], description=row['description'], assignment_id=assignment.id, ).first() if rubric_row is None: rubric_row = m.RubricRow( header=row['header'], description=row['description'], assignment=assignment, rubric_row_type='normal', ) db.session.add(rubric_row) for item in row['items']: if not db.session.query( m.RubricItem.query.filter_by( rubricrow_id=rubric_row.id, **item, ).exists()).scalar(): rubric_item = m.RubricItem( description=item['description'] * 5, header=item['header'], points=item['points'], rubricrow=rubric_row) db.session.add(rubric_item) db.session.commit()
def patch_rubric_row( header: str, description: str, rubric_row_id: int, items: t.Sequence[JSONType], ) -> int: """Update a rubric row of the assignment. .. note:: All items not present in the given ``items`` array will be deleted from the rubric row. :param rubric_row_id: The id of the rubric row that should be updated. :param items: The items (:py:class:`models.RubricItem`) that should be added or updated. The format should be the same as in :py:func:`add_new_rubric_row` with the addition that if ``id`` is in the item the item will be updated instead of added. :returns: The amount of items in the resulting row. :raises APIException: If `description` or `points` fields are not in `item`. (INVALID_PARAM) :raises APIException: If no rubric item with given id exists. (OBJECT_ID_NOT_FOUND) """ rubric_row = helpers.get_or_404(models.RubricRow, rubric_row_id) rubric_row.header = header rubric_row.description = description seen = set() for item in items: item = ensure_json_dict(item) ensure_keys_in_dict( item, [('description', str), ('points', numbers.Real), ('header', str)] ) description = t.cast(str, item['description']) header = t.cast(str, item['header']) points = t.cast(numbers.Real, item['points']) if 'id' in item: seen.add(item['id']) rubric_item = helpers.get_or_404(models.RubricItem, item['id']) rubric_item.header = header rubric_item.description = description rubric_item.points = float(points) else: rubric_item = models.RubricItem( rubricrow_id=rubric_row.id, description=description, header=header, points=points ) db.session.add(rubric_item) rubric_row.items.append(rubric_item) rubric_row.items = [ item for item in rubric_row.items if item.id is None or item.id in seen ] return len(rubric_row.items)