150 lines
6.5 KiB
C#
150 lines
6.5 KiB
C#
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:B000010 chapter_id:74 from_chapter_id:74
|
||
//task:ChineseNameExtractorTask book_id:B000010 from_chapter_id:177 to_chapter_id:200
|
||
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)
|
||
{
|
||
if (!bodyDict.ContainsKey("book_id")) return;
|
||
|
||
string bookId = bodyDict["book_id"];
|
||
string chapterId = string.Empty;
|
||
if (bodyDict.ContainsKey("chapter_id"))
|
||
chapterId = bodyDict["chapter_id"];
|
||
|
||
string from_chapter_id = string.Empty;
|
||
if (bodyDict.ContainsKey("from_chapter_id"))
|
||
from_chapter_id = bodyDict["from_chapter_id"];
|
||
|
||
string to_chapter_id = string.Empty;
|
||
if (bodyDict.ContainsKey("to_chapter_id"))
|
||
to_chapter_id = bodyDict["to_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 && (string.IsNullOrEmpty(chapterId) || x.ChapterId == Convert.ToInt32(chapterId)) && (string.IsNullOrEmpty(from_chapter_id) || x.ChapterId >= Convert.ToInt32(from_chapter_id)) && (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_chapter_id))).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)) && (string.IsNullOrEmpty(from_chapter_id) || x.ChapterId >= Convert.ToInt32(from_chapter_id)) && (string.IsNullOrEmpty(to_chapter_id) || x.ChapterId <= Convert.ToInt32(to_chapter_id))).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++;
|
||
try
|
||
{
|
||
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++;
|
||
|
||
repositoryAiChapterPersonEntity.InsertNow(aiChapterPerson);
|
||
cps.Add(aiChapterPerson);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine(ex.Message);
|
||
}
|
||
|
||
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();
|
||
}
|
||
|
||
|
||
}
|
||
}
|