class NewsItemController(FilterCrudRestController): '''CrudController for News''' model = NewsItem __table_options__ = { '__omit_fields__': ['event_id', 'user_id', 'user'], '__field_order__': ['id', 'date', 'subject', 'message', 'public'], 'date': lambda filler, obj: h.strftime(obj.date, False), '__base_widget_args__': { 'sortList': [[6, 0], [2, 0]] }, } __form_options__ = { '__omit_fields__': ['id'], '__hide_fields__': ['user'], '__field_order__': ['id', 'date', 'event', 'subject', 'message', 'public'], '__field_widget_args__': { 'event': { 'help_text': u''' If an event is set, the NewsItem will be shown on the event page; if no event is set, the NewsItem is shown on the news page''', }, }, }
class AssignmentsCrudController(FilterCrudRestController): '''CrudController for Assignments''' model = Assignment __table_options__ = { '__omit_fields__': [ 'id', 'event_id', '_event', '_url', 'teacher_id', 'teacher', #'allowed_languages', '_teacher', 'description', 'tests', 'show_compiler_msg', '_start_time', '_end_time', 'submission_filename', 'submission_template', 'submission_scaffold_show', 'submission_scaffold_head', 'submission_scaffold_foot', '_lti', ], '__field_order__': [ 'sheet_id', 'sheet', 'assignment_id', 'name', 'public', 'start_time', 'end_time', 'timeout', 'allowed_languages', 'submissions', ] + (['lti_url'] if _lti else []), '__search_fields__': ['id', 'sheet_id', 'assignment_id', 'name'], '__xml_fields__': [ 'name', 'sheet_id', 'assignment_id', 'sheet', 'allowed_languages', 'submissions', 'lti_url' ], '__headers__': { 'sheet_id': '', 'assignment_id': '', }, 'start_time': lambda filler, obj: h.strftime(obj.start_time, False), 'end_time': lambda filler, obj: h.strftime(obj.end_time, False), 'name': lambda filler, obj: literal(u'<span title="assignment_id=%d">%s</span>' % (obj.assignment_id, obj.name)), 'sheet_id': lambda filler, obj: literal(u'<span title="sheet_id=%d">%d</span>' % (obj.sheet_id, obj.sheet_id)), 'assignment_id': lambda filler, obj: literal(u'<span title="assignment_id=%d">%d</span>' % (obj.assignment_id, obj.assignment_id)), 'sheet': lambda filler, obj: link_to(obj.sheet.name, '../sheets/%d/edit' % obj.sheet.id, title='sheet_id=%d' % (obj.sheet_id)), 'allowed_languages': lambda filler, obj: ', '.join( link_to(l.name, '/languages/%d' % l.id) for l in obj.allowed_languages), 'lti_url': lambda filler, obj: u'<span title="%s:%s">%s</span>' % (obj.lti.oauth_key, obj.lti.oauth_secret, url(obj.lti_url, qualified=True)) if obj.lti else u'', 'submissions': _submissions, '__base_widget_args__': { 'sortList': [[1, 0], [3, 0]] }, } __form_options__ = { '__omit_fields__': [ 'id', 'tests', 'submissions', '_event', 'teacher', '_url', '_teacher', '_lti', ], '__add_fields__': { 'submission_note': twb.Label( 'submission_note', label='Note', css_class='bold', text='For obvious reasons, it might not be the best idea to ' 'pre-define submission data here, ' 'when multiple languages are allowed.'), }, '__field_order__': [ 'id', 'sheet', 'assignment_id', 'name', 'description', 'public', '_start_time', '_end_time', 'timeout', 'allowed_languages', 'show_compiler_msg', 'submission_note', 'submission_filename', 'submission_template', 'submission_scaffold_show', 'submission_scaffold_head', 'submission_scaffold_foot', ], '__field_widget_types__': { 'submission_template': SourceEditor, 'submission_scaffold_head': SourceEditor, 'submission_scaffold_foot': SourceEditor, }, '__field_widget_args__': { 'assignment_id': { 'label': u'Assignment Id', 'help_text': u'Will be part of the url and has to be unique for the parent sheet', }, 'public': { 'help_text': u'Make assignment visible for students', }, '_start_time': { 'help_text': u'Leave empty to use value from sheet', }, '_end_time': { 'help_text': u'Leave empty to use value from sheet', }, 'timeout': { 'help_text': u'Default timeout value for test cases, leave empty for no time limit', }, 'show_compiler_msg': { 'help_text': u'Show error messages or warnings from the compiler run', }, 'submission_filename': { 'help_text': u'Default filename for submission', }, 'submission_template': { 'help_text': u'Template for submission source body', 'css_class': 'span7', 'cols': 80, 'rows': 6, }, 'submission_scaffold_show': { 'help_text': u'Whether to show head and foot scaffold to student', }, 'submission_scaffold_head': { 'help_text': u'Enforced head for submission source', 'css_class': 'span7', 'cols': 80, 'rows': 6, }, 'submission_scaffold_foot': { 'help_text': u'Enforced foot for submission source', 'css_class': 'span7', 'cols': 80, 'rows': 6, }, }, '__require_fields__': ['assignment_id', 'sheet'], } __setters__ = { 'test': ('null', lambda assignment: run_tests(assignment.submissions)), } def _actions(self, obj): actions = super(AssignmentsCrudController, self)._actions(obj) actions.insert( 1, u''' <a href="%d/test" class="btn btn-mini btn-inverse" title="Re-run all tests for this assignment" onclick="show_processing_modal('Testing %d Submission(s) in %d Test(s)...'); return true;"> <i class="icon-repeat icon-white"></i> </a>''' % (obj.id, len( obj.submissions), len(obj.submissions) * len(obj.tests))) return actions
class SheetsCrudController(FilterCrudRestController): '''CrudController for Sheets''' model = Sheet __table_options__ = { '__omit_fields__': [ 'id', 'description', 'event_id', 'event', 'teacher', '_teacher', 'teacher_id', '_url', '_start_time', '_end_time', ], '__field_order__': [ 'sheet_id', 'name', 'public', 'start_time', 'end_time', 'assignments', 'submissions', ], '__search_fields__': ['id', 'sheet_id', 'name', ('assignments', 'assignment_id')], '__xml_fields__': ['sheet_id', 'name', 'assignments', 'submissions'], '__headers__': { 'sheet_id': '' }, 'start_time': lambda filler, obj: h.strftime(obj.start_time, False), 'end_time': lambda filler, obj: h.strftime(obj.end_time, False), 'sheet_id': lambda filler, obj: literal(u'<span title="sheet_id=%d">%d</span>' % (obj.sheet_id, obj.sheet_id)), 'name': lambda filler, obj: literal(u'<span title="sheet_id=%d">%s</span>' % (obj.sheet_id, obj.name)), 'assignments': lambda filler, obj: ', '.join( link_to(ass.name, '../assignments/%d/edit' % ass.id) for ass in obj.assignments), 'submissions': _submissions, '__base_widget_args__': { 'sortList': [[1, 0]] }, } __form_options__ = { '__omit_fields__': [ 'id', '_url', 'assignments', 'teacher', '_teacher', ], '__hide_fields__': ['event'], '__field_order__': [ 'id', 'sheet_id', 'name', 'description', 'public', '_start_time', '_end_time', ], '__field_widget_args__': { '_start_time': { 'help_text': u'Leave empty to use value from event', }, '_end_time': { 'help_text': u'Leave empty to use value from event', }, 'sheet_id': { 'label': u'Sheet Id', 'help_text': u'This id will be part of the url and has to be unique for the parent event', }, 'public': { 'help_text': u'Make sheet visible for students', }, }, '__require_fields__': ['sheet_id'], } __setters__ = { 'test': ('null', lambda sheet: run_tests( (submission for assignment in sheet.assignments for submission in assignment.submissions))), } def _actions(self, obj): actions = super(SheetsCrudController, self)._actions(obj) actions.insert( 1, u''' <a href="%d/test" class="btn btn-mini btn-inverse" title="Re-run all tests for this assignment" onclick="show_processing_modal('Testing %d Submission(s) in %d Test(s)...'); return true;"> <i class="icon-repeat icon-white"></i> </a>''' % (obj.id, sum((len(assignment.submissions) for assignment in obj.assignments)), sum((len(assignment.submissions) * len(assignment.tests) for assignment in obj.assignments)))) return actions
def modified(self, obj): return h.strftime(obj.modified, False)
def created(self, obj): return h.strftime(obj.created, False)
def judgement(self, obj): if obj.judgement: return u'<a href="%s/judge" class="label label-info" title="%s">Yes</a>' % (obj.url, h.strftime(obj.judgement.date, False)) else: return u'<a href="%s/judge" class="label">No</a>' % (obj.url)
def result(self, obj): if obj.result is not None: if obj.result: return u'<span class="label label-success" title="%s">Success</a>' % (h.strftime(obj.testrun_date, False)) else: return u'<span class="label label-important" title="%s">Failed</a>' % (h.strftime(obj.testrun_date, False)) else: return u'<span class="label">None</a>'
class EventsCrudController(FilterCrudRestController): '''CrudController for Events TODO: Use tw2.dynforms to only display password field when enroll is not None ''' model = Event __table_options__ = { '__omit_fields__': [ 'id', 'description', 'password', '_teacher', '_teacher_id', 'enabled', '_assignments', 'lessons', 'sheets', 'news', ] + ([] if _lti else ['lti']), '__field_order__': [ 'type', '_url', 'name', 'public', 'start_time', 'end_time', 'teachers', 'tutors', '_members', 'enroll', ] + (['lti'] if _lti else []), '__search_fields__': ['id', '_url', 'name'], # '__headers__': {'_url': 'Url'}, '__xml_fields__': ['teachers', 'tutors', '_members', 'lti'], 'start_time': lambda filler, obj: h.strftime(obj.start_time, False), 'end_time': lambda filler, obj: h.strftime(obj.end_time, False), 'teachers': lambda filler, obj: ', '.join( link_to(teacher.display_name, '../tutors/%d/edit' % teacher.id) for teacher in set(obj.teachers)), 'tutors': lambda filler, obj: ', '.join( link_to(tutor.display_name, '../tutors/%d/edit' % tutor.id) for tutor in obj.tutors), '_members': lambda filler, obj: ', '.join( link_to(student.display_name, '../students/%d/edit' % student.id) for student in obj._members), 'lti': lambda filler, obj: u'%s:%s' % (obj.lti.oauth_key, obj.lti.oauth_secret) if obj.lti else u'', '__base_widget_args__': { 'sortList': [[6, 1], [5, 1]] }, } __form_options__ = { '__omit_fields__': [ 'id', 'type', '_assignments', 'sheets', 'news', 'lessons', '_teacher', '_teacher_id', 'enabled', 'lti', ], '__field_order__': [ 'id', '_url', 'name', 'description', 'public', 'enroll', 'password', 'start_time', 'end_time', 'teachers', '_members', ], '__field_widget_types__': { 'type': twjc.ChosenSingleSelectField, 'enroll': twb.RadioButtonTable, 'password': MediumTextField, }, '__field_widget_args__': { '_url': { 'help_text': u'Will be part of the url, has to be unique and url-safe', }, 'public': { 'help_text': u'Make event visible for students', }, 'enroll': { 'name': 'enroll', 'id': 'enroll', 'cols': 3, 'options': [ ('', 'None'), ('event', 'Event'), ('lesson', 'Lesson'), #('lesson_team', 'Lesson/Team'), ('team', 'Team'), ('team_new', 'Team (Allow New Teams)'), ], 'value': 'None', 'help_text': u'Enrolling granularity', }, 'password': { 'help_text': u'Password for enrolling. If empty and enroll is not None, all students can enroll.', }, '_members': { 'help_text': u'These are only DIRECT members of this event. ' 'You might want to add users to lessons and/or teams instead.', }, }, '__field_validator_types__': { '_url': PlainText }, '__field_validators__': { 'enroll': twc.validation.OneOfValidator( values=['event', 'lesson', 'lesson_team', 'team', 'team_new']), }, '__possible_field_names__': ['user_name', '_name', 'name', 'title'], '__require_fields__': ['type', '_url'], }