private Course UnsafeLoad(DirectoryInfo dir) { var courseId = dir.Name; var loadFromDirectory = dir; var courseXmls = dir.GetFiles("course.xml", SearchOption.AllDirectories).ToList(); if (courseXmls.Count == 1) { loadFromDirectory = courseXmls[0].Directory; } else { loadFromDirectory = loadFromDirectory.HasSubdirectory("Slides") ? loadFromDirectory.GetSubdirectory("Slides") : loadFromDirectory; } CourseSettings settings; try { settings = CourseSettings.Load(loadFromDirectory); } catch (Exception e) { throw new CourseLoadingException($"Не удалось прочитать настройки курса из файла course.xml. {e.Message}", e.InnerException); } if (string.IsNullOrEmpty(settings.Title)) { try { settings.Title = GetCourseTitleFromFile(loadFromDirectory); } catch (Exception e) { throw new CourseLoadingException( "Не удалось прочитать настройки курса. Скорее всего, отсутствует или неправильно заполнен файл course.xml." ); } } var context = new CourseLoadingContext(courseId, settings, dir, loadFromDirectory.GetFile("course.xml")); var units = LoadUnits(context).ToList(); var slides = units.SelectMany(u => u.Slides).ToList(); CheckDuplicateSlideIds(slides); AddDefaultScoringGroupIfNeeded(units, slides, settings); CalculateScoringGroupScores(units, settings); return(new Course(courseId, units, settings, dir)); }
public InstructorNote(string markdown, Unit unit, FileInfo file, CourseLoadingContext courseLoadingContext, int slideIndex) { Markdown = markdown; Unit = unit; File = file; Slide = new Slide(new MarkdownBlock(Markdown) { Hide = true }) { Id = Unit.Id, Title = "Заметки преподавателю" }; var slideLoadingContext = new SlideLoadingContext(courseLoadingContext, unit, file, slideIndex); Slide.BuildUp(slideLoadingContext); Slide.Validate(slideLoadingContext); }
private IEnumerable <Unit> LoadUnits(CourseLoadingContext context) { var unitFiles = context.CourseSettings .UnitPaths .SelectMany(path => context.CourseXml.Directory.GetFilesByMask(path).OrderBy(f => f.FullName, StringComparer.InvariantCultureIgnoreCase)) .Distinct() /* Don't load unit from course file! Even accidentally */ .Where(f => f != context.CourseXml); var unitIds = new HashSet <Guid>(); var unitUrls = new HashSet <string>(); var slideIndex = 0; foreach (var unitFile in unitFiles) { var unit = unitLoader.Load(unitFile, context, slideIndex); if (unitIds.Contains(unit.Id)) { throw new CourseLoadingException($"Ошибка в курсе \"{context.CourseSettings.Title}\" при загрузке модуля \"{unit.Title}\" из {unitFile.FullName}. " + $"Повторяющийся идентификатор модуля: {unit.Id}. Идентификаторы модулей должны быть уникальными. " + $"К этому времени загружены модули {string.Join(", ", unitIds)}"); } unitIds.Add(unit.Id); if (unitUrls.Contains(unit.Url)) { throw new CourseLoadingException( $"Ошибка в курсе \"{context.CourseSettings.Title}\" при загрузке модуля \"{unit.Title}\" из {unitFile.FullName}. " + $"Повторяющийся url-адрес модуля: {unit.Url}. Url-адреса модулей должны быть уникальными" ); } unitUrls.Add(unit.Url); if (unit.Slides.OfType <FlashcardSlide>().Count() > 1) { throw new CourseLoadingException($"Ошибка в курсе \"{context.CourseSettings.Title}\" при загрузке модуля \"{unit.Title}\" из {unitFile.FullName}. " + $"Обнаружено более одного слайда с флеш-картами. Слайд с флеш-картами должен быть только один"); } yield return(unit); slideIndex += unit.Slides.Count; } }
public static InstructorNote Load(CourseLoadingContext context, FileInfo file, Unit unit) { return(new InstructorNote(file.ContentAsUtf8(), unit, file, context)); }