public async Task <ActionResult> AddExerciseCodeReview(string courseId, int checkingId, [FromBody] ReviewInfo reviewInfo) { var checking = slideCheckingsRepo.FindManualCheckingById <ManualExerciseChecking>(checkingId); if (!string.Equals(checking.CourseId, courseId, StringComparison.OrdinalIgnoreCase)) { return(new HttpStatusCodeResult(HttpStatusCode.Forbidden)); } /* Make start position less than finish position */ if (reviewInfo.StartLine > reviewInfo.FinishLine || (reviewInfo.StartLine == reviewInfo.FinishLine && reviewInfo.StartPosition > reviewInfo.FinishPosition)) { var tmp = reviewInfo.StartLine; reviewInfo.StartLine = reviewInfo.FinishLine; reviewInfo.FinishLine = tmp; tmp = reviewInfo.StartPosition; reviewInfo.StartPosition = reviewInfo.FinishPosition; reviewInfo.FinishPosition = tmp; } var review = await slideCheckingsRepo.AddExerciseCodeReview(checking, User.Identity.GetUserId(), reviewInfo.StartLine, reviewInfo.StartPosition, reviewInfo.FinishLine, reviewInfo.FinishPosition, reviewInfo.Comment); return(PartialView("_ExerciseReview", new ExerciseCodeReviewModel { Review = review, ManualChecking = checking, })); }
public async Task <ActionResult> ScoreQuiz(int id, string nextUrl, string errorUrl = "") { metricSender.SendCount("quiz.manual_score"); if (string.IsNullOrEmpty(errorUrl)) { errorUrl = nextUrl; } using (var transaction = db.Database.BeginTransaction()) { var checking = slideCheckingsRepo.FindManualCheckingById <ManualQuizChecking>(id); if (checking.IsChecked) { return(Redirect(errorUrl + "Эта работа уже была проверена")); } if (!checking.IsLockedBy(User.Identity)) { return(Redirect(errorUrl + "Эта работа проверяется другим инструктором")); } var course = courseManager.GetCourse(checking.CourseId); var unit = course.FindUnitBySlideId(checking.SlideId); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}"); var answers = userQuizzesRepo.GetAnswersForUser(checking.CourseId, checking.SlideId, checking.UserId); QuizVersion quizVersion; /* If there is no user's answers for quiz, get the latest quiz version */ if (answers.Count == 0) { quizVersion = quizzesRepo.GetLastQuizVersion(checking.CourseId, checking.SlideId); } else { var firstAnswer = answers.FirstOrDefault().Value.FirstOrDefault(); quizVersion = firstAnswer != null ? firstAnswer.QuizVersion : quizzesRepo.GetFirstQuizVersion(checking.CourseId, checking.SlideId); } var totalScore = 0; var quiz = quizVersion.GetRestoredQuiz(course, unit); foreach (var question in quiz.Blocks.OfType <AbstractQuestionBlock>()) { var scoreFieldName = "quiz__score__" + question.Id; var scoreStr = Request.Form[scoreFieldName]; /* Invalid form: score isn't integer */ if (!int.TryParse(scoreStr, out var score)) { return(Redirect(errorUrl + $"Неверное количество баллов в задании «{question.QuestionIndex}. {question.Text.TruncateWithEllipsis(50)}»")); } /* Invalid form: score isn't from range 0..MAX_SCORE */ if (score < 0 || score > question.MaxScore) { return(Redirect(errorUrl + $"Неверное количество баллов в задании «{question.QuestionIndex}. {question.Text.TruncateWithEllipsis(50)}»: {score}")); } await userQuizzesRepo.SetScoreForQuizBlock(checking.CourseId, checking.UserId, checking.SlideId, question.Id, score); totalScore += score; } await slideCheckingsRepo.MarkManualCheckingAsChecked(checking, totalScore); await visitsRepo.UpdateScoreForVisit(checking.CourseId, checking.SlideId, checking.UserId); transaction.Commit(); metricSender.SendCount($"quiz.manual_score.score", totalScore); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.score", totalScore); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}.score", totalScore); if (totalScore == quiz.MaxScore) { metricSender.SendCount($"quiz.manual_score.full_scored"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.full_scored"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}.full_scored"); } await NotifyAboutManualQuizChecking(checking); } return(Redirect(nextUrl)); }
public async Task <ActionResult> SlideById(string courseId, string slideId = "", int?checkQueueItemId = null, int?version = null, int autoplay = 0) { if (slideId.Contains("_")) { slideId = slideId.Substring(slideId.LastIndexOf('_') + 1); } var groupsIds = Request.GetMultipleValuesFromQueryString("group"); if (!Guid.TryParse(slideId, out var slideGuid)) { return(HttpNotFound()); } if (string.IsNullOrWhiteSpace(courseId)) { if (string.IsNullOrWhiteSpace(slideId)) { return(RedirectToAction("Index", "Home")); } return(RedirectToSlideById(slideGuid)); } var course = courseManager.FindCourse(courseId); if (course == null) { return(HttpNotFound()); } var visibleUnits = unitsRepo.GetVisibleUnits(course, User); var isGuest = !User.Identity.IsAuthenticated; var slide = slideGuid == Guid.Empty ? GetInitialSlideForStartup(courseId, visibleUnits) : course.FindSlideById(slideGuid); if (slide == null) { return(HttpNotFound()); } AbstractManualSlideChecking queueItem = null; var isManualCheckingReadonly = false; if (User.HasAccessFor(courseId, CourseRole.Instructor) && checkQueueItemId != null) { if (slide is QuizSlide) { queueItem = slideCheckingsRepo.FindManualCheckingById <ManualQuizChecking>(checkQueueItemId.Value); } if (slide is ExerciseSlide) { queueItem = slideCheckingsRepo.FindManualCheckingById <ManualExerciseChecking>(checkQueueItemId.Value); } if (queueItem == null) { /* It's possible when checking has not been fully checked, lock has been released, but after it user re-send his solution and we removed old waiting checking */ var fakeQueueItem = slide is QuizSlide ? (AbstractManualSlideChecking) new ManualQuizChecking() : new ManualExerciseChecking(); return(RedirectToAction("CheckingQueue", "Admin", new { courseId = courseId, message = "checking_removed" })); } } var model = isGuest ? CreateGuestCoursePageModel(course, slide, autoplay > 0) : await CreateCoursePageModel(course, slide, queueItem, version, groupsIds, autoplay > 0, isManualCheckingReadonly); if (!string.IsNullOrEmpty(Request.QueryString["error"])) { model.Error = Request.QueryString["error"]; } if (!visibleUnits.Contains(model.Slide.Info.Unit)) { return(HttpNotFound("Slide is hidden " + slideGuid)); } return(View("Slide", model)); }
public async Task <ActionResult> ScoreQuiz(int id, string nextUrl, string errorUrl = "") { metricSender.SendCount("quiz.manual_score"); if (string.IsNullOrEmpty(errorUrl)) { errorUrl = nextUrl; } using (var transaction = db.Database.BeginTransaction()) { var checking = slideCheckingsRepo.FindManualCheckingById <ManualQuizChecking>(id); var course = courseManager.GetCourse(checking.CourseId); var unit = course.FindUnitBySlideId(checking.SlideId); var slide = course.GetSlideById(checking.SlideId); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}"); var totalScore = 0; var quiz = course.FindSlideById(checking.SlideId); if (quiz == null) { return(Redirect(errorUrl + "Этого теста больше нет в курсе")); } foreach (var question in quiz.Blocks.OfType <AbstractQuestionBlock>()) { var scoreFieldName = "quiz__score__" + question.Id; var scoreStr = Request.Form[scoreFieldName]; /* Invalid form: score isn't integer */ if (!int.TryParse(scoreStr, out var score)) { return(Redirect(errorUrl + $"Неверное количество баллов в задании «{question.QuestionIndex}. {question.Text.TruncateWithEllipsis(50)}»")); } /* Invalid form: score isn't from range 0..MAX_SCORE */ if (score < 0 || score > question.MaxScore) { return(Redirect(errorUrl + $"Неверное количество баллов в задании «{question.QuestionIndex}. {question.Text.TruncateWithEllipsis(50)}»: {score}")); } await userQuizzesRepo.SetScoreForQuizBlock(checking.Submission.Id, question.Id, score).ConfigureAwait(false); totalScore += score; } await slideCheckingsRepo.MarkManualCheckingAsChecked(checking, totalScore).ConfigureAwait(false); await visitsRepo.UpdateScoreForVisit(checking.CourseId, checking.SlideId, slide.MaxScore, checking.UserId).ConfigureAwait(false); transaction.Commit(); metricSender.SendCount($"quiz.manual_score.score", totalScore); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.score", totalScore); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}.score", totalScore); if (totalScore == quiz.MaxScore) { metricSender.SendCount($"quiz.manual_score.full_scored"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.full_scored"); metricSender.SendCount($"quiz.manual_score.{checking.CourseId}.{checking.SlideId}.full_scored"); } if (unit != null && unitsRepo.IsUnitVisibleForStudents(course, unit.Id)) { await NotifyAboutManualQuizChecking(checking).ConfigureAwait(false); } } return(Redirect(nextUrl)); }
public async Task <ActionResult> SlideById(string courseId, string slideId = "", int?checkQueueItemId = null, int?version = null, int autoplay = 0) { if (slideId.Contains("_")) { slideId = slideId.Substring(slideId.LastIndexOf('_') + 1); } var groupsIds = Request.GetMultipleValues("group"); Guid slideGuid; if (!Guid.TryParse(slideId, out slideGuid)) { return(HttpNotFound()); } if (string.IsNullOrWhiteSpace(courseId)) { if (string.IsNullOrWhiteSpace(slideId)) { return(RedirectToAction("Index", "Home")); } return(RedirectToSlideById(slideGuid)); } var course = courseManager.FindCourse(courseId); if (course == null) { return(HttpNotFound()); } var visibleUnits = unitsRepo.GetVisibleUnits(course, User); var isGuest = !User.Identity.IsAuthenticated; var slide = slideGuid == Guid.Empty ? GetInitialSlideForStartup(courseId, course, visibleUnits) : course.FindSlideById(slideGuid); if (slide == null) { return(HttpNotFound()); } AbstractManualSlideChecking queueItem = null; var isManualCheckingReadonly = false; if (User.HasAccessFor(courseId, CourseRole.Instructor) && checkQueueItemId != null) { if (slide is QuizSlide) { queueItem = slideCheckingsRepo.FindManualCheckingById <ManualQuizChecking>(checkQueueItemId.Value); } if (slide is ExerciseSlide) { queueItem = slideCheckingsRepo.FindManualCheckingById <ManualExerciseChecking>(checkQueueItemId.Value); } if (queueItem == null) { return(HttpNotFound()); } /* If lock time is finished */ if (!queueItem.IsLockedBy(User.Identity) && queueItem.HasLastLockedBy(User.Identity)) { return(RedirectToAction(GetAdminQueueActionName(queueItem), "Admin", new { CourseId = courseId, group = string.Join(",", groupsIds), done = queueItem.IsChecked, message = "time_is_over", })); } /* If it's not locked then lock them! */ if (!queueItem.IsLocked) { return(RedirectToAction(GetAdminCheckActionName(queueItem), "Admin", new { CourseId = courseId, group = string.Join(",", groupsIds), id = queueItem.Id, recheck = true })); } if (queueItem.IsLocked && !queueItem.IsLockedBy(User.Identity)) { isManualCheckingReadonly = true; } } var model = isGuest ? CreateGuestCoursePageModel(course, slide, autoplay > 0) : await CreateCoursePageModel(course, slide, queueItem, version, groupsIds, autoplay > 0, isManualCheckingReadonly); if (!string.IsNullOrEmpty(Request.QueryString["error"])) { model.Error = Request.QueryString["error"]; } if (!visibleUnits.Contains(model.Slide.Info.Unit)) { return(HttpNotFound("Slide is hidden " + slideGuid)); } return(View("Slide", model)); }