解析用户命令 支持的命令格式: - "加个必读作者:Mohammed AlQuraishi" - "添加必读作者:张三" - "add must read author: John Doe" - "移除必读作者:张三" - "remove must read author: John Doe" - "查看必读清单" - "show must read" Args: text: 用户输入文本 Returns: 命令字典 {"action": "add/remove/li
(text: str)
| 196 | |
| 197 | |
| 198 | def parse_command(text: str) -> Optional[Dict[str, Any]]: |
| 199 | """ |
| 200 | 解析用户命令 |
| 201 | |
| 202 | 支持的命令格式: |
| 203 | - "加个必读作者:Mohammed AlQuraishi" |
| 204 | - "添加必读作者:张三" |
| 205 | - "add must read author: John Doe" |
| 206 | - "移除必读作者:张三" |
| 207 | - "remove must read author: John Doe" |
| 208 | - "查看必读清单" |
| 209 | - "show must read" |
| 210 | |
| 211 | Args: |
| 212 | text: 用户输入文本 |
| 213 | |
| 214 | Returns: |
| 215 | 命令字典 {"action": "add/remove/list", "type": "author/institution/keyword", "value": "..."} |
| 216 | """ |
| 217 | text = (text or "").strip() |
| 218 | text_lower = text.lower() |
| 219 | |
| 220 | # 查看清单 |
| 221 | if any(kw in text_lower for kw in LIST_COMMAND_HINTS): |
| 222 | return {"action": "list"} |
| 223 | |
| 224 | match = COMMAND_RE.match(text) |
| 225 | if match: |
| 226 | action_text = match.group("action").lower() |
| 227 | item_text = match.group("item_type").lower() |
| 228 | value = clean_must_read_value(match.group("value")) |
| 229 | |
| 230 | for canonical_type, aliases in ITEM_TYPE_ALIASES.items(): |
| 231 | if item_text in {alias.lower() for alias in aliases}: |
| 232 | return { |
| 233 | "action": "add" if action_text in ADD_ACTION_HINTS else "remove", |
| 234 | "type": canonical_type, |
| 235 | "value": value, |
| 236 | } |
| 237 | |
| 238 | is_add = any(kw in text_lower for kw in ADD_ACTION_HINTS) |
| 239 | is_remove = any(kw in text_lower for kw in REMOVE_ACTION_HINTS) |
| 240 | if not (is_add or is_remove): |
| 241 | return None |
| 242 | |
| 243 | item_type = None |
| 244 | matched_alias = None |
| 245 | for canonical_type, aliases in ITEM_TYPE_ALIASES.items(): |
| 246 | for alias in aliases: |
| 247 | alias_lower = alias.lower() |
| 248 | if alias_lower in text_lower: |
| 249 | item_type = canonical_type |
| 250 | matched_alias = alias |
| 251 | break |
| 252 | if item_type: |
| 253 | break |
| 254 | |
| 255 | if not item_type or not matched_alias: |
no test coverage detected