在《认知觉醒》读书笔记(二)——每日计划和总结里提到过,我为了让手帐中的日程规划能够被自动创建到日历自己写了一个脚本,本篇文章就介绍一下这个脚本的实现。脚本主要面向有一定Python基础(其实只要会执行以及很简单的修改)的MAC用户,由于是个人使用,因此代码功能比较粗糙(其实80%代码是GPT代工👀),大家可以根据需要自行扩展。
代码示例
Talk is cheap, show you my code!
import subprocess
import pandas as pd
import time
import re
import sys
def get_hour_minute(time_str):
parts = re.split("[::]", time_str)
if len(parts) != 2:
raise ValueError("Input string should be in HH:MM format")
hour = int(parts[0])
minute = int(parts[1])
return hour, minute
# 获取当天日期的YYYYMMDD格式
date = time.strftime("%Y%m%d")
print(date)
# 定义AppleScript获得标题和date一致的note
applescript = f"""
tell application "Notes"
body of note "{date}" of folder "Notes"
end tell
"""
# 使用osascript执行AppleScript得到note
result = subprocess.run(
["osascript", "-e", applescript], capture_output=True, text=True
)
# 打印Notes.app中的数据
# print(result.stdout)
if not result.stdout:
print(f"Note of date {date} not found!")
sys.exit(0)
# 使用pandas的read_html函数提取表格数据
tables = pd.read_html(result.stdout)
# read_html函数返回一个DataFrame列表,每个DataFrame对应HTML中的一个表格
# 在这个例子中,我们只有一个表格,所以我们只需要第一个DataFrame
table = tables[0]
new_script = """
set theTitle to "{desc}"
set theStartDate to current date
set hours of theStartDate to {start_hour}
set minutes of theStartDate to {start_minute}
set theEndDate to current date
set hours of theEndDate to {end_hour}
set minutes of theEndDate to {end_minute}
tell application "Calendar"
tell calendar "个人"
make new event at end with properties {{description:theTitle, summary:theTitle, start date:theStartDate, end date:theEndDate}}
end tell
end tell
"""
# print(table)
task_pattern = "[||]"
time_sep = "[-—]"
for item in table.itertuples():
try:
time_range, task_content = re.split(task_pattern, item[1])
except Exception as e:
print(item[1])
print(repr(e))
continue
print(time_range, task_content)
start_time, end_time = re.split(time_sep, time_range)
start_hour, start_minute = get_hour_minute(start_time)
end_hour, end_minute = get_hour_minute(end_time)
print(start_hour, start_minute, end_hour, end_minute)
result = subprocess.run(
[
"osascript",
"-e",
new_script.format(
start_hour=start_hour,
start_minute=start_minute,
end_hour=end_hour,
end_minute=end_minute,
desc=task_content,
),
],
capture_output=True,
text=True,
)
print("stdout", result.stdout)
print("stderr", result.stderr)
这个脚本的执行逻辑如下:
-
先获取当天的日期并且转成YYMMDD的格式(例如20240321)的「date」字符串。这里假设我们每天在「Notes.app」(即MAC自带的备忘录)新建的手帐的标题是此格式的,如果自己有其他格式的偏好可酌情修改
-
根据「date」字符串生成AppleScript执行语句,得到对应的note的文本数据(为html格式)
-
通过python的「DataFrame」库的「read_html」函数获取其中的table(记录了「每日计划」和「实际完成」的表格)
-
逐行读取表格,提取「计划完成」列中的时间段信息和事项描述。例如图中所示,我的记录格式是「start_time:end_time | desc」,那么很容易提取出来事项的开始时间、结束时间、描述文本
-
将每行得到的上述三个信息填充到用于生成日历日程的AppleScript语句模板中,并执行来创建(注意这里还需要指定日历的名字,上面的样例脚本里写死了创建到名为「个人」的日历,大家可以自行调整)
-
上述流程执行结束后,就可以在MAC自带的「日历」中看到基于表格创建的全部当天日程了,个人觉得还是比手动创建要方便很多的。不过我觉得每次都打开terminal来执行python也还是有些麻烦,所以希望把这一步也简化简化(「懒」果然是人类进步之光)。
懒人进阶
MAC用户的话对于「Spotlight」(「聚焦」)的功能应该不陌生,但后来出现了许多诸如Alfred、Raycast的快捷启动应用,作为它的进化版逐步替代了它。它们都具备一个基础功能就是自定义「Script Command」,顾名思义就是脚本命令——将我们自己写好的脚本绑定到一个简洁的命令名称上,直接通过快捷启动来快速执行。
脚本命令的构建非常简单,以我自己使用的Raycast为例,通过新建Script Command,我将上面的脚本的路径绑定到一个命名为「Note2Calendar」的命令上,这样我每次在备忘录中写完当日手帐之后,只需要唤起Raycast,然后搜索到这个命令并回车键执行即可(如下图),而不需要再手动去脚本所在文件夹打开terminal手动执行python xxx.py了。
还没有用过这类应用的朋友强烈建议体验一下,绝对是MAC上提升效率(装X)的利器,后面也打算单独花篇幅介绍下我自己的配置和使用经验。
基于MAC备忘录中的表格自动创建日程的方案就介绍到这里了,根据记录「手帐」的方式和习惯的不同还有很大的DIY空间。不过我们依然不要忘了,「手帐」的核心目的是为了获得「清晰力」,自动创建日程仅仅是节省时间的一个辅助功能,不要将其过度复杂化而喧宾夺主。
欢迎大家关注+转发+点赞👻