Esempio n. 1
0
        public IActionResult Edit(JuryEditModel model)
        {
            string msg;
            bool   suc = ModelState.IsValid;

            if (suc)
            {
                (msg, suc) = Service.UpdateContest(model);
            }
            else
            {
                var sb = new StringBuilder();
                foreach (var err in ModelState)
                {
                    foreach (var errr in err.Value.Errors)
                    {
                        sb.AppendLine(errr.ErrorMessage);
                    }
                }
                msg = sb.ToString();
            }

            if (suc)
            {
                DisplayMessage = msg;
                return(RedirectToAction(nameof(Edit), new { cid = Contest.ContestId }));
            }
            else
            {
                ViewBag.Categories = Service.QueryCategories(null).ToList();
                ViewBag.Repository = Service.GetAllProblems();
                ViewBag.Message    = msg;

                return(View(model));
            }
        }
Esempio n. 2
0
        public async Task <IActionResult> Edit(JuryEditModel model)
        {
            // check the category id
            var cates = await Context.ListCategoriesAsync(false);

            if ((model.RegisterCategory?.Values ?? Enumerable.Empty <int>()).Except(cates.Keys.Append(0)).Any())
            {
                ModelState.AddModelError(nameof(model.RegisterCategory), "No corresponding category found.");
            }

            // check time sequence
            if (Contest.Kind != CcsDefaults.KindProblemset &&
                !string.IsNullOrEmpty(model.StartTime) &&
                string.IsNullOrEmpty(model.StopTime))
            {
                ModelState.AddModelError(nameof(model.StopTime), "No stop time when start time filled.");
            }

            bool           contestTimeChanged = false;
            DateTimeOffset?startTime = null;
            TimeSpan?      endTime = null, freezeTime = null, unfreezeTime = null;

            if (!string.IsNullOrEmpty(model.StartTime))
            {
                startTime = DateTimeOffset.Parse(model.StartTime);
            }

            if (!string.IsNullOrWhiteSpace(model.StopTime))
            {
                model.StopTime.TryParseAsTimeSpan(out endTime);
            }

            if (!string.IsNullOrWhiteSpace(model.FreezeTime))
            {
                model.FreezeTime.TryParseAsTimeSpan(out freezeTime);
            }

            if (!string.IsNullOrWhiteSpace(model.UnfreezeTime))
            {
                model.UnfreezeTime.TryParseAsTimeSpan(out unfreezeTime);
            }

            if (!endTime.HasValue ||
                (freezeTime.HasValue && freezeTime.Value > endTime.Value) ||
                (unfreezeTime.HasValue && unfreezeTime.Value < endTime.Value))
            {
                ModelState.AddModelError("xys::time", "Time sequence is wrong.");
            }

            if (!ModelState.IsValid)
            {
                ViewBag.Categories = cates;
                ViewBag.Languages  = await Context.ListLanguagesAsync(false);

                return(View(model));
            }

            var freezeTimeSeconds = freezeTime?.TotalSeconds;
            var endTimeSeconds      = endTime?.TotalSeconds;
            var unfreezeTimeSeconds = unfreezeTime?.TotalSeconds;

            if (startTime != Contest.StartTime ||
                endTime != Contest.EndTime ||
                freezeTime != Contest.FreezeTime ||
                unfreezeTime != Contest.UnfreezeTime)
            {
                contestTimeChanged = true;
            }

            var settings     = model.CreateSettings(Contest);
            var settingsJson = settings.ToString();

            await Context.UpdateContestAsync(
                _ => new Contest
            {
                ShortName           = model.ShortName,
                Name                = model.Name,
                RankingStrategy     = model.RankingStrategy,
                IsPublic            = model.IsPublic,
                StartTime           = startTime,
                FreezeTimeSeconds   = freezeTimeSeconds,
                EndTimeSeconds      = endTimeSeconds,
                UnfreezeTimeSeconds = unfreezeTimeSeconds,
                SettingsJson        = settingsJson,
            });

            await HttpContext.AuditAsync("updated", $"{Contest.Id}", "via edit-page");

            StatusMessage = "Contest updated successfully.";
            if (contestTimeChanged)
            {
                StatusMessage += " Scoreboard cache should be refreshed later.";
            }

            return(RedirectToAction(nameof(Home)));
        }
Esempio n. 3
0
        public async Task <IActionResult> Edit(int cid, JuryEditModel model)
        {
            // check the category id
            var cates = await Facade.Teams.ListCategoryAsync(cid);

            if (model.DefaultCategory != 0 && !cates.Any(c => c.CategoryId == model.DefaultCategory))
            {
                ModelState.AddModelError("xys::nocat", "No corresponding category found.");
            }

            // check time sequence
            if (!string.IsNullOrEmpty(model.StartTime) && string.IsNullOrEmpty(model.StopTime))
            {
                ModelState.AddModelError("xys::startstop", "No stop time when start time filled.");
            }

            bool           contestTimeChanged = false;
            DateTimeOffset @base;
            DateTimeOffset?startTime, endTime = null, freezeTime = null, unfreezeTime = null;

            if (string.IsNullOrEmpty(model.StartTime))
            {
                @base     = DateTimeOffset.UnixEpoch;
                startTime = null;
            }
            else
            {
                @base     = DateTimeOffset.Parse(model.StartTime);
                startTime = @base;
            }

            if (!string.IsNullOrWhiteSpace(model.StopTime) &&
                model.StopTime.TryParseAsTimeSpan(out var ts1))
            {
                endTime = @base + ts1.Value;
            }

            if (!string.IsNullOrWhiteSpace(model.FreezeTime) &&
                model.FreezeTime.TryParseAsTimeSpan(out var ts2))
            {
                freezeTime = @base + ts2.Value;
            }

            if (!string.IsNullOrWhiteSpace(model.UnfreezeTime) &&
                model.UnfreezeTime.TryParseAsTimeSpan(out var ts3))
            {
                unfreezeTime = @base + ts3.Value;
            }

            if (!InSequence(startTime, freezeTime, endTime, unfreezeTime))
            {
                ModelState.AddModelError("xys::time", "Time sequence is wrong.");
            }

            if (!ModelState.IsValid)
            {
                ViewBag.Categories = cates;
                return(View(model));
            }

            var cst = Contest;

            if (startTime != cst.StartTime ||
                endTime != cst.EndTime ||
                freezeTime != cst.FreezeTime ||
                unfreezeTime != cst.UnfreezeTime)
            {
                contestTimeChanged = true;
            }

            await Store.UpdateAsync(cid, c => new Data.Contest
            {
                ShortName               = model.ShortName,
                Name                    = model.Name,
                RankingStrategy         = model.RankingStrategy,
                IsPublic                = model.IsPublic,
                StartTime               = startTime,
                FreezeTime              = freezeTime,
                EndTime                 = endTime,
                UnfreezeTime            = unfreezeTime,
                RegisterDefaultCategory = model.DefaultCategory,
                BalloonAvaliable        = model.UseBalloon,
                PrintingAvaliable       = model.UsePrintings,
                StatusAvaliable         = model.StatusAvailable,
            });

            await HttpContext.AuditAsync("updated", $"{cid}", "via edit-page");

            StatusMessage = "Contest updated successfully.";
            if (contestTimeChanged)
            {
                StatusMessage += " Scoreboard cache should be refreshed later.";
            }

            return(RedirectToAction(nameof(Home)));
        }
Esempio n. 4
0
        public (string, bool) UpdateContest(JuryEditModel model)
        {
            (string, bool) SolveAndUpdate()
            {
                var            cst = Contest;
                DateTimeOffset @base;
                DateTimeOffset?startTime, endTime, freezeTime, unfreezeTime;
                bool           contestTimeChanged = false;

                if (model.DefaultCategory != 0)
                {
                    var cts = QueryCategories(null).ToList();
                    if (!cts.Any(c => c.CategoryId == model.DefaultCategory))
                    {
                        return("Error default category.", false);
                    }
                }

                model.Problems = model.Problems ?? new Dictionary <int, ContestProblem>();
                if (model.Problems.Select(p => p.Value.ProblemId).Distinct().Count() != model.Problems.Count)
                {
                    return("Error duplicate problems.", false);
                }

                if (!string.IsNullOrEmpty(model.StartTime) &&
                    string.IsNullOrEmpty(model.StopTime))
                {
                    return("Error end time for the start time has been filled.", false);
                }

                if (string.IsNullOrEmpty(model.StartTime))
                {
                    @base     = DateTimeOffset.UnixEpoch;
                    startTime = null;
                }
                else
                {
                    @base     = DateTimeOffset.Parse(model.StartTime);
                    startTime = @base;
                }

                if (string.IsNullOrWhiteSpace(model.StopTime))
                {
                    endTime = null;
                }
                else
                {
                    model.StopTime.TryParseAsTimeSpan(out var ts);
                    endTime = @base + ts.Value;
                }

                if (string.IsNullOrWhiteSpace(model.FreezeTime))
                {
                    freezeTime = null;
                }
                else
                {
                    model.FreezeTime.TryParseAsTimeSpan(out var ts);
                    freezeTime = @base + ts.Value;
                }

                if (string.IsNullOrWhiteSpace(model.UnfreezeTime))
                {
                    unfreezeTime = null;
                }
                else
                {
                    model.UnfreezeTime.TryParseAsTimeSpan(out var ts);
                    unfreezeTime = @base + ts.Value;
                }

                if (!InSequence(startTime, freezeTime, endTime, unfreezeTime))
                {
                    return("Error time sequence.", false);
                }

                if (startTime != cst.StartTime ||
                    endTime != cst.EndTime ||
                    freezeTime != cst.FreezeTime ||
                    unfreezeTime != cst.UnfreezeTime)
                {
                    contestTimeChanged = true;
                }

                cst.ShortName               = model.ShortName;
                cst.Name                    = model.Name;
                cst.RankingStrategy         = model.RankingStrategy;
                cst.BronzeMedal             = model.BronzeMedal;
                cst.EndTime                 = endTime;
                cst.FreezeTime              = freezeTime;
                cst.GoldMedal               = model.GoldenMedal;
                cst.IsPublic                = model.IsPublic;
                cst.RegisterDefaultCategory = model.DefaultCategory;
                cst.SilverMedal             = model.SilverMedal;
                cst.StartTime               = startTime;
                cst.UnfreezeTime            = unfreezeTime;
                DbContext.Contests.Update(cst);

                var probs = model.Problems.Select(p => p.Value).ToList();

                probs.Sort((cp1, cp2) => cp1.ShortName.CompareTo(cp2.ShortName));
                probs.ForEach(cp => { cp.Color = "#" + cp.Color; cp.ContestId = ContestId; });
                for (int i = 0; i < probs.Count; i++)
                {
                    probs[i].Rank = i + 1;
                }

                var oldprobs = Problems;

                foreach (var item in oldprobs)
                {
                    if (!probs.Any(cp => cp.ProblemId == item.ProblemId))
                    {
                        DbContext.ContestProblem.Remove(item);
                    }
                }
                foreach (var item in probs)
                {
                    if (!oldprobs.Any(cp => cp.ProblemId == item.ProblemId))
                    {
                        DbContext.ContestProblem.Add(item);
                    }
                    else
                    {
                        DbContext.ContestProblem.Update(item);
                    }
                }

                DbContext.AuditLogs.Add(new AuditLog
                {
                    Comment   = "updated",
                    EntityId  = ContestId,
                    ContestId = ContestId,
                    Resolved  = !contestTimeChanged,
                    Time      = DateTimeOffset.Now,
                    UserName  = GetUserName(),
                    Type      = AuditLog.TargetType.Contest,
                });

                DbContext.SaveChanges();
                return($"Contest {ContestId} updated. " +
                       (contestTimeChanged ? "Rank cache will be refreshed in minutes. " : ""), true);
            }

            var result = SolveAndUpdate();

            QueryContest(true).FirstOrDefault();
            QueryProblems(true).ToArray();
            return(result);
        }