public async Task AddManualCheckingsForOldSolutionsAsync(string courseId, string userId)
        {
            log.Info($"Создаю ручные проверки для всех решения пользователя {userId} в курсе {courseId}");

            var course = await courseManager.GetCourseAsync(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.Id).ConfigureAwait(false);

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

            /* For quizzes */
            var passedQuizzesIds = await userQuizzesRepo.GetPassedSlideIdsAsync(courseId, userId).ConfigureAwait(false);

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

                    if (submission == null || submission.ManualChecking != null)
                    {
                        continue;
                    }
                    await slideCheckingsRepo.AddManualQuizChecking(submission, courseId, quizSlideId, userId).ConfigureAwait(false);

                    await visitsRepo.MarkVisitsAsWithManualChecking(courseId, quizSlideId, userId).ConfigureAwait(false);
                }
            }
        }
示例#2
0
        private async Task Send(MailNotificationTransport transport, NotificationDelivery notificationDelivery)
        {
            if (string.IsNullOrEmpty(transport.User.Email))
            {
                return;
            }

            var notification = notificationDelivery.Notification;
            var course       = await courseManager.GetCourseAsync(notification.CourseId);

            var notificationButton = notification.GetNotificationButton(transport, notificationDelivery, course, baseUrl);
            var htmlMessage        = notification.GetHtmlMessageForDelivery(transport, notificationDelivery, course, baseUrl);
            var textMessage        = notification.GetTextMessageForDelivery(transport, notificationDelivery, course, baseUrl);
            await emailSender.SendEmailAsync(
                transport.User.Email,
                notification.GetNotificationType().GetDisplayName(),
                textMessage,
                "<p>" + htmlMessage + "</p>",
                button : notificationButton != null?new EmailButton(notificationButton) : null,
                textContentAfterButton : GetEmailTextSignature(),
                htmlContentAfterButton : GetEmailHtmlSignature(notificationDelivery)
                );
        }
示例#3
0
        public async Task <bool> IsCourseVisibleForStudentsAsync(string courseId)
        {
            if (await courseManager.FindCourseAsync(courseId) == null)
            {
                return(false);
            }
            var visibleUnitsIds = await db.UnitAppearances
                                  .Where(u => u.CourseId == courseId)
                                  .Where(u => u.PublishTime <= DateTime.Now)
                                  .Select(u => u.UnitId)
                                  .ToListAsync();

            var units = (await courseManager.GetCourseAsync(courseId)).GetUnitsNotSafe().Select(u => u.Id).ToHashSet();

            units.IntersectWith(visibleUnitsIds);
            return(units.Any());
        }
示例#4
0
        private async Task <AutomaticExerciseChecking> UpdateAutomaticExerciseChecking(AutomaticExerciseChecking checking, RunningResults result)
        {
            var isWebRunner   = checking.CourseId == "web" && checking.SlideId == Guid.Empty;
            var exerciseSlide = isWebRunner
                                ? null
                                : (ExerciseSlide)(await courseManager.GetCourseAsync(checking.CourseId))
                                .GetSlideById(checking.SlideId, true);

            var withFullDescription = (exerciseSlide?.Exercise as PolygonExerciseBlock)?.ShowTestDescription ?? false;

            var compilationErrorHash = (await textsRepo.AddText(result.CompilationOutput)).Hash;
            var output     = result.GetOutput(withFullDescription).NormalizeEoln();
            var outputHash = (await textsRepo.AddText(output)).Hash;

            var logs     = result.GetLogs().NormalizeEoln();
            var logsHash = (await textsRepo.AddText(logs)).Hash;



            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               = result.Verdict == Verdict.SandboxError ? AutomaticExerciseCheckingStatus.Error : AutomaticExerciseCheckingStatus.Done,
                DisplayName          = checking.DisplayName,
                Elapsed              = elapsed,
                IsRightAnswer        = isRightAnswer,
                CheckingAgentName    = checking.CheckingAgentName,
                Points               = result.Points,
                DebugLogsHash        = logsHash
            };

            return(newChecking);
        }
示例#5
0
        public static async Task <bool> SendToReviewAndUpdateScore(UserExerciseSubmission submissionNoTracking,
                                                                   IWebCourseManager courseManager, ISlideCheckingsRepo slideCheckingsRepo, IGroupsRepo groupsRepo, IVisitsRepo visitsRepo, MetricSender metricSender)
        {
            var userId   = submissionNoTracking.UserId;
            var courseId = submissionNoTracking.CourseId;
            var course   = await courseManager.GetCourseAsync(courseId);

            var exerciseSlide = course.FindSlideById(submissionNoTracking.SlideId, true) as ExerciseSlide;             // SlideId проверен в вызывающем методе

            if (exerciseSlide == null)
            {
                return(false);
            }
            var exerciseMetricId                = GetExerciseMetricId(courseId, exerciseSlide);
            var automaticCheckingNoTracking     = submissionNoTracking.AutomaticChecking;
            var isProhibitedUserToSendForReview = await slideCheckingsRepo.IsProhibitedToSendExerciseToManualChecking(courseId, exerciseSlide.Id, userId);

            var sendToReview = exerciseSlide.Scoring.RequireReview &&
                               submissionNoTracking.AutomaticCheckingIsRightAnswer &&
                               !isProhibitedUserToSendForReview &&
                               await groupsRepo.IsManualCheckingEnabledForUserAsync(course, userId);

            if (sendToReview)
            {
                await slideCheckingsRepo.RemoveWaitingManualCheckings <ManualExerciseChecking>(courseId, exerciseSlide.Id, userId, false);

                await slideCheckingsRepo.AddManualExerciseChecking(courseId, exerciseSlide.Id, userId, submissionNoTracking.Id);

                await visitsRepo.MarkVisitsAsWithManualChecking(courseId, exerciseSlide.Id, userId);

                metricSender.SendCount($"exercise.{exerciseMetricId}.sent_to_review");
                metricSender.SendCount("exercise.sent_to_review");
            }

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

            if (automaticCheckingNoTracking != null)
            {
                var verdictForMetric = automaticCheckingNoTracking.GetVerdict().Replace(" ", "");
                metricSender.SendCount($"exercise.{exerciseMetricId}.{verdictForMetric}");
            }

            return(sendToReview);
        }