Exemplo n.º 1
0
        private async Task AddManualCheckingsForOldSolutionsAsync(string courseId, string userId)
        {
            logger.Information($"Создаю ручные проверки для всех решения пользователя {userId} в курсе {courseId}");

            var course = courseManager.GetCourse(courseId);

            /* For exercises */
            var acceptedSubmissionsBySlide = userSolutionsRepo.GetAllAcceptedSubmissionsByUser(courseId, userId)
                                             .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) as ExerciseSlide;
                    if (slide == null || !slide.Exercise.RequireReview)
                    {
                        continue;
                    }

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

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

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

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

                    await visitsRepo.MarkVisitsAsWithManualChecking(quizSlideId, userId).ConfigureAwait(false);
                }
            }
        }
Exemplo n.º 2
0
        public async Task <ActionResult> SubmitQuiz(string courseId, Guid slideId, string answer, bool isLti)
        {
            metricSender.SendCount("quiz.submit");
            if (isLti)
            {
                metricSender.SendCount("quiz.submit.lti");
            }
            metricSender.SendCount($"quiz.submit.{courseId}");
            metricSender.SendCount($"quiz.submit.{courseId}.{slideId}");

            var course = courseManager.GetCourse(courseId);
            var slide  = course.FindSlideById(slideId) as QuizSlide;

            if (slide == null)
            {
                return(new HttpNotFoundResult());
            }

            var userId        = User.Identity.GetUserId();
            var maxTriesCount = GetMaxTriesCount(courseId, slide);
            var quizState     = GetQuizState(courseId, userId, slideId);

            if (!CanUserFillQuiz(quizState.Item1))
            {
                return(new HttpStatusCodeResult(HttpStatusCode.OK, "Already answered"));
            }

            var tryIndex = quizState.Item2;

            metricSender.SendCount($"quiz.submit.try.{tryIndex}");
            metricSender.SendCount($"quiz.submit.{courseId}.try.{tryIndex}");
            metricSender.SendCount($"quiz.submit.{courseId}.{slideId}.try.{tryIndex}");

            if (slide.ManualChecking && !groupsRepo.IsManualCheckingEnabledForUser(course, userId))
            {
                return(new HttpStatusCodeResult(HttpStatusCode.OK, "Manual checking is disabled for you"));
            }

            var time    = DateTime.Now;
            var answers = JsonConvert.DeserializeObject <List <QuizAnswer> >(answer).GroupBy(x => x.QuizId);
            var quizBlockWithTaskCount = slide.Blocks.Count(x => x is AbstractQuestionBlock);
            var allQuizInfos           = new List <QuizInfoForDb>();

            foreach (var ans in answers)
            {
                var quizInfos = CreateQuizInfo(slide, ans);
                if (quizInfos != null)
                {
                    allQuizInfos.AddRange(quizInfos);
                }
            }
            var blocksInAnswerCount = allQuizInfos.Select(x => x.QuizId).Distinct().Count();

            if (blocksInAnswerCount != quizBlockWithTaskCount)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.Forbidden, "Has empty blocks"));
            }

            using (var transaction = db.Database.BeginTransaction())
            {
                await userQuizzesRepo.RemoveUserQuizzes(courseId, slideId, userId);

                foreach (var quizInfoForDb in allQuizInfos)
                {
                    await userQuizzesRepo.AddUserQuiz(courseId, quizInfoForDb.IsRightAnswer, quizInfoForDb.ItemId, quizInfoForDb.QuizId,
                                                      slideId, quizInfoForDb.Text, userId, time, quizInfoForDb.QuizBlockScore, quizInfoForDb.QuizBlockMaxScore);
                }

                transaction.Commit();
            }

            if (slide.ManualChecking)
            {
                /* If this quiz is already queued for checking for this user, don't add it to queue again */
                if (quizState.Item1 != QuizState.WaitForCheck)
                {
                    await slideCheckingsRepo.AddQuizAttemptForManualChecking(courseId, slideId, userId);

                    await visitsRepo.MarkVisitsAsWithManualChecking(courseId, slideId, userId);
                }
            }
            /* Recalculate score for quiz if this attempt is allowed. Don't recalculate score if this attempt is more then maxTriesCount */
            else if (tryIndex < maxTriesCount)
            {
                var score = allQuizInfos
                            .DistinctBy(forDb => forDb.QuizId)
                            .Sum(forDb => forDb.QuizBlockScore);

                metricSender.SendCount($"quiz.submit.try.{tryIndex}.score", score);
                metricSender.SendCount($"quiz.submit.{courseId}.try.{tryIndex}.score", score);
                metricSender.SendCount($"quiz.submit.{courseId}.{slideId}.try.{tryIndex}.score", score);
                metricSender.SendCount($"quiz.submit.score", score);
                metricSender.SendCount($"quiz.submit.{courseId}.score", score);
                metricSender.SendCount($"quiz.submit.{courseId}.{slideId}.score", score);

                if (score == slide.MaxScore)
                {
                    metricSender.SendCount($"quiz.submit.try.{tryIndex}.full_passed");
                    metricSender.SendCount($"quiz.submit.{courseId}.try.{tryIndex}.full_passed");
                    metricSender.SendCount($"quiz.submit.{courseId}.{slideId}.try.{tryIndex}.full_passed");
                    metricSender.SendCount($"quiz.submit.full_passed");
                    metricSender.SendCount($"quiz.submit.{courseId}.full_passed");
                    metricSender.SendCount($"quiz.submit.{courseId}.{slideId}.full_passed");
                }

                await slideCheckingsRepo.AddQuizAttemptWithAutomaticChecking(courseId, slideId, userId, score);

                await visitsRepo.UpdateScoreForVisit(courseId, slideId, userId);

                if (isLti)
                {
                    LtiUtils.SubmitScore(courseId, slide, userId);
                }
            }

            return(Json(new
            {
                url = Url.RouteUrl("Course.SlideById", new { courseId = courseId, slideId = slide.Url, send = 1 })
            }));
        }
Exemplo n.º 3
0
        public async Task <ActionResult> SubmitQuiz(string courseId, Guid slideId, string answer, bool isLti)
        {
            var course = courseManager.GetCourse(courseId);
            var slide  = course.FindSlideById(slideId) as QuizSlide;

            if (slide == null)
            {
                return(new HttpNotFoundResult());
            }

            var userId       = User.Identity.GetUserId();
            var maxDropCount = GetMaxDropCount(slide);
            var quizState    = GetQuizState(courseId, userId, slideId, maxDropCount).Item1;

            if (!CanUserFillQuiz(quizState))
            {
                return(new HttpStatusCodeResult(HttpStatusCode.OK, "Already answered"));
            }

            if (slide.ManualChecking && !groupsRepo.IsManualCheckingEnabledForUser(course, userId))
            {
                return(new HttpStatusCodeResult(HttpStatusCode.OK, "Manual checking is disabled for you"));
            }

            var time    = DateTime.Now;
            var answers = JsonConvert.DeserializeObject <List <QuizAnswer> >(answer).GroupBy(x => x.QuizId);
            var quizBlockWithTaskCount = slide.Blocks.Count(x => x is AbstractQuestionBlock);
            var allQuizInfos           = new List <QuizInfoForDb>();

            foreach (var ans in answers)
            {
                var quizInfos = CreateQuizInfo(slide, ans);
                if (quizInfos != null)
                {
                    allQuizInfos.AddRange(quizInfos);
                }
            }
            var blocksInAnswerCount = allQuizInfos.Select(x => x.QuizId).Distinct().Count();

            if (blocksInAnswerCount != quizBlockWithTaskCount)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.Forbidden, "Has empty blocks"));
            }

            using (var transaction = db.Database.BeginTransaction())
            {
                await userQuizzesRepo.RemoveUserQuizzes(courseId, slideId, userId);

                foreach (var quizInfoForDb in allQuizInfos)
                {
                    await userQuizzesRepo.AddUserQuiz(courseId, quizInfoForDb.IsRightAnswer, quizInfoForDb.ItemId, quizInfoForDb.QuizId,
                                                      slideId, quizInfoForDb.Text, userId, time, quizInfoForDb.QuizBlockScore, quizInfoForDb.QuizBlockMaxScore);
                }

                transaction.Commit();
            }

            if (slide.ManualChecking)
            {
                /* If this quiz is already queued for checking for this user, don't add it to queue again */
                if (quizState != QuizState.WaitForCheck)
                {
                    await slideCheckingsRepo.AddQuizAttemptForManualChecking(courseId, slideId, userId);

                    await visitsRepo.MarkVisitsAsWithManualChecking(slideId, userId);
                }
            }
            else
            {
                var score = allQuizInfos
                            .DistinctBy(forDb => forDb.QuizId)
                            .Sum(forDb => forDb.QuizBlockScore);
                await slideCheckingsRepo.AddQuizAttemptWithAutomaticChecking(courseId, slideId, userId, score);

                await visitsRepo.UpdateScoreForVisit(courseId, slideId, userId);

                if (isLti)
                {
                    LtiUtils.SubmitScore(slide, userId);
                }
            }

            return(new HttpStatusCodeResult(HttpStatusCode.OK));
        }