CloudBuilder.Topshelf/Task/AI/ChineseNameExtractorTask.cs
owenchen 4ea68c801f ow
2026-06-04 08:17:22 +08:00

135 lines
5.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using CloudBuilder.AI.Entity;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using CloudBuilder.Core.DependencyInjection.Task;
using CloudBuilder.Topshelf.Python;
using CloudBuilder.Topshelf.Utility;
using System.Text.RegularExpressions;
using static System.Net.Mime.MediaTypeNames;
namespace CloudBuilder.Topshelf.Task
{
//task:ChineseNameExtractorTask book_id:B000008 chapter_id:3
public class ChineseNameExtractorTask : IScheduleTask
{
private readonly IApplicationService service;
private List<string> commonSurnames;
public ChineseNameExtractorTask(IApplicationService service)
{
this.service = service;
}
public void Run(Dictionary<string, string> bodyDict)
{
//File.AppendAllText("log.txt", "ChineseNameExtractorTask:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
if (!bodyDict.ContainsKey("book_id")) return;
string bookId = bodyDict["book_id"];
string chapterId = string.Empty;
if (bodyDict.ContainsKey("chapter_id"))
chapterId = bodyDict["chapter_id"];
PythonCommand python = new PythonCommand(service);
try
{
Hanlp2 hanlp = new Hanlp2(python);
commonSurnames = hanlp.GetSurnames();
IRepository<AiSentenceViewEntity> repository = service.GetRepository<IRepository<AiSentenceViewEntity>>();
IRepository<AiSentenceEntity> repositoryAiSentenceEntity = service.GetRepository<IRepository<AiSentenceEntity>>();
IRepository<AiChapterPersonEntity> repositoryAiChapterPersonEntity = service.GetRepository<IRepository<AiChapterPersonEntity>>();
AiChapterPersonEntity[] dels = repositoryAiChapterPersonEntity.DetachedEntities.Where(x => x.BookId == bookId).ToArray();
if (dels != null && dels.Length > 0) repositoryAiChapterPersonEntity.DeleteNow(dels);
string depRoot;
List<NamedEntity> ners;
List<List<MeaningRepresentationParsingEntity>> srls;
List<HanlpConstituencyNode> cons = null;
SpeakerAnalysisHelper speakerAnalysisHelper = new SpeakerAnalysisHelper();
AiSentenceViewEntity[] ents = repository.DetachedEntities.Where(x => x.BookId == bookId && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId))).OrderBy(x => x.ChapterId).ThenBy(x => x.ParagraphId).ThenBy(x => x.SentenceIndex).ToArray();
if (ents == null || ents.Length == 0) return;
AiSentenceEntity aiSentenceEntity;
string person = null;
long paragraphIndex = 0;
int totalLines = ents.Length;
int processedLines = 0; // 已处理行数计数器
AiChapterPersonEntity aiChapterPerson;
List<AiChapterPersonEntity> cps = new List<AiChapterPersonEntity>();
foreach (var ent in ents)
{
processedLines++;
person = speakerAnalysisHelper.GetPerson(hanlp, ent.Content);
paragraphIndex = ent.ParagraphId;
if (!string.IsNullOrEmpty(person))
{
string[] ps = person.Split(',');
int orderIndex = 1;
foreach (var p in ps)
{
if (p.Length == 1) continue;
aiChapterPerson = new AiChapterPersonEntity();
aiChapterPerson.PersonName = KeepChineseCharactersOnly(p);
aiChapterPerson.BookId = ent.BookId;
aiChapterPerson.ChapterId = ent.ChapterId;
aiChapterPerson.ParagraphIndex = ent.ParagraphId;
aiChapterPerson.SentenceIndex = ent.SentenceIndex;
aiChapterPerson.DialogueIndc = ent.DialogueIndc;
aiChapterPerson.OrderIndex = orderIndex++;
cps.Add(aiChapterPerson);
repositoryAiChapterPersonEntity.InsertNow(aiChapterPerson);
}
}
ConsoleOutput.UpdateProgress(processedLines, totalLines);
}
speakerAnalysisHelper.AiChapterPersons = cps.ToArray();
speakerAnalysisHelper.CommonSurnames = commonSurnames;
speakerAnalysisHelper.MatchPerson(ents, repositoryAiSentenceEntity);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("");
python.Dispose();
}
}
private string KeepChineseCharactersOnly(string input)
{
if (string.IsNullOrEmpty(input))
return input;
// 方法1使用正则表达式
//return Regex.Replace(input, @"[^\u4e00-\u9fff]", "");
return Regex.Replace(input, @"[^\u4e00-\u9fff\【\】]", "");
// 方法2手动遍历性能更好
// var sb = new StringBuilder();
// foreach (char c in input)
// {
// if (c >= 0x4e00 && c <= 0x9fff)
// sb.Append(c);
// }
// return sb.ToString();
}
}
}