private async Task CreateStyleErrorsReviewsForSubmission(UserExerciseSubmission submission, IEnumerable <SolutionStyleError> styleErrors, string exerciseMetricId) { var ulearnBotUserId = usersRepo.GetUlearnBotUserId(); foreach (var error in styleErrors) { if (!await styleErrorsRepo.IsStyleErrorEnabledAsync(error.ErrorType)) { continue; } await slideCheckingsRepo.AddExerciseCodeReview( submission, ulearnBotUserId, error.Span.StartLinePosition.Line, error.Span.StartLinePosition.Character, error.Span.EndLinePosition.Line, error.Span.EndLinePosition.Character, error.Message ); var errorName = Enum.GetName(typeof(StyleErrorType), error.ErrorType); metricSender.SendCount("exercise.style_error"); metricSender.SendCount($"exercise.style_error.{errorName}"); metricSender.SendCount($"exercise.{exerciseMetricId}.style_error"); metricSender.SendCount($"exercise.{exerciseMetricId}.style_error.{errorName}"); } }
private async Task SendResultToObservers(UserExerciseSubmission submission, RunningResults result) { foreach (var o in resultObservers) { await o.ProcessResult(submission, result); } }
public async Task ProcessResult(ULearnDb db, UserExerciseSubmission submission, RunningResults result) { if (!isEnabled) { return; } if (result.Verdict != Verdict.Ok) { return; } /* Send to antiplagiarism service only accepted submissions */ var checking = submission.AutomaticChecking; if (!checking.IsRightAnswer) { return; } var parameters = new AddSubmissionParameters { TaskId = submission.SlideId, Language = AntiPlagiarism.Api.Models.Language.CSharp, Code = submission.SolutionCode.Text, AuthorId = Guid.Parse(submission.UserId), AdditionalInfo = new AntiPlagiarismAdditionalInfo { SubmissionId = submission.Id }.ToJsonString(), }; antiPlagiarismClient.AddSubmissionAsync(parameters).ConfigureAwait(false).GetAwaiter().OnCompleted(() => { }); }
public async Task ProcessResult(UserExerciseSubmission submission, RunningResults result) { if (!isEnabled) { return; } if (result.Verdict != Verdict.Ok) { return; } /* Send to antiplagiarism service only accepted submissions */ var checking = submission.AutomaticChecking; if (!checking.IsRightAnswer) { return; } var parameters = new AddSubmissionParameters { TaskId = submission.SlideId, Language = submission.Language, Code = submission.SolutionCode.Text, AuthorId = Guid.Parse(submission.UserId), AdditionalInfo = JsonConvert.SerializeObject(new AntiPlagiarismAdditionalInfo { SubmissionId = submission.Id }), ClientSubmissionId = submission.Id.ToString() }; await antiPlagiarismClient.AddSubmissionAsync(parameters).ConfigureAwait(false); }
private async Task <RunnerSubmission> ToRunnerSubmission(UserExerciseSubmission submission, IWebCourseManager courseManager) { log.Info($"Собираю для отправки в RunCsJob решение {submission.Id}"); var slide = (await courseManager.FindCourseAsync(submission.CourseId))?.FindSlideById(submission.SlideId, true); if (slide is ExerciseSlide exerciseSlide) { log.Info($"Ожидаю, если курс {submission.CourseId} заблокирован"); courseManager.WaitWhileCourseIsLocked(submission.CourseId); log.Info($"Курс {submission.CourseId} разблокирован"); if (exerciseSlide is PolygonExerciseSlide) { return(((PolygonExerciseBlock)exerciseSlide.Exercise).CreateSubmission( submission.Id.ToString(), submission.SolutionCode.Text, submission.Language )); } return(exerciseSlide.Exercise.CreateSubmission( submission.Id.ToString(), submission.SolutionCode.Text )); } return(new FileRunnerSubmission { Id = submission.Id.ToString(), Code = "// no slide anymore", Input = "", NeedRun = true }); }
public async Task RunAutomaticChecking(UserExerciseSubmission submission, TimeSpan timeout, bool waitUntilChecked) { log.Info($"Запускаю автоматическую проверку решения. ID посылки: {submission.Id}"); unhandledSubmissions.TryAdd(submission.Id, DateTime.Now); if (!waitUntilChecked) { log.Info($"Не буду ожидать результатов проверки посылки {submission.Id}"); return; } var sw = Stopwatch.StartNew(); while (sw.Elapsed < timeout) { await WaitUntilSubmissionHandled(TimeSpan.FromSeconds(5), submission.Id); var updatedSubmission = FindNoTrackingSubmission(submission.Id); if (updatedSubmission == null) { break; } if (updatedSubmission.AutomaticChecking.Status == AutomaticExerciseCheckingStatus.Done) { log.Info($"Посылка {submission.Id} проверена. Результат: {updatedSubmission.AutomaticChecking.GetVerdict()}"); return; } } /* If something is wrong */ unhandledSubmissions.TryRemove(submission.Id, out DateTime value); throw new SubmissionCheckingTimeout(); }
public async Task<UserExerciseSubmission> AddUserExerciseSubmission( string courseId, Guid slideId, string code, string compilationError, string output, string userId, string executionServiceName, string displayName, Language language, AutomaticExerciseCheckingStatus status = AutomaticExerciseCheckingStatus.Waiting) { if (string.IsNullOrWhiteSpace(code)) code = "// no code"; var hash = (await textsRepo.AddText(code)).Hash; var compilationErrorHash = (await textsRepo.AddText(compilationError)).Hash; var outputHash = (await textsRepo.AddText(output)).Hash; var exerciseBlock = (courseManager.FindCourse(courseId)?.FindSlideById(slideId) as ExerciseSlide)?.Exercise; AutomaticExerciseChecking automaticChecking; if (language.HasAutomaticChecking() && (language == Language.CSharp || exerciseBlock is UniversalExerciseBlock)) { automaticChecking = new AutomaticExerciseChecking { CourseId = courseId, SlideId = slideId, UserId = userId, Timestamp = DateTime.Now, CompilationErrorHash = compilationErrorHash, IsCompilationError = !string.IsNullOrWhiteSpace(compilationError), OutputHash = outputHash, ExecutionServiceName = executionServiceName, DisplayName = displayName, Status = status, IsRightAnswer = false, }; db.AutomaticExerciseCheckings.Add(automaticChecking); } else { automaticChecking = null; } var submission = new UserExerciseSubmission { CourseId = courseId, SlideId = slideId, UserId = userId, Timestamp = DateTime.Now, SolutionCodeHash = hash, CodeHash = code.Split('\n').Select(x => x.Trim()).Aggregate("", (x, y) => x + y).GetHashCode(), Likes = new List<Like>(), AutomaticChecking = automaticChecking, AutomaticCheckingIsRightAnswer = automaticChecking?.IsRightAnswer ?? true, Language = language, }; db.UserExerciseSubmissions.Add(submission); await db.SaveChangesAsync(); return submission; }
/* TODO(andgein): Remove isRightAnswer? */ public async Task <UserExerciseSubmission> AddUserExerciseSubmission(string courseId, Guid slideId, string code, bool isRightAnswer, string compilationError, string output, string userId, string executionServiceName, string displayName) { if (string.IsNullOrWhiteSpace(code)) { code = "// no code"; } var hash = (await textsRepo.AddText(code)).Hash; var compilationErrorHash = (await textsRepo.AddText(compilationError)).Hash; var outputHash = (await textsRepo.AddText(output)).Hash; var automaticChecking = new AutomaticExerciseChecking { CourseId = courseId, SlideId = slideId, UserId = userId, Timestamp = DateTime.Now, CompilationErrorHash = compilationErrorHash, IsCompilationError = !string.IsNullOrWhiteSpace(compilationError), OutputHash = outputHash, ExecutionServiceName = executionServiceName, DisplayName = displayName, Status = AutomaticExerciseCheckingStatus.Waiting, IsRightAnswer = isRightAnswer, }; db.AutomaticExerciseCheckings.Add(automaticChecking); var submission = new UserExerciseSubmission { CourseId = courseId, SlideId = slideId, UserId = userId, Timestamp = DateTime.Now, SolutionCodeHash = hash, CodeHash = code.Split('\n').Select(x => x.Trim()).Aggregate("", (x, y) => x + y).GetHashCode(), Likes = new List <Like>(), AutomaticChecking = automaticChecking, AutomaticCheckingIsRightAnswer = isRightAnswer, }; db.UserExerciseSubmissions.Add(submission); try { await db.SaveChangesAsync(); } catch (DbEntityValidationException e) { log.Error(e); throw new Exception( string.Join("\r\n", e.EntityValidationErrors.SelectMany(v => v.ValidationErrors).Select(err => err.PropertyName + " " + err.ErrorMessage))); } return(submission); }
public async Task ProcessResult(UserExerciseSubmission submission, RunningResults result) { if (result.StyleErrors == null || result.StyleErrors.Count == 0) { return; } if (result.Verdict != Verdict.Ok) { return; } var checking = submission.AutomaticChecking; if (!checking.IsRightAnswer) { return; } var exerciseSlide = (await courseManager.FindCourseAsync(submission.CourseId)) ?.FindSlideById(submission.SlideId, true) as ExerciseSlide; if (exerciseSlide == null) { return; } if (ulearnBotUserId == null) { ulearnBotUserId = await usersRepo.GetUlearnBotUserId(); } var exerciseMetricId = ExerciseController.GetExerciseMetricId(submission.CourseId, exerciseSlide); metricSender.SendCount($"exercise.{exerciseMetricId}.StyleViolation"); foreach (var error in result.StyleErrors) { await slideCheckingsRepo.AddExerciseCodeReview( submission.Id, ulearnBotUserId, error.Span.StartLinePosition.Line, error.Span.StartLinePosition.Character, error.Span.EndLinePosition.Line, error.Span.EndLinePosition.Character, error.Message ); var errorName = error.ErrorType; metricSender.SendCount("exercise.style_error"); metricSender.SendCount($"exercise.style_error.{errorName}"); metricSender.SendCount($"exercise.{exerciseMetricId}.style_error"); metricSender.SendCount($"exercise.{exerciseMetricId}.style_error.{errorName}"); } }
private async Task <UserExerciseSubmission> TryGetExerciseSubmission(string agentName, List <string> sandboxes) { UserExerciseSubmission submission = null; while (submission == null) { var work = await workQueueRepo.TakeNoTracking(queueId, sandboxes); if (work == null) { return(null); } var workItemId = int.Parse(work.ItemId); submission = await db.UserExerciseSubmissions .Include(s => s.AutomaticChecking) .Include(s => s.SolutionCode) .FirstOrDefaultAsync(s => s.Id == workItemId && (s.AutomaticChecking.Status == AutomaticExerciseCheckingStatus.Waiting || s.AutomaticChecking.Status == AutomaticExerciseCheckingStatus.Running)); var minutes = TimeSpan.FromMinutes(15); var notSoLongAgo = DateTime.Now - TimeSpan.FromMinutes(15); if (submission == null) { await workQueueRepo.Remove(work.Id); } else if (submission.Timestamp < notSoLongAgo) { await workQueueRepo.Remove(work.Id); submission.AutomaticChecking.Status = submission.AutomaticChecking.Status == AutomaticExerciseCheckingStatus.Waiting ? AutomaticExerciseCheckingStatus.RequestTimeLimit : AutomaticExerciseCheckingStatus.Error; await db.SaveChangesAsync(); if (submission.AutomaticChecking.Status == AutomaticExerciseCheckingStatus.Error) { log.Error($"Не получил ответ от чеккера по проверке {submission.Id} за {minutes} минут"); } if (!UnhandledSubmissionsWaiter.HandledSubmissions.TryAdd(submission.Id, DateTime.Now)) { log.Warn($"Не удалось запомнить, что {submission.Id} не удалось проверить, и этот результат сохранен в базу"); } submission = null; } } submission.AutomaticChecking.Status = AutomaticExerciseCheckingStatus.Running; submission.AutomaticChecking.CheckingAgentName = agentName; await db.SaveChangesAsync(); UnhandledSubmissionsWaiter.UnhandledSubmissions.TryRemove(submission.Id, out _); return(submission); }
public async Task RemoveSubmission(UserExerciseSubmission submission) { if (submission.Likes != null) db.SolutionLikes.RemoveRange(submission.Likes); if (submission.AutomaticChecking != null) db.AutomaticExerciseCheckings.Remove(submission.AutomaticChecking); if (submission.ManualCheckings != null) db.ManualExerciseCheckings.RemoveRange(submission.ManualCheckings); db.UserExerciseSubmissions.Remove(submission); await db.SaveChangesAsync(); }
public async Task <UserExerciseSubmission> AddUserExerciseSubmission( string courseId, Guid slideId, string code, string compilationError, string output, string userId, string executionServiceName, string displayName, AutomaticExerciseCheckingStatus status = AutomaticExerciseCheckingStatus.Waiting) { if (string.IsNullOrWhiteSpace(code)) { code = "// no code"; } var hash = (await textsRepo.AddText(code)).Hash; var compilationErrorHash = (await textsRepo.AddText(compilationError)).Hash; var outputHash = (await textsRepo.AddText(output)).Hash; var automaticChecking = new AutomaticExerciseChecking { CourseId = courseId, SlideId = slideId, UserId = userId, Timestamp = DateTime.Now, CompilationErrorHash = compilationErrorHash, IsCompilationError = !string.IsNullOrWhiteSpace(compilationError), OutputHash = outputHash, ExecutionServiceName = executionServiceName, DisplayName = displayName, Status = status, IsRightAnswer = false, }; db.AutomaticExerciseCheckings.Add(automaticChecking); var submission = new UserExerciseSubmission { CourseId = courseId, SlideId = slideId, UserId = userId, Timestamp = DateTime.Now, SolutionCodeHash = hash, CodeHash = code.Split('\n').Select(x => x.Trim()).Aggregate("", (x, y) => x + y).GetHashCode(), Likes = new List <Like>(), AutomaticChecking = automaticChecking, AutomaticCheckingIsRightAnswer = false, }; db.UserExerciseSubmissions.Add(submission); await db.SaveChangesAsync(); return(submission); }
public async Task ProcessResult(ULearnDb db, UserExerciseSubmission submission, RunningResults result) { /* Ignore all verdicts except SandboxError */ if (result.Verdict != Verdict.SandboxError) { return; } var output = result.Output; await bot.PostToChannelAsync( $"<b>Решение #{submission.Id} не запустилось в песочнице (SandboxError).</b>\n" + (string.IsNullOrEmpty(output) ? "" : $"Вывод:\n<pre>{output.EscapeHtml()}</pre>"), ParseMode.Html ).ConfigureAwait(false); }
public async Task ProcessResult(UserExerciseSubmission submission, RunningResults result) { var xQueueSubmission = await xQueueRepo.FindXQueueSubmission(submission); if (xQueueSubmission == null) { return; } var watcher = xQueueSubmission.Watcher; var client = new XQueueClient(watcher.BaseUrl, watcher.UserName, watcher.Password); await client.Login(); if (await SendSubmissionResultsToQueue(client, xQueueSubmission)) { await xQueueRepo.MarkXQueueSubmissionThatResultIsSent(xQueueSubmission); } }
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); }
public async Task ProcessResult(UserExerciseSubmission submission, RunningResults result) { var ltiRequestJson = await ltiRequestsRepo.Find(submission.CourseId, submission.UserId, submission.SlideId); if (ltiRequestJson != null) { try { var exerciseSlide = (await courseManager.FindCourseAsync(submission.CourseId)).FindSlideById(submission.SlideId, true) as ExerciseSlide; var score = await visitsRepo.GetScore(submission.CourseId, submission.SlideId, submission.UserId); await LtiUtils.SubmitScore(exerciseSlide, submission.UserId, score, ltiRequestJson, ltiConsumersRepo); } catch (Exception e) { log.Error(e, "Мы не смогли отправить баллы на образовательную платформу"); } } }
public static async Task <bool> SendToReviewAndUpdateScore(UserExerciseSubmission submission, CourseManager courseManager, SlideCheckingsRepo slideCheckingsRepo, GroupsRepo groupsRepo, VisitsRepo visitsRepo, MetricSender metricSender, bool startTransaction) { var userId = submission.User.Id; var courseId = submission.CourseId; var course = courseManager.GetCourse(courseId); var exerciseSlide = course.FindSlideById(submission.SlideId) as ExerciseSlide; if (exerciseSlide == null) { return(false); } var exerciseMetricId = GetExerciseMetricId(courseId, exerciseSlide); var automaticChecking = submission.AutomaticChecking; var isProhibitedUserToSendForReview = slideCheckingsRepo.IsProhibitedToSendExerciseToManualChecking(courseId, exerciseSlide.Id, userId); var sendToReview = exerciseSlide.Scoring.RequireReview && submission.AutomaticCheckingIsRightAnswer && !isProhibitedUserToSendForReview && groupsRepo.IsManualCheckingEnabledForUser(course, userId); if (sendToReview) { await slideCheckingsRepo.RemoveWaitingManualCheckings <ManualExerciseChecking>(courseId, exerciseSlide.Id, userId, false); await slideCheckingsRepo.AddManualExerciseChecking(courseId, exerciseSlide.Id, userId, submission); 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.Id, exerciseSlide.MaxScore, userId); if (automaticChecking != null) { var verdictForMetric = automaticChecking.GetVerdict().Replace(" ", ""); metricSender.SendCount($"exercise.{exerciseMetricId}.{verdictForMetric}"); } return(sendToReview); }
private async Task <ExerciseCodeReview> AddExerciseCodeReview([CanBeNull] UserExerciseSubmission submission, [CanBeNull] ManualExerciseChecking checking, string userId, int startLine, int startPosition, int finishLine, int finishPosition, string comment, bool setAddingTime) { var review = db.ExerciseCodeReviews.Add(new ExerciseCodeReview { AuthorId = userId, Comment = comment, ExerciseCheckingId = checking?.Id, SubmissionId = submission?.Id, StartLine = startLine, StartPosition = startPosition, FinishLine = finishLine, FinishPosition = finishPosition, AddingTime = setAddingTime ? DateTime.Now : ExerciseCodeReview.NullAddingTime, }); await db.SaveChangesAsync().ConfigureAwait(false); /* Extract review from database to fill review.Author by EF's DynamicProxy */ return(db.ExerciseCodeReviews.AsNoTracking().FirstOrDefault(r => r.Id == review.Id)); }
public async Task RunAutomaticChecking(UserExerciseSubmission submission, TimeSpan timeout, bool waitUntilChecked, int priority) { log.Info($"Запускаю автоматическую проверку решения. ID посылки: {submission.Id}"); unhandledSubmissions.TryAdd(submission.Id, DateTime.Now); await workQueueRepo.Add(queueId, submission.Id.ToString(), submission.Sandbox ?? "csharp", priority); if (!waitUntilChecked) { log.Info($"Не буду ожидать результатов проверки посылки {submission.Id}"); return; } var sw = Stopwatch.StartNew(); while (sw.Elapsed < timeout) { await WaitUntilSubmissionHandled(TimeSpan.FromSeconds(5), submission.Id); var submissionAutomaticCheckingStatus = await GetSubmissionAutomaticCheckingStatus(submission.Id); if (submissionAutomaticCheckingStatus == null) { break; } if (submissionAutomaticCheckingStatus == AutomaticExerciseCheckingStatus.Done) { log.Info($"Посылка {submission.Id} проверена"); return; } if (submissionAutomaticCheckingStatus == AutomaticExerciseCheckingStatus.Error) { log.Warn($"Во время проверки посылки {submission.Id} произошла ошибка"); return; } } /* If something is wrong */ unhandledSubmissions.TryRemove(submission.Id, out _); throw new SubmissionCheckingTimeout(); }
private RunnerSubmission ToRunnerSubmission(UserExerciseSubmission submission) { if (submission.IsWebSubmission) { return(new FileRunnerSubmission { Id = submission.Id.ToString(), Code = submission.SolutionCode.Text, Input = "", NeedRun = true }); } var exerciseSlide = (ExerciseSlide)courseManager .GetCourse(submission.CourseId) .GetSlideById(submission.SlideId); courseManager.WaitWhileCourseIsLocked(submission.CourseId); return(exerciseSlide.Exercise.CreateSubmition( submission.Id.ToString(), submission.SolutionCode.Text)); }
public async Task ProcessResult(ULearnDb db, UserExerciseSubmission submission, RunningResults result) { var courseManager = WebCourseManager.Instance; var xQueueRepo = new XQueueRepo(db, courseManager); var xQueueSubmission = xQueueRepo.FindXQueueSubmission(submission); if (xQueueSubmission == null) { return; } var watcher = xQueueSubmission.Watcher; var client = new XQueueClient(watcher.BaseUrl, watcher.UserName, watcher.Password); await client.Login().ConfigureAwait(false); if (await SendSubmissionResultsToQueue(client, xQueueSubmission).ConfigureAwait(false)) { await xQueueRepo.MarkXQueueSubmissionThatResultIsSent(xQueueSubmission).ConfigureAwait(false); } }
private RunnerSubmission ToRunnerSubmission(UserExerciseSubmission submission) { if (submission.IsWebSubmission) { return(new FileRunnerSubmission { Id = submission.Id.ToString(), Code = submission.SolutionCode.Text, Input = "", NeedRun = true }); } log.Info($"Собираю для отправки в RunCsJob решение {submission.Id}"); var exerciseSlide = courseManager.FindCourse(submission.CourseId)?.FindSlideById(submission.SlideId) as ExerciseSlide; if (exerciseSlide == null) { return new FileRunnerSubmission { Id = submission.Id.ToString(), Code = "// no slide anymore", Input = "", NeedRun = true } } ; log.Info($"Ожидаю, если курс {submission.CourseId} заблокирован"); courseManager.WaitWhileCourseIsLocked(submission.CourseId); log.Info($"Курс {submission.CourseId} разблокирован"); return(exerciseSlide.Exercise.CreateSubmission( submission.Id.ToString(), submission.SolutionCode.Text )); }
public async Task ProcessResult(UserExerciseSubmission submission, RunningResults result) { /* Ignore all verdicts except SandboxError */ if (result.Verdict != Verdict.SandboxError) { return; } var output = result.GetOutput(); var logs = result.Logs == null ? null : string.Join("\n", result.Logs); var message = $"<b>Решение #{submission.Id} не запустилось в песочнице {submission.Sandbox} (SandboxError).</b>\n"; if (!string.IsNullOrEmpty(output)) { message += $"Вывод:\n<pre>{output.EscapeHtml()}</pre>\n"; } if (!string.IsNullOrEmpty(logs)) { message += $"Логи:\n<pre>{logs.EscapeHtml()}</pre>\n"; } await bot.PostToChannelAsync(message, ParseMode.Html).ConfigureAwait(false); }
public async Task ProcessResult(ULearnDb db, UserExerciseSubmission submission, RunningResults result) { if (!isEnabled) { return; } if (result.Verdict != Verdict.Ok) { return; } /* Send to antiplagiarism service only accepted submissions */ var checking = submission.AutomaticChecking; if (!checking.IsRightAnswer) { return; } var parameters = new AddSubmissionParameters { TaskId = submission.SlideId, Language = AntiPlagiarism.Api.Models.Language.CSharp, Code = submission.SolutionCode.Text, AuthorId = Guid.Parse(submission.UserId), AdditionalInfo = new AntiPlagiarismAdditionalInfo { SubmissionId = submission.Id }.ToJsonString(), }; var antiPlagiarismResult = await antiPlagiarismClient.AddSubmissionAsync(parameters).ConfigureAwait(false); log.Info($"Получил ответ от сервиса антиплагиата: {antiPlagiarismResult}"); var userSolutionsRepo = new UserSolutionsRepo(db, WebCourseManager.Instance); await userSolutionsRepo.SetAntiPlagiarismSubmissionId(submission, antiPlagiarismResult.SubmissionId).ConfigureAwait(false); }
public static SubmissionInfo Build(UserExerciseSubmission submission, [CanBeNull] Dictionary <int, IEnumerable <ExerciseCodeReviewComment> > reviewId2Comments, bool showCheckerLogs) { var botReviews = submission.NotDeletedReviews .Select(r => ToReviewInfo(r, true, reviewId2Comments)) .ToList(); var manualCheckingReviews = submission.ManualCheckings .SelectMany(c => c.NotDeletedReviews) .Select(r => ToReviewInfo(r, false, reviewId2Comments)) .ToList(); var automaticChecking = submission.AutomaticChecking == null ? null : ExerciseAutomaticCheckingResponse.Build(submission.AutomaticChecking, botReviews, showCheckerLogs); return(new SubmissionInfo { Id = submission.Id, Code = submission.SolutionCode.Text, Language = submission.Language, Timestamp = submission.Timestamp, AutomaticChecking = automaticChecking, ManualCheckingPassed = submission.ManualCheckings.Any(mc => mc.IsChecked), ManualCheckingReviews = manualCheckingReviews.Where(r => r.Author != null).ToList() }); }
public async Task ProcessResult(UserExerciseSubmission submission, RunningResults result) { if (result.StyleErrors == null || result.StyleErrors.Count == 0) { return; } if (result.Verdict != Verdict.Ok) { return; } var checking = submission.AutomaticChecking; if (!checking.IsRightAnswer) { return; } var exerciseSlide = (await courseManager.FindCourseAsync(submission.CourseId)) ?.FindSlideById(submission.SlideId, true) as ExerciseSlide; if (exerciseSlide == null) { return; } if (ulearnBotUserId == null) { ulearnBotUserId = await usersRepo.GetUlearnBotUserId(); } var exerciseMetricId = RunnerSetResultController.GetExerciseMetricId(submission.CourseId, exerciseSlide); await CreateStyleErrorsReviewsForSubmission(submission.Id, result.StyleErrors, exerciseMetricId); }
public async Task SetAntiPlagiarismSubmissionId(UserExerciseSubmission submission, int antiPlagiarismSubmissionId) { submission.AntiPlagiarismSubmissionId = antiPlagiarismSubmissionId; await db.SaveChangesAsync(); }
public async Task <XQueueExerciseSubmission> FindXQueueSubmission(UserExerciseSubmission submission) { return(await db.XQueueExerciseSubmissions.FirstOrDefaultAsync(s => s.SubmissionId == submission.Id)); }
private Task SendResultToObservers(UserExerciseSubmission submission, RunningResults result) { var tasks = resultObserveres.Select(o => o.ProcessResult(db, submission, result)); return(Task.WhenAll(tasks)); }
public async Task <ManualExerciseChecking> AddManualExerciseChecking(string courseId, Guid slideId, string userId, UserExerciseSubmission submission) { var manualChecking = new ManualExerciseChecking { CourseId = courseId, SlideId = slideId, UserId = userId, Timestamp = DateTime.Now, SubmissionId = submission.Id, }; db.ManualExerciseCheckings.Add(manualChecking); await db.SaveChangesAsync().ConfigureAwait(false); return(manualChecking); }