示例#1
0
        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);
     }
 }
示例#3
0
        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
            });
        }
示例#6
0
        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();
        }
示例#7
0
		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;
		}
示例#8
0
        /* 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);
        }
示例#9
0
        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}");
            }
        }
示例#10
0
        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);
        }
示例#11
0
		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();
		}
示例#12
0
        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);
        }
示例#13
0
        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);
            }
        }
示例#15
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);
        }
示例#16
0
        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, "Мы не смогли отправить баллы на образовательную платформу");
                }
            }
        }
示例#17
0
        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);
        }
示例#18
0
        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));
        }
示例#19
0
        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();
        }
示例#20
0
        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));
        }
示例#21
0
        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);
            }
        }
示例#22
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        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()
            });
        }
示例#26
0
        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);
        }
示例#27
0
 public async Task SetAntiPlagiarismSubmissionId(UserExerciseSubmission submission, int antiPlagiarismSubmissionId)
 {
     submission.AntiPlagiarismSubmissionId = antiPlagiarismSubmissionId;
     await db.SaveChangesAsync();
 }
示例#28
0
 public async Task <XQueueExerciseSubmission> FindXQueueSubmission(UserExerciseSubmission submission)
 {
     return(await db.XQueueExerciseSubmissions.FirstOrDefaultAsync(s => s.SubmissionId == submission.Id));
 }
示例#29
0
        private Task SendResultToObservers(UserExerciseSubmission submission, RunningResults result)
        {
            var tasks = resultObserveres.Select(o => o.ProcessResult(db, submission, result));

            return(Task.WhenAll(tasks));
        }
示例#30
0
        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);
        }