Skip to content

Commit 3d0a7c5

Browse files
authored
Merge pull request #4 from stolenzc/fix/parser
fix: some bugs
2 parents 7484e80 + 7b96079 commit 3d0a7c5

8 files changed

Lines changed: 51 additions & 41 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ reminders add "明天下午3点开会"
4949
"model": "gpt-4-turbo-preview"
5050
},
5151
"default_list": "提醒事项",
52-
"default_reminder_minutes": [15, 30]
52+
"default_reminder_minutes": [0]
5353
}
5454
```
5555

examples/config.example.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55
"model": "gpt-4-turbo-preview"
66
},
77
"default_list": "reminders",
8-
"default_reminder_minutes": [15, 30],
8+
"default_reminder_minutes": [0],
99
"use_ai": true
1010
}

src/apple_reminders.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::cors::{Priority, Recurrence};
22
use crate::reminder::Reminder;
33
use anyhow::{Result, anyhow};
44
use chrono::{DateTime, Datelike, Local, Timelike};
5-
use std::process::Command;
5+
use std::process::{Command, Output};
66

77
/// 苹果提醒事项集成(通过 AppleScript 与 Reminders.app 通信)
88
pub struct AppleReminders;
@@ -29,20 +29,25 @@ impl AppleReminders {
2929

3030
/// 检查列表是否存在
3131
pub fn list_exists(list_name: &str) -> Result<bool> {
32-
let script = format!(
33-
r#"tell application "Reminders"
32+
let script = r#"tell application "Reminders"
3433
set listNames to name of every list
35-
repeat with n in listNames
36-
if n = "{}" then return "yes"
37-
end repeat
38-
return "no"
39-
end tell"#,
40-
escape_string(list_name)
41-
);
42-
43-
let output = Command::new("osascript").arg("-e").arg(&script).output()?;
44-
let stdout = String::from_utf8_lossy(&output.stdout);
45-
Ok(stdout.trim() == "yes")
34+
return listNames
35+
end tell"#;
36+
37+
// 获取全部列表名称, 不使用AppleScript检测
38+
let output: Output = Command::new("osascript").arg("-e").arg(script).output()?;
39+
let list_str = String::from_utf8_lossy(&output.stdout);
40+
let list_vec: Vec<String> = list_str
41+
.replace("\n", ",")
42+
.split(",")
43+
.map(|s| s.to_string())
44+
.collect();
45+
for exist_name in list_vec {
46+
if exist_name == list_name {
47+
return Ok(true);
48+
}
49+
}
50+
Ok(false)
4651
}
4752

4853
/// 创建新列表(如果不存在)

src/cli.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{cors::Recurrence, parser::ParsedReminder};
1+
use crate::{
2+
cors::{Priority, Recurrence},
3+
parser::ParsedReminder,
4+
};
25
use clap::{Arg, Command};
36
use std::io::{self, Write};
47

@@ -166,7 +169,9 @@ pub fn show_parsed_summary(parsed: &ParsedReminder) {
166169
println!(" │ 截止时间: {}", due_date.format("%Y-%m-%d %H:%M"));
167170
}
168171

169-
println!(" │ 优先级: {}", parsed.priority);
172+
if parsed.priority != Priority::None {
173+
println!(" │ 优先级: {}", parsed.priority);
174+
}
170175

171176
if parsed.is_urgent {
172177
println!(" │ 是否紧急: 是");

src/config.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{Result, anyhow};
1+
use anyhow::Result;
22
use serde::{Deserialize, Serialize};
33
use std::fs;
44
use std::path::Path;
@@ -16,37 +16,39 @@ pub struct AIConfig {
1616

1717
/// 应用配置
1818
#[derive(Debug, Clone, Serialize, Deserialize)]
19+
#[serde(default)]
1920
pub struct AppConfig {
2021
/// AI 配置
2122
pub ai: AIConfig,
2223
/// 默认列表
2324
pub default_list: String,
2425
/// 默认提醒时间(分钟)
2526
pub default_reminder_minutes: Vec<i32>,
26-
/// 是否使用 AI 解析(默认 true)
27-
#[serde(default = "default_true")]
27+
/// 是否使用 AI 解析
2828
pub use_ai: bool,
2929
}
3030

31-
fn default_true() -> bool {
32-
true
33-
}
34-
3531
impl Default for AppConfig {
3632
fn default() -> Self {
3733
Self {
38-
ai: AIConfig {
39-
api_url: "https://api.openai.com/v1/chat/completions".to_string(),
40-
api_key: "".to_string(),
41-
model: "gpt-4-turbo-preview".to_string(),
42-
},
34+
ai: AIConfig::default(),
4335
default_list: "提醒事项".to_string(),
44-
default_reminder_minutes: vec![15],
36+
default_reminder_minutes: vec![0],
4537
use_ai: false,
4638
}
4739
}
4840
}
4941

42+
impl Default for AIConfig {
43+
fn default() -> Self {
44+
Self {
45+
api_url: "".to_string(),
46+
api_key: "".to_string(),
47+
model: "".to_string(),
48+
}
49+
}
50+
}
51+
5052
/// 配置管理器
5153
#[derive(Clone)]
5254
pub struct ConfigManager {
@@ -56,9 +58,7 @@ pub struct ConfigManager {
5658
impl ConfigManager {
5759
/// 创建新的配置管理器
5860
pub fn new() -> Result<Self> {
59-
let config_dir = dirs::config_dir()
60-
.ok_or_else(|| anyhow!("无法获取配置目录"))?
61-
.join("reminders");
61+
let config_dir = dirs::home_dir().unwrap().join(".config/reminders");
6262

6363
if !config_dir.exists() {
6464
fs::create_dir_all(&config_dir)?;
@@ -119,7 +119,7 @@ mod tests {
119119
fn test_default_config() {
120120
let config = AppConfig::default();
121121
assert_eq!(config.default_list, "提醒事项");
122-
assert_eq!(config.default_reminder_minutes, vec![15]);
122+
assert_eq!(config.default_reminder_minutes, vec![0]);
123123
assert!(!config.use_ai);
124124
}
125125
}

src/parser/parser_ai.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ impl AIParser {
145145
let current_time = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
146146
let default_list = self.config_manager.get_default_list();
147147

148-
let template = "你是一个智能提醒事项解析器。请将用户输入的自然语言解析为结构化的提醒事项信息。\n\n输入:{input}\n\n请按照以下 JSON 格式返回解析结果:\n\n{{\n \"title\": \"提醒事项标题\",\n \"description\": \"可选描述\",\n \"due_date\": \"截止日期时间,格式:YYYY-MM-DD HH:MM:SS,如果无法确定则为 null\",\n \"start_date\": \"开始日期时间,格式:YYYY-MM-DD HH:MM:SS,可选\",\n \"priority\": \"优先级,可选值:none, low, medium, high\",\n \"is_urgent\": \"是否紧急,布尔值\",\n \"recurrence\": \"重复模式,可选:none, daily, weekly, monthly, yearly, weekdays, weekends\",\n \"location\": {{\n \"name\": \"位置名称\",\n \"address\": \"详细地址,可选\"\n }},\n \"reminder_minutes\": [15, 30],\n \"tags\": [\"标签1\", \"标签2\"],\n \"list\": \"列表名称\"\n}}\n\n注意:\n1. 当前时间:{current_time}\n2. 如果用户没有指定时间,请根据上下文推断合理的时间\n3. 标题应该简洁明了\n4. 优先使用中文标签\n5. 如果用户指定了列表,使用用户指定的列表,否则使用 \"{default_list}\"\n6. 日期时间请使用 24 小时制\n7. 如果无法确定某些字段,请使用合理的默认值\n8. 请确保返回的是有效的 JSON 格式";
148+
let template = "你是一个智能提醒事项解析器。请将用户输入的自然语言解析为结构化的提醒事项信息。\n\n输入:{input}\n\n请按照以下 JSON 格式返回解析结果:\n\n{{\n \"title\": \"提醒事项标题\",\n \"description\": \"可选描述\",\n \"due_date\": \"截止日期时间,格式:YYYY-MM-DD HH:MM:SS,如果无法确定则为 null\",\n \"start_date\": \"开始日期时间,格式:YYYY-MM-DD HH:MM:SS,可选\",\n \"priority\": \"优先级,可选值:none, low, medium, high\",\n \"is_urgent\": \"是否紧急,布尔值\",\n \"recurrence\": \"重复模式,可选:none, daily, weekly, monthly, yearly, weekdays, weekends\",\n \"location\": {{\n \"name\": \"位置名称\",\n \"address\": \"详细地址,可选\"\n }},\n \"reminder_minutes\": [0],\n \"tags\": [\"标签1\", \"标签2\"],\n \"list\": \"列表名称\"\n}}\n\n注意:\n1. 当前时间:{current_time}\n2. 如果用户没有指定时间,请根据上下文推断合理的时间\n3. 标题应该简洁明了\n4. 优先使用中文标签\n5. 如果用户指定了列表,使用用户指定的列表,否则使用 \"{default_list}\"\n6. 日期时间请使用 24 小时制\n7. 如果无法确定某些字段,请使用合理的默认值\n8. 请确保返回的是有效的 JSON 格式";
149149
template
150150
.replace("{input}", input)
151151
.replace("{current_time}", &current_time)

src/parser/parser_regexp.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,11 @@ pub fn parse_input(input: &str, default_list: &str) -> Result<ParsedReminder> {
236236
title: String::new(),
237237
due_date: None,
238238
start_date: None,
239-
priority: Priority::Medium,
239+
priority: Priority::None,
240240
is_urgent: false,
241241
recurrence: Recurrence::None,
242242
location: None,
243-
reminder_minutes: vec![15],
243+
reminder_minutes: vec![0],
244244
tags: Vec::new(),
245245
list: default_list.to_string(),
246246
};
@@ -306,7 +306,7 @@ pub fn parse_input(input: &str, default_list: &str) -> Result<ParsedReminder> {
306306
if let Some(caps) = pattern.captures(&text)
307307
&& let Some(m) = caps.get(1)
308308
{
309-
let value: i32 = m.as_str().parse().unwrap_or(15);
309+
let value: i32 = m.as_str().parse().unwrap_or(0);
310310
let minutes = match *kind {
311311
"hours" => value * 60,
312312
"days" => value * 24 * 60,

src/reminder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl Reminder {
4242
is_urgent: false,
4343
recurrence: Recurrence::None,
4444
location: None,
45-
reminder_minutes: vec![15, 5], // 默认提前15分钟和5分钟提醒
45+
reminder_minutes: vec![0],
4646
tags: Vec::new(),
4747
list,
4848
}
@@ -157,7 +157,7 @@ mod tests {
157157
assert_eq!(reminder.list, "默认列表");
158158
assert_eq!(reminder.priority, Priority::Medium);
159159
assert!(!reminder.is_urgent);
160-
assert_eq!(reminder.reminder_minutes, vec![15, 5]);
160+
assert_eq!(reminder.reminder_minutes, vec![0]);
161161
}
162162

163163
#[test]

0 commit comments

Comments
 (0)