Example #1
0
        private UserModel GetUserModel(UserRolesInfo userRoles, Dictionary <string, Dictionary <CourseRole, List <string> > > coursesForUsers,
                                       List <string> coursesIds, HashSet <string> tempCoursesIds)
        {
            var user = new UserModel(userRoles)
            {
                CourseRoles = new Dictionary <string, ICoursesRolesListModel>
                {
                    {
                        LmsRoles.SysAdmin.ToString(),
                        new SingleCourseRolesModel
                        {
                            HasAccess = userRoles.Roles.Contains(LmsRoles.SysAdmin.ToString()),
                            ToggleUrl = Url.Content($"~/Account/{nameof(ToggleSystemRole)}?userId={userRoles.UserId}&role={LmsRoles.SysAdmin}"),                             // Url.Action is slow: https://www.jitbit.com/alexblog/263-fastest-way-to-generate-urls-in-an-aspnet-mvc-app/
                        }
                    }
                }
            };

            if (!coursesForUsers.TryGetValue(userRoles.UserId, out var coursesForUser))
            {
                coursesForUser = new Dictionary <CourseRole, List <string> >();
            }

            foreach (var role in Enum.GetValues(typeof(CourseRole)).Cast <CourseRole>().Where(roles => roles != CourseRole.Student))
            {
                user.CourseRoles[role.ToString()] = new ManyCourseRolesModel
                {
                    CourseRoles = coursesIds
                                  .Select(s => new CourseRoleModel
                    {
                        Role         = role,
                        CourseId     = s,
                        CourseTitle  = courseManager.GetCourse(s).Title,
                        HasAccess    = coursesForUser.ContainsKey(role) && coursesForUser[role].Contains(s.ToLower()),
                        ToggleUrl    = Url.Content($"~/Account/{nameof(ToggleRole)}?courseId={s}&userId={user.UserId}&role={role}"),
                        UserName     = user.UserVisibleName,
                        IsTempCourse = tempCoursesIds.Contains(s)
                    })
                                  .OrderBy(s => s.CourseTitle, StringComparer.InvariantCultureIgnoreCase)
                                  .ToList()
                };
            }

            var systemAccesses = systemAccessesRepo.GetSystemAccesses(user.UserId).Select(a => a.AccessType);

            user.SystemAccesses = Enum.GetValues(typeof(SystemAccessType))
                                  .Cast <SystemAccessType>()
                                  .ToDictionary(
                a => a,
                a => new SystemAccessModel
            {
                HasAccess = systemAccesses.Contains(a),
                ToggleUrl = Url.Content($"~/Account/{nameof(ToggleSystemAccess)}?userId={user.UserId}&accessType={a}"),
                UserName  = user.UserVisibleName,
            }
                );

            return(user);
        }
Example #2
0
        private async Task <AutomaticExerciseChecking> UpdateAutomaticExerciseChecking(AutomaticExerciseChecking checking, RunningResults result)
        {
            var compilationErrorHash = (await textsRepo.AddText(result.CompilationOutput)).Hash;
            var output     = result.GetOutput().NormalizeEoln();
            var outputHash = (await textsRepo.AddText(output)).Hash;

            var isWebRunner   = checking.CourseId == "web" && checking.SlideId == Guid.Empty;
            var exerciseSlide = isWebRunner ? null : (ExerciseSlide)courseManager.GetCourse(checking.CourseId).GetSlideById(checking.SlideId, true);

            var isRightAnswer = IsRightAnswer(result, output, exerciseSlide?.Exercise);

            var elapsed = DateTime.Now - checking.Timestamp;

            elapsed = elapsed < TimeSpan.FromDays(1) ? elapsed : new TimeSpan(0, 23, 59, 59);
            var newChecking = new AutomaticExerciseChecking
            {
                Id                   = checking.Id,
                CourseId             = checking.CourseId,
                SlideId              = checking.SlideId,
                UserId               = checking.UserId,
                Timestamp            = checking.Timestamp,
                CompilationErrorHash = compilationErrorHash,
                IsCompilationError   = result.Verdict == Verdict.CompilationError,
                OutputHash           = outputHash,
                ExecutionServiceName = checking.ExecutionServiceName,
                Status               = AutomaticExerciseCheckingStatus.Done,
                DisplayName          = checking.DisplayName,
                Elapsed              = elapsed,
                IsRightAnswer        = isRightAnswer,
                CheckingAgentName    = checking.CheckingAgentName,
                Points               = result.Points
            };

            return(newChecking);
        }
Example #3
0
        private async Task AddManualCheckingsForOldSolutions(string courseId, string userId)
        {
            log.Info($"Создаю ручные проверки для всех решения пользователя {userId} в курсе {courseId}");

            var course = courseManager.GetCourse(courseId);

            /* For exercises */
            var acceptedSubmissionsBySlide = userSolutionsRepo.GetAllAcceptedSubmissionsByUser(courseId, userId)
                                             .ToList()
                                             .GroupBy(s => s.SlideId)
                                             .ToDictionary(g => g.Key, g => g.ToList());

            foreach (var acceptedSubmissionsForSlide in acceptedSubmissionsBySlide.Values)
            {
                /* If exists at least one manual checking for at least one submissions on slide, then ignore this slide */
                if (!acceptedSubmissionsForSlide.Any(s => s.ManualCheckings.Any()))
                {
                    /* Otherwise found the latest accepted submission */
                    var lastSubmission = acceptedSubmissionsForSlide.OrderByDescending(s => s.Timestamp).First();

                    var slideId = lastSubmission.SlideId;
                    var slide   = course.FindSlideById(slideId, false) as ExerciseSlide;
                    if (slide == null || !slide.Scoring.RequireReview)
                    {
                        continue;
                    }

                    log.Info($"Создаю ручную проверку для решения {lastSubmission.Id}, слайд {slideId}");
                    await slideCheckingsRepo.AddManualExerciseChecking(courseId, slideId, userId, lastSubmission).ConfigureAwait(false);

                    await visitsRepo.MarkVisitsAsWithManualChecking(courseId, slideId, userId).ConfigureAwait(false);
                }
            }

            /* For quizzes */
            var passedQuizzesIds = userQuizzesRepo.GetPassedSlideIds(courseId, userId);

            foreach (var quizSlideId in passedQuizzesIds)
            {
                var slide = course.FindSlideById(quizSlideId, false) as QuizSlide;
                if (slide == null || !slide.ManualChecking)
                {
                    continue;
                }
                if (!userQuizzesRepo.IsWaitingForManualCheck(courseId, quizSlideId, userId))
                {
                    log.Info($"Создаю ручную проверку для теста {slide.Id}");
                    var submission = userQuizzesRepo.FindLastUserSubmission(courseId, quizSlideId, userId);
                    if (submission == null || submission.ManualChecking != null)
                    {
                        continue;
                    }

                    await slideCheckingsRepo.AddManualQuizChecking(submission, courseId, quizSlideId, userId).ConfigureAwait(false);

                    await visitsRepo.MarkVisitsAsWithManualChecking(courseId, quizSlideId, userId).ConfigureAwait(false);
                }
            }
        }
        public ActionResult GetDetails(int id)
        {
            var submission = solutionsRepo.FindNoTrackingSubmission(id);

            if (submission == null)
            {
                return(HttpNotFound());
            }

            submission.SolutionCode.Text = ((ExerciseSlide)courseManager
                                            .GetCourse(submission.CourseId)
                                            .GetSlideById(submission.SlideId, true))
                                           .Exercise
                                           .GetSourceCode(submission.SolutionCode.Text);

            return(View(submission));
        }
Example #5
0
        public HashSet <string> GetVisibleCourses()
        {
            var appearances = db.UnitAppearances
                              .Where(u => u.PublishTime <= DateTime.Now)
                              .Select(u => new { u.CourseId, u.UnitId })
                              .AsEnumerable()
                              .GroupBy(p => p.CourseId)
                              .Where(g => courseManager.FindCourse(g.Key) != null)
                              .Where(g =>
            {
                var units = courseManager.GetCourse(g.Key).GetUnitsNotSafe().Select(u => u.Id).ToHashSet();
                units.IntersectWith(g.Select(p => p.UnitId));
                return(units.Any());
            })
                              .Select(g => g.Key);

            return(new HashSet <string>(appearances, StringComparer.OrdinalIgnoreCase));
        }
Example #6
0
        private async Task <AutomaticExerciseChecking> UpdateAutomaticExerciseChecking(AutomaticExerciseChecking checking, RunningResults result)
        {
            var compilationErrorHash = (await textsRepo.AddText(result.CompilationOutput)).Hash;
            var output     = result.GetOutput().NormalizeEoln();
            var outputHash = (await textsRepo.AddText(output)).Hash;

            var isWebRunner   = checking.CourseId == "web" && checking.SlideId == Guid.Empty;
            var exerciseSlide = isWebRunner ? null : (ExerciseSlide)courseManager.GetCourse(checking.CourseId).GetSlideById(checking.SlideId);

            var expectedOutput = exerciseSlide?.Exercise.ExpectedOutput.NormalizeEoln();
            var isRightAnswer  = result.Verdict == Verdict.Ok && output.Equals(expectedOutput);
            var score          = isRightAnswer ? exerciseSlide.Exercise.CorrectnessScore : 0;

            /* For skipped slides score is always 0 */
            if (visitsRepo.IsSkipped(checking.CourseId, checking.SlideId, checking.UserId))
            {
                score = 0;
            }

            var newChecking = new AutomaticExerciseChecking
            {
                Id                   = checking.Id,
                CourseId             = checking.CourseId,
                SlideId              = checking.SlideId,
                UserId               = checking.UserId,
                Timestamp            = checking.Timestamp,
                CompilationErrorHash = compilationErrorHash,
                IsCompilationError   = result.Verdict == Verdict.CompilationError,
                OutputHash           = outputHash,
                ExecutionServiceName = checking.ExecutionServiceName,
                Status               = AutomaticExerciseCheckingStatus.Done,
                DisplayName          = checking.DisplayName,
                Elapsed              = DateTime.Now - checking.Timestamp,
                IsRightAnswer        = isRightAnswer,
                Score                = score,
            };

            return(newChecking);
        }
Example #7
0
        public async Task <ActionResult> LtiSlide(string courseId, Guid slideId)
        {
            if (string.IsNullOrWhiteSpace(courseId))
            {
                return(RedirectToAction("Index", "Home"));
            }

            var course = courseManager.GetCourse(courseId);
            var slide  = course.GetSlideById(slideId, false);

            string userId;
            var    owinRequest = Request.GetOwinContext().Request;

            if (await owinRequest.IsAuthenticatedLtiRequestAsync())
            {
                var ltiRequest = await owinRequest.ParseLtiRequestAsync();

                log.Info($"Нашёл LTI request в запросе: {ltiRequest.JsonSerialize()}");
                userId = Request.GetOwinContext().Authentication.AuthenticationResponseGrant.Identity.GetUserId();
                await ltiRequestsRepo.Update(courseId, userId, slide.Id, ltiRequest.JsonSerialize());

                /* Substitute http(s) scheme with real scheme from header */
                var uriBuilder = new UriBuilder(ltiRequest.Url)
                {
                    Scheme = owinRequest.GetRealRequestScheme(),
                    Port   = owinRequest.GetRealRequestPort()
                };
                return(Redirect(uriBuilder.Uri.AbsoluteUri));
            }

            /* For now user should be authenticated */
            if (!User.Identity.IsAuthenticated)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.Forbidden));
            }

            userId = User.Identity.GetUserId();
            var visit = await VisitSlide(courseId, slide.Id, userId);

            /* Try to send score via LTI immediately after slide visiting */
            try
            {
                if (visit.IsPassed)
                {
                    LtiUtils.SubmitScore(courseId, slide, userId, visit);
                }
            }
            catch (Exception e)
            {
                ErrorLog.GetDefault(System.Web.HttpContext.Current).Log(new Error(e));
            }

            var exerciseSlide = slide as ExerciseSlide;

            if (exerciseSlide != null)
            {
                var model = new CodeModel
                {
                    CourseId      = courseId,
                    SlideId       = exerciseSlide.Id,
                    ExerciseBlock = exerciseSlide.Exercise,
                    Context       = CreateRenderContext(course, exerciseSlide, isLti: true)
                };
                return(View("LtiExerciseSlide", model));
            }

            var quizSlide = slide as QuizSlide;

            if (quizSlide != null)
            {
                var model = new LtiQuizModel
                {
                    CourseId = courseId,
                    Slide    = quizSlide,
                    UserId   = userId
                };
                return(View("LtiQuizSlide", model));
            }

            return(View());
        }