def get_yaml_from_repo_no_events_file_side_effect(repo, full_name, commit_sha, cached=True): if full_name in [events_file, my_events_file]: raise ObjectDoesNotExist else: return get_yaml_from_repo(repo, full_name, commit_sha, cached)
def validate_course_content(repo, course_file, events_file, validate_sha, course=None): course_desc = get_yaml_from_repo_safely(repo, course_file, commit_sha=validate_sha) vctx = ValidationContext(repo=repo, commit_sha=validate_sha, course=course) validate_course_desc_struct(vctx, course_file, course_desc) try: from course.content import get_yaml_from_repo events_desc = get_yaml_from_repo(repo, events_file, commit_sha=validate_sha, cached=False) except ObjectDoesNotExist: # That's OK--no calendar info. pass else: validate_calendar_desc_struct(vctx, events_file, events_desc) check_attributes_yml(vctx, repo, "", get_repo_blob(repo, "", validate_sha)) try: flows_tree = get_repo_blob(repo, "flows", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: for entry in flows_tree.items(): if not entry.path.endswith(".yml"): continue from course.constants import FLOW_ID_REGEX flow_id = entry.path[:-4] match = re.match("^" + FLOW_ID_REGEX + "$", flow_id) if match is None: raise ValidationError( string_concat( "%s: ", _("invalid flow name. " "Flow names may only contain (roman) " "letters, numbers, " "dashes and underscores.")) % entry.path) location = "flows/%s" % entry.path flow_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_flow_desc(vctx, location, flow_desc) return vctx.warnings
def validate_course_content(repo, course_file, events_file, validate_sha, course=None): course_desc = get_yaml_from_repo_safely(repo, course_file, commit_sha=validate_sha) vctx = ValidationContext( repo=repo, commit_sha=validate_sha, course=course) validate_course_desc_struct(vctx, course_file, course_desc) try: from course.content import get_yaml_from_repo events_desc = get_yaml_from_repo(repo, events_file, commit_sha=validate_sha, cached=False) except ObjectDoesNotExist: # That's OK--no calendar info. pass else: validate_calendar_desc_struct(vctx, events_file, events_desc) check_attributes_yml( vctx, repo, "", get_repo_blob(repo, "", validate_sha)) try: flows_tree = get_repo_blob(repo, "flows", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: for entry in flows_tree.items(): if not entry.path.endswith(".yml"): continue from course.constants import FLOW_ID_REGEX flow_id = entry.path[:-4] match = re.match("^"+FLOW_ID_REGEX+"$", flow_id) if match is None: raise ValidationError( string_concat("%s: ", _("invalid flow name. " "Flow names may only contain (roman) " "letters, numbers, " "dashes and underscores.")) % entry.path) location = "flows/%s" % entry.path flow_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_flow_desc(vctx, location, flow_desc) return vctx.warnings
def get_yaml_from_repo_safely(repo, full_name, commit_sha): from course.content import get_yaml_from_repo try: return get_yaml_from_repo( repo=repo, full_name=full_name, commit_sha=commit_sha) except: from traceback import print_exc print_exc() tp, e, _ = sys.exc_info() raise ValidationError("%s: %s: %s" % ( full_name, tp.__name__, str(e)))
def get_yaml_from_repo_side_effect(repo, full_name, commit_sha, cached=True): if full_name == events_file: return dict_to_struct( {"event_kinds": dict_to_struct({ "lecture": dict_to_struct({ "title": "Lecture {nr}", "color": "blue" })}), "events": dict_to_struct({ "lecture 1": dict_to_struct({ "title": "l1"}) })}) else: return get_yaml_from_repo(repo, full_name, commit_sha, cached)
def get_yaml_from_repo_safely(repo, full_name, commit_sha): from course.content import get_yaml_from_repo try: return get_yaml_from_repo(repo=repo, full_name=full_name, commit_sha=commit_sha, cached=False) except: from traceback import print_exc print_exc() tp, e, _ = sys.exc_info() raise ValidationError("%s: %s: %s" % (full_name, tp.__name__, unicode(e)))
def get_yaml_from_repo_safely(repo, full_name, commit_sha): from course.content import get_yaml_from_repo try: return get_yaml_from_repo(repo=repo, full_name=full_name, commit_sha=commit_sha, cached=False) except: from traceback import print_exc print_exc() tp, e, _ = sys.exc_info() raise ValidationError( "%(fullname)s: %(err_type)s: %(err_str)s" % {"fullname": full_name, "err_type": tp.__name__, "err_str": six.text_type(e)} )
def get_yaml_from_repo_side_effect(repo, full_name, commit_sha, cached=True): if full_name == events_file: return dict_to_struct({ "event_kinds": dict_to_struct({ "lecture": dict_to_struct({ "title": "Lecture {nr}", "color": "blue" }) }), "events": dict_to_struct({"lecture 1": dict_to_struct({"title": "l1"})}) }) else: return get_yaml_from_repo(repo, full_name, commit_sha, cached)
def get_yaml_from_repo_safely(repo, full_name, commit_sha): from course.content import get_yaml_from_repo try: return get_yaml_from_repo( repo=repo, full_name=full_name, commit_sha=commit_sha, cached=False) except: from traceback import print_exc print_exc() tp, e, _ = sys.exc_info() raise ValidationError( "%(fullname)s: %(err_type)s: %(err_str)s" % { 'fullname': full_name, "err_type": tp.__name__, "err_str": six.text_type(e)})
def validate_course_content(repo, course_file, events_file, validate_sha, datespec_callback=None): course_desc = get_yaml_from_repo_safely(repo, course_file, commit_sha=validate_sha) ctx = ValidationContext(repo=repo, commit_sha=validate_sha, datespec_callback=datespec_callback) validate_course_desc_struct(ctx, course_file, course_desc) try: from course.content import get_yaml_from_repo events_desc = get_yaml_from_repo(repo, events_file, commit_sha=validate_sha, cached=False) except ObjectDoesNotExist: # That's OK--no calendar info. pass else: validate_calendar_desc_struct(ctx, events_file, events_desc) try: flows_tree = get_repo_blob(repo, "flows", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: for entry in flows_tree.items(): if not entry.path.endswith(".yml"): continue location = "flows/%s" % entry.path flow_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_flow_desc(ctx, location, flow_desc) return ctx.warnings
def validate_course_content(repo, course_file, events_file, validate_sha, datespec_callback=None): course_desc = get_yaml_from_repo_safely(repo, course_file, commit_sha=validate_sha) ctx = ValidationContext( repo=repo, commit_sha=validate_sha, datespec_callback=datespec_callback) validate_course_desc_struct(ctx, course_file, course_desc) try: from course.content import get_yaml_from_repo events_desc = get_yaml_from_repo(repo, events_file, commit_sha=validate_sha, cached=False) except ObjectDoesNotExist: # That's OK--no calendar info. pass else: validate_calendar_desc_struct(ctx, events_file, events_desc) try: flows_tree = get_repo_blob(repo, "flows", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: for entry in flows_tree.items(): if not entry.path.endswith(".yml"): continue location = "flows/%s" % entry.path flow_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_flow_desc(ctx, location, flow_desc) return ctx.warnings
def validate_course_content(repo, course_file, events_file, validate_sha, course=None): vctx = ValidationContext( repo=repo, commit_sha=validate_sha, course=course) course_desc = get_yaml_from_repo_safely(repo, course_file, commit_sha=validate_sha) validate_staticpage_desc(vctx, course_file, course_desc) try: from course.content import get_yaml_from_repo events_desc = get_yaml_from_repo(repo, events_file, commit_sha=validate_sha, cached=False) except ObjectDoesNotExist: if events_file != "events.yml": vctx.add_warning( _("Events file"), _("Your course repository does not have an events " "file named '%s'.") % events_file) else: # That's OK--no calendar info. pass else: validate_calendar_desc_struct(vctx, events_file, events_desc) if vctx.course is not None: from course.models import ( ParticipationPermission, ParticipationRolePermission) access_kinds = frozenset( ParticipationPermission.objects .filter( participation__course=vctx.course, permission=pperm.access_files_for, ) .values_list("argument", flat=True)) | frozenset( ParticipationRolePermission.objects .filter( role__course=vctx.course, permission=pperm.access_files_for, ) .values_list("argument", flat=True)) else: access_kinds = ["public", "in_exam", "student", "ta", "unenrolled", "instructor"] check_attributes_yml( vctx, repo, "", get_repo_blob(repo, "", validate_sha), access_kinds) try: flows_tree = get_repo_blob(repo, "media", validate_sha) except ObjectDoesNotExist: # That's great--no media directory. pass else: vctx.add_warning( 'media/', _( "Your course repository has a 'media/' directory. " "Linking to media files using 'media:' is discouraged. " "Use the 'repo:' and 'repocur:' linkng schemes instead.")) # {{{ flows try: flows_tree = get_repo_blob(repo, "flows", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: used_grade_identifiers = set() for entry in flows_tree.items(): entry_path = entry.path.decode("utf-8") if not entry_path.endswith(".yml"): continue from course.constants import FLOW_ID_REGEX flow_id = entry_path[:-4] match = re.match("^"+FLOW_ID_REGEX+"$", flow_id) if match is None: raise ValidationError( string_concat("%s: ", _("invalid flow name. " "Flow names may only contain (roman) " "letters, numbers, " "dashes and underscores.")) % entry_path) location = "flows/%s" % entry_path flow_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_flow_desc(vctx, location, flow_desc) # {{{ check grade_identifier flow_grade_identifier = None if hasattr(flow_desc, "rules"): flow_grade_identifier = getattr( flow_desc.rules, "grade_identifier", None) if ( flow_grade_identifier is not None and set([flow_grade_identifier]) & used_grade_identifiers): raise ValidationError( string_concat("%s: ", _("flow uses the same grade_identifier " "as another flow")) % location) used_grade_identifiers.add(flow_grade_identifier) if (course is not None and flow_grade_identifier is not None): check_grade_identifier_link( vctx, location, course, flow_id, flow_grade_identifier) # }}} if course is not None: check_for_page_type_changes( vctx, location, course, flow_id, flow_desc) # }}} # {{{ static pages try: pages_tree = get_repo_blob(repo, "staticpages", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: for entry in pages_tree.items(): entry_path = entry.path.decode("utf-8") if not entry_path.endswith(".yml"): continue from course.constants import STATICPAGE_PATH_REGEX page_name = entry_path[:-4] match = re.match("^"+STATICPAGE_PATH_REGEX+"$", page_name) if match is None: raise ValidationError( string_concat("%s: ", _( "invalid page name. " "Page names may only contain " "alphanumeric characters (any language) " "and hyphens." )) % entry_path) location = "staticpages/%s" % entry_path page_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_staticpage_desc(vctx, location, page_desc) # }}} return vctx.warnings
def get_yaml_from_repo_no_events_file_side_effect( repo, full_name, commit_sha, cached=True): if full_name in [events_file, my_events_file]: raise ObjectDoesNotExist else: return get_yaml_from_repo(repo, full_name, commit_sha, cached)
def validate_course_content(repo, course_file, events_file, validate_sha, course=None): course_desc = get_yaml_from_repo_safely(repo, course_file, commit_sha=validate_sha) vctx = ValidationContext(repo=repo, commit_sha=validate_sha, course=course) validate_course_desc_struct(vctx, course_file, course_desc) try: from course.content import get_yaml_from_repo events_desc = get_yaml_from_repo(repo, events_file, commit_sha=validate_sha, cached=False) except ObjectDoesNotExist: if events_file != "events.yml": vctx.add_warning( _("Events file"), _("Your course repository does not have an events " "file named '%s'.") % events_file) else: # That's OK--no calendar info. pass else: validate_calendar_desc_struct(vctx, events_file, events_desc) check_attributes_yml(vctx, repo, "", get_repo_blob(repo, "", validate_sha)) try: flows_tree = get_repo_blob(repo, "media", validate_sha) except ObjectDoesNotExist: # That's great--no media directory. pass else: vctx.add_warning( 'media/', _("Your course repository has a 'media/' directory. " "Linking to media files using 'media:' is discouraged. " "Use the 'repo:' and 'repocur:' linkng schemes instead.")) try: flows_tree = get_repo_blob(repo, "flows", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: used_grade_identifiers = set() for entry in flows_tree.items(): entry_path = entry.path.decode("utf-8") if not entry_path.endswith(".yml"): continue from course.constants import FLOW_ID_REGEX flow_id = entry_path[:-4] match = re.match("^" + FLOW_ID_REGEX + "$", flow_id) if match is None: raise ValidationError( string_concat( "%s: ", _("invalid flow name. " "Flow names may only contain (roman) " "letters, numbers, " "dashes and underscores.")) % entry_path) location = "flows/%s" % entry_path flow_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_flow_desc(vctx, location, flow_desc) # {{{ check grade_identifier flow_grade_identifier = None if hasattr(flow_desc, "rules"): flow_grade_identifier = getattr(flow_desc.rules, "grade_identifier", None) if (flow_grade_identifier is not None and set([flow_grade_identifier]) & used_grade_identifiers): raise ValidationError( string_concat( "%s: ", _("flow uses the same grade_identifier " "as another flow")) % location) used_grade_identifiers.add(flow_grade_identifier) if (course is not None and flow_grade_identifier is not None): check_grade_identifier_link(vctx, location, course, flow_id, flow_grade_identifier) # }}} if course is not None: check_for_page_type_changes(vctx, location, course, flow_id, flow_desc) return vctx.warnings
def validate_course_content(repo, course_file, events_file, validate_sha, course=None): course_desc = get_yaml_from_repo_safely(repo, course_file, commit_sha=validate_sha) vctx = ValidationContext(repo=repo, commit_sha=validate_sha, course=course) validate_course_desc_struct(vctx, course_file, course_desc) try: from course.content import get_yaml_from_repo events_desc = get_yaml_from_repo(repo, events_file, commit_sha=validate_sha, cached=False) except ObjectDoesNotExist: if events_file != "events.yml": vctx.add_warning( _("Events file"), _("Your course repository does not have an events " "file named '%s'.") % events_file ) else: # That's OK--no calendar info. pass else: validate_calendar_desc_struct(vctx, events_file, events_desc) check_attributes_yml(vctx, repo, "", get_repo_blob(repo, "", validate_sha)) try: flows_tree = get_repo_blob(repo, "media", validate_sha) except ObjectDoesNotExist: # That's great--no media directory. pass else: vctx.add_warning( "media/", _( "Your course repository has a 'media/' directory. " "Linking to media files using 'media:' is discouraged. " "Use the 'repo:' and 'repocur:' linkng schemes instead." ), ) try: flows_tree = get_repo_blob(repo, "flows", validate_sha) except ObjectDoesNotExist: # That's OK--no flows yet. pass else: used_grade_identifiers = set() for entry in flows_tree.items(): entry_path = entry.path.decode("utf-8") if not entry_path.endswith(".yml"): continue from course.constants import FLOW_ID_REGEX flow_id = entry_path[:-4] match = re.match("^" + FLOW_ID_REGEX + "$", flow_id) if match is None: raise ValidationError( string_concat( "%s: ", _( "invalid flow name. " "Flow names may only contain (roman) " "letters, numbers, " "dashes and underscores." ), ) % entry_path ) location = "flows/%s" % entry_path flow_desc = get_yaml_from_repo_safely(repo, location, commit_sha=validate_sha) validate_flow_desc(vctx, location, flow_desc) # {{{ check grade_identifier flow_grade_identifier = None if hasattr(flow_desc, "rules"): flow_grade_identifier = getattr(flow_desc.rules, "grade_identifier", None) if flow_grade_identifier is not None and set([flow_grade_identifier]) & used_grade_identifiers: raise ValidationError( string_concat("%s: ", _("flow uses the same grade_identifier " "as another flow")) % location ) used_grade_identifiers.add(flow_grade_identifier) if course is not None and flow_grade_identifier is not None: check_grade_identifier_link(vctx, location, course, flow_id, flow_grade_identifier) # }}} if course is not None: check_for_page_type_changes(vctx, location, course, flow_id, flow_desc) return vctx.warnings