我编写了一个Python程序来处理使用notify-send向dunst发送通知。我知道有更好的选择,但我想自己做。 这是我的程序,位于 /home/theo/Repos/volumebar-dunst
import os
import json
import time
import sys
global name, standard_ttl, standard_ttl_s
data_path = 'data.json'
name = 'Volume Control'
standard_ttl = 1000
standard_ttl_s = standard_ttl / 1000
def get_timestanp():
return int(round(time.time(), 0))
def get_volume_master():
command = 'awk -F"[][]" \'/Left:/ { print $2 }\' <(amixer sget Master)'
return os.popen(f'{command}').read().strip()
def get_if_muted():
command = "amixer get Master | grep 'Left:' | awk -F'[][]' '{print $4}'"
returnstate = os.popen(command).read().strip()
if returnstate == "off":
return True
else:
return False
def data_exists(data_path):
if not os.path.exists(data_path):
data = {"message" : {"last_called" : get_timestanp(), "last_message_id" : 0, "volume" : get_volume_master()},
"mute" : {"state" : get_if_muted()}}
save_data(data)
def save_data(data):
with open('data.json', 'w') as file:
json.dump(data, file)
def load_data(data_path):
data_exists(data_path)
with open(data_path, 'r') as file:
return json.load(file)
def cli_command(command):
return os.popen(f'{command}').read().strip()
def notify(message="No message provided.", id=0, ttl=standard_ttl):
return_data = os.popen(f'notify-send -t {ttl} -r {id} -p "{name}" "{message}"').read().strip()
print(return_data)
return return_data
def main():
args = sys.argv
data = load_data(data_path)
if len(args) == 1:
notify("Error: No arguments provided. Please provide an argument.")
return
# check if the argument is valid
if not (args[1] == "raise" or args[1] == "lower" or args[1] == "mute"):
notify("Error: Invalid argument provided. Please provide a valid argument.")
return
# do if argument raise
if args[1] == "raise":
cli_command(f'amixer set Master {args[2]}+')
if get_timestanp() - data['message']['last_called'] <= standard_ttl_s:
return_data = notify(f'Volume raised from {data["message"]["volume"]} to {get_volume_master()}', data['message']['last_message_id'])
else:
return_data = notify(f'Volume raised from {data["message"]["volume"]} to {get_volume_master()}')
# update the data
data['message']['volume'] = get_volume_master()
data['message']['last_message_id'] = return_data.strip()
data['message']['last_called'] = get_timestanp()
save_data(data)
# do if argument lower
elif args[1] == "lower":
cli_command(f'amixer set Master {args[2]}-')
if get_timestanp() - data['message']['last_called'] <= standard_ttl_s:
return_data = notify(f'Volume lowered from {data["message"]["volume"]} to {get_volume_master()}', data['message']['last_message_id'])
else:
return_data = notify(f'Volume lowered from {data["message"]["volume"]} to {get_volume_master()}')
# update the data
data['message']['volume'] = get_volume_master()
data['message']['last_message_id'] = return_data.strip()
data['message']['last_called'] = get_timestanp()
save_data(data)
# do if argument mute
elif args[1] == "mute":
if data['mute']['state']:
cli_command('amixer set Master unmute')
if (get_timestanp() - data['message']['last_called'] <= standard_ttl_s):
return_data = notify('Unmuted', data['message']['last_message_id'])
else:
return_data = notify('Unmuted')
# update the data
data['message']['last_message_id'] = return_data.strip()
data['mute']['state'] = False
data['message']['last_called'] = get_timestanp()
save_data(data)
elif not data['mute']['state']:
cli_command('amixer set Master mute')
if (get_timestanp() - data['message']['last_called'] <= standard_ttl_s):
return_data = notify('Muted', data['message']['last_message_id'])
else:
return_data = notify('Muted')
# update the data
data['message']['last_message_id'] = return_data.strip()
data['mute']['state'] = True
data['message']['last_called'] = get_timestanp()
save_data(data)
else:
notify("Error: Something went wrong.")
main()
当我从命令行运行程序时,例如:
/home/theo/Repos/volumebar-dunst/bin/python /home/theo/Repos/volumebar-dunst/main.py raise 10%
会弹出一条通知,说明应该说什么。
但是如果我尝试使用 home/theo/.config/sway/config
中设置的按键绑定来触发它,即:
# sound
# amixer set Master 10%+
bindsym XF86AudioRaiseVolume exec "/home/theo/Repos/volumebar-dunst/bin/python /home/theo/Repos/volumebar-dunst/main.py raise 10%"
# amixer set Master 10%-
bindsym XF86AudioLowerVolume exec "/home/theo/Repos/volumebar-dunst/bin/python /home/theo/Repos/volumebar-dunst/main.py lower 10%"
# amixer set Master mute/unmute
bindsym XF86AudioMute exec "/home/theo/Repos/volumebar-dunst/bin/python /home/theo/Repos/volumebar-dunst/main.py mute"
它只是到达 python 脚本的一部分,其中向 cli 发送命令,例如使用 raise 来提高音量
# do if argument raise
if args[1] == "raise":
cli_command(f'amixer set Master {args[2]}+')
此后似乎出现错误或只是退出程序。但最后的调整仍然进行。 令我不安的是,我和 sway 执行的同一个命令似乎做了不同的事情,我不明白为什么。
为了尝试解决这个问题,我尝试记录 sway 执行的程序的行为,并且它会发送通知,直到执行
cli_command(f'amixer set Master {args[2]}+')
为止。之后程序似乎崩溃了。不幸的是我在网上没有找到任何相关信息。
错误只是,sway 在 /home/theo 中运行命令,并且 data.json 文件保存在 /home/theo/Repos/volumebar-control 中。通过将 swayconfig 中的命令设置为:
bindsym examplekey exec "cd /home/theo/Repos/volumebar-control && bin/python main.py
,脚本将在正确的目录中执行,并找到 data.json 文件。