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); } } }
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) ); }
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()); }
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); }
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); }