我使用日历和日程安排应用程序 calcurse。这是一款出色的命令行程序。
例如,calcurse -a
您可以显示当天的事件。
我如何将此信息发送到notify-send
,以便在桌面上显示通知?
$ calcurse -a | notify-send
不管用 ...
答案1
关于 Calcurse
像往常一样,恢复到(非常)基本但功能齐全的功能感觉很奇怪,但在某种程度上却令人耳目一新。但我不确定我是否会使用它。
尽管 Calcurse 窗口底部建议了一个选项管道, 和Calcurse 的网站提到“用户可配置的通知系统“我找不到使用它来自动安排通知全部事件。
同时:这样的提醒功能确实是一个有用的补充。下面的脚本可以用作calcurse
显示提醒的插件。希望您觉得它有用。
它使用起来非常简单;只需在后台运行脚本即可。它所做的就是检查当天的事件(每分钟更新两次),并在到期前的任意时间运行通知。
创建提醒需要什么
命令的输出:
calcurse -a
好像:
12/29/15:
* Free today!
- 12:00 -> ..:..
See if this script does its job :)
马上就出现了预定物品以“-”开头,而物品一整天以“*”开头。我们需要做的是创建两组项目(列表):
- 预定的
- 计划外的
对于第一类,我们需要解析出时间,将其转换为可以计算的格式,这样我们就可以在n
到期前几分钟显示提醒。
随后,我们需要“时刻关注时钟”,将(事件的)设定时间与当前时间进行比较。如果两者之间的时间跨度进入设定的警告时间,则只需显示通知。
最后,为了防止重复通知,我们需要将该项目添加到“已完成”列表中。
此外,脚本还会清理“已完成”列表;如果某个项目不再出现在今天的项目中(无论您将其删除还是在会话期间切换了日期),则该项目将被自动删除。
结果
启动时(登录)
到期前的任意时间(本例中为 15 分钟)
剧本
#!/usr/bin/env python3
import subprocess
import time
import sys
warn = int(sys.argv[1])
def get(command):
return subprocess.check_output(command).decode("utf-8")
def convert(t):
# convert set time into a calculate- able time
return [int(n) for n in t.split(":")]
def calc_diff(t_curr, t_event):
# calculate time span
diff_hr = (t_event[0] - t_curr[0])*60
diff_m = t_event[1] - t_curr[1]
return diff_hr + diff_m
def cleanup(done, newlist):
# clean up "done" -lists
for item in done:
if not item in newlist:
done.remove(item)
return done
def show_time(event, s = ""):
# show scheduled event
hrs = str(event[0][0]); mnts = str(event[0][1])
mnts = "0"+mnts if len(mnts) != 2 else mnts
subprocess.call(["notify-send", s, "At "+hrs+":"+mnts+" - "+event[1]])
startups = []; times = []
while True:
currtime = convert(time.strftime("%H:%M"))
events = [l.strip() for l in get(["calcurse", "-a"]).splitlines()][1:]
# arrange event data:
groups = []; sub = []
for l in events:
if l.startswith("* "):
groups.append([l.replace("* ", "")])
elif l.startswith("- "):
sub.append(convert(l.split("->")[0].replace("-", "").strip()))
else:
groups.append(sub+[l])
sub = []
# run notifications
for item in groups:
# on startup:
if not item in startups:
# all- day events
if len(item) == 1:
subprocess.call(["notify-send", "Today - "+item[0]])
# time- specific events
elif len(item) == 2:
show_time(item, "Appointment")
startups.append(item)
# as a reminder:
if all([len(item) == 2, not item in times]):
span = calc_diff(currtime, item[0])
if span <= warn:
show_time(item, "[Reminder]")
times.append(item)
# clean up events
startups = cleanup(startups, groups); times = cleanup(times, groups)
time.sleep(30)
如何使用
- 将脚本复制到一个空文件中,另存为
run_ccursereminders.py
测试运行它,并使用您希望收到警告的时间(到期时间之前,以分钟为单位)作为参数。例如,在约会前 30 分钟运行提醒:
python3 /path/to/run_ccursereminders.py 30
如果一切顺利,请将其添加到启动应用程序:选择 Dash > 启动应用程序 > 添加。添加命令
/bin/bash -c "sleep 30 && python3 /path/to/run_ccursereminders.py 30"
其中 last
30
是预约到期前提醒您的分钟数
答案2
我能够通过命令替换使其工作:
notify-send "calcurse notification header" "$(calcurse -n)"
答案3
我知道这已经过时了,但如果有人仍然感兴趣,以下设置在我的~/.calcurse/conf
文件中对我有用:
notification.command=calcurse --next | xargs -0 notify-send "Appointment"
daemon.enable=yes
notification.warning=300
答案4
我写一个简短的 bash 脚本与 结合使用以cron
获取通知。它还支持以可变间隔通知以及全天事件通知。
这是脚本的当前版本:
#!/bin/bash
#Will send a notification if the next appointment in the next 24 hours occurs within $1 minutes
#Set $1 to be the time (minutes) you want the notification to pop up in advance before the appointment actually happens.
#This script should be executed by cron every minute or something like that thus it cannot run exactly $1 minutes before event.
#So we use $2 to be the time +/- of $1 that it is okay to send the notification.
#Probably set $2 this to the same period between when cron runs this script
notify_within=$1
script_frequency=$2
#if there are no appointments in the next two days, the stop right away
if [ "$(calcurse -a -d 2)" = "" ] ; then
exit 0
fi
if ! [ "$(calcurse -n)" = "" ] ; then #There is an event today with an associated time
hours_remaining=$(calcurse -n | tail -1 | sed 's/ //g' | sed 's/\[//g' | sed 's/\].*//g' | sed 's/:..//g')
minutes_remaining=$(calcurse -n | tail -1 | sed 's/ //g' | sed 's/\[//g' | sed 's/\].*//g' | sed 's/..://g')
time_remaining=$( echo "$hours_remaining * 60 + $minutes_remaining" | bc ) #in minutes. just adding the hours to minutes
#Test whether the next event is within the given time frame
#We need bc (calculator) to do the calculation. Will return "1" if the conditional is true
#0.95 factor because you can get notifications to pop 3 times if cron is running every 1 minute and you use script_frequency=1
notify_boolean=$( echo "$time_remaining <= ($script_frequency*0.95 + $notify_within) && $time_remaining >= ($notify_within - $script_frequency*0.95)" | bc )
if [ "$notify_boolean" = 1 ] ; then
eventname="$(calcurse -n | sed -n 2p | sed 's/^ \[..:..\] //g')"
event_in="$(calcurse -n | sed -n 2p | sed 's/^ \[//g' | sed 's/\].*//g')"
notify-send "Appointment: ${eventname} in ${event_in}"
fbcli -t -1 -E message-new-instant 2>&1 >/dev/null || true #send a request to vibrate and make sound with feedbackd if possible
fi
fi
tomorrow="$(date --date 'next day' +"%Y-%m-%d")"
daily_events="$(calcurse -a -d 2 | tr "\n" "@" | sed "0,/^.*${tomorrow}/ s///" | sed 's/^:@ \* //g' | sed 's/@ \* /, /g' | sed 's/@$//g' )" #Gives list of daily events tomorrow, Hopefully your event doesn't have "@" in it
if ! [ "$daily_events" = "" ] ; then
current_hour="$(date +"%H")"
current_minute="$(date +"%H")"
minutes_today=$(( $current_hour * 60 + $current_minute )) #Minutes that have elapsed today
minutes_left_today=$(( 24*60 - $minutes_today )) #Minutes elapsed at midnight
notify_boolean_2="$(echo "$minutes_left_today <= ($script_frequency*0.95 + $notify_within)" | bc )" #It is $notify_within minutes of midnight!
if [ "$notify_boolean_2" = 1 ] ; then
notify-send "Daily Events: $daily_events"
fbcli -t -1 -E message-new-instant 2>&1 >/dev/null || true #send a request to vibrate and make sound with feedbackd if possible
fi
fi
这是cron
调用它的行:
*/2 * * * * export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id -u)/bus; /path/to/calendar_appointment_notify.sh 30 2
此脚本取决于
- 通知库
- 计算
- 公元前
- 日期
当然,当前版本可以在GitHUB上找到。