public ActionResult UserUnitStatistics(string courseId, Guid unitId, string userId) { var course = courseManager.GetCourse(courseId); var user = usersRepo.FindUserById(userId); if (user == null) { return(HttpNotFound()); } var unit = course.GetUnitById(unitId); var slides = unit.Slides; var exercises = slides.OfType <ExerciseSlide>(); var acceptedSubmissions = userSolutionsRepo .GetAllAcceptedSubmissionsByUser(courseId, exercises.Select(s => s.Id), userId) .OrderByDescending(s => s.Timestamp) .DistinctBy(u => u.SlideId); var userScores = visitsRepo.GetScoresForSlides(courseId, userId, slides.Select(s => s.Id)); var model = new UserUnitStatisticsPageModel { Course = course, Unit = unit, User = user, Slides = slides.ToDictionary(s => s.Id), Submissions = acceptedSubmissions.ToList(), Scores = userScores, }; return(View(model)); }
public ActionResult UserUnitStatistics(string courseId, Guid unitId, string userId) { var course = courseManager.GetCourse(courseId); var user = usersRepo.FindUserById(userId); if (user == null) { return(HttpNotFound()); } var unit = course.FindUnitById(unitId); if (unit == null) { return(HttpNotFound()); } var slides = unit.Slides; var exercises = slides.OfType <ExerciseSlide>().ToList(); var acceptedSubmissions = userSolutionsRepo .GetAllAcceptedSubmissionsByUser(courseId, exercises.Select(s => s.Id), userId) .OrderByDescending(s => s.Timestamp) .DistinctBy(u => u.SlideId) .ToList(); var reviewedSubmissions = userSolutionsRepo .GetAllAcceptedSubmissionsByUser(courseId, exercises.Select(s => s.Id), userId) .Where(s => s.ManualCheckings.Any(c => c.IsChecked)) .OrderByDescending(s => s.Timestamp) .DistinctBy(u => u.SlideId) .ToList(); var userScores = visitsRepo.GetScoresForSlides(courseId, userId, slides.Select(s => s.Id)); var unitIndex = course.Units.FindIndex(u => u.Id == unitId); var previousUnit = unitIndex == 0 ? null : course.Units[unitIndex - 1]; var nextUnit = unitIndex == course.Units.Count - 1 ? null : course.Units[unitIndex + 1]; var model = new UserUnitStatisticsPageModel { Course = course, Unit = unit, User = user, Slides = slides.ToDictionary(s => s.Id), Submissions = acceptedSubmissions, ReviewedSubmissions = reviewedSubmissions, Scores = userScores, PreviousUnit = previousUnit, NextUnit = nextUnit, }; return(View(model)); }
private TocModel CreateTocModel(Course course, Guid?currentSlideId, string userId) { var visibleUnits = unitsRepo.GetVisibleUnits(course, User); var visited = visitsRepo.GetIdOfVisitedSlides(course.Id, userId); var scoresForSlides = visitsRepo.GetScoresForSlides(course.Id, userId); var solvedSlidesIds = ControllerUtils.GetSolvedSlides(solutionsRepo, userQuizzesRepo, course, userId); var slidesWithUsersManualChecking = visitsRepo.GetSlidesWithUsersManualChecking(course.Id, userId).ToImmutableHashSet(); var enabledManualCheckingForUser = groupsRepo.IsManualCheckingEnabledForUser(course, userId); Func <Slide, int> getSlideMaxScoreFunc = s => ControllerUtils.GetMaxScoreForUsersSlide(s, solvedSlidesIds.Contains(s.Id), slidesWithUsersManualChecking.Contains(s.Id), enabledManualCheckingForUser); var userGroupsIds = groupsRepo.GetUserGroupsIds(course.Id, userId); var enabledScoringGroupsIds = groupsRepo.GetEnabledAdditionalScoringGroups(course.Id) .Where(e => userGroupsIds.Contains(e.GroupId)) .Select(e => e.ScoringGroupId) .ToList(); var additionalScores = additionalScoresRepo.GetAdditionalScoresForUser(course.Id, userId); var builder = new TocModelBuilder( s => Url.RouteUrl("Course.SlideById", new { courseId = course.Id, slideId = s.Url }), s => scoresForSlides.ContainsKey(s.Id) ? scoresForSlides[s.Id] : 0, getSlideMaxScoreFunc, (u, g) => additionalScores.GetOrDefault(Tuple.Create(u.Id, g.Id), 0), course, currentSlideId) { GetUnitInstructionNotesUrl = unit => Url.Action("InstructorNote", "Course", new { courseId = course.Id, unitId = unit.Id }), GetUnitStatisticsUrl = unit => Url.Action("UnitStatistics", "Analytics", new { courseId = course.Id, unitId = unit.Id }), IsInstructor = User.HasAccessFor(course.Id, CourseRole.Instructor), IsSolved = s => solvedSlidesIds.Contains(s.Id), IsVisited = s => visited.Contains(s.Id), IsUnitVisible = visibleUnits.Contains, IsSlideHidden = s => s is QuizSlide && ((QuizSlide)s).ManualChecking && !enabledManualCheckingForUser && !solvedSlidesIds.Contains(s.Id), EnabledScoringGroupsIds = enabledScoringGroupsIds, }; var userGroups = groupsRepo.GetUserGroups(course.Id, User.Identity.GetUserId()); var tocGroupsForStatistics = userGroups.Select(g => new TocGroupForStatistics { GroupName = g.Name, StatisticsUrl = Url.Action("CourseStatistics", "Analytics", new { courseId = course.Id, group = g.Id }) }); var toc = builder.CreateTocModel(tocGroupsForStatistics.ToList()); toc.NextUnitTime = unitsRepo.GetNextUnitPublishTime(course.Id); return(toc); }
private string SubstituteBuiltinParameters(string content, Certificate certificate, Course course, string certificateUrl) { content = ReplaceBasicBuiltinParameters(content, certificate, course, certificateUrl); /* Replace %score% for total course score */ var userScore = visitsRepo.GetScoresForSlides(course.Id, certificate.UserId).Sum(p => p.Value); content = SubstituteOneParameter(content, "score", userScore.ToString()); /* Replace %codereviews.*% */ content = ReplaceCodeReviewsBuiltinParameters(content, certificate, course); /* Replace %quizzes.*% */ content = ReplaceQuizzesBuiltinParameters(content, certificate, course); var acceptedSolutionsCount = userSolutionsRepo.GetAllAcceptedSubmissionsByUser(course.Id, course.Slides.Select(s => s.Id), certificate.UserId).Select(s => s.SlideId).Distinct().Count(); content = SubstituteOneParameter(content, "exercises.accepted", acceptedSolutionsCount.ToString()); return(content); }
private TocModel CreateTocModel(Course course, int slideIndex, string userId) { var visibleUnits = unitsRepo.GetVisibleUnits(course.Id, User); var solved = GetSolvedSlides(course, userId); var visited = visitsRepo.GetIdOfVisitedSlides(course.Id, userId); var scoresForSlides = visitsRepo.GetScoresForSlides(course.Id, userId); var builder = new TocModelBuilder( s => Url.Action("Slide", "Course", new { courseId = course.Id, slideIndex = s.Index }), s => scoresForSlides.ContainsKey(s.Id) ? scoresForSlides[s.Id] : 0, course, slideIndex); builder.GetUnitInstructionNotesUrl = unitName => Url.Action("InstructorNote", "Course", new { courseId = course.Id, unitName }); builder.GetUnitStatisticsUrl = unitName => Url.Action("UnitStatistics", "Analytics", new { courseId = course.Id, unitName }); builder.IsInstructor = User.HasAccessFor(course.Id, CourseRole.Instructor); builder.IsSolved = s => solved.Contains(s.Id); builder.IsVisited = s => visited.Contains(s.Id); builder.IsUnitVisible = visibleUnits.Contains; var toc = builder.CreateTocModel(); toc.NextUnitTime = unitsRepo.GetNextUnitPublishTime(course.Id); return(toc); }