예제 #1
0
 public UpdatePromptCommandValidatorTest()
 {
     _validator = new UpdatePromptCommandValidator();
 }
예제 #2
0
        public async Task <IActionResult> Edit(int?id, bool addWi, bool saveDraft, bool confirm, bool addChild,
                                               bool uploadWi, int?wiDelete, UpdatePromptViewModel model, IFormFile?scenarioFile, IFormFile?holoFile, CancellationToken cancellationToken)
        {
            model.Command.SaveDraft = saveDraft;

            if (id == null || !_currentUserService.TryGetCurrentUser(out GetUserViewModel? user))
            {
                return(NotFound());
            }

            GetPromptViewModel?prompt = await _mediator.Send(new GetPromptQuery(id.Value), cancellationToken);

            if (prompt == null || (prompt.OwnerId != user !.Id && !RoleHelper.CanEdit(user.Role)))
            {
                return(NotFound());
            }

            model.Children        = prompt.Children.ToList();
            model.Command.Id      = prompt.Id;
            model.Command.OwnerId = prompt.OwnerId;

            if (scenarioFile != null)
            {
                var novelAiScenarioString = await ReadFormFile(scenarioFile);

                try
                {
                    NovelAiScenario?novelAiScenario = JsonSerializer.Deserialize <NovelAiScenario>(novelAiScenarioString);


                    if (novelAiScenario != null)
                    {
                        model.Command.Description   = novelAiScenario.Description;
                        model.Command.Memory        = novelAiScenario.Context.FirstOrDefault()?.Text;
                        model.Command.AuthorsNote   = novelAiScenario.Context.ElementAtOrDefault(1)?.Text;
                        model.Command.Title         = novelAiScenario.Title;
                        model.Command.PromptContent = novelAiScenario.Prompt;
                        model.Command.PromptTags    = string.Join(", ", novelAiScenario.Tags);
                        model.Command.WorldInfos    = novelAiScenario.Lorebook.LorebookEntries.Any()
                                                        ? novelAiScenario.Lorebook.LorebookEntries.Select(lore =>
                                                                                                          new UpdatePromptCommandWorldInfo
                        {
                            Keys = string.Join(", ", lore.Keys), Entry = lore.Text
                        })
                                                      .ToList()
                                                        : new List <UpdatePromptCommandWorldInfo> {
                            new()
                        };
                        model.Command.NovelAiScenario = novelAiScenarioString;
                    }
                }
                catch (JsonException e)
                {
                    _logger.LogError(e, "Could not decode NAI Json data");
                }

                ModelState.Clear();
                return(View(model));
            }

            if (holoFile != null)
            {
                var holoScenarioString = await ReadFormFile(holoFile);

                try
                {
                    HoloAiScenario?holoScenario =
                        JsonSerializer.Deserialize <HoloAiScenario>(holoScenarioString, new JsonSerializerOptions(JsonSerializerDefaults.Web));
                    if (holoScenario != null)
                    {
                        model.Command.Description   = null;
                        model.Command.Memory        = holoScenario.Memory;
                        model.Command.AuthorsNote   = holoScenario.AuthorsNote;
                        model.Command.Title         = holoScenario.Title;
                        model.Command.PromptContent = string.Join('\n',
                                                                  holoScenario.Content.Select(content =>
                                                                                              string.Join(' ', content.Children.Select(child => child.Text))));
                        model.Command.PromptTags = string.Join(", ", holoScenario.Tags);
                        model.Command.WorldInfos = holoScenario.WorldInfo.ConvertAll(e => new UpdatePromptCommandWorldInfo
                        {
                            Entry = e.Value, Keys = string.Join(", ", e.Keys)
                        });
                        model.Command.HoloAiScenario = holoScenarioString;
                    }
                }
                catch (JsonException e)
                {
                    _logger.LogError(e, "Could not decode Holo Json data");
                }

                ModelState.Clear();
                return(View(model));
            }

            if (uploadWi)
            {
                ModelState.Clear();
                if (model.WorldInfoFile != null)
                {
                    List <WorldInfoJson> worldInfos = await ReadWorldInfoFromFileAsync(model.WorldInfoFile);

                    if (worldInfos.Count > 0)
                    {
                        if (model.Command.WorldInfos.Count == 1 &&
                            string.IsNullOrWhiteSpace(model.Command.WorldInfos[0].Entry) &&
                            string.IsNullOrWhiteSpace(model.Command.WorldInfos[0].Keys))
                        {
                            model.Command.WorldInfos = worldInfos.Select(wi => new UpdatePromptCommandWorldInfo
                            {
                                Keys = wi.Keys, Entry = wi.Entry
                            }).ToList();
                        }
                        else
                        {
                            model.Command.WorldInfos.AddRange(worldInfos.Select(wi =>
                                                                                new UpdatePromptCommandWorldInfo {
                                Keys = wi.Keys, Entry = wi.Entry
                            }));
                        }
                    }
                }

                return(View(model));
            }

            if (wiDelete.HasValue)
            {
                ModelState.Clear();
                model.Command.WorldInfos.RemoveAt(wiDelete.Value);
                if (model.Command.WorldInfos.Count < 1)
                {
                    model.Command.WorldInfos.Add(new UpdatePromptCommandWorldInfo());
                }

                return(View(model));
            }

            if (addWi)
            {
                ModelState.Clear();
                model.Command.WorldInfos.Add(new UpdatePromptCommandWorldInfo());
                return(View(model));
            }

            if (model.ScriptZip != null)
            {
                using var stream = new MemoryStream();
                await model.ScriptZip.CopyToAsync(stream, cancellationToken);

                model.Command.ScriptZip = stream.ToArray();

                var validator            = new UpdatePromptCommandValidator();
                ValidationResult?results = await validator.ValidateAsync(model.Command, cancellationToken);

                results.AddToModelState(ModelState, nameof(model.Command));
            }

            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            if (!model.Command.SaveDraft && !addChild && !model.Command.ParentId.HasValue)
            {
                SimilarPromptViewModel?duplicate =
                    await _mediator.Send(new SimilarPromptQuery(model.Command.Title, model.Command.Id),
                                         cancellationToken);

                if (duplicate.Matched && !confirm)
                {
                    model.SimilarPromptQuery = duplicate;
                    return(View(model));
                }
            }

            await _mediator.Send(model.Command, cancellationToken);

            if (addChild)
            {
                return(RedirectToAction("Create", new { parentId = id }));
            }

            if (model.Command.ParentId.HasValue)
            {
                return(RedirectToAction("Edit", new { id = model.Command.ParentId }));
            }

            return(RedirectToAction("View", new { id }));
        }