EyeStrainReminder/eyestrainreminder/EyeStrainReminder.py

120 lines
3.3 KiB
Python
Executable File

#!/usr/bin/python3
import notify2
from time import sleep
from playsound import playsound
import os
from pystray import MenuItem as item
import pystray
from PIL import Image
import argparse
import threading
NAME = 'Eye Strain Reminder'
MESSAGE = 'Friendly reminder to observe the 20-20-20 rule'
MESSAGE_MISSED = 'Missed notification(s), resuming countdown'
TIMEOUT = 20
MILLISECOND = 1000
MINUTE = 60
DIR = os.path.dirname(os.path.abspath(__file__))
icon = mute = disable_notifs = invert_icons = notify_thread = sound = None
#mute = False
#disable_notifs = False
#invert_icons = False
#notify_thread = None
def init():
print("Initializing EyeStrainReminder...")
notify2.init(NAME)
def create_tray_icon():
global icon
image = get_image()
icon = pystray.Icon(NAME, image, NAME, generate_menu_items())
icon.run()
def update_icon():
global icon
image = get_image()
icon.icon = image
def get_image():
theme = [[f"{DIR}/files/eye_light.png", f"{DIR}/files/eye_dark.png"],
[f"{DIR}/files/eye_dark.png", f"{DIR}/files/eye_light.png"]]
return Image.open(theme[invert_icons][disable_notifs])
def generate_menu_items():
menu_items = []
menu_items.append(item('Mute' if not mute else 'Unmute', toggle_mute))
menu_items.append(item('Do Not Disturb' if not disable_notifs else 'Enable Notifications', toggle_notifications))
return menu_items
def toggle_mute():
global mute
mute = not mute
update_menu()
def toggle_notifications():
global disable_notifs
disable_notifs = not disable_notifs
update_menu()
update_icon()
def update_menu():
global icon
icon.menu = generate_menu_items()
icon.update_menu()
def uninit():
notify2.uninit()
def wait():
#sleep(TIMEOUT*MINUTE)
pass
def send_notification():
if not disable_notifs:
notify(MESSAGE)
else:
print("Notifications are disabled, waiting for an enable...")
while disable_notifs:
sleep(10)
notify(MESSAGE_MISSED)
def notify(message):
print(message)
notification = notify2.Notification(NAME, message, "notification-device-eject")
notification.set_timeout(TIMEOUT * MILLISECOND)
notification.set_urgency(notify2.URGENCY_LOW)
notification.show()
play_sound()
sleep(TIMEOUT)
notification.close()
play_sound()
def play_sound():
if not mute:
playsound(sound)
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--invert_icons", action="store_true", default=False, help="Default to the dark icon for light themes")
parser.add_argument("-m", "--mute", action="store_true", default=False, help="Mute notification sounds by default")
parser.add_argument("-n", "--disable_notifs", action="store_true", default=False, help="Disable notifications by default")
parser.add_argument("-s", "--sound", action="store", default=f"{DIR}/files/default.wav", help="Custom notification sound")
args = parser.parse_args()
globals().update(args.__dict__)
def main():
init()
while 1:
wait()
send_notification()
uninit()
if __name__ == '__main__':
parse_args()
notify_thread = threading.Thread(target=main, name="Notify Thread")
notify_thread.start()
create_tray_icon()
notify_thread.join()