EyeStrainReminder/eyestrainreminder/EyeStrainReminder.py

154 lines
3.7 KiB
Python
Raw Normal View History

2019-10-21 00:14:56 +03:00
#!/usr/bin/python3
2019-10-29 11:35:33 +02:00
import argparse
2019-10-23 10:52:39 +03:00
import os
2019-10-29 11:35:33 +02:00
import threading
from time import sleep
import notify2
2019-10-24 16:12:32 +03:00
import pystray
from PIL import Image
2019-10-29 11:35:33 +02:00
from playsound import playsound
2019-10-29 19:25:32 +02:00
from pystray import Menu as menu, MenuItem as item
2019-10-21 00:14:56 +03:00
NAME = 'Eye Strain Reminder'
MESSAGE = 'Friendly reminder to observe the 20-20-20 rule'
2019-10-28 16:16:04 +02:00
MESSAGE_MISSED = 'Missed notification(s), resuming countdown'
2019-10-21 00:14:56 +03:00
TIMEOUT = 20
MILLISECOND = 1000
2019-10-22 13:55:16 +03:00
MINUTE = 60
2019-10-23 10:52:39 +03:00
DIR = os.path.dirname(os.path.abspath(__file__))
2019-10-21 00:14:56 +03:00
2021-01-15 23:20:48 +02:00
icon = mute = disable_notifs = invert_icons = notify_thread = start_sound = end_sound = None
2019-10-24 16:12:32 +03:00
2019-10-28 16:16:04 +02:00
def init():
2019-10-29 09:39:22 +02:00
print("Initializing EyeStrainReminder...")
notify2.init(NAME)
2021-01-15 23:20:48 +02:00
2019-10-29 09:39:22 +02:00
def create_tray_icon():
2019-10-28 16:16:04 +02:00
global icon
2019-10-29 08:52:31 +02:00
image = get_image()
2019-10-28 16:16:04 +02:00
icon = pystray.Icon(NAME, image, NAME, generate_menu_items())
icon.run()
2019-10-29 19:25:32 +02:00
2021-01-15 23:20:48 +02:00
2019-10-29 08:52:31 +02:00
def update_icon():
global icon
image = get_image()
icon.icon = image
2021-01-15 23:20:48 +02:00
2019-10-29 08:52:31 +02:00
def get_image():
theme = [[DIR + "/files/eye_light.png", DIR + "/files/eye_dark.png"],
2021-01-15 23:20:48 +02:00
[DIR + "/files/eye_dark.png", DIR + "/files/eye_light.png"]]
2019-10-29 11:06:36 +02:00
return Image.open(theme[invert_icons][disable_notifs])
2019-10-29 08:52:31 +02:00
2021-01-15 23:20:48 +02:00
def generate_menu_items():
2019-10-24 16:12:32 +03:00
menu_items = []
2019-10-29 08:52:31 +02:00
menu_items.append(item('Mute' if not mute else 'Unmute', toggle_mute))
2021-01-15 23:20:48 +02:00
menu_items.append(item(
'Do Not Disturb' if not disable_notifs else 'Enable Notifications', toggle_notifications))
2019-10-29 19:25:32 +02:00
menu_items.append(menu.SEPARATOR)
menu_items.append(item('Exit', exit))
2019-10-24 16:12:32 +03:00
return menu_items
2021-01-15 23:20:48 +02:00
2019-10-28 16:16:04 +02:00
def toggle_mute():
global mute
2019-10-29 08:52:31 +02:00
mute = not mute
update_menu()
2021-01-15 23:20:48 +02:00
2019-10-29 08:52:31 +02:00
def toggle_notifications():
2019-10-29 11:06:36 +02:00
global disable_notifs
disable_notifs = not disable_notifs
2019-10-28 16:16:04 +02:00
update_menu()
2019-10-29 08:52:31 +02:00
update_icon()
2019-10-28 16:16:04 +02:00
2021-01-15 23:20:48 +02:00
2019-10-29 19:25:32 +02:00
def exit():
global icon
icon.stop()
os._exit(0)
2021-01-15 23:20:48 +02:00
2019-10-28 15:09:55 +02:00
def update_menu():
global icon
icon.menu = generate_menu_items()
icon.update_menu()
2021-01-15 23:20:48 +02:00
2019-10-21 00:14:56 +03:00
def uninit():
notify2.uninit()
2021-01-15 23:20:48 +02:00
2019-10-22 13:55:16 +03:00
def wait():
2019-10-29 11:16:27 +02:00
sleep(TIMEOUT*MINUTE)
2019-10-22 13:55:16 +03:00
2021-01-15 23:20:48 +02:00
2019-10-21 00:14:56 +03:00
def send_notification():
2019-10-29 11:06:36 +02:00
if not disable_notifs:
2019-10-28 16:16:04 +02:00
notify(MESSAGE)
else:
print("Notifications are disabled, waiting for an enable...")
2019-10-29 11:06:36 +02:00
while disable_notifs:
2019-10-28 16:16:04 +02:00
sleep(10)
notify(MESSAGE_MISSED)
2021-01-15 23:20:48 +02:00
2019-10-28 16:16:04 +02:00
def notify(message):
2019-10-29 08:52:31 +02:00
print(message)
2021-01-15 23:20:48 +02:00
notification = notify2.Notification(
NAME, message, "notification-device-eject")
2019-10-21 00:14:56 +03:00
notification.set_timeout(TIMEOUT * MILLISECOND)
notification.set_urgency(notify2.URGENCY_LOW)
notification.show()
2021-01-15 23:20:48 +02:00
play_sound(start_sound)
2019-10-21 00:14:56 +03:00
sleep(TIMEOUT)
notification.close()
2021-01-15 23:20:48 +02:00
play_sound(end_sound)
2019-10-28 16:16:04 +02:00
2021-01-15 23:20:48 +02:00
def play_sound(sound):
2019-10-28 16:16:04 +02:00
if not mute:
2019-10-29 11:06:36 +02:00
playsound(sound)
2019-10-21 00:14:56 +03:00
2021-01-15 23:20:48 +02:00
2019-10-29 10:33:03 +02:00
def parse_args():
parser = argparse.ArgumentParser()
2021-01-15 23:20:48 +02:00
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("-ss", "--start_sound", action="store", default=DIR +
"/files/ptt-s.wav", help="Custom start notification sound")
parser.add_argument("-es", "--end_sound", action="store", default=DIR +
"/files/ptt-e.wav", help="Custom end notification sound")
2019-10-29 10:33:03 +02:00
args = parser.parse_args()
globals().update(args.__dict__)
2021-01-15 23:20:48 +02:00
2019-10-29 11:30:06 +02:00
def notification_loop():
2019-10-21 00:14:56 +03:00
init()
2019-10-22 13:55:16 +03:00
while 1:
wait()
send_notification()
2019-10-22 14:43:20 +03:00
uninit()
2021-01-15 23:20:48 +02:00
2019-10-29 11:30:06 +02:00
def main():
2019-10-29 10:33:03 +02:00
parse_args()
2021-01-15 23:20:48 +02:00
notify_thread = threading.Thread(
target=notification_loop, name="Notify Thread")
2019-10-29 09:39:22 +02:00
notify_thread.start()
create_tray_icon()
2019-10-29 11:30:06 +02:00
notify_thread.join()
2021-01-15 23:20:48 +02:00
2019-10-29 11:30:06 +02:00
if __name__ == '__main__':
2019-10-29 11:35:33 +02:00
main()