From 00af6e8528baf11efde02b4b36677b60b6761918 Mon Sep 17 00:00:00 2001 From: lychang Date: Mon, 20 Jul 2026 04:07:40 +0800 Subject: [PATCH] update --- dict/tags.json | 324 ++++++++++++++++++++++++++++++++++++- src/engine/pipeline.rs | 12 +- src/engine/tag_dict.rs | 18 +++ src/engine/title_parser.rs | 5 +- 4 files changed, 354 insertions(+), 5 deletions(-) diff --git a/dict/tags.json b/dict/tags.json index 69148f5..7c44812 100644 --- a/dict/tags.json +++ b/dict/tags.json @@ -346,6 +346,7 @@ "color_bg": "#f0fdfa", "color_fg": "#0f766e", "words": [ + "香格里拉", "苏梅岛", "日本", "韩国", @@ -520,6 +521,9 @@ } }, "stop_words": [ + "写真", + "性感", + "美女", "photos", "photo", "pictures", @@ -688,7 +692,325 @@ "张馨予", "程开心", "赵小米", - "小齿优喵" + "小齿优喵", + "周于希", + "王雨纯", + "绮里嘉", + "唐安琪", + "筱慧", + "冯木木", + "许诺", + "言沫", + "丽莎", + "易阳", + "陈良玲", + "蓝夏", + "凯竹", + "郑颖姗", + "刘飞儿", + "于姬", + "玉兔", + "穆菲菲", + "夏沫沫", + "雪晴", + "熊吖", + "小夕", + "谢芷馨", + "顾奈奈", + "唐琪儿", + "熊小诺", + "黄歆苑", + "艾小青", + "李雅", + "晓茜", + "李宓儿", + "林乐", + "雪千寻", + "艾静香", + "阿薰", + "李承美", + "葛征", + "沈佳熹", + "陈思琪", + "刘娅", + "小瑶", + "张思允", + "李梓", + "宝儿", + "程小烦", + "馬吉", + "叶佳", + "冯雪娇", + "栗子", + "丁筱南", + "小仓", + "小玉", + "何嘉颖", + "皮卡丘", + "小娜", + "李李", + "安妮", + "艾栗栗", + "李雅柔", + "静安", + "利世", + "云溪溪", + "白莉", + "小青茗", + "战姝羽", + "若兮", + "韩恩熙", + "娜露", + "周大萌", + "刘艾琳", + "王婉悠", + "李猩", + "西儿", + "木之本", + "瓜希", + "嘉嘉", + "阳光", + "琳琳", + "娜比", + "梁莹", + "李雪婷", + "栗栗栗", + "斯朵拉", + "吴雪瑶", + "小欣奈", + "鹿初", + "阿依", + "努尔", + "瓦娅", + "白茹雪", + "顾乔楠", + "玄子", + "艾莉", + "绮梦", + "陈宇曦", + "王乔恩", + "雪峰", + "夏瑶", + "秋和柯", + "莫子", + "六味帝皇酱", + "娜娜", + "白领", + "桂林", + "周井空", + "伊莉娜", + "李妍", + "思淇", + "杨漫妮", + "陈雅漫", + "梓诺", + "秋雨", + "芊芊", + "伊小七", + "赵芸", + "蔡文钰", + "张静燕", + "白露", + "欧派", + "小沫琳", + "菲菲", + "徐妍馨", + "安琪", + "文芮", + "珊珊", + "延智恩", + "苏梅", + "苏雨", + "唐雨辰", + "乔漫妮", + "陈天扬", + "周思乔", + "允儿", + "香艳", + "程彤", + "卓芷伊", + "苏可", + "王雨", + "周妍", + "楊衣", + "封疆", + "阿雪雪", + "小九", + "朴正允", + "朱若慕", + "施忆佳", + "陈欣", + "大晗", + "夏诗雯", + "白衬衣", + "子纯儿", + "容颜", + "陈嘉嘉", + "艾小", + "奥莉", + "艾比", + "张优", + "赵伊", + "谭小灵", + "若姬子", + "乔依琳", + "慕羽茜", + "王语纯", + "吉普", + "白兔", + "陈一涵", + "瑞莎", + "闫盼盼", + "赵惟依", + "杨柳", + "小猫咪", + "孙允珠", + "张齐郡", + "唐思琪", + "朱赢", + "小潘鼠", + "顾灿", + "费若拉", + "白一晗", + "李薇薇", + "张雅筑", + "雪瑞", + "高开", + "白桃", + "陈舒羽", + "周熙", + "黄可", + "小琳", + "梦小楠", + "紫藤", + "余馨妍", + "米妮", + "西希", + "之恋", + "乐儿", + "石心琪", + "余心曼", + "蓝白", + "夏西", + "卿卿", + "小秘书", + "黑与白", + "杨晓", + "李玲", + "刘美辰", + "薄荷叶", + "乔雪", + "孔雀", + "唐婉儿", + "徐珍儿", + "何梦兮", + "瑞宝儿", + "夏诗诗", + "韩子", + "夏倪", + "谢小蒽", + "白銀", + "莱可", + "星萌", + "森森", + "白烨", + "熊仔", + "鹿野", + "艾西", + "内衣秀", + "林静瑶", + "崔灿", + "李师师", + "宋黛", + "花桃桃", + "谭晓彤", + "沈善熙", + "陳雅漫", + "红顾灿", + "心妍", + "温心怡", + "张美荧", + "李夫人", + "李筱乔", + "宝宝", + "王紫琳", + "贾诗晗", + "王梓", + "岑雨桥", + "于大乔", + "小雅", + "朴秀妍", + "楚恬", + "林煊煊", + "水嫩", + "古韵", + "苏小曼", + "于思琪", + "邓雪", + "智秀", + "大萌萌", + "林佳沫", + "小奈樱", + "阮阮", + "南歌", + "林幼", + "晓晓可", + "小琪", + "轩萧", + "小七", + "夏树", + "雪琪", + "筱田甜", + "曲奇", + "黄婧", + "陈雨涵", + "韩秀冉", + "王曼妮", + "丛林", + "小熊猫", + "韩好甜", + "曾水", + "王慧慧", + "孔雀蓝", + "雨纯", + "周小然", + "宛恩", + "陈宝拉", + "毛绒", + "李小星", + "高尔夫", + "小雨", + "木木", + "夏希子", + "童千艺", + "小可爱", + "琳娜", + "小萝莉", + "戴小唯", + "墨绿", + "白领丽人", + "程慧", + "刘艺蕾", + "巨无霸", + "安吉", + "浅紫色", + "唐心", + "吕婉柔", + "柴婉艺", + "金允乔", + "荣耀", + "李秀彬", + "迈阿密", + "赵智妍", + "花娇", + "廖挺", + "姜贞语", + "趙芸", + "夏可馨", + "雷丝", + "陈圆圆", + "赵梦洁", + "斯戴媛" ] } } \ No newline at end of file diff --git a/src/engine/pipeline.rs b/src/engine/pipeline.rs index f1dc621..963369b 100644 --- a/src/engine/pipeline.rs +++ b/src/engine/pipeline.rs @@ -357,8 +357,14 @@ pub async fn phase_parse_dirty(db: &Database, dirty_set: &DirtySet) -> (usize, u let mut pending_tx: Option> = None; if let Some(name) = &best_person { - let (primary, aliases) = title_parser::split_person_name_with_aliases(name); - let final_name = if primary.is_empty() { name.clone() } else { primary }; + // 尝试用 include 列表扩展为更长的完整匹配(如 "杨晨晨" → "杨晨晨Yome") + let expanded = tag_dict::get_tag_dict() + .find_longest_included_match(name) + .filter(|longer| longer.len() > name.len()); // 仅当更长时替换 + let effective_name = expanded.as_deref().unwrap_or(name.as_str()); + + let (primary, aliases) = title_parser::split_person_name_with_aliases(effective_name); + let final_name = if primary.is_empty() { effective_name.to_string() } else { primary }; // 跳过字符串 <= 2 的人名(太短不像人名) if final_name.chars().count() <= 2 { @@ -366,7 +372,7 @@ pub async fn phase_parse_dirty(db: &Database, dirty_set: &DirtySet) -> (usize, u } let mut tx = db.pool.begin().await.expect("begin tx"); - db.update_album_person_with_tx(&mut tx, &album.id, name, &final_name).await; + db.update_album_person_with_tx(&mut tx, &album.id, effective_name, &final_name).await; let pid = db.insert_person_with_tx(&mut tx, &final_name, None).await; // 先清旧关联:删除该相册的所有旧 person_album 记录 db.delete_album_person_albums_with_tx(&mut tx, &album.id).await; diff --git a/src/engine/tag_dict.rs b/src/engine/tag_dict.rs index eeb723a..44bd3f6 100644 --- a/src/engine/tag_dict.rs +++ b/src/engine/tag_dict.rs @@ -275,6 +275,24 @@ impl TagDict { || self.included_person_names.contains(&name_lower) } + /// 在 include 列表中查找以 name 开头的最长匹配。 + /// + /// 例如 include 中有 "杨晨晨Yome", "杨晨晨Sugar", + /// 传入 "杨晨晨" 会返回 "杨晨晨Yome"(取最长的那条)。 + /// 传入 "Yome" 也返回 "杨晨晨Yome"(取包含该词的最长的那条)。 + pub fn find_longest_included_match(&self, name: &str) -> Option { + let name_lower = name.to_lowercase(); + self.included_person_names.iter() + .filter(|included| { + let inc_lower = included.to_lowercase(); + // include 以 name 开头 ? 或 name 以 include 开头 ? + inc_lower.starts_with(&name_lower) || name_lower.starts_with(&inc_lower) + || inc_lower.contains(&name_lower) // include 包含 name(中文核心→全名) + }) + .max_by_key(|s| s.len()) + .cloned() + } + /// 获取强制包含人名集合 pub fn get_included_persons(&self) -> &HashSet { &self.included_person_names diff --git a/src/engine/title_parser.rs b/src/engine/title_parser.rs index aac0b37..04dbd38 100644 --- a/src/engine/title_parser.rs +++ b/src/engine/title_parser.rs @@ -291,8 +291,11 @@ pub fn is_likely_person_name(name: &str) -> bool { if name.is_empty() { return false; } // 强制包含名单优先放行(已知模特名,跳过所有启发式检查) + // 同时支持通过更长匹配扩展 name(如 "杨晨晨" → "杨晨晨Yome") let dict = tag_dict::get_tag_dict(); - if dict.is_included_person(name) { return true; } + if dict.is_included_person(name) || dict.find_longest_included_match(name).is_some() { + return true; + } // 字符数必须 >= 3(人名至少需要 2 个中文字或 3 个英文字母) if name.chars().count() <= 2 { return false; }