From 92440d10686241f9b69d88d7ab520e7a0837cdc4 Mon Sep 17 00:00:00 2001 From: Wojciech Ceret Date: Tue, 30 May 2017 13:33:08 +0200 Subject: [PATCH 01/40] Update Polish translation - next break time in system tray --- safeeyes/config/lang/pl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/config/lang/pl.json b/safeeyes/config/lang/pl.json index 0667dcb..916eee2 100644 --- a/safeeyes/config/lang/pl.json +++ b/safeeyes/config/lang/pl.json @@ -47,7 +47,7 @@ "save": "Zapisz", "settings": "Ustawienia", "short_break_duration": "Czas trwania krótkiej przerwy (w sekundach)", - "show_time_in_tray": "Show the next break time in system tray", + "show_time_in_tray": "Pokaż czas następnej przerwy w zasobniku systemowym", "skip": "Pomiń", "strict_break": "Bezwzględna przerwa (ukryj przycisk pominięcia)", "system_language": "Język systemu", From 758600835fea5bca486436ee6527f3ba239b3aff Mon Sep 17 00:00:00 2001 From: Robert Orzanna Date: Wed, 31 May 2017 06:46:25 +0200 Subject: [PATCH 02/40] Update DE for next break time in system tray --- safeeyes/config/lang/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/config/lang/de.json b/safeeyes/config/lang/de.json index c79f60b..fc83936 100644 --- a/safeeyes/config/lang/de.json +++ b/safeeyes/config/lang/de.json @@ -47,7 +47,7 @@ "save": "Speichern", "settings": "Einstellungen", "short_break_duration": "Kleine-Pause-Intervall (in Sekunden)", - "show_time_in_tray": "Show the next break time in system tray", + "show_time_in_tray": "Zeige Zeit für nächste Pause im Bereich der Systemnotifikationen", "skip": "Überspringen", "strict_break": "Strikte Pause (Überspringen nicht möglich)", "system_language": "Systemsprache", From e2b278750e9dcce2eeaabec161fa2b4a0eb57fcf Mon Sep 17 00:00:00 2001 From: radek-sprta Date: Fri, 2 Jun 2017 16:06:29 +0200 Subject: [PATCH 03/40] Update Czech translation --- safeeyes/config/lang/cs.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/safeeyes/config/lang/cs.json b/safeeyes/config/lang/cs.json index c38d266..df582fb 100644 --- a/safeeyes/config/lang/cs.json +++ b/safeeyes/config/lang/cs.json @@ -4,7 +4,7 @@ "language_name_en": "Czech" }, "app_info": { - "description": "Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you to take breaks while you're working long hours at the computer." + "description": "Safe Eyes vám připomíná dělat si přestávky, když trávíte dlouhé hodiny počítače a tak chrání vaše oči před únavou (asthenopií)." }, "exercises": { "short_break_close_eyes": "Zavřete oči", @@ -25,7 +25,7 @@ }, "ui_controls": { "about": "O aplikaci", - "allow_postpone": "Allow postponing the breaks", + "allow_postpone": "Povolit odložení přestávky", "audible_alert": "Zvukové upozornění na konec přestávky", "cancel": "Zrušit", "close": "Close", @@ -38,7 +38,7 @@ "idle_time": "Pozastavit při nečinnosti delší než (minut)", "interval_between_two_breaks": "Interval mezi dvěma přestávkami", "language": "Jazyk", - "license": "License", + "license": "Licence", "long_break_duration": "Trvání dlouhé přestávky (v sekundách)", "no_of_short_breaks_between_two_long_breaks": "Počet krátkých přestávek mezi dvěma dlouhými", "postpone": "Odložit", @@ -47,7 +47,7 @@ "save": "Uložit", "settings": "Nastavení", "short_break_duration": "Trvání krátké přestávky (v sekundách)", - "show_time_in_tray": "Show the next break time in system tray", + "show_time_in_tray": "Zobrazit čas příští přestávky v systémové oblasti", "skip": "Přeskočit", "strict_break": "Povinná přestávka (skrýt tlačítko pro přeskočení)", "system_language": "Systémový jazyk", From b8f3ed2fc14d483a50084a34cbaaafc65a6067a0 Mon Sep 17 00:00:00 2001 From: radek-sprta Date: Fri, 2 Jun 2017 16:29:31 +0200 Subject: [PATCH 04/40] Update cs.json --- safeeyes/config/lang/cs.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/safeeyes/config/lang/cs.json b/safeeyes/config/lang/cs.json index df582fb..c5b1c86 100644 --- a/safeeyes/config/lang/cs.json +++ b/safeeyes/config/lang/cs.json @@ -4,7 +4,7 @@ "language_name_en": "Czech" }, "app_info": { - "description": "Safe Eyes vám připomíná dělat si přestávky, když trávíte dlouhé hodiny počítače a tak chrání vaše oči před únavou (asthenopií)." + "description": "Safe Eyes vám připomíná dělat si přestávky, když trávíte dlouhé hodiny u počítače a tak chrání vaše oči před únavou (asthenopií)." }, "exercises": { "short_break_close_eyes": "Zavřete oči", @@ -50,7 +50,7 @@ "show_time_in_tray": "Zobrazit čas příští přestávky v systémové oblasti", "skip": "Přeskočit", "strict_break": "Povinná přestávka (skrýt tlačítko pro přeskočení)", - "system_language": "Systémový jazyk", + "system_language": "Jazyk systému", "time_to_prepare_for_break": "Čas k přípravě na přestávku (v sekundách)", "time_to_screen_lock": "O kolik nejvýše přeskočit, obcházející zámek obrazovky (v sekundách)", "until_restart": "Do restartu" From f8d703799459caa9eee0465a1eaf5d4d21766a81 Mon Sep 17 00:00:00 2001 From: radek-sprta Date: Fri, 2 Jun 2017 16:30:48 +0200 Subject: [PATCH 05/40] Update Slovak translation --- safeeyes/config/lang/sk.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/safeeyes/config/lang/sk.json b/safeeyes/config/lang/sk.json index 2304027..287da7c 100644 --- a/safeeyes/config/lang/sk.json +++ b/safeeyes/config/lang/sk.json @@ -4,7 +4,7 @@ "language_name_en": "Slovak" }, "app_info": { - "description": "Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you to take breaks while you're working long hours at the computer." + "description": "Safe Eyes vám pripomína robiť si prestávky, keď trávite dlhé hodiny u počítača a tak chráni vaše oči pred přílišným namáhaním (asthenopií).." }, "exercises": { "short_break_close_eyes": "Pevne zavri oči", @@ -25,34 +25,34 @@ }, "ui_controls": { "about": "Ohľadom", - "allow_postpone": "Allow postponing the breaks", + "allow_postpone": "Povoliť odkladanie prestávok", "audible_alert": "Zvukový signál na konci prestávky", "cancel": "Zrušiť", "close": "Close", "disable": "Zakázať Safe Eyes", "enable": "Povoliť Safe Eyes", - "enable_screen_lock": "Lock the screen after every long break", + "enable_screen_lock": "Zablokovať obrazovku po každej dlhej prestávke", "for_x_hour": "Počas {} hodiny", "for_x_hours": "Počas {} hodín", "for_x_minutes": "Počas {} minút", "idle_time": "Pozastaviť pri nečinnosti dlhšej ako (v minútach)", "interval_between_two_breaks": "Interval medzi dvomi prestávkami", "language": "Jazyk", - "license": "License", + "license": "Licencie", "long_break_duration": "Trvanie dlhej prestávky (v sekundách)", "no_of_short_breaks_between_two_long_breaks": "Počet krátkych prestávok medzi dvomi dlhými prestávkami", - "postpone": "Postpone", - "postpone_duration": "Postpone duration (in minutes)", + "postpone": "Odložiť", + "postpone_duration": "O koĺko odložiť (minút)", "quit": "Koniec", "save": "Uložiť", "settings": "Nastavenia", "short_break_duration": "Trvanie krátkej prestávky (v sekundách)", - "show_time_in_tray": "Show the next break time in system tray", + "show_time_in_tray": "Zobrazit čas následujúcej prestávky v system tray", "skip": "Preskočiť", "strict_break": "Povinná prestávka (Skryje tlačitko Preskočiť)", - "system_language": "System Language", + "system_language": "Jazyk systému", "time_to_prepare_for_break": "Čas na prípravu na prestávku (v sekundách)", - "time_to_screen_lock": "Maximum time to skip, bypassing the lock screen (in seconds)", + "time_to_screen_lock": "O koľko sekúnd najviac preskočiť (obchádza zámok obrazovky)", "until_restart": "Do reštartu" } } From a5370f3711dcb7645c78879880273162088a8e10 Mon Sep 17 00:00:00 2001 From: radek-sprta Date: Fri, 2 Jun 2017 16:31:34 +0200 Subject: [PATCH 06/40] Update cs.json --- safeeyes/config/lang/cs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/config/lang/cs.json b/safeeyes/config/lang/cs.json index c5b1c86..ea20c3e 100644 --- a/safeeyes/config/lang/cs.json +++ b/safeeyes/config/lang/cs.json @@ -52,7 +52,7 @@ "strict_break": "Povinná přestávka (skrýt tlačítko pro přeskočení)", "system_language": "Jazyk systému", "time_to_prepare_for_break": "Čas k přípravě na přestávku (v sekundách)", - "time_to_screen_lock": "O kolik nejvýše přeskočit, obcházející zámek obrazovky (v sekundách)", + "time_to_screen_lock": "O kolik sekund nejvýše přeskočit (obejde zámek obrazovky)", "until_restart": "Do restartu" } } From 297922536e52be0eaae20a86856cfd81d128f36b Mon Sep 17 00:00:00 2001 From: David Aguilera Date: Mon, 19 Jun 2017 13:14:32 +0200 Subject: [PATCH 07/40] Added Catalan translation --- safeeyes/config/lang/ca.json | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 safeeyes/config/lang/ca.json diff --git a/safeeyes/config/lang/ca.json b/safeeyes/config/lang/ca.json new file mode 100644 index 0000000..eba795c --- /dev/null +++ b/safeeyes/config/lang/ca.json @@ -0,0 +1,58 @@ +{ + "meta_info": { + "language_name": "Català", + "language_name_en": "Catalan" + }, + "app_info": { + "description": "Safe Eyes protegeix els vostres ulls de la fatiga visual (astenopia) recordant-vos que feu petits descansos mentre esteu treballant amb l'ordinador." + }, + "exercises": { + "short_break_close_eyes": "Tanqueu fortament els ulls", + "short_break_roll_eyes": "Moveu els ulls a banda i banda", + "short_break_rotate_clockwise": "Gireu els ulls en sentit horari", + "short_break_rotate_counter_clockwise": "Gireu els ulls en sentit antihorari", + "short_break_blink": "Parpallegeu", + "short_break_focus_far_distance": "Fixeu la mirada en un punt llunyà", + "short_break_drink_water": "Bebeu una mica d'aigua", + "long_break_walk": "Camineu una estona", + "long_break_lean_back": "Reclineu-vos sobre la cadira i relaxeu-vos" + }, + "messages": { + "ready_for_a_break": "Prepareu-vos per a una pausa en {} segons", + "disabled_until_restart": "Inhabilita fins que es reinicïi", + "disabled_until_x": "Inhabilitat fins {}", + "next_break_at": "Propera pausa a les {}" + }, + "ui_controls": { + "about": "Quant a", + "allow_postpone": "Permet posposar les pauses", + "audible_alert": "Alerta sonora en finalitzar una pausa", + "cancel": "Canceŀla", + "close": "Tanca", + "disable": "Desactiva Safe Eyes", + "enable": "Activa Safe Eyes", + "enable_screen_lock": "Bloca la pantalla després de cada pausa llarga", + "for_x_hour": "Durant {} hora", + "for_x_hours": "Durant {} hores", + "for_x_minutes": "Durant {} minuts", + "idle_time": "Temps mínim inactiu per a pausar (en minuts)", + "interval_between_two_breaks": "Interval entre dues pauses (en minuts)", + "language": "Llengua", + "license": "Llicència", + "long_break_duration": "Durada d'una pausa llarga (en segons)", + "no_of_short_breaks_between_two_long_breaks": "Nombre de pauses breus entre dues pauses llargues", + "postpone": "Posposa", + "postpone_duration": "Durada d'una posposició (en minuts)", + "quit": "Tanca", + "save": "Desa", + "settings": "Configuració", + "short_break_duration": "Durada d'una pausa breu (en segons)", + "show_time_in_tray": "Mostra l'hora de la propera pausa a l'àrea de notificacions", + "skip": "Omet", + "strict_break": "Pausa estrica (sense botó per ometre-la)", + "system_language": "Idioma del sistema", + "time_to_prepare_for_break": "Temps per preparar-se per a una pausa (en segons)", + "time_to_screen_lock": "Temps màxim per saltar-se una pausa, evitant la pantalla de bloqueig (en segons)", + "until_restart": "Fins que es reinicïi" + } +} From 5a515d99d4ed1f1ab85e64209c9dc0f7a2c99e5b Mon Sep 17 00:00:00 2001 From: misaghlb Date: Mon, 19 Jun 2017 17:15:13 +0430 Subject: [PATCH 08/40] add persian translation --- share/applications/safeeyes.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/share/applications/safeeyes.desktop b/share/applications/safeeyes.desktop index aea6423..df40aca 100755 --- a/share/applications/safeeyes.desktop +++ b/share/applications/safeeyes.desktop @@ -15,6 +15,7 @@ Comment[ru]=Защитите свои глаза от зрительного п Comment[pl]=Chroń oczy przed zmęczeniem Comment[mk]=Заштитете се од замор на очите Comment[vi]=Bảo vệ đôi mắt của bạn khỏi sự mệt mỏi +Comment[fa]=محافظت چشم هااز ضعیف شدن Exec=env GDK_BACKEND=x11 safeeyes Icon=safeeyes Terminal=false From 2b69dfef7280a886ca92cc2aed57daa8e451f192 Mon Sep 17 00:00:00 2001 From: misaghlb Date: Mon, 19 Jun 2017 17:18:44 +0430 Subject: [PATCH 09/40] add persian translation --- safeeyes/config/lang/fa.json | 58 ++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 safeeyes/config/lang/fa.json diff --git a/safeeyes/config/lang/fa.json b/safeeyes/config/lang/fa.json new file mode 100644 index 0000000..3da2f4c --- /dev/null +++ b/safeeyes/config/lang/fa.json @@ -0,0 +1,58 @@ +{ + "meta_info": { + "language_name": "فارسی", + "language_name_en": "Persian" + }, + "app_info": { + "description": "Safe Eyes .با یاد آوری شما برای استراحت کردن، وقتی ساعت های طولانی را در پشت کامپیوتر سپری میکنید. از تضعیف چشم های شما جلوگیری میکند " + }, + "exercises": { + "short_break_close_eyes": "چشم هایتان را محکم ببندید", + "short_break_roll_eyes": "چشم هایتان را چندین مرتبه به طرفین بچرخانید", + "short_break_rotate_clockwise": "چشم هایتان را در جهت عقربه های ساعت بچرخانید", + "short_break_rotate_counter_clockwise": "چشم هایتان را در خلاف جهت عقربه های ساعت بچرخانید", + "short_break_blink": "پلک بزنید", + "short_break_focus_far_distance": "روی یک نقطه در دور دست تمرکز کنید", + "short_break_drink_water": "مقداری آب بنوشید", + "long_break_walk": "مدتی قدم بزنید", + "long_break_lean_back": "به صندلی تکیه داده و راحت باشید" + }, + "messages": { + "ready_for_a_break": "آماده استراحت در {} ثانیه بعد باشید", + "disabled_until_restart": "غیرفعال تا بارگذاری مجدد", + "disabled_until_x": "غیرفعال تا {}", + "next_break_at": "استراحت بعد در {}" + }, + "ui_controls": { + "about": "درباره", + "allow_postpone": "اجازه به تعویق انداختن استراحت", + "audible_alert": "هشدار همراه با صدا در پایان استراحت", + "cancel": "لغو", + "close": "بستن", + "disable": "غیر فعال کردن Safe Eyes", + "enable": "فعال کردن Safe Eyes", + "enable_screen_lock": "قفل کردن صفحه بعد از هر استراحت طولانی", + "for_x_hour": "برای {} ساعت", + "for_x_hours": "برای {} ساعت", + "for_x_minutes": "برای {} دقیقه", + "idle_time": "حداقل زمان بیکاری برای توقف کردن برنامه (‌به دقیقه)", + "interval_between_two_breaks": "فاصله بین دو استراحت (به ثانیه‌)", + "language": "زبان", + "license": "لایسنس", + "long_break_duration": "زمان استراحت بلند مدت (به دقیقه)", + "no_of_short_breaks_between_two_long_breaks": "تعداد استراحت های کوتاه بین هر دو استراحت بلند", + "postpone": "به تعویق انداختن", + "postpone_duration": "زمان به تعویق انداختن (به دقیقه)", + "quit": "خروج", + "save": "ذخیره", + "settings": "تنظیمات", + "short_break_duration": "مدت زمان استراحت کوتاه", + "show_time_in_tray": "نشان دادن زمان استراحت بعدی در بخش Tray", + "skip": "رد کردن", + "strict_break": "استراحت سخت گیرانه (پنهان کردن دکمه رد کردن استراحت)", + "system_language": "زبان سیستم", + "time_to_prepare_for_break": "زمان آماده شدن برای استراحت (به ثانیه)", + "time_to_screen_lock": "حداکثر زمان برای رد کردن، جلوگیری از قفل شدن صفحه (به ثانیه‌)", + "until_restart": "تا زمان بارگذاری مجدد" + } +} From 59f25dcd90ec6497afa93a69f336fe1c4030ffb0 Mon Sep 17 00:00:00 2001 From: David Aguilera Date: Mon, 19 Jun 2017 14:54:12 +0200 Subject: [PATCH 10/40] Translated DESKTOP file to Catalan --- share/applications/safeeyes.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/share/applications/safeeyes.desktop b/share/applications/safeeyes.desktop index aea6423..3109fc0 100755 --- a/share/applications/safeeyes.desktop +++ b/share/applications/safeeyes.desktop @@ -1,6 +1,7 @@ [Desktop Entry] Name=Safe Eyes Comment=Protect your eyes from eye strain +Comment[ca]=Protegiu-vos els ulls de la fatiga visual Comment[ge]=დაიცავით თქვენი თვალები დაღლილობისაგან Comment[de]=Schützt die Augen vor Überanstrengung Comment[cs]=Chraňte své oči před únavou From 1943c385d16e0804ab31ba5c0d59b0f3b900a57e Mon Sep 17 00:00:00 2001 From: Gobinath Date: Mon, 19 Jun 2017 11:23:28 -0400 Subject: [PATCH 11/40] Fix flickering screen in KDE --- safeeyes/BreakScreen.py | 6 +++++- safeeyes/Utility.py | 24 ++++++++++++++++++++++++ safeeyes/__main__.py | 3 ++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index 6e39cd3..f6c82c9 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -31,7 +31,8 @@ class BreakScreen: """ Read the break_screen.glade and build the user interface. """ - def __init__(self, on_skip, on_postpone, glade_file, style_sheet_path): + def __init__(self, context, on_skip, on_postpone, glade_file, style_sheet_path): + self.context = context self.on_skip = on_skip self.on_postpone = on_postpone self.is_pretified = False @@ -170,6 +171,9 @@ class BreakScreen: # Set visual to apply css theme. It should be called before show method. window.set_visual(window.get_screen().get_rgba_visual()) + if self.context['desktop'] == 'kde': + # Fix flickering screen in KDE by setting opacity to 1 + window.set_opacity(1) window.move(x, y) window.stick() diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index 159031a..517c92b 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -249,6 +249,30 @@ def read_lang_files(): return languages + +def desktop_environment(): + """ + Detect the desktop environment. + """ + desktop_session = os.environ.get('DESKTOP_SESSION') + current_desktop = os.environ.get('XDG_CURRENT_DESKTOP') + if desktop_session is not None: + desktop_session = desktop_session.lower() + if desktop_session in ['gnome','unity', 'budgie-desktop', 'cinnamon', 'mate', 'xfce4', 'lxde', 'pantheon', 'fluxbox', 'blackbox', 'openbox', 'icewm', 'jwm', 'afterstep','trinity', 'kde']: + return desktop_session + elif (desktop_session.startswith('xubuntu') or (current_desktop is not None and 'xfce' in current_desktop)): + return 'xfce' + elif desktop_session.startswith('ubuntu'): + return 'unity' + elif desktop_session.startswith('lubuntu'): + return 'lxde' + elif 'plasma' in desktop_session or desktop_session.startswith('kubuntu') or os.environ.get('KDE_FULL_SESSION') == 'true': + return 'kde' + elif os.environ.get('GNOME_DESKTOP_SESSION_ID'): + return 'gnome' + return 'unknown' + + def lock_screen_command(): """ Function tries to detect the screensaver command based on the current envinroment diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index 30dd98a..f3818c3 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -256,9 +256,10 @@ def main(): # Initialize the Safe Eyes Context context['version'] = SAFE_EYES_VERSION + context['desktop'] = Utility.desktop_environment() tray_icon = TrayIcon(config, language, show_settings, show_about, enable_safeeyes, disable_safeeyes, on_quit) - break_screen = BreakScreen(on_skipped, on_postponed, break_screen_glade, Utility.style_sheet_path) + break_screen = BreakScreen(context, on_skipped, on_postponed, break_screen_glade, Utility.style_sheet_path) break_screen.initialize(config, language) notification = Notification(language) plugins = Plugins(config) From a8aab4e680e2546333cdb456c24917f679db65b2 Mon Sep 17 00:00:00 2001 From: misaghlb Date: Mon, 19 Jun 2017 22:04:15 +0430 Subject: [PATCH 12/40] fix kde flickering --- safeeyes/BreakScreen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index f6c82c9..a12146e 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -173,7 +173,7 @@ class BreakScreen: window.set_visual(window.get_screen().get_rgba_visual()) if self.context['desktop'] == 'kde': # Fix flickering screen in KDE by setting opacity to 1 - window.set_opacity(1) + window.set_opacity(0.9) window.move(x, y) window.stick() From b1b0bb378dc4ea9b944a2ad12abb3f5676a41a3d Mon Sep 17 00:00:00 2001 From: taras_kapushchak Date: Wed, 21 Jun 2017 13:45:23 +0300 Subject: [PATCH 13/40] Translated to Ukrainian --- safeeyes/config/lang/uk.json | 58 +++++++++++++++++++++++++++++ share/applications/safeeyes.desktop | 1 + 2 files changed, 59 insertions(+) create mode 100644 safeeyes/config/lang/uk.json diff --git a/safeeyes/config/lang/uk.json b/safeeyes/config/lang/uk.json new file mode 100644 index 0000000..dd2066c --- /dev/null +++ b/safeeyes/config/lang/uk.json @@ -0,0 +1,58 @@ +{ + "meta_info": { + "language_name": "Українська", + "language_name_en": "Ukrainian" + }, + "app_info": { + "description": "Safe Eyes нагадує вам робити перерви, при довгій роботі за комп'ютером, захищаючи ваші очі від втоми (asthenopia)." + }, + "exercises": { + "short_break_close_eyes": "Сильно заплющіть очі", + "short_break_roll_eyes": "Закотіть очі в різні боки", + "short_break_rotate_clockwise": "Покрутіть очима за годинниковою стрілкою", + "short_break_rotate_counter_clockwise": "Покрутіть очима проти годинникової стрілки", + "short_break_blink": "Поморгайте", + "short_break_focus_far_distance": "Подивіться на далекий об'єкт", + "short_break_drink_water": "Випийте води", + "long_break_walk": "Трохи пройдіться", + "long_break_lean_back": "Відкиньтеся на спинку і розслабтеся" + }, + "messages": { + "ready_for_a_break": "Приготуйтеся до перерви через {} секунд", + "disabled_until_restart": "Відключено до перезапуску", + "disabled_until_x": "Відключено до {}", + "next_break_at": "Наступна перерва о {}" + }, + "ui_controls": { + "about": "Про SafeEyes", + "allow_postpone": "Дозволити відкладати перерви", + "audible_alert": "Звуковий сигнал вкінці перерви", + "cancel": "Відмінити", + "close": "Закрити", + "disable": "Відключити Safe Eyes", + "enable": "Включити Safe Eyes", + "enable_screen_lock": "Блокувати екран після довгих перерв", + "for_x_hour": "На {} годину", + "for_x_hours": "На {} години", + "for_x_minutes": "На {} хвилин", + "idle_time": "Час бездіяльності для паузи (в хвилинах)", + "interval_between_two_breaks": "Інтервал між двома перервами (в хвилинах)", + "language": "Мова", + "license": "Ліцензія", + "long_break_duration": "Тривалість довгої перерви (в секундах)", + "no_of_short_breaks_between_two_long_breaks": "Кількість коротких перерв між двома довгими", + "postpone": "Відкласти", + "postpone_duration": "На скільки відкласти (в хвилинах)", + "quit": "Вийти", + "save": "Зберегти", + "settings": "Налаштування", + "short_break_duration": "Тривалість короткої перерви (в секундах)", + "show_time_in_tray": "Показувати час наступної перерви в системному треї", + "skip": "Пропустити", + "strict_break": "Обов'язкова перерва (прибрати кнопку для пропускання)", + "system_language": "Мова системи", + "time_to_prepare_for_break": "Час підготовки до перерви (в секундах)", + "time_to_screen_lock": "Найбільший час для пропуску, без блокування екрану (в секундах)", + "until_restart": "До перезапуску" + } +} diff --git a/share/applications/safeeyes.desktop b/share/applications/safeeyes.desktop index 4b65df6..d7f1185 100755 --- a/share/applications/safeeyes.desktop +++ b/share/applications/safeeyes.desktop @@ -17,6 +17,7 @@ Comment[pl]=Chroń oczy przed zmęczeniem Comment[mk]=Заштитете се од замор на очите Comment[vi]=Bảo vệ đôi mắt của bạn khỏi sự mệt mỏi Comment[fa]=محافظت چشم هااز ضعیف شدن +Comment[uk]=Захистіть свої очі від втоми Exec=env GDK_BACKEND=x11 safeeyes Icon=safeeyes Terminal=false From 87d4ba7d4955b4d1b9d8546bbb9b623514e7ad51 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Wed, 21 Jun 2017 08:44:50 -0400 Subject: [PATCH 14/40] Update language list --- README.md | 5 +++++ share/applications/safeeyes.desktop | 26 ++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 7ccce53..7e172a5 100644 --- a/README.md +++ b/README.md @@ -53,21 +53,26 @@ Optional Features: For more details: [SafeEyes Features](http://slgobinath.github.io/SafeEyes/#features) ## Currently available translations + * [Català](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/ca.json) * [Čeština](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/cs.json) * [Deutsch](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/de.json) * [English](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/en.json) * [Español](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/es.json) + * [فارسی](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/fa.json) * [Français](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/fr.json) * [ქართული](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/ge.json) * [हिंदी](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/hi.json) * [Magyar](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/hu.json) * [Bahasa Indonesia](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/id.json) + * [Македонски](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/mk.json) * [Polski](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/pl.json) * [Português](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/pt.json) * [Русский](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/ru.json) * [Slovenský](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/sk.json) * [தமிழ்](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/ta.json) * [Türkçe](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/tr.json) + * [Українська](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/uk.json) + * [Tiếng Việt](https://github.com/slgobinath/SafeEyes/tree/master/safeeyes/config/lang/vi.json) Do you want to see your language here? Please translate Safe Eyes to whatever the languages you know. Visit to **Translate Safe Eyes** in [Customize Safe Eyes](http://slgobinath.github.io/SafeEyes/#customize) to see how to translate. diff --git a/share/applications/safeeyes.desktop b/share/applications/safeeyes.desktop index d7f1185..602a8c4 100755 --- a/share/applications/safeeyes.desktop +++ b/share/applications/safeeyes.desktop @@ -2,22 +2,24 @@ Name=Safe Eyes Comment=Protect your eyes from eye strain Comment[ca]=Protegiu-vos els ulls de la fatiga visual -Comment[ge]=დაიცავით თქვენი თვალები დაღლილობისაგან -Comment[de]=Schützt die Augen vor Überanstrengung Comment[cs]=Chraňte své oči před únavou -Comment[fr]=Protégez vos yeux de la fatigue -Comment[id]=Melindungi mata Anda dari kelelahan -Comment[ta]=உங்கள் கண்களை சோர்வடையாது பாதுகாத்திடுங்கள் -Comment[pt]=Proteja seus olhos da tensão ocular -Comment[tr]=Gözünüzü yorgunluğa karşı koruyun -Comment[hi]=तनाव से आंखों की रक्षा +Comment[de]=Schützt die Augen vor Überanstrengung Comment[es]=Protege tus ojos de la fatiga ocular -Comment[ru]=Защитите свои глаза от зрительного перенапряжения -Comment[pl]=Chroń oczy przed zmęczeniem -Comment[mk]=Заштитете се од замор на очите -Comment[vi]=Bảo vệ đôi mắt của bạn khỏi sự mệt mỏi Comment[fa]=محافظت چشم هااز ضعیف شدن +Comment[fr]=Protégez vos yeux de la fatigue +Comment[ge]=დაიცავით თქვენი თვალები დაღლილობისაგან +Comment[hi]=तनाव से आंखों की रक्षा +Comment[hu]=Protect your eyes from eye strain +Comment[id]=Melindungi mata Anda dari kelelahan +Comment[mk]=Заштитете се од замор на очите +Comment[pl]=Chroń oczy przed zmęczeniem +Comment[pt]=Proteja seus olhos da tensão ocular +Comment[ru]=Защитите свои глаза от зрительного перенапряжения +Comment[sk]=Protect your eyes from eye strain +Comment[ta]=உங்கள் கண்களை சோர்வடையாது பாதுகாத்திடுங்கள் +Comment[tr]=Gözünüzü yorgunluğa karşı koruyun Comment[uk]=Захистіть свої очі від втоми +Comment[vi]=Bảo vệ đôi mắt của bạn khỏi sự mệt mỏi Exec=env GDK_BACKEND=x11 safeeyes Icon=safeeyes Terminal=false From b7e32286d370503e8c006c50289f0286156984d6 Mon Sep 17 00:00:00 2001 From: radek-sprta Date: Wed, 21 Jun 2017 15:21:17 +0200 Subject: [PATCH 15/40] Update safeeyes.desktop --- share/applications/safeeyes.desktop | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/applications/safeeyes.desktop b/share/applications/safeeyes.desktop index 602a8c4..cd87524 100755 --- a/share/applications/safeeyes.desktop +++ b/share/applications/safeeyes.desktop @@ -15,7 +15,7 @@ Comment[mk]=Заштитете се од замор на очите Comment[pl]=Chroń oczy przed zmęczeniem Comment[pt]=Proteja seus olhos da tensão ocular Comment[ru]=Защитите свои глаза от зрительного перенапряжения -Comment[sk]=Protect your eyes from eye strain +Comment[sk]=Chráňte svoje oči pred únavou Comment[ta]=உங்கள் கண்களை சோர்வடையாது பாதுகாத்திடுங்கள் Comment[tr]=Gözünüzü yorgunluğa karşı koruyun Comment[uk]=Захистіть свої очі від втоми From 08932e5fff0c867a5b9d034781c38666648cbd22 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Wed, 21 Jun 2017 15:14:31 -0400 Subject: [PATCH 16/40] Make pyaudio optional --- safeeyes/SettingsDialog.py | 4 +++ safeeyes/Utility.py | 63 ++++++++++++++++++++++---------------- setup.py | 7 +++-- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/safeeyes/SettingsDialog.py b/safeeyes/SettingsDialog.py index 842de04..1dc2e06 100644 --- a/safeeyes/SettingsDialog.py +++ b/safeeyes/SettingsDialog.py @@ -85,6 +85,10 @@ class SettingsDialog: # Enable idle_time_to_pause only if xprintidle is available self.spin_idle_time_to_pause.set_sensitive(Utility.command_exist('xprintidle')) + # Enable optional audible alert only if pyaudio is available + self.switch_audible_alert.set_sensitive(Utility.pyaudio is not None) + self.switch_audible_alert.set_active(Utility.pyaudio is not None and config['audible_alert']) + self.switch_screen_lock.set_sensitive(able_to_lock_screen) self.switch_screen_lock.set_active(able_to_lock_screen and config['enable_screen_lock']) self.switch_postpone.set_active(config['allow_postpone'] and not config['strict_break']) diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index 517c92b..8d83f6c 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -22,7 +22,7 @@ from gi.repository import Gdk, GLib from html.parser import HTMLParser from distutils.version import LooseVersion from logging.handlers import RotatingFileHandler -import babel.dates, os, errno, re, subprocess, threading, logging, locale, json, shutil, pyaudio, wave +import babel.dates, os, errno, re, subprocess, threading, logging, locale, json, shutil, wave bin_directory = os.path.dirname(os.path.realpath(__file__)) home_directory = os.path.expanduser('~') @@ -33,43 +33,52 @@ style_sheet_path = os.path.join(config_directory, 'style/safeeyes_style.css') system_config_file_path = os.path.join(bin_directory, "config/safeeyes.json") system_style_sheet_path = os.path.join(bin_directory, "config/style/safeeyes_style.css") log_file_path = os.path.join(config_directory, 'safeeyes.log') +pyaudio = None + +# Import pyaudio if exists +try: + pyaudio = __import__("pyaudio") +except ImportError: + pass + def play_notification(): """ Play the alert.wav """ - logging.info('Playing audible alert') - CHUNK = 1024 + if pyaudio: + logging.info('Playing audible alert') + CHUNK = 1024 - try: - # Open the sound file - path = get_resource_path('alert.wav') - if path is None: - return - sound = wave.open(path, 'rb') + try: + # Open the sound file + path = get_resource_path('alert.wav') + if path is None: + return + sound = wave.open(path, 'rb') - # Create a sound stream - wrapper = pyaudio.PyAudio() - stream = wrapper.open(format=wrapper.get_format_from_width(sound.getsampwidth()), - channels=sound.getnchannels(), - rate=sound.getframerate(), - output=True) + # Create a sound stream + wrapper = pyaudio.PyAudio() + stream = wrapper.open(format=wrapper.get_format_from_width(sound.getsampwidth()), + channels=sound.getnchannels(), + rate=sound.getframerate(), + output=True) - # Write file data into the sound stream - data = sound.readframes(CHUNK) - while data != b'': - stream.write(data) + # Write file data into the sound stream data = sound.readframes(CHUNK) + while data != b'': + stream.write(data) + data = sound.readframes(CHUNK) - # Close steam - stream.stop_stream() - stream.close() - sound.close() - wrapper.terminate() + # Close steam + stream.stop_stream() + stream.close() + sound.close() + wrapper.terminate() - except Exception as e: - logging.warning('Unable to play audible alert') - logging.exception(e) + except Exception as e: + logging.warning('Unable to play audible alert') + logging.exception(e) def get_resource_path(resource_name): diff --git a/setup.py b/setup.py index ce30fdd..ed5210f 100644 --- a/setup.py +++ b/setup.py @@ -1,14 +1,16 @@ import os - import setuptools requires = [ 'python-xlib', - 'pyaudio', 'psutil', 'babel'] +extras = { + 'audible_alert': ['pyaudio'] + } + here = os.path.abspath(os.path.dirname(__file__)) @@ -49,6 +51,7 @@ setuptools.setup( ('/usr/share/icons/hicolor/16x16/status', ['share/icons/hicolor/16x16/status/safeeyes_enabled.png', 'share/icons/hicolor/16x16/status/safeeyes_disabled.png', 'share/icons/hicolor/16x16/status/safeeyes_timer.png']) ], install_requires=requires, + extras_require=extras, entry_points={'console_scripts': ['safeeyes = safeeyes.__main__:main']}, keywords='linux utility health eye-strain safe-eyes', classifiers=[ From 8d41f013e0e31da8e2eda860f54f9f0972a1a12d Mon Sep 17 00:00:00 2001 From: Radek SPRTA Date: Mon, 26 Jun 2017 22:28:26 +0200 Subject: [PATCH 17/40] Show a popup notification if pyaudio is not installed --- safeeyes/SettingsDialog.py | 9 +++++++-- safeeyes/Utility.py | 15 +++++++++++++-- safeeyes/config/lang/ca.json | 2 ++ safeeyes/config/lang/cs.json | 2 ++ safeeyes/config/lang/de.json | 2 ++ safeeyes/config/lang/en.json | 2 ++ safeeyes/config/lang/es.json | 2 ++ safeeyes/config/lang/fa.json | 2 ++ safeeyes/config/lang/fr.json | 2 ++ safeeyes/config/lang/ge.json | 2 ++ safeeyes/config/lang/hi.json | 2 ++ safeeyes/config/lang/hu.json | 2 ++ safeeyes/config/lang/id.json | 2 ++ safeeyes/config/lang/mk.json | 2 ++ safeeyes/config/lang/pl.json | 2 ++ safeeyes/config/lang/pt.json | 2 ++ safeeyes/config/lang/ru.json | 2 ++ safeeyes/config/lang/sk.json | 2 ++ safeeyes/config/lang/ta.json | 2 ++ safeeyes/config/lang/tr.json | 2 ++ safeeyes/config/lang/uk.json | 2 ++ safeeyes/config/lang/vi.json | 2 ++ 22 files changed, 60 insertions(+), 4 deletions(-) diff --git a/safeeyes/SettingsDialog.py b/safeeyes/SettingsDialog.py index 1dc2e06..99168db 100644 --- a/safeeyes/SettingsDialog.py +++ b/safeeyes/SettingsDialog.py @@ -86,7 +86,6 @@ class SettingsDialog: self.spin_idle_time_to_pause.set_sensitive(Utility.command_exist('xprintidle')) # Enable optional audible alert only if pyaudio is available - self.switch_audible_alert.set_sensitive(Utility.pyaudio is not None) self.switch_audible_alert.set_active(Utility.pyaudio is not None and config['audible_alert']) self.switch_screen_lock.set_sensitive(able_to_lock_screen) @@ -182,11 +181,17 @@ class SettingsDialog: self.config['postpone_duration'] = self.spin_postpone_duration.get_value_as_int() self.config['show_time_in_tray'] = self.switch_show_time_in_tray.get_active() self.config['strict_break'] = self.switch_strict_break.get_active() - self.config['audible_alert'] = self.switch_audible_alert.get_active() self.config['language'] = self.languages[self.cmb_language.get_active()] self.config['time_to_screen_lock'] = self.spin_time_to_screen_lock.get_value_as_int() self.config['enable_screen_lock'] = self.switch_screen_lock.get_active() self.config['allow_postpone'] = self.switch_postpone.get_active() + # Check if pyaudio is installed when turning audible notifications on + if self.switch_audible_alert.get_active() and not Utility.pyaudio: + # Notify user that pyaudio is not installed + Utility.pyaudio_popup(self, self.language) + self.config['audible_alert'] = False + else: + self.config['audible_alert'] = self.switch_audible_alert.get_active() self.on_save_settings(self.config) # Call the provided save method self.window.destroy() # Close the settings window diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index 8d83f6c..44b5bd0 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -18,7 +18,7 @@ import gi gi.require_version('Gdk', '3.0') -from gi.repository import Gdk, GLib +from gi.repository import Gtk, Gdk, GLib from html.parser import HTMLParser from distutils.version import LooseVersion from logging.handlers import RotatingFileHandler @@ -39,8 +39,19 @@ pyaudio = None try: pyaudio = __import__("pyaudio") except ImportError: - pass + logging.warning('Install pyaudio for audible notifications.') +def pyaudio_popup(parent, language): + """ + Show a popup informing user to install pyaudio. + """ + dialog = Gtk.MessageDialog( + parent, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, + language['ui_controls']['pyaudio_not_installed']) + dialog.format_secondary_text( + language['ui_controls']['pyaudio_explanation']) + dialog.run() + dialog.destroy() def play_notification(): """ diff --git a/safeeyes/config/lang/ca.json b/safeeyes/config/lang/ca.json index eba795c..4501ef6 100644 --- a/safeeyes/config/lang/ca.json +++ b/safeeyes/config/lang/ca.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Nombre de pauses breus entre dues pauses llargues", "postpone": "Posposa", "postpone_duration": "Durada d'una posposició (en minuts)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Tanca", "save": "Desa", "settings": "Configuració", diff --git a/safeeyes/config/lang/cs.json b/safeeyes/config/lang/cs.json index ea20c3e..58eb8bf 100644 --- a/safeeyes/config/lang/cs.json +++ b/safeeyes/config/lang/cs.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Počet krátkých přestávek mezi dvěma dlouhými", "postpone": "Odložit", "postpone_duration": "O kolik odložit (v minutách)", + "pyaudio_not_installed": "Nelze zapnout zvuková upozornění", + "pyaudio_explanation": "Nejdříve musíte nainstalovat pyaudio", "quit": "Ukončit", "save": "Uložit", "settings": "Nastavení", diff --git a/safeeyes/config/lang/de.json b/safeeyes/config/lang/de.json index fc83936..657fc24 100644 --- a/safeeyes/config/lang/de.json +++ b/safeeyes/config/lang/de.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Anzahl von kleinen Pausen zwischen zwei langen Pausen", "postpone": "Verzögernn", "postpone_duration": "Verzögerungsdauer (in Minuten)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Schließen", "save": "Speichern", "settings": "Einstellungen", diff --git a/safeeyes/config/lang/en.json b/safeeyes/config/lang/en.json index c53b3e1..2ec82a8 100644 --- a/safeeyes/config/lang/en.json +++ b/safeeyes/config/lang/en.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Number of short breaks between two long breaks", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Quit", "save": "Save", "settings": "Settings", diff --git a/safeeyes/config/lang/es.json b/safeeyes/config/lang/es.json index 25426bc..e1db18a 100644 --- a/safeeyes/config/lang/es.json +++ b/safeeyes/config/lang/es.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Número de pausas cortas entre dos pausas largas", "postpone": "Posponer", "postpone_duration": "Duración de cada posposición (en minutos)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Salir", "save": "Guardar", "settings": "Preferencias", diff --git a/safeeyes/config/lang/fa.json b/safeeyes/config/lang/fa.json index 3da2f4c..ac90424 100644 --- a/safeeyes/config/lang/fa.json +++ b/safeeyes/config/lang/fa.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "تعداد استراحت های کوتاه بین هر دو استراحت بلند", "postpone": "به تعویق انداختن", "postpone_duration": "زمان به تعویق انداختن (به دقیقه)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "خروج", "save": "ذخیره", "settings": "تنظیمات", diff --git a/safeeyes/config/lang/fr.json b/safeeyes/config/lang/fr.json index dea77ae..924e2fe 100644 --- a/safeeyes/config/lang/fr.json +++ b/safeeyes/config/lang/fr.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Nombre de pauses courtes entre deux pauses longues", "postpone": "Reporter", "postpone_duration": "Durée de report (en minutes)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Quitter", "save": "Enregistrer", "settings": "Paramètres", diff --git a/safeeyes/config/lang/ge.json b/safeeyes/config/lang/ge.json index 3506ec4..53cf55d 100644 --- a/safeeyes/config/lang/ge.json +++ b/safeeyes/config/lang/ge.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "მცირე შესვენებების რაოდენობა ორ დიდ შესვენებას შორის", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "გასვლა", "save": "დამახსოვრება", "settings": "პარამეტრები", diff --git a/safeeyes/config/lang/hi.json b/safeeyes/config/lang/hi.json index 8bc82a3..2218cba 100644 --- a/safeeyes/config/lang/hi.json +++ b/safeeyes/config/lang/hi.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "दो बड़े आराम के बीच कितने छोटे आराम", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "बंद", "save": "रखें", "settings": "सेटिंग्स", diff --git a/safeeyes/config/lang/hu.json b/safeeyes/config/lang/hu.json index 28407bb..6e6fb63 100644 --- a/safeeyes/config/lang/hu.json +++ b/safeeyes/config/lang/hu.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Hány rövid szünet legyen a hosszabbak között?", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Kilépés", "save": "Mentés", "settings": "Beállítások", diff --git a/safeeyes/config/lang/id.json b/safeeyes/config/lang/id.json index 11bf9e2..86ace59 100644 --- a/safeeyes/config/lang/id.json +++ b/safeeyes/config/lang/id.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Jumlah istirahat singkat di antara dua istirahat panjang", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Keluar", "save": "Simpan", "settings": "Pengaturan", diff --git a/safeeyes/config/lang/mk.json b/safeeyes/config/lang/mk.json index 82702ec..1fd701e 100644 --- a/safeeyes/config/lang/mk.json +++ b/safeeyes/config/lang/mk.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Број на кратки паузи помеѓу две долги", "postpone": "Одложи", "postpone_duration": "Траење на одложувањето (Во секунди)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Исклучи", "save": "Зачувај", "settings": "Подесувања", diff --git a/safeeyes/config/lang/pl.json b/safeeyes/config/lang/pl.json index 916eee2..8a948c3 100644 --- a/safeeyes/config/lang/pl.json +++ b/safeeyes/config/lang/pl.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Liczba krótkich przerw między długimi przerwami", "postpone": "Odrocz", "postpone_duration": "Odroczenie przerwy (w minutach)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Wyjdź", "save": "Zapisz", "settings": "Ustawienia", diff --git a/safeeyes/config/lang/pt.json b/safeeyes/config/lang/pt.json index c502644..7b38748 100644 --- a/safeeyes/config/lang/pt.json +++ b/safeeyes/config/lang/pt.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Número de pausas curtas entre duas pausas longas", "postpone": "Adiar", "postpone_duration": "Duração do adiamento (em minutos)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Sair", "save": "Salvar", "settings": "Configuração", diff --git a/safeeyes/config/lang/ru.json b/safeeyes/config/lang/ru.json index 33b1aee..7f6da0d 100644 --- a/safeeyes/config/lang/ru.json +++ b/safeeyes/config/lang/ru.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Количество коротких перерывов между двумя длинными", "postpone": "Отложить", "postpone_duration": "Отложить на время (в минутах)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Выйти", "save": "Сохранить", "settings": "Настройки", diff --git a/safeeyes/config/lang/sk.json b/safeeyes/config/lang/sk.json index 287da7c..a133f57 100644 --- a/safeeyes/config/lang/sk.json +++ b/safeeyes/config/lang/sk.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Počet krátkych prestávok medzi dvomi dlhými prestávkami", "postpone": "Odložiť", "postpone_duration": "O koĺko odložiť (minút)", + "pyaudio_not_installed": "Nieje možné zapnúť zvukové upozornenie", + "pyaudio_explanation": "Pro ích povolenie nainstalujte pyaudio", "quit": "Koniec", "save": "Uložiť", "settings": "Nastavenia", diff --git a/safeeyes/config/lang/ta.json b/safeeyes/config/lang/ta.json index 527cb5c..e56fa3e 100644 --- a/safeeyes/config/lang/ta.json +++ b/safeeyes/config/lang/ta.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "இரண்டு நீண்ட இடைவேளைகளுக்கிடையிலான குறுகிய இடைவேளைகள்", "postpone": "ஒத்தி வை", "postpone_duration": "இடைவேளையை ஒத்தி வைக்கும் காலம் (நிமிடங்களில்)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "நிறுத்து", "save": "சேமி", "settings": "அமைப்பு", diff --git a/safeeyes/config/lang/tr.json b/safeeyes/config/lang/tr.json index ecb803d..8a503b5 100644 --- a/safeeyes/config/lang/tr.json +++ b/safeeyes/config/lang/tr.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "İki uzun mola arasındaki kısa mola sayısı", "postpone": "Ertele", "postpone_duration": "Ertelme süresi (dakika)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Çıkış", "save": "Kaydet", "settings": "Ayarlar", diff --git a/safeeyes/config/lang/uk.json b/safeeyes/config/lang/uk.json index dd2066c..317b4f1 100644 --- a/safeeyes/config/lang/uk.json +++ b/safeeyes/config/lang/uk.json @@ -43,6 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "Кількість коротких перерв між двома довгими", "postpone": "Відкласти", "postpone_duration": "На скільки відкласти (в хвилинах)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Вийти", "save": "Зберегти", "settings": "Налаштування", diff --git a/safeeyes/config/lang/vi.json b/safeeyes/config/lang/vi.json index aa67e3c..92f1436 100644 --- a/safeeyes/config/lang/vi.json +++ b/safeeyes/config/lang/vi.json @@ -48,6 +48,8 @@ "no_of_short_breaks_between_two_long_breaks": "Số lần nghỉ ngơi ngắn giữa hai lần nghỉ ngơi dài", "postpone": "Tạm hoãn", "postpone_duration": "Thời gian tạm hoãn (tính bằng phút)", + "pyaudio_not_installed": "Cannot enable audible notifications", + "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Thoát", "save": "Lưu", "settings": "Cài đặt", From aa1deda9e24c326c10431fdb824eca4dd05b6e74 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Mon, 26 Jun 2017 17:18:11 -0400 Subject: [PATCH 18/40] Fix some errors with last commit --- safeeyes/SettingsDialog.py | 15 ++++++++------- safeeyes/Utility.py | 16 +++++++++++----- safeeyes/__main__.py | 3 +++ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/safeeyes/SettingsDialog.py b/safeeyes/SettingsDialog.py index 99168db..e6b69be 100644 --- a/safeeyes/SettingsDialog.py +++ b/safeeyes/SettingsDialog.py @@ -29,6 +29,7 @@ class SettingsDialog: self.config = config self.on_save_settings = on_save_settings self.languages = [] + self.language = language builder = Gtk.Builder() builder.add_from_file(glade_file) @@ -86,7 +87,7 @@ class SettingsDialog: self.spin_idle_time_to_pause.set_sensitive(Utility.command_exist('xprintidle')) # Enable optional audible alert only if pyaudio is available - self.switch_audible_alert.set_active(Utility.pyaudio is not None and config['audible_alert']) + # self.switch_audible_alert.set_active(Utility.pyaudio is not None and config['audible_alert']) self.switch_screen_lock.set_sensitive(able_to_lock_screen) self.switch_screen_lock.set_active(able_to_lock_screen and config['enable_screen_lock']) @@ -185,13 +186,13 @@ class SettingsDialog: self.config['time_to_screen_lock'] = self.spin_time_to_screen_lock.get_value_as_int() self.config['enable_screen_lock'] = self.switch_screen_lock.get_active() self.config['allow_postpone'] = self.switch_postpone.get_active() - # Check if pyaudio is installed when turning audible notifications on - if self.switch_audible_alert.get_active() and not Utility.pyaudio: - # Notify user that pyaudio is not installed - Utility.pyaudio_popup(self, self.language) + # Check if pyaudio is installed when turning audible notifications on + if self.switch_audible_alert.get_active() and not Utility.pyaudio: + # Notify user that pyaudio is not installed + Utility.pyaudio_popup(self.window, self.language) self.config['audible_alert'] = False - else: - self.config['audible_alert'] = self.switch_audible_alert.get_active() + else: + self.config['audible_alert'] = self.switch_audible_alert.get_active() self.on_save_settings(self.config) # Call the provided save method self.window.destroy() # Close the settings window diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index 44b5bd0..49426ed 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -35,11 +35,17 @@ system_style_sheet_path = os.path.join(bin_directory, "config/style/safeeyes_sty log_file_path = os.path.join(config_directory, 'safeeyes.log') pyaudio = None -# Import pyaudio if exists -try: - pyaudio = __import__("pyaudio") -except ImportError: - logging.warning('Install pyaudio for audible notifications.') + +def import_dependencies(): + """ + Import the optional Python dependencies. + """ + try: + # Import pyaudio if exists + global pyaudio + pyaudio = __import__("pyaudio") + except ImportError: + logging.warning('Install pyaudio for audible notifications.') def pyaudio_popup(parent, language): """ diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index f3818c3..f67f8a4 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -231,6 +231,9 @@ def main(): logging.info("Starting Safe Eyes") + # Import the dependencies + Utility.import_dependencies() + if not running(): global break_screen From 723d8dd946300aaf986f22fdac30d61158bbe82f Mon Sep 17 00:00:00 2001 From: Gobinath Date: Mon, 26 Jun 2017 17:28:58 -0400 Subject: [PATCH 19/40] Update Tamil translation to install pyaudio --- safeeyes/config/lang/ta.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/safeeyes/config/lang/ta.json b/safeeyes/config/lang/ta.json index e56fa3e..453a30b 100644 --- a/safeeyes/config/lang/ta.json +++ b/safeeyes/config/lang/ta.json @@ -26,7 +26,7 @@ "ui_controls": { "about": "Safe Eyes குறித்த தகவல்கள்", "allow_postpone": "ஒத்திவைக்க அனுமதிக்கவும்", - "audible_alert": "இடைவேளையின் இறுதியில் ஒலி சமிக்கை", + "audible_alert": "இடைவேளையின் இறுதியில் ஒலி சமிக்ஞை", "cancel": "ரத்து", "close": "மூடு", "disable": "Safe Eyes ஐ நிறுத்துக", @@ -43,8 +43,8 @@ "no_of_short_breaks_between_two_long_breaks": "இரண்டு நீண்ட இடைவேளைகளுக்கிடையிலான குறுகிய இடைவேளைகள்", "postpone": "ஒத்தி வை", "postpone_duration": "இடைவேளையை ஒத்தி வைக்கும் காலம் (நிமிடங்களில்)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", + "pyaudio_not_installed": "ஒலிச் சமிக்ஞையை செயற்படுத்த முடியாதுள்ளது", + "pyaudio_explanation": "ஒலிச் சமிக்ஞையை செயற்படுத்த pyaudio ஐ நிறுவவும்", "quit": "நிறுத்து", "save": "சேமி", "settings": "அமைப்பு", From 78a500bae4049c121f73122688313d2cb04afde5 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Sun, 2 Jul 2017 14:05:48 -0400 Subject: [PATCH 20/40] Show the break type in the notification --- safeeyes/Notification.py | 20 ++++++++++++++++++-- safeeyes/SafeEyesCore.py | 9 +++++---- safeeyes/Utility.py | 4 ++-- safeeyes/__main__.py | 3 ++- safeeyes/config/lang/ca.json | 9 +++++---- safeeyes/config/lang/cs.json | 9 +++++---- safeeyes/config/lang/de.json | 9 +++++---- safeeyes/config/lang/en.json | 9 +++++---- safeeyes/config/lang/es.json | 9 +++++---- safeeyes/config/lang/fa.json | 9 +++++---- safeeyes/config/lang/fr.json | 9 +++++---- safeeyes/config/lang/ge.json | 11 ++++++----- safeeyes/config/lang/hi.json | 9 +++++---- safeeyes/config/lang/hu.json | 9 +++++---- safeeyes/config/lang/id.json | 9 +++++---- safeeyes/config/lang/mk.json | 9 +++++---- safeeyes/config/lang/pl.json | 9 +++++---- safeeyes/config/lang/pt.json | 9 +++++---- safeeyes/config/lang/ru.json | 11 ++++++----- safeeyes/config/lang/sk.json | 9 +++++---- safeeyes/config/lang/ta.json | 9 +++++---- safeeyes/config/lang/tr.json | 9 +++++---- safeeyes/config/lang/uk.json | 9 +++++---- safeeyes/config/lang/vi.json | 9 +++++---- 24 files changed, 129 insertions(+), 91 deletions(-) diff --git a/safeeyes/Notification.py b/safeeyes/Notification.py index 068d884..96b48bc 100644 --- a/safeeyes/Notification.py +++ b/safeeyes/Notification.py @@ -30,21 +30,37 @@ class Notification: """ - def __init__(self, language): + def __init__(self, context, language): """ Initialize the notification. """ logging.info('Initialize the notification') Notify.init(APPINDICATOR_ID) + self.context = context self.language = language + def initialize(self, language): + """ + Initialize the notification object. + """ + self.language = language + + def show(self, warning_time): """ Show the notification """ logging.info('Show pre-break notification') - self.notification = Notify.Notification.new('Safe Eyes', '\n' + self.language['messages']['ready_for_a_break'].format(warning_time), icon='safeeyes_enabled') + + # Construct the message based on the type of the next break + message = '\n' + if self.context['break_type'] == 'short': + message += self.language['messages']['ready_for_a_short_break'].format(warning_time) + else: + message += self.language['messages']['ready_for_a_long_break'].format(warning_time) + + self.notification = Notify.Notification.new('Safe Eyes', message, icon='safeeyes_enabled') try: self.notification.show() except Exception as e: diff --git a/safeeyes/SafeEyesCore.py b/safeeyes/SafeEyesCore.py index c2aa7fd..7961df7 100644 --- a/safeeyes/SafeEyesCore.py +++ b/safeeyes/SafeEyesCore.py @@ -213,6 +213,11 @@ class SafeEyesCore: next_break_time = datetime.datetime.now() + datetime.timedelta(minutes=time_to_wait) self.update_next_break_info(next_break_time) + self.break_count = ((self.break_count + 1) % self.no_of_short_breaks_per_long_break) + if self.__is_long_break(): + self.context['break_type'] = 'long' + else: + self.context['break_type'] = 'short' # Wait for the pre break warning period logging.info("Pre-break waiting for {} minutes".format(time_to_wait)) @@ -227,8 +232,6 @@ class SafeEyesCore: logging.info("Ready to show the break") - self.break_count = ((self.break_count + 1) % self.no_of_short_breaks_per_long_break) - self.is_before_break = False Utility.execute_main_thread(self.__check_active_window) @@ -288,7 +291,6 @@ class SafeEyesCore: seconds = self.long_break_exercises[self.long_break_message_index][1] audible_alert = self.long_break_exercises[self.long_break_message_index][2] image = self.long_break_exercises[self.long_break_message_index][3] - self.context['break_type'] = 'long' else: logging.info("Count is {}; get a short beak message".format(self.break_count)) self.short_break_message_index = (self.short_break_message_index + 1) % len(self.short_break_exercises) @@ -296,7 +298,6 @@ class SafeEyesCore: seconds = self.short_break_exercises[self.short_break_message_index][1] audible_alert = self.short_break_exercises[self.short_break_message_index][2] image = self.short_break_exercises[self.short_break_message_index][3] - self.context['break_type'] = 'short' self.context['break_length'] = seconds self.context['audible_alert'] = audible_alert diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index 49426ed..3535b6c 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -53,9 +53,9 @@ def pyaudio_popup(parent, language): """ dialog = Gtk.MessageDialog( parent, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, - language['ui_controls']['pyaudio_not_installed']) + language['messages']['audible_alert_disabled']) dialog.format_secondary_text( - language['ui_controls']['pyaudio_explanation']) + language['messages']['software_required'].format('pyaudio')) dialog.run() dialog.destroy() diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index f67f8a4..0ce9df9 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -175,6 +175,7 @@ def save_settings(config): # Restart the core and intialize the components core.initialize(config, language) break_screen.initialize(config, language) + notification.initialize(language) if is_active: # 1 sec delay is required to give enough time for core to be stopped Timer(1.0, core.start).start() @@ -264,7 +265,7 @@ def main(): tray_icon = TrayIcon(config, language, show_settings, show_about, enable_safeeyes, disable_safeeyes, on_quit) break_screen = BreakScreen(context, on_skipped, on_postponed, break_screen_glade, Utility.style_sheet_path) break_screen.initialize(config, language) - notification = Notification(language) + notification = Notification(context, language) plugins = Plugins(config) core = SafeEyesCore(context, show_notification, show_alert, close_alert, break_screen.show_count_down, tray_icon.next_break_time) core.initialize(config, language) diff --git a/safeeyes/config/lang/ca.json b/safeeyes/config/lang/ca.json index 4501ef6..f97dd52 100644 --- a/safeeyes/config/lang/ca.json +++ b/safeeyes/config/lang/ca.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Reclineu-vos sobre la cadira i relaxeu-vos" }, "messages": { - "ready_for_a_break": "Prepareu-vos per a una pausa en {} segons", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Prepareu-vos per a una pausa en {} segons", + "ready_for_a_long_break": "Prepareu-vos per a una pausa en {} segons", "disabled_until_restart": "Inhabilita fins que es reinicïi", "disabled_until_x": "Inhabilitat fins {}", - "next_break_at": "Propera pausa a les {}" + "next_break_at": "Propera pausa a les {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Quant a", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Nombre de pauses breus entre dues pauses llargues", "postpone": "Posposa", "postpone_duration": "Durada d'una posposició (en minuts)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Tanca", "save": "Desa", "settings": "Configuració", diff --git a/safeeyes/config/lang/cs.json b/safeeyes/config/lang/cs.json index 58eb8bf..8937c9b 100644 --- a/safeeyes/config/lang/cs.json +++ b/safeeyes/config/lang/cs.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Opřete se do židle a relaxujte" }, "messages": { - "ready_for_a_break": "Připravte se na přestávku za {} sekund", + "audible_alert_disabled": "Nelze zapnout zvuková upozornění", + "ready_for_a_short_break": "Připravte se na přestávku za {} sekund", + "ready_for_a_long_break": "Připravte se na přestávku za {} sekund", "disabled_until_restart": "Pozastaveno do restartu", "disabled_until_x": "Pozastaveno na {}", - "next_break_at": "Příští přestávka v {}" + "next_break_at": "Příští přestávka v {}", + "software_required": "Nejdříve musíte nainstalovat {}" }, "ui_controls": { "about": "O aplikaci", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Počet krátkých přestávek mezi dvěma dlouhými", "postpone": "Odložit", "postpone_duration": "O kolik odložit (v minutách)", - "pyaudio_not_installed": "Nelze zapnout zvuková upozornění", - "pyaudio_explanation": "Nejdříve musíte nainstalovat pyaudio", "quit": "Ukončit", "save": "Uložit", "settings": "Nastavení", diff --git a/safeeyes/config/lang/de.json b/safeeyes/config/lang/de.json index 657fc24..e3487f2 100644 --- a/safeeyes/config/lang/de.json +++ b/safeeyes/config/lang/de.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Lehnen Sie sich zurück und entspannen Sie sich" }, "messages": { - "ready_for_a_break": "Nächste Pause in {} Sekunden", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Nächste Pause in {} Sekunden", + "ready_for_a_long_break": "Nächste Pause in {} Sekunden", "disabled_until_restart": "Deaktiviert bis zum Neustart", "disabled_until_x": "Deaktiviert bis {}", - "next_break_at": "Nächste Pause um {}" + "next_break_at": "Nächste Pause um {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Über", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Anzahl von kleinen Pausen zwischen zwei langen Pausen", "postpone": "Verzögernn", "postpone_duration": "Verzögerungsdauer (in Minuten)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Schließen", "save": "Speichern", "settings": "Einstellungen", diff --git a/safeeyes/config/lang/en.json b/safeeyes/config/lang/en.json index 2ec82a8..2581d4e 100644 --- a/safeeyes/config/lang/en.json +++ b/safeeyes/config/lang/en.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Lean back at your seat and relax" }, "messages": { - "ready_for_a_break": "Ready for a break in {} seconds", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Ready for a short break in {} seconds", + "ready_for_a_long_break": "Ready for a long break in {} seconds", "disabled_until_restart": "Disabled until restart", "disabled_until_x": "Disabled until {}", - "next_break_at": "Next break at {}" + "next_break_at": "Next break at {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "About", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Number of short breaks between two long breaks", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Quit", "save": "Save", "settings": "Settings", diff --git a/safeeyes/config/lang/es.json b/safeeyes/config/lang/es.json index e1db18a..a3216b2 100644 --- a/safeeyes/config/lang/es.json +++ b/safeeyes/config/lang/es.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Reclínate sobre tu silla y relájate" }, "messages": { - "ready_for_a_break": "Listo para una pausa en {} segundos", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Listo para una pausa en {} segundos", + "ready_for_a_long_break": "Listo para una pausa en {} segundos", "disabled_until_restart": "Deshabilitado hasta reinicio", "disabled_until_x": "Deshabilitado hasta {}", - "next_break_at": "Próxima pausa a las {}" + "next_break_at": "Próxima pausa a las {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Acerca de", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Número de pausas cortas entre dos pausas largas", "postpone": "Posponer", "postpone_duration": "Duración de cada posposición (en minutos)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Salir", "save": "Guardar", "settings": "Preferencias", diff --git a/safeeyes/config/lang/fa.json b/safeeyes/config/lang/fa.json index ac90424..ecc2750 100644 --- a/safeeyes/config/lang/fa.json +++ b/safeeyes/config/lang/fa.json @@ -18,10 +18,13 @@ "long_break_lean_back": "به صندلی تکیه داده و راحت باشید" }, "messages": { - "ready_for_a_break": "آماده استراحت در {} ثانیه بعد باشید", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "آماده استراحت در {} ثانیه بعد باشید", + "ready_for_a_long_break": "آماده استراحت در {} ثانیه بعد باشید", "disabled_until_restart": "غیرفعال تا بارگذاری مجدد", "disabled_until_x": "غیرفعال تا {}", - "next_break_at": "استراحت بعد در {}" + "next_break_at": "استراحت بعد در {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "درباره", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "تعداد استراحت های کوتاه بین هر دو استراحت بلند", "postpone": "به تعویق انداختن", "postpone_duration": "زمان به تعویق انداختن (به دقیقه)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "خروج", "save": "ذخیره", "settings": "تنظیمات", diff --git a/safeeyes/config/lang/fr.json b/safeeyes/config/lang/fr.json index 924e2fe..1e7ab20 100644 --- a/safeeyes/config/lang/fr.json +++ b/safeeyes/config/lang/fr.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Adossez-vous à votre siège et relaxez-vous" }, "messages": { - "ready_for_a_break": "Préparez-vous à une pause dans {} secondes", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Préparez-vous à une pause dans {} secondes", + "ready_for_a_long_break": "Préparez-vous à une pause dans {} secondes", "disabled_until_restart": "Désactivé jusqu'au redémarrage", "disabled_until_x": "Désactivé jusqu'à {}", - "next_break_at": "Prochaine pause à {}" + "next_break_at": "Prochaine pause à {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "À propos", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Nombre de pauses courtes entre deux pauses longues", "postpone": "Reporter", "postpone_duration": "Durée de report (en minutes)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Quitter", "save": "Enregistrer", "settings": "Paramètres", diff --git a/safeeyes/config/lang/ge.json b/safeeyes/config/lang/ge.json index 53cf55d..4aee8ae 100644 --- a/safeeyes/config/lang/ge.json +++ b/safeeyes/config/lang/ge.json @@ -18,10 +18,13 @@ "long_break_lean_back": "სავარძლის საზურგეზე გადაწექით და ცოტა დაისვენეთ" }, "messages": { - "ready_for_a_break": "მოემზადეთ შესვენებისთვის {} წამში", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "მოემზადეთ შესვენებისთვის {} წამში", + "ready_for_a_long_break": "მოემზადეთ შესვენებისთვის {} წამში", "disabled_until_restart": "გავაუქმოთ შემდეგ რესტარტამდე", "disabled_until_x": "გაუქმებულია {} მდე", - "next_break_at": "შემდეგი შესვენება {}" + "next_break_at": "შემდეგი შესვენება {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "პროგრამის შესახებ", @@ -43,13 +46,11 @@ "no_of_short_breaks_between_two_long_breaks": "მცირე შესვენებების რაოდენობა ორ დიდ შესვენებას შორის", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "გასვლა", "save": "დამახსოვრება", "settings": "პარამეტრები", "short_break_duration": "მცირე შესვენების ხანგრძლივობა (წამებში)", - "show_time_in_tray": "Show the next break time in system tray", + "show_time_in_tray": "Show the next break time in system tray", "skip": "გამოტოვება", "strict_break": "აუცილებელი შესვენება (დავმალოთ ღილაკი 'გამოტოვება')", "system_language": "System Language", diff --git a/safeeyes/config/lang/hi.json b/safeeyes/config/lang/hi.json index 2218cba..c6e0350 100644 --- a/safeeyes/config/lang/hi.json +++ b/safeeyes/config/lang/hi.json @@ -18,10 +18,13 @@ "long_break_lean_back": "पीछे हट कर आराम करें" }, "messages": { - "ready_for_a_break": "{} पलों में आराम", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "{} पलों में आराम", + "ready_for_a_long_break": "{} पलों में आराम", "disabled_until_restart": "अगले आरंभ तक बंद", "disabled_until_x": "{} तक बंद", - "next_break_at": "अगला आराम {} में" + "next_break_at": "अगला आराम {} में", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "हमारे बारे में", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "दो बड़े आराम के बीच कितने छोटे आराम", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "बंद", "save": "रखें", "settings": "सेटिंग्स", diff --git a/safeeyes/config/lang/hu.json b/safeeyes/config/lang/hu.json index 6e6fb63..2939cf2 100644 --- a/safeeyes/config/lang/hu.json +++ b/safeeyes/config/lang/hu.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Dőljön hátra és pihenjen!" }, "messages": { - "ready_for_a_break": "Tervezett szünet {} másodperc múlva!", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Tervezett szünet {} másodperc múlva!", + "ready_for_a_long_break": "Tervezett szünet {} másodperc múlva!", "disabled_until_restart": "Disabled until restart", "disabled_until_x": "Disabled until {}", - "next_break_at": "A következő szünet {}" + "next_break_at": "A következő szünet {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Ról ről", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Hány rövid szünet legyen a hosszabbak között?", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Kilépés", "save": "Mentés", "settings": "Beállítások", diff --git a/safeeyes/config/lang/id.json b/safeeyes/config/lang/id.json index 86ace59..eeb60ee 100644 --- a/safeeyes/config/lang/id.json +++ b/safeeyes/config/lang/id.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Silakan bersandar ke kursi dan bersantai" }, "messages": { - "ready_for_a_break": "Bersiap beristirahat dalam {} detik", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Bersiap beristirahat dalam {} detik", + "ready_for_a_long_break": "Bersiap beristirahat dalam {} detik", "disabled_until_restart": "Dimatikan hingga dijalankan ulang", "disabled_until_x": "Dimatikan hingga {}", - "next_break_at": "Istirahat selanjutnya pada {}" + "next_break_at": "Istirahat selanjutnya pada {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Tentang", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Jumlah istirahat singkat di antara dua istirahat panjang", "postpone": "Postpone", "postpone_duration": "Postpone duration (in minutes)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Keluar", "save": "Simpan", "settings": "Pengaturan", diff --git a/safeeyes/config/lang/mk.json b/safeeyes/config/lang/mk.json index 1fd701e..2e2daea 100644 --- a/safeeyes/config/lang/mk.json +++ b/safeeyes/config/lang/mk.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Наслонете се на столот и одморете" }, "messages": { - "ready_for_a_break": "Пауза за {} секунди", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Пауза за {} секунди", + "ready_for_a_long_break": "Пауза за {} секунди", "disabled_until_restart": "Оневозможено до рестарт", "disabled_until_x": "Оневозможено до {}", - "next_break_at": "Следна пауза во {}" + "next_break_at": "Следна пауза во {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "За", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Број на кратки паузи помеѓу две долги", "postpone": "Одложи", "postpone_duration": "Траење на одложувањето (Во секунди)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Исклучи", "save": "Зачувај", "settings": "Подесувања", diff --git a/safeeyes/config/lang/pl.json b/safeeyes/config/lang/pl.json index 8a948c3..631dfad 100644 --- a/safeeyes/config/lang/pl.json +++ b/safeeyes/config/lang/pl.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Oprzyj się wygodnie na krześle i zrelaksuj" }, "messages": { - "ready_for_a_break": "Przygotuj się! Przerwa za {} sekund(y).", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Przygotuj się! Przerwa za {} sekund(y).", + "ready_for_a_long_break": "Przygotuj się! Przerwa za {} sekund(y).", "disabled_until_restart": "Wyłączony do ponownego uruchomienia", "disabled_until_x": "Wyłączony do {}", - "next_break_at": "Następna przerwa o {}" + "next_break_at": "Następna przerwa o {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "O programie", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Liczba krótkich przerw między długimi przerwami", "postpone": "Odrocz", "postpone_duration": "Odroczenie przerwy (w minutach)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Wyjdź", "save": "Zapisz", "settings": "Ustawienia", diff --git a/safeeyes/config/lang/pt.json b/safeeyes/config/lang/pt.json index 7b38748..cb6dcd2 100644 --- a/safeeyes/config/lang/pt.json +++ b/safeeyes/config/lang/pt.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Encoste na cadeira e relaxe" }, "messages": { - "ready_for_a_break": "Pronto para uma pausa em {} segundos", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Pronto para uma pausa em {} segundos", + "ready_for_a_long_break": "Pronto para uma pausa em {} segundos", "disabled_until_restart": "Desativado até reiniciar", "disabled_until_x": "Desativado até {}", - "next_break_at": "Próxima pausa em {}" + "next_break_at": "Próxima pausa em {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Sobre", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Número de pausas curtas entre duas pausas longas", "postpone": "Adiar", "postpone_duration": "Duração do adiamento (em minutos)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Sair", "save": "Salvar", "settings": "Configuração", diff --git a/safeeyes/config/lang/ru.json b/safeeyes/config/lang/ru.json index 7f6da0d..204de83 100644 --- a/safeeyes/config/lang/ru.json +++ b/safeeyes/config/lang/ru.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Откиньтесь на спинку стула и расслабьтесь" }, "messages": { - "ready_for_a_break": "Приготовьтесь к перерыву через {} секунд", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Приготовьтесь к перерыву через {} секунд", + "ready_for_a_long_break": "Приготовьтесь к перерыву через {} секунд", "disabled_until_restart": "Отключено до перезагрузки", "disabled_until_x": "Отключено до {}", - "next_break_at": "Следующий перерыв в {}" + "next_break_at": "Следующий перерыв в {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "О программе", @@ -43,13 +46,11 @@ "no_of_short_breaks_between_two_long_breaks": "Количество коротких перерывов между двумя длинными", "postpone": "Отложить", "postpone_duration": "Отложить на время (в минутах)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Выйти", "save": "Сохранить", "settings": "Настройки", "short_break_duration": "Продолжительность короткого перерыва (в секундах)", - "show_time_in_tray": "Show the next break time in system tray", + "show_time_in_tray": "Show the next break time in system tray", "skip": "Пропустить", "strict_break": "Обязательный перерыв (Скрыть кнопку 'Пропустить')", "system_language": "System Language", diff --git a/safeeyes/config/lang/sk.json b/safeeyes/config/lang/sk.json index a133f57..bfd5a82 100644 --- a/safeeyes/config/lang/sk.json +++ b/safeeyes/config/lang/sk.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Opri sa o kreslo a relaxuj" }, "messages": { - "ready_for_a_break": "Priprav sa na prestávku o {} sekúnd", + "audible_alert_disabled": "Nieje možné zapnúť zvukové upozornenie", + "ready_for_a_short_break": "Priprav sa na prestávku o {} sekúnd", + "ready_for_a_long_break": "Priprav sa na prestávku o {} sekúnd", "disabled_until_restart": "Zakázať do reštartu", "disabled_until_x": "Zakázať do {}", - "next_break_at": "Ďalšia prestávka o {}" + "next_break_at": "Ďalšia prestávka o {}", + "software_required": "Pro ích povolenie nainstalujte {}" }, "ui_controls": { "about": "Ohľadom", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Počet krátkych prestávok medzi dvomi dlhými prestávkami", "postpone": "Odložiť", "postpone_duration": "O koĺko odložiť (minút)", - "pyaudio_not_installed": "Nieje možné zapnúť zvukové upozornenie", - "pyaudio_explanation": "Pro ích povolenie nainstalujte pyaudio", "quit": "Koniec", "save": "Uložiť", "settings": "Nastavenia", diff --git a/safeeyes/config/lang/ta.json b/safeeyes/config/lang/ta.json index 453a30b..9c39acf 100644 --- a/safeeyes/config/lang/ta.json +++ b/safeeyes/config/lang/ta.json @@ -18,10 +18,13 @@ "long_break_lean_back": "கதிைரயில் பின்பக்கமாக சாய்ந்து ஓய்வெடுங்கள்" }, "messages": { - "ready_for_a_break": "{} விநாடிகளில் இடைவேளைக்கு தயாராகுங்கள்", + "audible_alert_disabled": "ஒலிச் சமிக்ஞையை செயற்படுத்த முடியாதுள்ளது", + "ready_for_a_short_break": "{} விநாடிகளில் குறுகிய இடைவேளைக்கு தயாராகுங்கள்", + "ready_for_a_long_break": "{} விநாடிகளில் நீண்ட இடைவேளைக்கு தயாராகுங்கள்", "disabled_until_restart": "மறுதுவக்கம் வரை நிறுத்தி வைக்கப்பட்டுள்ளது", "disabled_until_x": "{} வரை நிறுத்தி வைக்கப்பட்டுள்ளது", - "next_break_at": "அடுத்த இடைவேளை {}" + "next_break_at": "அடுத்த இடைவேளை {}", + "software_required": "இந்த வசதியை செயற்படுத்த {} ஐ நிறுவவும்" }, "ui_controls": { "about": "Safe Eyes குறித்த தகவல்கள்", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "இரண்டு நீண்ட இடைவேளைகளுக்கிடையிலான குறுகிய இடைவேளைகள்", "postpone": "ஒத்தி வை", "postpone_duration": "இடைவேளையை ஒத்தி வைக்கும் காலம் (நிமிடங்களில்)", - "pyaudio_not_installed": "ஒலிச் சமிக்ஞையை செயற்படுத்த முடியாதுள்ளது", - "pyaudio_explanation": "ஒலிச் சமிக்ஞையை செயற்படுத்த pyaudio ஐ நிறுவவும்", "quit": "நிறுத்து", "save": "சேமி", "settings": "அமைப்பு", diff --git a/safeeyes/config/lang/tr.json b/safeeyes/config/lang/tr.json index 8a503b5..43234d5 100644 --- a/safeeyes/config/lang/tr.json +++ b/safeeyes/config/lang/tr.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Arkanıza yaslanın ve biraz gevşeyin" }, "messages": { - "ready_for_a_break": "{} Saniye içerisinde bir molaya hazır olun", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "{} Saniye içerisinde bir molaya hazır olun", + "ready_for_a_long_break": "{} Saniye içerisinde bir molaya hazır olun", "disabled_until_restart": "Tekrar başlatılana kadar devre dışı", "disabled_until_x": "{}'e kadar devre dışı", - "next_break_at": "Bir sonraki mola zamanı: {}" + "next_break_at": "Bir sonraki mola zamanı: {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Hakkında", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "İki uzun mola arasındaki kısa mola sayısı", "postpone": "Ertele", "postpone_duration": "Ertelme süresi (dakika)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Çıkış", "save": "Kaydet", "settings": "Ayarlar", diff --git a/safeeyes/config/lang/uk.json b/safeeyes/config/lang/uk.json index 317b4f1..95affab 100644 --- a/safeeyes/config/lang/uk.json +++ b/safeeyes/config/lang/uk.json @@ -18,10 +18,13 @@ "long_break_lean_back": "Відкиньтеся на спинку і розслабтеся" }, "messages": { - "ready_for_a_break": "Приготуйтеся до перерви через {} секунд", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Приготуйтеся до перерви через {} секунд", + "ready_for_a_long_break": "Приготуйтеся до перерви через {} секунд", "disabled_until_restart": "Відключено до перезапуску", "disabled_until_x": "Відключено до {}", - "next_break_at": "Наступна перерва о {}" + "next_break_at": "Наступна перерва о {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { "about": "Про SafeEyes", @@ -43,8 +46,6 @@ "no_of_short_breaks_between_two_long_breaks": "Кількість коротких перерв між двома довгими", "postpone": "Відкласти", "postpone_duration": "На скільки відкласти (в хвилинах)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Вийти", "save": "Зберегти", "settings": "Налаштування", diff --git a/safeeyes/config/lang/vi.json b/safeeyes/config/lang/vi.json index 92f1436..fe18e76 100644 --- a/safeeyes/config/lang/vi.json +++ b/safeeyes/config/lang/vi.json @@ -22,10 +22,13 @@ }, "messages": { - "ready_for_a_break": "Sẵn sàng để nghỉ ngơi {} giây", + "audible_alert_disabled": "Cannot enable audible notifications", + "ready_for_a_short_break": "Sẵn sàng để nghỉ ngơi {} giây", + "ready_for_a_long_break": "Sẵn sàng để nghỉ ngơi {} giây", "disabled_until_restart": "Vô hiệu hóa cho đến khi khởi động lại", "disabled_until_x": "Vô hiệu hóa cho đến khi {}", - "next_break_at": "Giờ nghỉ ngơi tiếp theo là {}" + "next_break_at": "Giờ nghỉ ngơi tiếp theo là {}", + "software_required": "To enable this feature, please install {}" }, "ui_controls": { @@ -48,8 +51,6 @@ "no_of_short_breaks_between_two_long_breaks": "Số lần nghỉ ngơi ngắn giữa hai lần nghỉ ngơi dài", "postpone": "Tạm hoãn", "postpone_duration": "Thời gian tạm hoãn (tính bằng phút)", - "pyaudio_not_installed": "Cannot enable audible notifications", - "pyaudio_explanation": "To enable them, install pyaudio", "quit": "Thoát", "save": "Lưu", "settings": "Cài đặt", From 8767dbef00a6fbf78e360d549a0f37433e4e09ca Mon Sep 17 00:00:00 2001 From: Gobinath Date: Sun, 2 Jul 2017 14:25:42 -0400 Subject: [PATCH 21/40] Show audible alert disabled message immediately to the user --- safeeyes/SettingsDialog.py | 27 +++++++++++++++++++++++---- safeeyes/Utility.py | 11 ----------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/safeeyes/SettingsDialog.py b/safeeyes/SettingsDialog.py index e6b69be..934b418 100644 --- a/safeeyes/SettingsDialog.py +++ b/safeeyes/SettingsDialog.py @@ -86,9 +86,6 @@ class SettingsDialog: # Enable idle_time_to_pause only if xprintidle is available self.spin_idle_time_to_pause.set_sensitive(Utility.command_exist('xprintidle')) - # Enable optional audible alert only if pyaudio is available - # self.switch_audible_alert.set_active(Utility.pyaudio is not None and config['audible_alert']) - self.switch_screen_lock.set_sensitive(able_to_lock_screen) self.switch_screen_lock.set_active(able_to_lock_screen and config['enable_screen_lock']) self.switch_postpone.set_active(config['allow_postpone'] and not config['strict_break']) @@ -103,6 +100,9 @@ class SettingsDialog: self.on_switch_screen_lock_activate(self.switch_screen_lock, self.switch_screen_lock.get_active()) self.on_switch_postpone_activate(self.switch_postpone, self.switch_postpone.get_active()) + if Utility.pyaudio is None: + self.switch_audible_alert.connect('state-set', self.on_switch_audible_alert_activate) + # Initialize the language combobox language_list_store = Gtk.ListStore(GObject.TYPE_STRING) language_index = 2 @@ -162,6 +162,16 @@ class SettingsDialog: """ self.spin_postpone_duration.set_sensitive(self.switch_postpone.get_active()) + def on_switch_audible_alert_activate(self, switch, state): + """ + Event handler to the state change of the audible_alert switch. + Show the information message dialog to install pyaudio if not installed. + """ + if state and Utility.pyaudio is None: + self.__show_message_dialog(self.language['messages']['audible_alert_disabled'], self.language['messages']['software_required'].format('pyaudio')) + switch.emit_stop_by_name('state-set') + self.switch_audible_alert.set_active(False) + def on_window_delete(self, *args): """ Event handler for Settings dialog close action. @@ -189,7 +199,7 @@ class SettingsDialog: # Check if pyaudio is installed when turning audible notifications on if self.switch_audible_alert.get_active() and not Utility.pyaudio: # Notify user that pyaudio is not installed - Utility.pyaudio_popup(self.window, self.language) + self.__show_message_dialog(self.language['messages']['audible_alert_disabled'], self.language['messages']['software_required'].format('pyaudio')) self.config['audible_alert'] = False else: self.config['audible_alert'] = self.switch_audible_alert.get_active() @@ -203,3 +213,12 @@ class SettingsDialog: Event handler for Cancel button click. """ self.window.destroy() + + def __show_message_dialog(self, primary_text, secondary_text): + """ + Show a popup message dialog. + """ + dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, primary_text) + dialog.format_secondary_text(secondary_text) + dialog.run() + dialog.destroy() \ No newline at end of file diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index 3535b6c..bda6109 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -47,17 +47,6 @@ def import_dependencies(): except ImportError: logging.warning('Install pyaudio for audible notifications.') -def pyaudio_popup(parent, language): - """ - Show a popup informing user to install pyaudio. - """ - dialog = Gtk.MessageDialog( - parent, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, - language['messages']['audible_alert_disabled']) - dialog.format_secondary_text( - language['messages']['software_required'].format('pyaudio')) - dialog.run() - dialog.destroy() def play_notification(): """ From 0f08c14cf4f2ce72da5bad3e1e8f92ea647d641c Mon Sep 17 00:00:00 2001 From: Gobinath Date: Sun, 2 Jul 2017 14:30:53 -0400 Subject: [PATCH 22/40] Set default values to optional properties --- safeeyes/SettingsDialog.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/safeeyes/SettingsDialog.py b/safeeyes/SettingsDialog.py index 934b418..e474e25 100644 --- a/safeeyes/SettingsDialog.py +++ b/safeeyes/SettingsDialog.py @@ -35,6 +35,8 @@ class SettingsDialog: builder.add_from_file(glade_file) builder.connect_signals(self) + xprintidle_available = Utility.command_exist('xprintidle') + # Get the UI components self.window = builder.get_object('window_settings') self.spin_short_break_duration = builder.get_object('spin_short_break_duration') @@ -76,15 +78,15 @@ class SettingsDialog: self.spin_interval_between_two_breaks.set_value(config['break_interval']) self.spin_short_between_long.set_value(config['no_of_short_breaks_per_long_break']) self.spin_time_to_prepare.set_value(config['pre_break_warning_time']) - self.spin_idle_time_to_pause.set_value(config['idle_time']) + self.spin_idle_time_to_pause.set_value(config['idle_time'] and xprintidle_available) self.spin_postpone_duration.set_value(config['postpone_duration']) self.switch_show_time_in_tray.set_active(config['show_time_in_tray']) self.switch_strict_break.set_active(config['strict_break']) - self.switch_audible_alert.set_active(config['audible_alert']) + self.switch_audible_alert.set_active(config['audible_alert'] and Utility.pyaudio is None) self.spin_time_to_screen_lock.set_value(config['time_to_screen_lock']) # Enable idle_time_to_pause only if xprintidle is available - self.spin_idle_time_to_pause.set_sensitive(Utility.command_exist('xprintidle')) + self.spin_idle_time_to_pause.set_sensitive(xprintidle_available) self.switch_screen_lock.set_sensitive(able_to_lock_screen) self.switch_screen_lock.set_active(able_to_lock_screen and config['enable_screen_lock']) From 4509aa1d189343dc51332c209714ba861c594fc2 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Sun, 2 Jul 2017 16:27:07 -0400 Subject: [PATCH 23/40] Add keyboard shortcuts to skip and postpone --- safeeyes/BreakScreen.py | 135 ++++++++++++++++----------- safeeyes/SafeEyesCore.py | 7 +- safeeyes/SettingsDialog.py | 4 + safeeyes/config/lang/ca.json | 1 + safeeyes/config/lang/cs.json | 1 + safeeyes/config/lang/de.json | 1 + safeeyes/config/lang/en.json | 1 + safeeyes/config/lang/es.json | 1 + safeeyes/config/lang/fa.json | 1 + safeeyes/config/lang/fr.json | 1 + safeeyes/config/lang/ge.json | 1 + safeeyes/config/lang/hi.json | 1 + safeeyes/config/lang/hu.json | 1 + safeeyes/config/lang/id.json | 1 + safeeyes/config/lang/mk.json | 1 + safeeyes/config/lang/pl.json | 1 + safeeyes/config/lang/pt.json | 1 + safeeyes/config/lang/ru.json | 1 + safeeyes/config/lang/sk.json | 1 + safeeyes/config/lang/ta.json | 1 + safeeyes/config/lang/tr.json | 1 + safeeyes/config/lang/uk.json | 1 + safeeyes/config/lang/vi.json | 1 + safeeyes/config/safeeyes.json | 6 +- safeeyes/glade/settings_dialog.glade | 68 ++++++++++---- 25 files changed, 160 insertions(+), 80 deletions(-) diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index a12146e..83da6fc 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -28,18 +28,18 @@ from gi.repository import Gtk, Gdk, GLib, GdkX11 """ class BreakScreen: - """ - Read the break_screen.glade and build the user interface. - """ def __init__(self, context, on_skip, on_postpone, glade_file, style_sheet_path): + """ + Read the break_screen.glade and build the user interface. + """ self.context = context self.on_skip = on_skip self.on_postpone = on_postpone self.is_pretified = False - self.key_lock_condition = threading.Condition() self.windows = [] self.count_labels = [] self.glade_file = glade_file + self.enable_shortcut = False # Initialize the theme css_provider = Gtk.CssProvider() @@ -47,63 +47,81 @@ class BreakScreen: Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - """ - Initialize the internal properties from configuration - """ def initialize(self, config, language): + """ + Initialize the internal properties from configuration + """ logging.info("Initialize the break screen") self.skip_button_text = language['ui_controls']['skip'] self.postpone_button_text = language['ui_controls']['postpone'] self.strict_break = config.get('strict_break', False) self.enable_postpone = config.get('allow_postpone', False) + self.keycode_shortcut_skip = config.get('shortcut_skip', 9) + self.keycode_shortcut_postpone = config.get('shortcut_postpone', 65) + self.shortcut_disable_time = config.get('shortcut_disable_time', 2) - """ - Window close event handler. - """ - def on_window_delete(self, *args): - logging.info("Closing the break screen") - self.lock_keyboard = False - self.close() - - - """ - Skip button press event handler. - """ - def on_skip_clicked(self, button): + def skip_break(self): + """ + Skip the break from the break screen + """ logging.info("User skipped the break") # Must call on_skip before close to lock screen before closing the break screen self.on_skip() self.close() - - - """ - Postpone button press event handler. - """ - def on_postpone_clicked(self, button): + + def postpone_break(self): + """ + Postpone the break from the break screen + """ logging.info("User postponed the break") self.on_postpone() self.close() + def on_window_delete(self, *args): + """ + Window close event handler. + """ + logging.info("Closing the break screen") + self.__release_keyboard() + self.close() - """ + + def on_skip_clicked(self, button): + """ + Skip button press event handler. + """ + self.skip_break() + + + def on_postpone_clicked(self, button): + """ + Postpone button press event handler. + """ + self.postpone_break() + + def show_count_down(self, count_down, seconds): + """ Show/update the count down on all screens. - """ - def show_count_down(self, count): - GLib.idle_add(lambda: self.__update_count_down(count)) + """ + self.enable_shortcut = not self.strict_break and self.shortcut_disable_time <= count_down + mins, secs = divmod(seconds, 60) + timeformat = '{:02d}:{:02d}'.format(mins, secs) + GLib.idle_add(lambda: self.__update_count_down(timeformat)) - """ - Show the break screen with the given message on all displays. - """ def show_message(self, message, image_path, plugins_data): + """ + Show the break screen with the given message on all displays. + """ + self.enable_shortcut = not self.strict_break and self.shortcut_disable_time <= 0 GLib.idle_add(lambda: self.__show_break_screen(message, image_path, plugins_data)) - """ - Hide the break screen from active window and destroy all other windows - """ def close(self): + """ + Hide the break screen from active window and destroy all other windows + """ logging.info("Close the break screen(s)") self.__release_keyboard() @@ -111,10 +129,10 @@ class BreakScreen: GLib.idle_add(lambda: self.__destroy_all_screens()) - """ - Show an empty break screen on all screens. - """ def __show_break_screen(self, message, image_path, plugins_data): + """ + Show an empty break screen on all screens. + """ # Lock the keyboard thread = threading.Thread(target=self.__lock_keyboard) thread.start() @@ -182,18 +200,18 @@ class BreakScreen: window.fullscreen() - """ - Update the countdown on all break screens. - """ def __update_count_down(self, count): + """ + Update the countdown on all break screens. + """ for label in self.count_labels: label.set_text(count) - """ - Lock the keyboard to prevent the user from using keyboard shortcuts - """ def __lock_keyboard(self): + """ + Lock the keyboard to prevent the user from using keyboard shortcuts + """ logging.info("Lock the keyboard") self.lock_keyboard = True display = Display() @@ -201,10 +219,16 @@ class BreakScreen: # Grap the keyboard root.grab_keyboard(owner_events = False, pointer_mode = X.GrabModeAsync, keyboard_mode = X.GrabModeAsync, time = X.CurrentTime) # Consume keyboard events - self.key_lock_condition.acquire() while self.lock_keyboard: - self.key_lock_condition.wait() - self.key_lock_condition.release() + event = display.next_event() + display.allow_events(mode = X.AsyncBoth, time = X.CurrentTime) + if self.enable_shortcut and event.type == X.KeyPress: + if event.detail == self.keycode_shortcut_skip: + self.skip_break() + break + elif self.enable_postpone and event.detail == self.keycode_shortcut_postpone: + self.postpone_break() + break # Ungrap the keyboard logging.info("Unlock the keyboard") @@ -212,20 +236,17 @@ class BreakScreen: display.flush() - """ - Release the locked keyboard. - """ def __release_keyboard(self): - self.key_lock_condition.acquire() + """ + Release the locked keyboard. + """ self.lock_keyboard = False - self.key_lock_condition.notify() - self.key_lock_condition.release() - """ - Close all the break screens. - """ def __destroy_all_screens(self): + """ + Close all the break screens. + """ for win in self.windows: win.destroy() del self.windows[:] diff --git a/safeeyes/SafeEyesCore.py b/safeeyes/SafeEyesCore.py index 7961df7..3cba336 100644 --- a/safeeyes/SafeEyesCore.py +++ b/safeeyes/SafeEyesCore.py @@ -308,10 +308,9 @@ class SafeEyesCore: # Use self.active instead of self.__is_running to avoid idle pause interrupting the break while seconds and self.active and not self.context['skipped'] and not self.context['postponed']: - self.context['count_down'] = total_break_time - seconds - mins, secs = divmod(seconds, 60) - timeformat = '{:02d}:{:02d}'.format(mins, secs) - self.on_countdown(timeformat) + count_down = total_break_time - seconds + self.context['count_down'] = count_down + self.on_countdown(count_down, seconds) time.sleep(1) # Sleep for 1 second seconds -= 1 diff --git a/safeeyes/SettingsDialog.py b/safeeyes/SettingsDialog.py index e474e25..c278a02 100644 --- a/safeeyes/SettingsDialog.py +++ b/safeeyes/SettingsDialog.py @@ -46,6 +46,7 @@ class SettingsDialog: self.spin_time_to_prepare = builder.get_object('spin_time_to_prepare') self.spin_idle_time_to_pause = builder.get_object('spin_idle_time_to_pause') self.spin_postpone_duration = builder.get_object('spin_postpone_duration') + self.spin_disable_keyboard_shortcut = builder.get_object('spin_disable_keyboard_shortcut') self.switch_show_time_in_tray = builder.get_object('switch_show_time_in_tray') self.switch_strict_break = builder.get_object('switch_strict_break') self.switch_postpone = builder.get_object('switch_postpone') @@ -63,6 +64,7 @@ class SettingsDialog: builder.get_object('lbl_idle_time_to_pause').set_label(language['ui_controls']['idle_time']) builder.get_object('lbl_postpone_duration').set_label(language['ui_controls']['postpone_duration']) builder.get_object('lbl_allow_postpone').set_label(language['ui_controls']['allow_postpone']) + builder.get_object('lbl_disable_keyboard_shortcut').set_label(language['ui_controls']['disable_keyboard_shortcut']) builder.get_object('lbl_show_time_in_tray').set_label(language['ui_controls']['show_time_in_tray']) builder.get_object('lbl_strict_break').set_label(language['ui_controls']['strict_break']) builder.get_object('lbl_audible_alert').set_label(language['ui_controls']['audible_alert']) @@ -80,6 +82,7 @@ class SettingsDialog: self.spin_time_to_prepare.set_value(config['pre_break_warning_time']) self.spin_idle_time_to_pause.set_value(config['idle_time'] and xprintidle_available) self.spin_postpone_duration.set_value(config['postpone_duration']) + self.spin_disable_keyboard_shortcut.set_value(config['shortcut_disable_time']) self.switch_show_time_in_tray.set_active(config['show_time_in_tray']) self.switch_strict_break.set_active(config['strict_break']) self.switch_audible_alert.set_active(config['audible_alert'] and Utility.pyaudio is None) @@ -192,6 +195,7 @@ class SettingsDialog: self.config['pre_break_warning_time'] = self.spin_time_to_prepare.get_value_as_int() self.config['idle_time'] = self.spin_idle_time_to_pause.get_value_as_int() self.config['postpone_duration'] = self.spin_postpone_duration.get_value_as_int() + self.config['shortcut_disable_time'] = self.spin_disable_keyboard_shortcut.get_value_as_int() self.config['show_time_in_tray'] = self.switch_show_time_in_tray.get_active() self.config['strict_break'] = self.switch_strict_break.get_active() self.config['language'] = self.languages[self.cmb_language.get_active()] diff --git a/safeeyes/config/lang/ca.json b/safeeyes/config/lang/ca.json index f97dd52..dee29a4 100644 --- a/safeeyes/config/lang/ca.json +++ b/safeeyes/config/lang/ca.json @@ -33,6 +33,7 @@ "cancel": "Canceŀla", "close": "Tanca", "disable": "Desactiva Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Activa Safe Eyes", "enable_screen_lock": "Bloca la pantalla després de cada pausa llarga", "for_x_hour": "Durant {} hora", diff --git a/safeeyes/config/lang/cs.json b/safeeyes/config/lang/cs.json index 8937c9b..27f58f2 100644 --- a/safeeyes/config/lang/cs.json +++ b/safeeyes/config/lang/cs.json @@ -33,6 +33,7 @@ "cancel": "Zrušit", "close": "Close", "disable": "Pozastavit Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Zapnout Safe Eyes", "enable_screen_lock": "Po každé dlouhé přestávce uzamknout obrazovku", "for_x_hour": "Na {} hodinu", diff --git a/safeeyes/config/lang/de.json b/safeeyes/config/lang/de.json index e3487f2..67a61dc 100644 --- a/safeeyes/config/lang/de.json +++ b/safeeyes/config/lang/de.json @@ -33,6 +33,7 @@ "cancel": "Abbrechen", "close": "Schließen", "disable": "Safe Eyes deaktivieren", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Safe Eyes aktivieren", "enable_screen_lock": "Sperrt den Bildschirm nach einer langen Pause", "for_x_hour": "Für {} Stunde", diff --git a/safeeyes/config/lang/en.json b/safeeyes/config/lang/en.json index 2581d4e..1c851df 100644 --- a/safeeyes/config/lang/en.json +++ b/safeeyes/config/lang/en.json @@ -33,6 +33,7 @@ "cancel": "Cancel", "close": "Close", "disable": "Disable Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Enable Safe Eyes", "enable_screen_lock": "Lock the screen after every long break", "for_x_hour": "For {} Hour", diff --git a/safeeyes/config/lang/es.json b/safeeyes/config/lang/es.json index a3216b2..703be5f 100644 --- a/safeeyes/config/lang/es.json +++ b/safeeyes/config/lang/es.json @@ -33,6 +33,7 @@ "cancel": "Cancelar", "close": "Close", "disable": "Desactivar Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Activar Safe Eyes", "enable_screen_lock": "Bloquear la pantalla despues de cada pausa larga", "for_x_hour": "Durante {} hora", diff --git a/safeeyes/config/lang/fa.json b/safeeyes/config/lang/fa.json index ecc2750..57a7ecc 100644 --- a/safeeyes/config/lang/fa.json +++ b/safeeyes/config/lang/fa.json @@ -33,6 +33,7 @@ "cancel": "لغو", "close": "بستن", "disable": "غیر فعال کردن Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "فعال کردن Safe Eyes", "enable_screen_lock": "قفل کردن صفحه بعد از هر استراحت طولانی", "for_x_hour": "برای {} ساعت", diff --git a/safeeyes/config/lang/fr.json b/safeeyes/config/lang/fr.json index 1e7ab20..4bb3ed8 100644 --- a/safeeyes/config/lang/fr.json +++ b/safeeyes/config/lang/fr.json @@ -33,6 +33,7 @@ "cancel": "Annuler", "close": "Fermer", "disable": "Désactiver Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Activer Safe Eyes", "enable_screen_lock": "Verrouiller l'écran après chaque pause longue", "for_x_hour": "Pendant {} heure", diff --git a/safeeyes/config/lang/ge.json b/safeeyes/config/lang/ge.json index 4aee8ae..a711ca8 100644 --- a/safeeyes/config/lang/ge.json +++ b/safeeyes/config/lang/ge.json @@ -33,6 +33,7 @@ "cancel": "უარყოფა", "close": "Close", "disable": "Safe Eyes გამორთვა", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Safe Eyes ჩართვა", "enable_screen_lock": "Lock the screen after every long break", "for_x_hour": "{} საათით", diff --git a/safeeyes/config/lang/hi.json b/safeeyes/config/lang/hi.json index c6e0350..db39c16 100644 --- a/safeeyes/config/lang/hi.json +++ b/safeeyes/config/lang/hi.json @@ -33,6 +33,7 @@ "cancel": "रखना नहीं", "close": "Close", "disable": "सेफ आईज बंद", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "सेफ आईज शुरू", "enable_screen_lock": "Lock the screen after every long break", "for_x_hour": "{} घंटे के लिए", diff --git a/safeeyes/config/lang/hu.json b/safeeyes/config/lang/hu.json index 2939cf2..8d1ca81 100644 --- a/safeeyes/config/lang/hu.json +++ b/safeeyes/config/lang/hu.json @@ -33,6 +33,7 @@ "cancel": "Mégse", "close": "Close", "disable": "Disable Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Safe Eyes Bekapcsolása", "enable_screen_lock": "Lock the screen after every long break", "for_x_hour": "For {} Hour", diff --git a/safeeyes/config/lang/id.json b/safeeyes/config/lang/id.json index eeb60ee..a879b53 100644 --- a/safeeyes/config/lang/id.json +++ b/safeeyes/config/lang/id.json @@ -33,6 +33,7 @@ "cancel": "Batal", "close": "Close", "disable": "Matikan Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Hidupkan Safe Eyes", "enable_screen_lock": "Lock the screen after every long break", "for_x_hour": "Selama {} Jam", diff --git a/safeeyes/config/lang/mk.json b/safeeyes/config/lang/mk.json index 2e2daea..920e8db 100644 --- a/safeeyes/config/lang/mk.json +++ b/safeeyes/config/lang/mk.json @@ -33,6 +33,7 @@ "cancel": "Откажи", "close": "Затвори", "disable": "Оневозможете го Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Овозможете го Safe Eyes", "enable_screen_lock": "Заклучување на екранот по секоја долга пауза", "for_x_hour": "За {} час", diff --git a/safeeyes/config/lang/pl.json b/safeeyes/config/lang/pl.json index 631dfad..3545eea 100644 --- a/safeeyes/config/lang/pl.json +++ b/safeeyes/config/lang/pl.json @@ -33,6 +33,7 @@ "cancel": "Anuluj", "close": "Zamknij", "disable": "Zatrzymaj Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Uruchom Safe Eyes", "enable_screen_lock": "Zablokuj ekran po każdej długiej przerwie", "for_x_hour": "Na {} godzinę", diff --git a/safeeyes/config/lang/pt.json b/safeeyes/config/lang/pt.json index cb6dcd2..f68de6b 100644 --- a/safeeyes/config/lang/pt.json +++ b/safeeyes/config/lang/pt.json @@ -33,6 +33,7 @@ "cancel": "Cancelar", "close": "Fechar", "disable": "Desativar Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Habilitar Safe Eyes", "enable_screen_lock": "Bloqueie a tela após cada pausa longa", "for_x_hour": "Por {} Hora", diff --git a/safeeyes/config/lang/ru.json b/safeeyes/config/lang/ru.json index 204de83..2211935 100644 --- a/safeeyes/config/lang/ru.json +++ b/safeeyes/config/lang/ru.json @@ -33,6 +33,7 @@ "cancel": "Отменить", "close": "Close", "disable": "Отключить Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Активировать Safe Eyes", "enable_screen_lock": "Включить блокировку экрана", "for_x_hour": "На {} час", diff --git a/safeeyes/config/lang/sk.json b/safeeyes/config/lang/sk.json index bfd5a82..20ecc8e 100644 --- a/safeeyes/config/lang/sk.json +++ b/safeeyes/config/lang/sk.json @@ -33,6 +33,7 @@ "cancel": "Zrušiť", "close": "Close", "disable": "Zakázať Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Povoliť Safe Eyes", "enable_screen_lock": "Zablokovať obrazovku po každej dlhej prestávke", "for_x_hour": "Počas {} hodiny", diff --git a/safeeyes/config/lang/ta.json b/safeeyes/config/lang/ta.json index 9c39acf..b65ead2 100644 --- a/safeeyes/config/lang/ta.json +++ b/safeeyes/config/lang/ta.json @@ -33,6 +33,7 @@ "cancel": "ரத்து", "close": "மூடு", "disable": "Safe Eyes ஐ நிறுத்துக", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Safe Eyes ஐ செயல்படுத்துக", "enable_screen_lock": "நீண்ட கால இடைவேளைகளின் பின்னர் திரையை பூட்டுக", "for_x_hour": "{} மணித்தியாலத்திற்கு", diff --git a/safeeyes/config/lang/tr.json b/safeeyes/config/lang/tr.json index 43234d5..be3efb2 100644 --- a/safeeyes/config/lang/tr.json +++ b/safeeyes/config/lang/tr.json @@ -33,6 +33,7 @@ "cancel": "İptal", "close": "Kapat", "disable": "Safe Eyes'ı devre dışı bırak", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Safe Eyes'ı etkinleştir", "enable_screen_lock": "Her uzun mola sonunda ekranı kilitle", "for_x_hour": "{} Saat", diff --git a/safeeyes/config/lang/uk.json b/safeeyes/config/lang/uk.json index 95affab..6bf82a3 100644 --- a/safeeyes/config/lang/uk.json +++ b/safeeyes/config/lang/uk.json @@ -33,6 +33,7 @@ "cancel": "Відмінити", "close": "Закрити", "disable": "Відключити Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Включити Safe Eyes", "enable_screen_lock": "Блокувати екран після довгих перерв", "for_x_hour": "На {} годину", diff --git a/safeeyes/config/lang/vi.json b/safeeyes/config/lang/vi.json index fe18e76..abd03d8 100644 --- a/safeeyes/config/lang/vi.json +++ b/safeeyes/config/lang/vi.json @@ -38,6 +38,7 @@ "cancel": "Huỷ", "close": "Đóng", "disable": "Tắt Safe Eyes", + "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", "enable": "Bật Safe Eyes", "enable_screen_lock": "Khoá màn hình ở mỗi thời điểm nghỉ ngơi dài", "for_x_hour": "Trong {} giờ", diff --git a/safeeyes/config/safeeyes.json b/safeeyes/config/safeeyes.json index 016cf83..0a7b9f2 100644 --- a/safeeyes/config/safeeyes.json +++ b/safeeyes/config/safeeyes.json @@ -1,6 +1,6 @@ { "meta": { - "config_version": "5.0.1" + "config_version": "5.0.2" }, "allow_postpone": false, "break_interval": 15, @@ -10,7 +10,11 @@ "pre_break_warning_time": 10, "short_break_duration": 15, "idle_time": 5, + "persist_state": true, "postpone_duration": 5, + "shortcut_disable_time": 2, + "shortcut_skip": 9, + "shortcut_postpone": 65, "show_time_in_tray": false, "strict_break": false, "audible_alert": false, diff --git a/safeeyes/glade/settings_dialog.glade b/safeeyes/glade/settings_dialog.glade index f2d1308..ecc02ab 100644 --- a/safeeyes/glade/settings_dialog.glade +++ b/safeeyes/glade/settings_dialog.glade @@ -52,6 +52,12 @@ 1 5 + + 1 + 15 + 1 + 5 + 1 60 @@ -189,7 +195,7 @@ 0 - 9 + 10 @@ -202,7 +208,7 @@ 0 - 6 + 7 @@ -215,7 +221,7 @@ 0 - 7 + 8 @@ -346,7 +352,7 @@ 1 - 9 + 10 @@ -358,7 +364,7 @@ 1 - 6 + 7 @@ -370,7 +376,7 @@ 1 - 7 + 8 @@ -382,7 +388,7 @@ 1 - 10 + 11 @@ -395,7 +401,7 @@ 0 - 10 + 11 @@ -405,7 +411,7 @@ 1 - 13 + 14 @@ -418,7 +424,7 @@ 0 - 13 + 14 @@ -431,7 +437,7 @@ 0 - 11 + 12 @@ -442,7 +448,7 @@ 1 - 11 + 12 @@ -455,7 +461,7 @@ 0 - 12 + 13 @@ -474,7 +480,7 @@ 1 - 12 + 13 @@ -487,7 +493,7 @@ 0 - 8 + 9 @@ -498,14 +504,40 @@ 1 - 8 + 9 - + + True + False + start + center + Disable keyboard shortcut + + + 0 + 6 + - + + True + True + end + center + 1 + number + adjust_disable_keyboard_shortcut_duration + 1 + True + if-valid + 1 + + + 1 + 6 + From 1162d19c63b79abf10a9169ae223a8a4f5a4a48b Mon Sep 17 00:00:00 2001 From: Jalakas Date: Wed, 5 Jul 2017 22:59:04 +0300 Subject: [PATCH 24/40] flake8 suggested fixes Ignored these: tabs vs spaces, multiple imports on single line, import not on top of file, too long lines. --- safeeyes/AboutDialog.py | 7 +++---- safeeyes/BreakScreen.py | 30 +++++++++--------------------- safeeyes/Notification.py | 10 +++------- safeeyes/Plugins.py | 26 +++++++++++--------------- safeeyes/SafeEyesCore.py | 31 +++++++++---------------------- safeeyes/SettingsDialog.py | 22 +++++++++------------- safeeyes/TrayIcon.py | 3 +-- safeeyes/Utility.py | 26 ++++++++++++++------------ safeeyes/__main__.py | 21 +++++++++++++++++---- setup.py | 12 +++++++----- 10 files changed, 83 insertions(+), 105 deletions(-) diff --git a/safeeyes/AboutDialog.py b/safeeyes/AboutDialog.py index f750488..aeea6a5 100644 --- a/safeeyes/AboutDialog.py +++ b/safeeyes/AboutDialog.py @@ -18,13 +18,15 @@ import gi gi.require_version('Gtk', '3.0') -from gi.repository import Gtk, Gdk, GdkX11 +from gi.repository import Gtk """ AboutDialog reads the about_dialog.glade and build the user interface using that file. It shows the application name with version, a small description, license and the GitHub url. """ + + class AboutDialog: """ @@ -42,21 +44,18 @@ class AboutDialog: # Set the version at the runtime builder.get_object("lbl_app_name").set_label("Safe Eyes " + version) - """ Show the About dialog. """ def show(self): self.window.show_all() - """ Window close event handler. """ def on_window_delete(self, *args): self.window.destroy() - """ Close button click event handler. """ diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index 83da6fc..68d437c 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -16,16 +16,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import gi, signal, sys, threading, logging -from Xlib import Xatom, Xutil +import gi, threading, logging from Xlib.display import Display, X gi.require_version('Gtk', '3.0') -from gi.repository import Gtk, Gdk, GLib, GdkX11 +from gi.repository import Gtk, Gdk, GLib """ The fullscreen window which prevents users from using the computer. """ + + class BreakScreen: def __init__(self, context, on_skip, on_postpone, glade_file, style_sheet_path): @@ -46,7 +47,6 @@ class BreakScreen: css_provider.load_from_path(style_sheet_path) Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - def initialize(self, config, language): """ Initialize the internal properties from configuration @@ -60,7 +60,6 @@ class BreakScreen: self.keycode_shortcut_postpone = config.get('shortcut_postpone', 65) self.shortcut_disable_time = config.get('shortcut_disable_time', 2) - def skip_break(self): """ Skip the break from the break screen @@ -69,7 +68,7 @@ class BreakScreen: # Must call on_skip before close to lock screen before closing the break screen self.on_skip() self.close() - + def postpone_break(self): """ Postpone the break from the break screen @@ -86,14 +85,12 @@ class BreakScreen: self.__release_keyboard() self.close() - def on_skip_clicked(self, button): """ Skip button press event handler. """ self.skip_break() - def on_postpone_clicked(self, button): """ Postpone button press event handler. @@ -109,7 +106,6 @@ class BreakScreen: timeformat = '{:02d}:{:02d}'.format(mins, secs) GLib.idle_add(lambda: self.__update_count_down(timeformat)) - def show_message(self, message, image_path, plugins_data): """ Show the break screen with the given message on all displays. @@ -117,7 +113,6 @@ class BreakScreen: self.enable_shortcut = not self.strict_break and self.shortcut_disable_time <= 0 GLib.idle_add(lambda: self.__show_break_screen(message, image_path, plugins_data)) - def close(self): """ Hide the break screen from active window and destroy all other windows @@ -128,7 +123,6 @@ class BreakScreen: # Destroy other windows if exists GLib.idle_add(lambda: self.__destroy_all_screens()) - def __show_break_screen(self, message, image_path, plugins_data): """ Show an empty break screen on all screens. @@ -175,14 +169,12 @@ class BreakScreen: btn_skip.set_visible(True) box_buttons.pack_start(btn_skip, True, True, 0) - - # Set values if image_path: img_break.set_from_file(image_path) lbl_message.set_label(message) - lbl_left.set_markup(plugins_data['left']); - lbl_right.set_markup(plugins_data['right']); + lbl_left.set_markup(plugins_data['left']) + lbl_right.set_markup(plugins_data['right']) self.windows.append(window) self.count_labels.append(lbl_count) @@ -199,7 +191,6 @@ class BreakScreen: window.present() window.fullscreen() - def __update_count_down(self, count): """ Update the countdown on all break screens. @@ -207,7 +198,6 @@ class BreakScreen: for label in self.count_labels: label.set_text(count) - def __lock_keyboard(self): """ Lock the keyboard to prevent the user from using keyboard shortcuts @@ -217,11 +207,11 @@ class BreakScreen: display = Display() root = display.screen().root # Grap the keyboard - root.grab_keyboard(owner_events = False, pointer_mode = X.GrabModeAsync, keyboard_mode = X.GrabModeAsync, time = X.CurrentTime) + root.grab_keyboard(owner_events=False, pointer_mode=X.GrabModeAsync, keyboard_mode=X.GrabModeAsync, time=X.CurrentTime) # Consume keyboard events while self.lock_keyboard: event = display.next_event() - display.allow_events(mode = X.AsyncBoth, time = X.CurrentTime) + display.allow_events(mode=X.AsyncBoth, time=X.CurrentTime) if self.enable_shortcut and event.type == X.KeyPress: if event.detail == self.keycode_shortcut_skip: self.skip_break() @@ -235,14 +225,12 @@ class BreakScreen: display.ungrab_keyboard(X.CurrentTime) display.flush() - def __release_keyboard(self): """ Release the locked keyboard. """ self.lock_keyboard = False - def __destroy_all_screens(self): """ Close all the break screens. diff --git a/safeeyes/Notification.py b/safeeyes/Notification.py index 96b48bc..affbd49 100644 --- a/safeeyes/Notification.py +++ b/safeeyes/Notification.py @@ -24,12 +24,12 @@ from safeeyes import Utility APPINDICATOR_ID = 'safeeyes' + class Notification: """ This class is responsible for the notification to the user before the break. """ - def __init__(self, context, language): """ Initialize the notification. @@ -39,13 +39,11 @@ class Notification: self.context = context self.language = language - def initialize(self, language): """ Initialize the notification object. """ self.language = language - def show(self, warning_time): """ @@ -59,14 +57,13 @@ class Notification: message += self.language['messages']['ready_for_a_short_break'].format(warning_time) else: message += self.language['messages']['ready_for_a_long_break'].format(warning_time) - + self.notification = Notify.Notification.new('Safe Eyes', message, icon='safeeyes_enabled') try: self.notification.show() except Exception as e: logging.exception('Error in showing notification', e) - def close(self): """ Close the notification if it is not closed by the system already. @@ -78,10 +75,9 @@ class Notification: # Some Linux systems automatically close the notification. pass - def quite(self): """ Uninitialize the notification. Call this method when closing the application. """ logging.info('Uninitialize Safe Eyes notification') - Utility.execute_main_thread(Notify.uninit) \ No newline at end of file + Utility.execute_main_thread(Notify.uninit) diff --git a/safeeyes/Plugins.py b/safeeyes/Plugins.py index 6fa18bd..221cd5b 100644 --- a/safeeyes/Plugins.py +++ b/safeeyes/Plugins.py @@ -23,12 +23,12 @@ from safeeyes import Utility plugins_directory = os.path.join(Utility.config_directory, 'plugins') sys.path.append(os.path.abspath(plugins_directory)) + class Plugins: """ This class manages imports the plugins and calls the methods defined in those plugins. """ - def __init__(self, config): """ Load the plugins. @@ -47,18 +47,17 @@ class Plugins: else: logging.warning('Plugin file ' + str(plugin['name']) + '.py not found') else: - logging.warning('Ignoring the plugin ' + str(plugin['name']) + ' due to invalid location value: ' + plugin['location']) - + logging.warning('Ignoring the plugin ' + str(plugin['name']) + ' due to invalid location value: ' + plugin['location']) + if self.__plugins: self.__thread_pool = ThreadPool(min([4, len(self.__plugins)])) - def start(self, context): """ Call the start function of all the plugins in separate thread. """ if self.__plugins: - context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes + context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes for plugin in self.__plugins: try: self.__thread_pool.apply_async(plugin['module'].start, (context,)) @@ -70,14 +69,13 @@ class Plugins: Call the pre_notification function of all the plugins in separate thread. """ if self.__plugins: - context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes + context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes for plugin in self.__plugins: try: self.__thread_pool.apply_async(plugin['module'].pre_notification, (context,)) except Exception as e: pass - def pre_break(self, context): """ Call the pre_break function of all the plugins and provide maximum 1 second to return the result. @@ -87,14 +85,14 @@ class Plugins: """ output = {'left': ' \n', 'right': ' \n'} if self.__plugins: - context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes + context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes multiple_results = [self.__thread_pool.apply_async(plugin['module'].pre_break, (context,)) for plugin in self.__plugins] for i in range(len(multiple_results)): try: result = multiple_results[i].get(timeout=1) if result: # Limit the line length to 50 characters - large_lines = list(filter(lambda x: len(x) > 50, Utility.html_to_text(result).splitlines())) + large_lines = list(filter(lambda x: len(x) > 50, Utility.html_to_text(result).splitlines())) if large_lines: logging.warning('Ignoring lengthy result from the plugin ' + self.__plugins[i]['name']) continue @@ -105,13 +103,12 @@ class Plugins: return output - def post_break(self, context): """ Call the post_break function of all the plugins in separate thread. """ if self.__plugins: - context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes + context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes for plugin in self.__plugins: try: self.__thread_pool.apply_async(plugin['module'].post_break, (context,)) @@ -123,7 +120,7 @@ class Plugins: Call the exit function of all the plugins in separate thread. """ if self.__plugins: - context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes + context = copy.deepcopy(context) # If plugins change the context, it should not affect Safe Eyes # Give maximum 1 sec for all plugins before terminating the thread pool multiple_results = [self.__thread_pool.apply_async(plugin['module'].exit, (context,)) for plugin in self.__plugins] @@ -135,12 +132,11 @@ class Plugins: pass try: - self.__thread_pool.terminate() # Shutdown the pool + self.__thread_pool.terminate() # Shutdown the pool except Exception as e: pass - - def __has_method(self, module, method_name, no_of_args = 1): + def __has_method(self, module, method_name, no_of_args=1): """ Check whether the given function is defined in the module or not. """ diff --git a/safeeyes/SafeEyesCore.py b/safeeyes/SafeEyesCore.py index 3cba336..fa79e92 100644 --- a/safeeyes/SafeEyesCore.py +++ b/safeeyes/SafeEyesCore.py @@ -17,13 +17,15 @@ # along with this program. If not, see . -import time, datetime, threading, sys, subprocess, logging +import time, datetime, threading, logging from safeeyes import Utility """ Core of Safe Eyes which runs the scheduler and notifies the breaks. """ + + class SafeEyesCore: """ @@ -48,14 +50,13 @@ class SafeEyesCore: self.context['skipped'] = False self.context['postponed'] = False - """ Initialize the internal properties from configuration """ def initialize(self, config, language): logging.info("Initialize the core") - self.short_break_exercises = [] #language['exercises']['short_break_exercises'] - self.long_break_exercises = [] #language['exercises']['long_break_exercises'] + self.short_break_exercises = [] # language['exercises']['short_break_exercises'] + self.long_break_exercises = [] # language['exercises']['long_break_exercises'] self.no_of_short_breaks_per_long_break = config['no_of_short_breaks_per_long_break'] self.pre_break_warning_time = config['pre_break_warning_time'] @@ -111,7 +112,6 @@ class SafeEyesCore: self.long_break_exercises.append([name, break_time, audible_alert, image]) - """ Start Safe Eyes is it is not running already. """ @@ -125,7 +125,6 @@ class SafeEyesCore: if self.context['idle_pause_enabled']: Utility.start_thread(self.__start_idle_monitor) - """ Stop Safe Eyes if it is running. """ @@ -150,7 +149,6 @@ class SafeEyesCore: self.idle_condition.notify_all() self.idle_condition.release() - """ Pause Safe Eyes if it is running. """ @@ -162,7 +160,6 @@ class SafeEyesCore: self.notification_condition.notify_all() self.notification_condition.release() - """ Resume Safe Eyes if it is not running. """ @@ -172,7 +169,6 @@ class SafeEyesCore: self.running = True Utility.start_thread(self.__scheduler_job) - """ User skipped the break using Skip button """ @@ -185,7 +181,6 @@ class SafeEyesCore: def postpone_break(self): self.context['postponed'] = True - """ Scheduler task to execute during every interval """ @@ -193,7 +188,7 @@ class SafeEyesCore: if not self.__is_running(): return - time_to_wait = self.break_interval # In minutes + time_to_wait = self.break_interval # In minutes if self.context['postponed']: # Reduce the break count by 1 to show the same break again @@ -222,7 +217,7 @@ class SafeEyesCore: # Wait for the pre break warning period logging.info("Pre-break waiting for {} minutes".format(time_to_wait)) self.notification_condition.acquire() - self.notification_condition.wait(time_to_wait * 60) # Convert to seconds + self.notification_condition.wait(time_to_wait * 60) # Convert to seconds self.notification_condition.release() logging.info("Pre-break waiting is over") @@ -235,7 +230,6 @@ class SafeEyesCore: self.is_before_break = False Utility.execute_main_thread(self.__check_active_window) - """ Show the notification and start the break after the notification. """ @@ -252,13 +246,12 @@ class SafeEyesCore: self.is_before_break = True Utility.execute_main_thread(self.__check_active_window) - """ Check the active window for full-screen and user defined exceptions. """ def __check_active_window(self): # Check the active window again. (User might changed the window) - if self.__is_running() and Utility.is_active_window_skipped(self.skip_break_window_classes, self.take_break_window_classes, self.is_before_break): + if self.__is_running() and Utility.is_active_window_skipped(self.skip_break_window_classes, self.take_break_window_classes, self.is_before_break): # If full screen app found, do not show break screen logging.info("Found a skip_break or full-screen window. Skip the break") if self.__is_running(): @@ -272,8 +265,6 @@ class SafeEyesCore: else: Utility.start_thread(self.__show_notification) - - """ Start the break screen. """ @@ -311,7 +302,7 @@ class SafeEyesCore: count_down = total_break_time - seconds self.context['count_down'] = count_down self.on_countdown(count_down, seconds) - time.sleep(1) # Sleep for 1 second + time.sleep(1) # Sleep for 1 second seconds -= 1 # Loop terminated because of timeout (not skipped) -> Close the break alert @@ -327,22 +318,18 @@ class SafeEyesCore: # Schedule the break again Utility.start_thread(self.__scheduler_job) - - """ Tells whether Safe Eyes is running or not. """ def __is_running(self): return self.active and self.running - """ Check if the current break is long break or short current """ def __is_long_break(self): return self.break_count == self.no_of_short_breaks_per_long_break - 1 - """ Continuously check the system idle time and pause/resume Safe Eyes based on it. """ diff --git a/safeeyes/SettingsDialog.py b/safeeyes/SettingsDialog.py index c278a02..476ace9 100644 --- a/safeeyes/SettingsDialog.py +++ b/safeeyes/SettingsDialog.py @@ -18,9 +18,10 @@ import gi gi.require_version('Gtk', '3.0') -from gi.repository import Gtk, Gdk, GdkX11, GObject +from gi.repository import Gtk, GObject from safeeyes import Utility + class SettingsDialog: """ Create and initialize SettingsDialog instance. @@ -117,7 +118,7 @@ class SettingsDialog: language_list_store.append([language['ui_controls']['system_language']]) language_list_store.append(['-']) self.languages.append('system') - self.languages.append('system') # Dummy record for row separator + self.languages.append('system') # Dummy record for row separator if 'system' == lang_code: self.cmb_language.set_active(0) @@ -129,19 +130,17 @@ class SettingsDialog: language_index += 1 self.cmb_language.set_model(language_list_store) - self.cmb_language.set_row_separator_func(lambda m,i: m.get_value(i, 0) == '-') + self.cmb_language.set_row_separator_func(lambda m, i: m.get_value(i, 0) == '-') cell = Gtk.CellRendererText() self.cmb_language.pack_start(cell, True) self.cmb_language.add_attribute(cell, 'text', 0) - def show(self): """ Show the SettingsDialog. """ self.window.show_all() - def on_switch_screen_lock_activate(self, switch, state): """ Event handler to the state change of the screen_lock switch. @@ -149,13 +148,12 @@ class SettingsDialog: """ self.spin_time_to_screen_lock.set_sensitive(self.switch_screen_lock.get_active()) - def on_switch_strict_break_activate(self, switch, state): """ Event handler to the state change of the postpone switch. Enable or disable the self.spin_postpone_duration based on the state of the postpone switch. """ - strict_break_enable = state #self.switch_strict_break.get_active() + strict_break_enable = state # self.switch_strict_break.get_active() self.switch_postpone.set_sensitive(not strict_break_enable) if strict_break_enable: self.switch_postpone.set_active(False) @@ -176,14 +174,13 @@ class SettingsDialog: self.__show_message_dialog(self.language['messages']['audible_alert_disabled'], self.language['messages']['software_required'].format('pyaudio')) switch.emit_stop_by_name('state-set') self.switch_audible_alert.set_active(False) - + def on_window_delete(self, *args): """ Event handler for Settings dialog close action. """ self.window.destroy() - def on_save_clicked(self, button): """ Event handler for Save button click. @@ -210,9 +207,8 @@ class SettingsDialog: else: self.config['audible_alert'] = self.switch_audible_alert.get_active() - self.on_save_settings(self.config) # Call the provided save method - self.window.destroy() # Close the settings window - + self.on_save_settings(self.config) # Call the provided save method + self.window.destroy() # Close the settings window def on_cancel_clicked(self, button): """ @@ -227,4 +223,4 @@ class SettingsDialog: dialog = Gtk.MessageDialog(self.window, 0, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, primary_text) dialog.format_secondary_text(secondary_text) dialog.run() - dialog.destroy() \ No newline at end of file + dialog.destroy() diff --git a/safeeyes/TrayIcon.py b/safeeyes/TrayIcon.py index 4c2ef57..f1d3d52 100644 --- a/safeeyes/TrayIcon.py +++ b/safeeyes/TrayIcon.py @@ -231,7 +231,6 @@ class TrayIcon: Utility.start_thread(self.__schedule_resume, time_minutes=time_to_wait) self.item_info.set_label(self.language['messages']['disabled_until_x'].format(Utility.format_time(self.wakeup_time))) - """ This method is called by the core to prevent user from disabling Safe Eyes after the notification. """ @@ -254,7 +253,7 @@ class TrayIcon: def __schedule_resume(self, time_minutes): self.idle_condition.acquire() - self.idle_condition.wait(time_minutes * 60) # Convert to seconds + self.idle_condition.wait(time_minutes * 60) # Convert to seconds self.idle_condition.release() with self.lock: diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index bda6109..56f0eeb 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -18,7 +18,7 @@ import gi gi.require_version('Gdk', '3.0') -from gi.repository import Gtk, Gdk, GLib +from gi.repository import Gdk, GLib from html.parser import HTMLParser from distutils.version import LooseVersion from logging.handlers import RotatingFileHandler @@ -65,10 +65,11 @@ def play_notification(): # Create a sound stream wrapper = pyaudio.PyAudio() - stream = wrapper.open(format=wrapper.get_format_from_width(sound.getsampwidth()), - channels=sound.getnchannels(), - rate=sound.getframerate(), - output=True) + stream = wrapper.open(format=wrapper.get_format_from_width( + sound.getsampwidth()), + channels=sound.getnchannels(), + rate=sound.getframerate(), + output=True) # Write file data into the sound stream data = sound.readframes(CHUNK) @@ -110,7 +111,7 @@ def system_idle_time(): Return the idle time if xprintidle is available, otherwise return 0. """ try: - return int(subprocess.check_output(['xprintidle']).decode('utf-8')) / 60000 # Convert to minutes + return int(subprocess.check_output(['xprintidle']).decode('utf-8')) / 60000 # Convert to minutes except: return 0 @@ -144,7 +145,7 @@ def is_active_window_skipped(skip_break_window_classes, take_break_window_classe active_window = screen.get_active_window() if active_window: active_xid = str(active_window.get_xid()) - cmdlist = ['xprop', '-root', '-notype','-id',active_xid, 'WM_CLASS', '_NET_WM_STATE'] + cmdlist = ['xprop', '-root', '-notype', '-id', active_xid, 'WM_CLASS', '_NET_WM_STATE'] try: stdout = subprocess.check_output(cmdlist).decode('utf-8') @@ -206,6 +207,7 @@ def mkdir(path): logging.error('Error while creating ' + str(path)) raise + def parse_language_code(lang_code): """ Convert the user defined language code to a valid one. @@ -273,7 +275,7 @@ def desktop_environment(): current_desktop = os.environ.get('XDG_CURRENT_DESKTOP') if desktop_session is not None: desktop_session = desktop_session.lower() - if desktop_session in ['gnome','unity', 'budgie-desktop', 'cinnamon', 'mate', 'xfce4', 'lxde', 'pantheon', 'fluxbox', 'blackbox', 'openbox', 'icewm', 'jwm', 'afterstep','trinity', 'kde']: + if desktop_session in ['gnome', 'unity', 'budgie-desktop', 'cinnamon', 'mate', 'xfce4', 'lxde', 'pantheon', 'fluxbox', 'blackbox', 'openbox', 'icewm', 'jwm', 'afterstep', 'trinity', 'kde']: return desktop_session elif (desktop_session.startswith('xubuntu') or (current_desktop is not None and 'xfce' in current_desktop)): return 'xfce' @@ -314,14 +316,14 @@ def lock_screen_command(): return ['mate-screensaver-command', '--lock'] elif desktop_session == 'kde' or 'plasma' in desktop_session or desktop_session.startswith('kubuntu') or os.environ.get('KDE_FULL_SESSION') == 'true': return ['qdbus', 'org.freedesktop.ScreenSaver', '/ScreenSaver', 'Lock'] - elif desktop_session in ['gnome','unity', 'budgie-desktop'] or desktop_session.startswith('ubuntu'): + elif desktop_session in ['gnome', 'unity', 'budgie-desktop'] or desktop_session.startswith('ubuntu'): if command_exist('gnome-screensaver-command'): return ['gnome-screensaver-command', '--lock'] else: # From Gnome 3.8 no gnome-screensaver-command return ['dbus-send', '--type=method_call', '--dest=org.gnome.ScreenSaver', '/org/gnome/ScreenSaver', 'org.gnome.ScreenSaver.Lock'] elif os.environ.get('GNOME_DESKTOP_SESSION_ID'): - if not 'deprecated' in os.environ.get('GNOME_DESKTOP_SESSION_ID') and command_exist('gnome-screensaver-command'): + if 'deprecated' not in os.environ.get('GNOME_DESKTOP_SESSION_ID') and command_exist('gnome-screensaver-command'): # Gnome 2 return ['gnome-screensaver-command', '--lock'] return None @@ -417,7 +419,7 @@ def intialize_logging(): log_formatter = logging.Formatter('%(asctime)s [%(levelname)s]:[%(threadName)s] %(message)s') # Apped the logs and overwrite once reached 5MB - handler = RotatingFileHandler(log_file_path, mode='a', maxBytes=5*1024*1024, backupCount=2, encoding=None, delay=0) + handler = RotatingFileHandler(log_file_path, mode='a', maxBytes=5 * 1024 * 1024, backupCount=2, encoding=None, delay=0) handler.setFormatter(log_formatter) handler.setLevel(logging.INFO) @@ -484,7 +486,7 @@ class __HTMLTextExtractor(HTMLParser): def __init__(self): self.reset() self.strict = False - self.convert_charrefs= True + self.convert_charrefs = True self.fed = [] def handle_data(self, d): diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index 0ce9df9..685c545 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -18,7 +18,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import os, gi, json, dbus, logging, operator, psutil, sys +import os, gi, json, dbus, logging, psutil, sys from threading import Timer from dbus.mainloop.glib import DBusGMainLoop gi.require_version('Gtk', '3.0') @@ -41,6 +41,7 @@ about_dialog_glade = os.path.join(Utility.bin_directory, "glade/about_dialog.gla is_active = True SAFE_EYES_VERSION = "1.2.1" + """ Listen to tray icon Settings action and send the signal to Settings dialog. """ @@ -52,6 +53,7 @@ def show_settings(): settings_dialog = SettingsDialog(config, language, Utility.read_lang_files(), able_to_lock_screen, save_settings, settings_dialog_glade) settings_dialog.show() + """ Listen to tray icon About action and send the signal to About dialog. """ @@ -60,6 +62,7 @@ def show_about(): about_dialog = AboutDialog(about_dialog_glade, SAFE_EYES_VERSION, language) about_dialog.show() + """ Receive the signal from core and pass it to the Notification. """ @@ -69,6 +72,7 @@ def show_notification(): plugins.pre_notification(context) notification.show(config['pre_break_warning_time']) + """ Receive the break signal from core and pass it to the break screen. """ @@ -80,6 +84,7 @@ def show_alert(message, image_name): if config['strict_break'] and is_active: Utility.execute_main_thread(tray_icon.unlock_menu) + """ Receive the stop break signal from core and pass it to the break screen. """ @@ -101,9 +106,10 @@ def on_quit(): logging.info("Quit Safe Eyes") plugins.exit(context) core.stop() - notification.quite(); + notification.quite() Gtk.main_quit() + """ If the system goes to sleep, Safe Eyes stop the core if it is already active. If it was active, Safe Eyes will become active after wake up. @@ -120,6 +126,7 @@ def handle_suspend_callback(sleeping): core.start() logging.info("Resumed Safe Eyes after system wakeup") + """ Setup system suspend listener. """ @@ -128,6 +135,7 @@ def handle_system_suspend(): bus = dbus.SystemBus() bus.add_signal_receiver(handle_suspend_callback, 'PrepareForSleep', 'org.freedesktop.login1.Manager', 'org.freedesktop.login1') + """ Listen to break screen Skip action and send the signal to core. """ @@ -139,6 +147,7 @@ def on_skipped(): core.skip_break() plugins.post_break(context) + """ Listen to break screen Postpone action and send the signal to core. """ @@ -149,6 +158,7 @@ def on_postponed(): Utility.lock_desktop(system_lock_command) core.postpone_break() + """ Listen to Settings dialog Save action and write to the config file. """ @@ -180,6 +190,7 @@ def save_settings(config): # 1 sec delay is required to give enough time for core to be stopped Timer(1.0, core.start).start() + """ Listen to tray icon enable action and send the signal to core. """ @@ -188,6 +199,7 @@ def enable_safeeyes(): is_active = True core.start() + """ Listen to tray icon disable action and send the signal to core. """ @@ -203,7 +215,8 @@ def running(): """ process_count = 0 for proc in psutil.process_iter(): - if not proc.cmdline: continue + if not proc.cmdline: + continue try: # Check if safeeyes is in process arguments if callable(proc.cmdline): @@ -257,7 +270,6 @@ def main(): else: system_lock_command = Utility.lock_screen_command() - # Initialize the Safe Eyes Context context['version'] = SAFE_EYES_VERSION context['desktop'] = Utility.desktop_environment() @@ -279,5 +291,6 @@ def main(): logging.info('Another instance of safeeyes is already running') sys.exit(0) + if __name__ == '__main__': main() diff --git a/setup.py b/setup.py index ed5210f..13f821f 100644 --- a/setup.py +++ b/setup.py @@ -3,13 +3,13 @@ import setuptools requires = [ - 'python-xlib', - 'psutil', - 'babel'] + 'python-xlib', + 'psutil', + 'babel'] extras = { - 'audible_alert': ['pyaudio'] - } + 'audible_alert': ['pyaudio'] +} here = os.path.abspath(os.path.dirname(__file__)) @@ -17,12 +17,14 @@ here = os.path.abspath(os.path.dirname(__file__)) with open(os.path.join(here, 'README.md')) as f: long_description = '\n' + f.read() + def _data_files(path): for root, dirs, files in os.walk(path): if not files: continue yield (os.path.join('/usr', root), [os.path.join(root, f) for f in files]) + setuptools.setup( name="safeeyes", version="1.2.1", From ca65add8e836decaf883623539695d235c727ca3 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Thu, 6 Jul 2017 16:49:44 -0400 Subject: [PATCH 25/40] Improve the kyboard lock and shortcut logic --- safeeyes/BreakScreen.py | 43 ++++++++++++++++------------ safeeyes/glade/settings_dialog.glade | 2 +- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index 68d437c..2aa00a9 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import gi, threading, logging +import gi, threading, logging, time from Xlib.display import Display, X gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk, GLib @@ -41,6 +41,7 @@ class BreakScreen: self.count_labels = [] self.glade_file = glade_file self.enable_shortcut = False + self.display = Display() # Initialize the theme css_provider = Gtk.CssProvider() @@ -204,32 +205,36 @@ class BreakScreen: """ logging.info("Lock the keyboard") self.lock_keyboard = True - display = Display() - root = display.screen().root - # Grap the keyboard - root.grab_keyboard(owner_events=False, pointer_mode=X.GrabModeAsync, keyboard_mode=X.GrabModeAsync, time=X.CurrentTime) + + # Grab the keyboard + root = self.display.screen().root + root.change_attributes(event_mask = X.KeyPressMask|X.KeyReleaseMask) + root.grab_keyboard(True, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) + # Consume keyboard events while self.lock_keyboard: - event = display.next_event() - display.allow_events(mode=X.AsyncBoth, time=X.CurrentTime) - if self.enable_shortcut and event.type == X.KeyPress: - if event.detail == self.keycode_shortcut_skip: - self.skip_break() - break - elif self.enable_postpone and event.detail == self.keycode_shortcut_postpone: - self.postpone_break() - break - - # Ungrap the keyboard - logging.info("Unlock the keyboard") - display.ungrab_keyboard(X.CurrentTime) - display.flush() + if self.display.pending_events() > 0: + # Avoid waiting for next event by checking pending events + event = self.display.next_event() + if self.enable_shortcut and event.type == X.KeyPress: + if event.detail == self.keycode_shortcut_skip: + self.skip_break() + break + elif self.enable_postpone and event.detail == self.keycode_shortcut_postpone: + self.postpone_break() + break + else: + # Reduce the CPU usage by sleeping for a second + time.sleep(1) def __release_keyboard(self): """ Release the locked keyboard. """ + logging.info("Unlock the keyboard") self.lock_keyboard = False + self.display.ungrab_keyboard(X.CurrentTime) + self.display.flush() def __destroy_all_screens(self): """ diff --git a/safeeyes/glade/settings_dialog.glade b/safeeyes/glade/settings_dialog.glade index ecc02ab..94d3370 100644 --- a/safeeyes/glade/settings_dialog.glade +++ b/safeeyes/glade/settings_dialog.glade @@ -53,7 +53,7 @@ 5 - 1 + 0 15 1 5 From c95df477e21e832685a86d9119b353b76b3396d2 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Thu, 6 Jul 2017 17:58:08 -0400 Subject: [PATCH 26/40] Refactor comments --- safeeyes/AboutDialog.py | 29 +++++------- safeeyes/BreakScreen.py | 12 ++--- safeeyes/Notification.py | 5 +-- safeeyes/Plugins.py | 5 +-- safeeyes/SafeEyesCore.py | 95 +++++++++++++++++++--------------------- safeeyes/TrayIcon.py | 63 ++++++++++++++++++++------ safeeyes/__main__.py | 94 +++++++++++++++++---------------------- 7 files changed, 153 insertions(+), 150 deletions(-) diff --git a/safeeyes/AboutDialog.py b/safeeyes/AboutDialog.py index aeea6a5..6ecdbaa 100644 --- a/safeeyes/AboutDialog.py +++ b/safeeyes/AboutDialog.py @@ -21,17 +21,12 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk -""" +class AboutDialog: + """ AboutDialog reads the about_dialog.glade and build the user interface using that file. It shows the application name with version, a small description, license and the GitHub url. -""" - - -class AboutDialog: - - """ - Read the about_dialog.glade and build the user interface. """ + def __init__(self, glade_file, version, language): builder = Gtk.Builder() builder.add_from_file(glade_file) @@ -44,20 +39,20 @@ class AboutDialog: # Set the version at the runtime builder.get_object("lbl_app_name").set_label("Safe Eyes " + version) - """ - Show the About dialog. - """ def show(self): + """ + Show the About dialog. + """ self.window.show_all() - """ - Window close event handler. - """ def on_window_delete(self, *args): + """ + Window close event handler. + """ self.window.destroy() - """ - Close button click event handler. - """ def on_close_clicked(self, button): + """ + Close button click event handler. + """ self.window.destroy() diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index 2aa00a9..7f2a7c2 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -22,17 +22,13 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk, Gdk, GLib -""" - The fullscreen window which prevents users from using the computer. -""" - - class BreakScreen: + """ + The fullscreen window which prevents users from using the computer. + This class reads the break_screen.glade and build the user interface. + """ def __init__(self, context, on_skip, on_postpone, glade_file, style_sheet_path): - """ - Read the break_screen.glade and build the user interface. - """ self.context = context self.on_skip = on_skip self.on_postpone = on_postpone diff --git a/safeeyes/Notification.py b/safeeyes/Notification.py index affbd49..9c6e831 100644 --- a/safeeyes/Notification.py +++ b/safeeyes/Notification.py @@ -27,13 +27,10 @@ APPINDICATOR_ID = 'safeeyes' class Notification: """ - This class is responsible for the notification to the user before the break. + This class is responsible for the notification to the user before the break. """ def __init__(self, context, language): - """ - Initialize the notification. - """ logging.info('Initialize the notification') Notify.init(APPINDICATOR_ID) self.context = context diff --git a/safeeyes/Plugins.py b/safeeyes/Plugins.py index 221cd5b..d28c729 100644 --- a/safeeyes/Plugins.py +++ b/safeeyes/Plugins.py @@ -26,13 +26,10 @@ sys.path.append(os.path.abspath(plugins_directory)) class Plugins: """ - This class manages imports the plugins and calls the methods defined in those plugins. + Imports the Safe Eyes plugins and calls the methods defined in those plugins. """ def __init__(self, config): - """ - Load the plugins. - """ logging.info('Load all the plugins') self.__plugins = [] diff --git a/safeeyes/SafeEyesCore.py b/safeeyes/SafeEyesCore.py index fa79e92..252e0f6 100644 --- a/safeeyes/SafeEyesCore.py +++ b/safeeyes/SafeEyesCore.py @@ -21,16 +21,11 @@ import time, datetime, threading, logging from safeeyes import Utility -""" - Core of Safe Eyes which runs the scheduler and notifies the breaks. -""" - - class SafeEyesCore: + """ + Core of Safe Eyes which runs the scheduler and notifies the breaks. + """ - """ - Initialize the internal variables of the core. - """ def __init__(self, context, show_notification, start_break, end_break, on_countdown, update_next_break_info): # Initialize the variables self.break_count = -1 @@ -50,10 +45,10 @@ class SafeEyesCore: self.context['skipped'] = False self.context['postponed'] = False - """ - Initialize the internal properties from configuration - """ def initialize(self, config, language): + """ + Initialize the internal properties from configuration + """ logging.info("Initialize the core") self.short_break_exercises = [] # language['exercises']['short_break_exercises'] self.long_break_exercises = [] # language['exercises']['long_break_exercises'] @@ -112,10 +107,10 @@ class SafeEyesCore: self.long_break_exercises.append([name, break_time, audible_alert, image]) - """ - Start Safe Eyes is it is not running already. - """ def start(self): + """ + Start Safe Eyes is it is not running already. + """ with self.lock: if not self.active: logging.info("Scheduling next break") @@ -125,10 +120,10 @@ class SafeEyesCore: if self.context['idle_pause_enabled']: Utility.start_thread(self.__start_idle_monitor) - """ - Stop Safe Eyes if it is running. - """ def stop(self): + """ + Stop Safe Eyes if it is running. + """ with self.lock: if self.active: logging.info("Stop the core") @@ -149,10 +144,10 @@ class SafeEyesCore: self.idle_condition.notify_all() self.idle_condition.release() - """ - Pause Safe Eyes if it is running. - """ def pause(self): + """ + Pause Safe Eyes if it is running. + """ with self.lock: if self.active and self.running: self.notification_condition.acquire() @@ -160,31 +155,31 @@ class SafeEyesCore: self.notification_condition.notify_all() self.notification_condition.release() - """ - Resume Safe Eyes if it is not running. - """ def resume(self): + """ + Resume Safe Eyes if it is not running. + """ with self.lock: if self.active and not self.running: self.running = True Utility.start_thread(self.__scheduler_job) - """ - User skipped the break using Skip button - """ def skip_break(self): + """ + User skipped the break using Skip button + """ self.context['skipped'] = True - """ - User postponed the break using Postpone button - """ def postpone_break(self): + """ + User postponed the break using Postpone button + """ self.context['postponed'] = True - """ - Scheduler task to execute during every interval - """ def __scheduler_job(self): + """ + Scheduler task to execute during every interval + """ if not self.__is_running(): return @@ -230,10 +225,10 @@ class SafeEyesCore: self.is_before_break = False Utility.execute_main_thread(self.__check_active_window) - """ - Show the notification and start the break after the notification. - """ def __show_notification(self): + """ + Show the notification and start the break after the notification. + """ # Show the notification self.show_notification() @@ -246,10 +241,10 @@ class SafeEyesCore: self.is_before_break = True Utility.execute_main_thread(self.__check_active_window) - """ - Check the active window for full-screen and user defined exceptions. - """ def __check_active_window(self): + """ + Check the active window for full-screen and user defined exceptions. + """ # Check the active window again. (User might changed the window) if self.__is_running() and Utility.is_active_window_skipped(self.skip_break_window_classes, self.take_break_window_classes, self.is_before_break): # If full screen app found, do not show break screen @@ -265,10 +260,10 @@ class SafeEyesCore: else: Utility.start_thread(self.__show_notification) - """ - Start the break screen. - """ def __start_break(self): + """ + Start the break screen. + """ # User can disable SafeEyes during notification if self.__is_running(): message = "" @@ -318,22 +313,22 @@ class SafeEyesCore: # Schedule the break again Utility.start_thread(self.__scheduler_job) - """ - Tells whether Safe Eyes is running or not. - """ def __is_running(self): + """ + Tells whether Safe Eyes is running or not. + """ return self.active and self.running - """ - Check if the current break is long break or short current - """ def __is_long_break(self): + """ + Check if the current break is long break or short current + """ return self.break_count == self.no_of_short_breaks_per_long_break - 1 - """ - Continuously check the system idle time and pause/resume Safe Eyes based on it. - """ def __start_idle_monitor(self): + """ + Continuously check the system idle time and pause/resume Safe Eyes based on it. + """ while self.active: # Wait for 2 seconds self.idle_condition.acquire() diff --git a/safeeyes/TrayIcon.py b/safeeyes/TrayIcon.py index f1d3d52..1306f2b 100644 --- a/safeeyes/TrayIcon.py +++ b/safeeyes/TrayIcon.py @@ -26,8 +26,10 @@ from safeeyes import Utility # Global variables APPINDICATOR_ID = 'safeeyes' - class TrayIcon: + """ + Create and show the tray icon along with the tray menu. + """ def __init__(self, config, language, on_show_settings, on_show_about, on_enable, on_disable, on_quite): logging.info("Initialize the tray icon") @@ -133,9 +135,15 @@ class TrayIcon: self.indicator.set_menu(self.menu) def initialize(self, config): + """ + Initialize the tray icon by setting the config. + """ self.config = config def set_labels(self, language): + """ + Update the text of menu items based on the selected language. + """ self.language = language for entry in self.sub_menu_items: entry[0].set_label(self.language['ui_controls'][entry[1]].format(entry[2])) @@ -158,12 +166,22 @@ class TrayIcon: self.item_quit.set_label(self.language['ui_controls']['quit']) def show_icon(self): + """ + Show the tray icon. + """ Utility.execute_main_thread(self.indicator.set_status, appindicator.IndicatorStatus.ACTIVE) def hide_icon(self): + """ + Hide the tray icon. + """ Utility.execute_main_thread(self.indicator.set_status, appindicator.IndicatorStatus.PASSIVE) def quit_safe_eyes(self, *args): + """ + Handle Quit menu action. + This action terminates the application. + """ self.on_quite() with self.lock: self.active = True @@ -173,17 +191,31 @@ class TrayIcon: self.idle_condition.release() def show_settings(self, *args): + """ + Handle Settings menu action. + This action shows the Settings dialog. + """ self.on_show_settings() def show_about(self, *args): + """ + Handle About menu action. + This action shows the About dialog. + """ self.on_show_about() def next_break_time(self, dateTime): + """ + Update the next break time to be displayed in the menu and optionally in the tray icon. + """ logging.info("Update next break information") self.dateTime = dateTime self.__set_next_break_info() def __set_next_break_info(self): + """ + A private method to be called within this class to update the next break information using self.dateTime. + """ formatted_time = Utility.format_time(self.dateTime) message = self.language['messages']['next_break_at'].format(formatted_time) # Update the tray icon label @@ -195,6 +227,10 @@ class TrayIcon: Utility.execute_main_thread(self.item_info.set_label, message) def on_enable_clicked(self, *args): + """ + Handle 'Enable Safe Eyes' menu action. + This action enables the application if it is currently disabled. + """ # active = self.item_enable.get_active() if not self.active: with self.lock: @@ -211,6 +247,10 @@ class TrayIcon: self.idle_condition.release() def on_disable_clicked(self, *args): + """ + Handle the menu actions of all the sub menus of 'Disable Safe Eyes'. + This action disables the application if it is currently active. + """ # active = self.item_enable.get_active() if self.active and len(args) > 1: logging.info('Disable Safe Eyes') @@ -231,27 +271,24 @@ class TrayIcon: Utility.start_thread(self.__schedule_resume, time_minutes=time_to_wait) self.item_info.set_label(self.language['messages']['disabled_until_x'].format(Utility.format_time(self.wakeup_time))) - """ - This method is called by the core to prevent user from disabling Safe Eyes after the notification. - """ def lock_menu(self): + """ + This method is called by the core to prevent user from disabling Safe Eyes after the notification. + """ if self.active: - # self.item_disable.set_sensitive(False) - # self.item_settings.set_sensitive(False) - # self.item_quit.set_sensitive(False) self.menu.set_sensitive(False) - """ - This method is called by the core to activate the disable menu after the the break. - """ def unlock_menu(self): + """ + This method is called by the core to activate the menu after the the break. + """ if self.active: - # self.item_disable.set_sensitive(True) - # self.item_settings.set_sensitive(True) - # self.item_quit.set_sensitive(True) self.menu.set_sensitive(True) def __schedule_resume(self, time_minutes): + """ + Schedule a local timer to enable Safe Eyes after the given timeout. + """ self.idle_condition.acquire() self.idle_condition.wait(time_minutes * 60) # Convert to seconds self.idle_condition.release() diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index 685c545..1ecec81 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -37,15 +37,13 @@ break_screen_glade = os.path.join(Utility.bin_directory, "glade/break_screen.gla settings_dialog_glade = os.path.join(Utility.bin_directory, "glade/settings_dialog.glade") about_dialog_glade = os.path.join(Utility.bin_directory, "glade/about_dialog.glade") - is_active = True SAFE_EYES_VERSION = "1.2.1" - -""" - Listen to tray icon Settings action and send the signal to Settings dialog. -""" def show_settings(): + """ + Listen to tray icon Settings action and send the signal to Settings dialog. + """ logging.info("Show Settings dialog") able_to_lock_screen = False if system_lock_command: @@ -53,30 +51,27 @@ def show_settings(): settings_dialog = SettingsDialog(config, language, Utility.read_lang_files(), able_to_lock_screen, save_settings, settings_dialog_glade) settings_dialog.show() - -""" - Listen to tray icon About action and send the signal to About dialog. -""" def show_about(): + """ + Listen to tray icon About action and send the signal to About dialog. + """ logging.info("Show About dialog") about_dialog = AboutDialog(about_dialog_glade, SAFE_EYES_VERSION, language) about_dialog.show() - -""" - Receive the signal from core and pass it to the Notification. -""" def show_notification(): + """ + Receive the signal from core and pass it to the Notification. + """ if config['strict_break']: Utility.execute_main_thread(tray_icon.lock_menu) plugins.pre_notification(context) notification.show(config['pre_break_warning_time']) - -""" - Receive the break signal from core and pass it to the break screen. -""" def show_alert(message, image_name): + """ + Receive the break signal from core and pass it to the break screen. + """ logging.info("Show the break screen") notification.close() plugins_data = plugins.pre_break(context) @@ -84,11 +79,10 @@ def show_alert(message, image_name): if config['strict_break'] and is_active: Utility.execute_main_thread(tray_icon.unlock_menu) - -""" - Receive the stop break signal from core and pass it to the break screen. -""" def close_alert(audible_alert_on): + """ + Receive the stop break signal from core and pass it to the break screen. + """ logging.info("Close the break screen") if config['enable_screen_lock'] and context['break_type'] == 'long': # Lock the screen before closing the break screen @@ -98,23 +92,21 @@ def close_alert(audible_alert_on): Utility.play_notification() plugins.post_break(context) - -""" - Listen to the tray menu quit action and stop the core, notification and the app itself. -""" def on_quit(): + """ + Listen to the tray menu quit action and stop the core, notification and the app itself. + """ logging.info("Quit Safe Eyes") plugins.exit(context) core.stop() notification.quite() Gtk.main_quit() - -""" +def handle_suspend_callback(sleeping): + """ If the system goes to sleep, Safe Eyes stop the core if it is already active. If it was active, Safe Eyes will become active after wake up. -""" -def handle_suspend_callback(sleeping): + """ if sleeping: # Sleeping / suspending if is_active: @@ -126,20 +118,18 @@ def handle_suspend_callback(sleeping): core.start() logging.info("Resumed Safe Eyes after system wakeup") - -""" - Setup system suspend listener. -""" def handle_system_suspend(): + """ + Setup system suspend listener. + """ DBusGMainLoop(set_as_default=True) bus = dbus.SystemBus() bus.add_signal_receiver(handle_suspend_callback, 'PrepareForSleep', 'org.freedesktop.login1.Manager', 'org.freedesktop.login1') - -""" - Listen to break screen Skip action and send the signal to core. -""" def on_skipped(): + """ + Listen to break screen Skip action and send the signal to core. + """ logging.info("User skipped the break") if config['enable_screen_lock'] and context['break_type'] == 'long' and context.get('count_down', 0) >= config['time_to_screen_lock']: # Lock the screen before closing the break screen @@ -147,22 +137,20 @@ def on_skipped(): core.skip_break() plugins.post_break(context) - -""" - Listen to break screen Postpone action and send the signal to core. -""" def on_postponed(): + """ + Listen to break screen Postpone action and send the signal to core. + """ logging.info("User postponed the break") if config['enable_screen_lock'] and context['break_type'] == 'long' and context.get('count_down', 0) >= config['time_to_screen_lock']: # Lock the screen before closing the break screen Utility.lock_desktop(system_lock_command) core.postpone_break() - -""" - Listen to Settings dialog Save action and write to the config file. -""" def save_settings(config): + """ + Listen to Settings dialog Save action and write to the config file. + """ global language logging.info("Saving settings to safeeyes.json") @@ -190,20 +178,18 @@ def save_settings(config): # 1 sec delay is required to give enough time for core to be stopped Timer(1.0, core.start).start() - -""" - Listen to tray icon enable action and send the signal to core. -""" def enable_safeeyes(): + """ + Listen to tray icon enable action and send the signal to core. + """ global is_active is_active = True core.start() - -""" - Listen to tray icon disable action and send the signal to core. -""" def disable_safeeyes(): + """ + Listen to tray icon disable action and send the signal to core. + """ global is_active is_active = False core.stop() @@ -211,7 +197,7 @@ def disable_safeeyes(): def running(): """ - Check if SafeEyes is already running. + Check if SafeEyes is already running. """ process_count = 0 for proc in psutil.process_iter(): From bea206f732847bdec889faa48e240f6c59838b84 Mon Sep 17 00:00:00 2001 From: giappi Date: Wed, 12 Jul 2017 21:01:07 +0700 Subject: [PATCH 27/40] - Update translation in Vietnamese --- safeeyes/config/lang/vi.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/safeeyes/config/lang/vi.json b/safeeyes/config/lang/vi.json index abd03d8..1e186cf 100644 --- a/safeeyes/config/lang/vi.json +++ b/safeeyes/config/lang/vi.json @@ -22,13 +22,13 @@ }, "messages": { - "audible_alert_disabled": "Cannot enable audible notifications", + "audible_alert_disabled": "Không thể bật thông báo âm thanh", "ready_for_a_short_break": "Sẵn sàng để nghỉ ngơi {} giây", "ready_for_a_long_break": "Sẵn sàng để nghỉ ngơi {} giây", "disabled_until_restart": "Vô hiệu hóa cho đến khi khởi động lại", "disabled_until_x": "Vô hiệu hóa cho đến khi {}", "next_break_at": "Giờ nghỉ ngơi tiếp theo là {}", - "software_required": "To enable this feature, please install {}" + "software_required": "Để bật tính năng này, vui lòng cài đặt {}" }, "ui_controls": { @@ -38,13 +38,13 @@ "cancel": "Huỷ", "close": "Đóng", "disable": "Tắt Safe Eyes", - "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", + "disable_keyboard_shortcut": "Th.gian vô hiệu hóa phím tắt để tránh tắt nhầm Nhắc nhở khi nó hiện lên (giây)", "enable": "Bật Safe Eyes", "enable_screen_lock": "Khoá màn hình ở mỗi thời điểm nghỉ ngơi dài", "for_x_hour": "Trong {} giờ", "for_x_hours": "Trong {} giờ", "for_x_minutes": "Trong {} phút", - "idle_time": "Minimum idle time to pause (tính bằng phút)", + "idle_time": "Thơi gian rỗi nhỏ nhất để tạm dừng (tính bằng phút)", "interval_between_two_breaks": "Khoảng thời gian giữa hai lần nghỉ ngơi (tính bằng phút)", "language": "Language (Ngôn ngữ)", "license": "Giấy phép", From 35c6cdee4846985b5a8df7b364f865218f62d1b8 Mon Sep 17 00:00:00 2001 From: Jalakas Date: Sun, 16 Jul 2017 22:51:52 +0300 Subject: [PATCH 28/40] flake8 suggested fixes 2 Ignored these: tabs vs spaces, multiple imports on single line, import not on top of file, too long lines. --- safeeyes/BreakScreen.py | 4 ++-- safeeyes/TrayIcon.py | 1 + safeeyes/__main__.py | 13 +++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index 7f2a7c2..7b6fe84 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -201,10 +201,10 @@ class BreakScreen: """ logging.info("Lock the keyboard") self.lock_keyboard = True - + # Grab the keyboard root = self.display.screen().root - root.change_attributes(event_mask = X.KeyPressMask|X.KeyReleaseMask) + root.change_attributes(event_mask=X.KeyPressMask | X.KeyReleaseMask) root.grab_keyboard(True, X.GrabModeAsync, X.GrabModeAsync, X.CurrentTime) # Consume keyboard events diff --git a/safeeyes/TrayIcon.py b/safeeyes/TrayIcon.py index 1306f2b..08ea21a 100644 --- a/safeeyes/TrayIcon.py +++ b/safeeyes/TrayIcon.py @@ -26,6 +26,7 @@ from safeeyes import Utility # Global variables APPINDICATOR_ID = 'safeeyes' + class TrayIcon: """ Create and show the tray icon along with the tray menu. diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index 1ecec81..7cb0ef7 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -40,6 +40,7 @@ about_dialog_glade = os.path.join(Utility.bin_directory, "glade/about_dialog.gla is_active = True SAFE_EYES_VERSION = "1.2.1" + def show_settings(): """ Listen to tray icon Settings action and send the signal to Settings dialog. @@ -51,6 +52,7 @@ def show_settings(): settings_dialog = SettingsDialog(config, language, Utility.read_lang_files(), able_to_lock_screen, save_settings, settings_dialog_glade) settings_dialog.show() + def show_about(): """ Listen to tray icon About action and send the signal to About dialog. @@ -59,6 +61,7 @@ def show_about(): about_dialog = AboutDialog(about_dialog_glade, SAFE_EYES_VERSION, language) about_dialog.show() + def show_notification(): """ Receive the signal from core and pass it to the Notification. @@ -68,6 +71,7 @@ def show_notification(): plugins.pre_notification(context) notification.show(config['pre_break_warning_time']) + def show_alert(message, image_name): """ Receive the break signal from core and pass it to the break screen. @@ -79,6 +83,7 @@ def show_alert(message, image_name): if config['strict_break'] and is_active: Utility.execute_main_thread(tray_icon.unlock_menu) + def close_alert(audible_alert_on): """ Receive the stop break signal from core and pass it to the break screen. @@ -92,6 +97,7 @@ def close_alert(audible_alert_on): Utility.play_notification() plugins.post_break(context) + def on_quit(): """ Listen to the tray menu quit action and stop the core, notification and the app itself. @@ -102,6 +108,7 @@ def on_quit(): notification.quite() Gtk.main_quit() + def handle_suspend_callback(sleeping): """ If the system goes to sleep, Safe Eyes stop the core if it is already active. @@ -118,6 +125,7 @@ def handle_suspend_callback(sleeping): core.start() logging.info("Resumed Safe Eyes after system wakeup") + def handle_system_suspend(): """ Setup system suspend listener. @@ -126,6 +134,7 @@ def handle_system_suspend(): bus = dbus.SystemBus() bus.add_signal_receiver(handle_suspend_callback, 'PrepareForSleep', 'org.freedesktop.login1.Manager', 'org.freedesktop.login1') + def on_skipped(): """ Listen to break screen Skip action and send the signal to core. @@ -137,6 +146,7 @@ def on_skipped(): core.skip_break() plugins.post_break(context) + def on_postponed(): """ Listen to break screen Postpone action and send the signal to core. @@ -147,6 +157,7 @@ def on_postponed(): Utility.lock_desktop(system_lock_command) core.postpone_break() + def save_settings(config): """ Listen to Settings dialog Save action and write to the config file. @@ -178,6 +189,7 @@ def save_settings(config): # 1 sec delay is required to give enough time for core to be stopped Timer(1.0, core.start).start() + def enable_safeeyes(): """ Listen to tray icon enable action and send the signal to core. @@ -186,6 +198,7 @@ def enable_safeeyes(): is_active = True core.start() + def disable_safeeyes(): """ Listen to tray icon disable action and send the signal to core. From ae34763d02dce61594954137d6fa81956ffc28dd Mon Sep 17 00:00:00 2001 From: Jalakas Date: Sun, 16 Jul 2017 23:54:35 +0300 Subject: [PATCH 29/40] language: add Estonian translation --- safeeyes/config/lang/et.json | 62 ++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 safeeyes/config/lang/et.json diff --git a/safeeyes/config/lang/et.json b/safeeyes/config/lang/et.json new file mode 100644 index 0000000..63526ac --- /dev/null +++ b/safeeyes/config/lang/et.json @@ -0,0 +1,62 @@ +{ + "meta_info": { + "language_name": "Eesti", + "language_name_en": "Estonian" + }, + "app_info": { + "description": "Safe Eyes aitab vähendada arvutiga töötamisel silmade väsimust, tuletades meelde puhkepause." + }, + "exercises": { + "short_break_close_eyes": "Sulge silmad", + "short_break_roll_eyes": "Vaata vasakule ja paremale", + "short_break_rotate_clockwise": "Liiguta silmi kellaosuti suunas", + "short_break_rotate_counter_clockwise": "Liiguta silmi kellaosutile vastupidiselt", + "short_break_blink": "Pilguta silmi", + "short_break_focus_far_distance": "Vaata kaugusesse", + "short_break_drink_water": "Joo vett", + "long_break_walk": "Jaluta ringi", + "long_break_lean_back": "Toetu seljatoele ja lõõgastu" + }, + "messages": { + "audible_alert_disabled": "Helimärguandeid ei tekitata", + "ready_for_a_short_break": "Lühike paus {} sekundi pärast", + "ready_for_a_long_break": "Pikk paus {} sekundi pärast", + "disabled_until_restart": "Peatatud taaskäivituseni", + "disabled_until_x": "Peatatud kuni {}", + "next_break_at": "Järgmine paus {}", + "software_required": "Selle võimaluse jaoks tuleb paigaldada tarkvara {}" + }, + "ui_controls": { + "about": "Programmist", + "allow_postpone": "Pauside edasilükkamine lubatud", + "audible_alert": "Pausi lõpus helimärguanne", + "cancel": "Tühista", + "close": "Sulge", + "disable": "Peata Safe Eyes", + "disable_keyboard_shortcut": "Klaviatuurikäskude eiramise aeg, et vältida juhuslikku edasilükkamist (sekundit)", + "enable": "Luba Safe Eyes", + "enable_screen_lock": "Pikka pausi lõpus ekraani lukustamine", + "for_x_hour": "{}-ks tunniks", + "for_x_hours": "{}-ks tunniks", + "for_x_minutes": "{}-ks minutiks", + "idle_time": "Minimaalne pausi aeg (minutites)", + "interval_between_two_breaks": "Kahe pausi vaheline aeg (minutites)", + "language": "Keel", + "license": "Litsents", + "long_break_duration": "Pika pausi kestvus (sekundites)", + "no_of_short_breaks_between_two_long_breaks": "Kui mitu lühikest pausi tehaks pikkade pauside vahel", + "postpone": "Lükka edasi", + "postpone_duration": "Edasilükkamise aeg (minutites)", + "quit": "Välju", + "save": "Salvesta", + "settings": "Seaded", + "short_break_duration": "Lühikese pausi kestvus (sekundites)", + "show_time_in_tray": "Kuvatakse järgmise pausi aega", + "skip": "Jäta vahele", + "strict_break": "Range paus (vahelejätmise nuppu ei näidata)", + "system_language": "Süsteemi keel", + "time_to_prepare_for_break": "Kui kaua enne pausi kuvatakse pausi hoiatust (sekundites)", + "time_to_screen_lock": "Kui kaua enne ekraani lukustamist saab pausi edasi lükata (sekundites)", + "until_restart": "Kuni taaskäivituseni" + } +} From d21a02d0f3cd372f6db0d77646442d4af1d34e8c Mon Sep 17 00:00:00 2001 From: Jalakas Date: Tue, 18 Jul 2017 22:26:20 +0300 Subject: [PATCH 30/40] language: add Estonian language into desktop file --- share/applications/safeeyes.desktop | 1 + 1 file changed, 1 insertion(+) diff --git a/share/applications/safeeyes.desktop b/share/applications/safeeyes.desktop index cd87524..ed6306a 100755 --- a/share/applications/safeeyes.desktop +++ b/share/applications/safeeyes.desktop @@ -5,6 +5,7 @@ Comment[ca]=Protegiu-vos els ulls de la fatiga visual Comment[cs]=Chraňte své oči před únavou Comment[de]=Schützt die Augen vor Überanstrengung Comment[es]=Protege tus ojos de la fatiga ocular +Comment[et]=Kaitse oma silmi väsimuse eest Comment[fa]=محافظت چشم هااز ضعیف شدن Comment[fr]=Protégez vos yeux de la fatigue Comment[ge]=დაიცავით თქვენი თვალები დაღლილობისაგან From c7294a9137553711ffcc8365196f456bb6bd5c56 Mon Sep 17 00:00:00 2001 From: Brian Lamb Date: Sun, 23 Jul 2017 12:05:12 -0600 Subject: [PATCH 31/40] Move the break screen window after presenting Some window managers do not honor the location set on a window before presentation. This can cause multi-display setups to show all break screens on the same display. By calling window.move() after presenting the window, more window managers will move the windows to the correct display. --- safeeyes/BreakScreen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/BreakScreen.py b/safeeyes/BreakScreen.py index 7b6fe84..9e324ed 100644 --- a/safeeyes/BreakScreen.py +++ b/safeeyes/BreakScreen.py @@ -182,10 +182,10 @@ class BreakScreen: # Fix flickering screen in KDE by setting opacity to 1 window.set_opacity(0.9) - window.move(x, y) window.stick() window.set_keep_above(True) window.present() + window.move(x, y) window.fullscreen() def __update_count_down(self, count): From 19710c8221e9a4bbabded1c27a8d5a3b36f0313a Mon Sep 17 00:00:00 2001 From: Serdar Arslan Date: Sat, 29 Jul 2017 06:26:22 +0300 Subject: [PATCH 32/40] Update Turkish translations. --- safeeyes/config/lang/tr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/config/lang/tr.json b/safeeyes/config/lang/tr.json index be3efb2..5e96e7d 100644 --- a/safeeyes/config/lang/tr.json +++ b/safeeyes/config/lang/tr.json @@ -24,7 +24,7 @@ "disabled_until_restart": "Tekrar başlatılana kadar devre dışı", "disabled_until_x": "{}'e kadar devre dışı", "next_break_at": "Bir sonraki mola zamanı: {}", - "software_required": "To enable this feature, please install {}" + "software_required": "Bu özelliği etkinleştirmek için lütfen {} yükleyiniz." }, "ui_controls": { "about": "Hakkında", From 3f37bc29b97d3b3f67c92161002303f5676d726f Mon Sep 17 00:00:00 2001 From: Serdar Arslan Date: Sat, 29 Jul 2017 06:26:22 +0300 Subject: [PATCH 33/40] Update Turkish translations. --- safeeyes/config/lang/tr.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/safeeyes/config/lang/tr.json b/safeeyes/config/lang/tr.json index be3efb2..a130468 100644 --- a/safeeyes/config/lang/tr.json +++ b/safeeyes/config/lang/tr.json @@ -24,7 +24,7 @@ "disabled_until_restart": "Tekrar başlatılana kadar devre dışı", "disabled_until_x": "{}'e kadar devre dışı", "next_break_at": "Bir sonraki mola zamanı: {}", - "software_required": "To enable this feature, please install {}" + "software_required": "Bu özelliği etkinleştirmek için lütfen {} yükleyiniz." }, "ui_controls": { "about": "Hakkında", @@ -33,7 +33,7 @@ "cancel": "İptal", "close": "Kapat", "disable": "Safe Eyes'ı devre dışı bırak", - "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", + "disable_keyboard_shortcut": "İstem dışı geçişi engellemek için kısayol tuşunun etkisiz kalma süresi (saniye)", "enable": "Safe Eyes'ı etkinleştir", "enable_screen_lock": "Her uzun mola sonunda ekranı kilitle", "for_x_hour": "{} Saat", From 8b2af970e09ebd96578ef95736a5287b68b570d6 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Sun, 30 Jul 2017 11:51:51 -0400 Subject: [PATCH 34/40] Prevent resuming from long break --- safeeyes/SafeEyesCore.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/safeeyes/SafeEyesCore.py b/safeeyes/SafeEyesCore.py index 252e0f6..cf0efa5 100644 --- a/safeeyes/SafeEyesCore.py +++ b/safeeyes/SafeEyesCore.py @@ -127,10 +127,16 @@ class SafeEyesCore: with self.lock: if self.active: logging.info("Stop the core") - # Reset the state properties in case of restart - # self.break_count = 0 - # self.long_break_message_index = -1 - # self.short_break_message_index = -1 + + # Prevent resuming from a long break + current_break_count = self.break_count = 0 + self.break_count = ((self.break_count + 1) % self.no_of_short_breaks_per_long_break) + if self.__is_long_break(): + # Next break will be a long break. Leave the increment so that next break will be short break after the long + pass + else: + # Reset to the current state + self.break_count = current_break_count # Stop the break thread self.notification_condition.acquire() @@ -212,7 +218,7 @@ class SafeEyesCore: # Wait for the pre break warning period logging.info("Pre-break waiting for {} minutes".format(time_to_wait)) self.notification_condition.acquire() - self.notification_condition.wait(time_to_wait * 60) # Convert to seconds + self.notification_condition.wait(time_to_wait * 1) # Convert to seconds self.notification_condition.release() logging.info("Pre-break waiting is over") From 9698517177730a729f83bccca5b2dbf5af159618 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Sun, 30 Jul 2017 11:53:08 -0400 Subject: [PATCH 35/40] Fix a bug introduced in last commit --- safeeyes/SafeEyesCore.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/SafeEyesCore.py b/safeeyes/SafeEyesCore.py index cf0efa5..ce14ce4 100644 --- a/safeeyes/SafeEyesCore.py +++ b/safeeyes/SafeEyesCore.py @@ -218,7 +218,7 @@ class SafeEyesCore: # Wait for the pre break warning period logging.info("Pre-break waiting for {} minutes".format(time_to_wait)) self.notification_condition.acquire() - self.notification_condition.wait(time_to_wait * 1) # Convert to seconds + self.notification_condition.wait(time_to_wait * 60) # Convert to seconds self.notification_condition.release() logging.info("Pre-break waiting is over") From 8ea2c85c9a4700e4a73e7bc6de7c513604c086e0 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Mon, 31 Jul 2017 15:08:35 -0400 Subject: [PATCH 36/40] Release v1.2.2 --- debian/changelog | 12 +++++++++++- safeeyes/__main__.py | 2 +- safeeyes/config/safeeyes.json | 2 +- setup.py | 4 ++-- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/debian/changelog b/debian/changelog index 373213e..0fe0e9a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,14 @@ -safeeyes (1.2.1-1) xenial; urgency=low +safeeyes (1.2.2-1) xenial; urgency=low + + * Show next break time in tray icon in supported environments + + * Enable keyboard shortcuts + + * Fix screen flickering in KDE + + * Show the break type in the notification + + * Make pyaudio optional * Support postponing the break diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index 7cb0ef7..1d4f8bb 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -38,7 +38,7 @@ settings_dialog_glade = os.path.join(Utility.bin_directory, "glade/settings_dial about_dialog_glade = os.path.join(Utility.bin_directory, "glade/about_dialog.glade") is_active = True -SAFE_EYES_VERSION = "1.2.1" +SAFE_EYES_VERSION = "1.2.2" def show_settings(): diff --git a/safeeyes/config/safeeyes.json b/safeeyes/config/safeeyes.json index 0a7b9f2..8cc7603 100644 --- a/safeeyes/config/safeeyes.json +++ b/safeeyes/config/safeeyes.json @@ -1,6 +1,6 @@ { "meta": { - "config_version": "5.0.2" + "config_version": "5.0.1" }, "allow_postpone": false, "break_interval": 15, diff --git a/setup.py b/setup.py index 13f821f..45bbc7f 100644 --- a/setup.py +++ b/setup.py @@ -27,13 +27,13 @@ def _data_files(path): setuptools.setup( name="safeeyes", - version="1.2.1", + version="1.2.2", description="Protect your eyes from eye strain using this continuous breaks reminder.", long_description=long_description, author="Gobinath Loganathan", author_email="slgobinath@gmail.com", url="https://github.com/slgobinath/SafeEyes", - download_url="https://github.com/slgobinath/SafeEyes/archive/v1.2.1.tar.gz", + download_url="https://github.com/slgobinath/SafeEyes/archive/v{}.tar.gz".format(version), packages=setuptools.find_packages(), package_data={'safeeyes': ['config/*.json', 'config/style/*.css', From a8e198d7f894aa589816c66721dc070944c60369 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Mon, 31 Jul 2017 15:12:04 -0400 Subject: [PATCH 37/40] Fix error in setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 45bbc7f..5a72e2e 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ setuptools.setup( author="Gobinath Loganathan", author_email="slgobinath@gmail.com", url="https://github.com/slgobinath/SafeEyes", - download_url="https://github.com/slgobinath/SafeEyes/archive/v{}.tar.gz".format(version), + download_url="https://github.com/slgobinath/SafeEyes/archive/v1.2.2.tar.gz", packages=setuptools.find_packages(), package_data={'safeeyes': ['config/*.json', 'config/style/*.css', From 75d67e9d4abd0e54354d839abf6e6852909aaff5 Mon Sep 17 00:00:00 2001 From: Gobinath Date: Mon, 31 Jul 2017 15:44:23 -0400 Subject: [PATCH 38/40] Fix error in Ubuntu 14.04 --- safeeyes/Utility.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/safeeyes/Utility.py b/safeeyes/Utility.py index 56f0eeb..c6388b5 100644 --- a/safeeyes/Utility.py +++ b/safeeyes/Utility.py @@ -18,7 +18,7 @@ import gi gi.require_version('Gdk', '3.0') -from gi.repository import Gdk, GLib +from gi.repository import Gtk, Gdk, GLib, GdkX11 from html.parser import HTMLParser from distutils.version import LooseVersion from logging.handlers import RotatingFileHandler From 1a6c9c4b29b24126191586b2ad344527d8707af6 Mon Sep 17 00:00:00 2001 From: Wojciech Ceret Date: Wed, 2 Aug 2017 12:36:18 +0200 Subject: [PATCH 39/40] Update Polish translation - 'Disable keyboard shortcut' time setting, 'Audible alert disabled' and 'Software required' messages translations --- safeeyes/config/lang/pl.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/safeeyes/config/lang/pl.json b/safeeyes/config/lang/pl.json index 3545eea..435df8b 100644 --- a/safeeyes/config/lang/pl.json +++ b/safeeyes/config/lang/pl.json @@ -18,13 +18,13 @@ "long_break_lean_back": "Oprzyj się wygodnie na krześle i zrelaksuj" }, "messages": { - "audible_alert_disabled": "Cannot enable audible notifications", + "audible_alert_disabled": "Nie można aktywować powiadomień dźwiękowych", "ready_for_a_short_break": "Przygotuj się! Przerwa za {} sekund(y).", "ready_for_a_long_break": "Przygotuj się! Przerwa za {} sekund(y).", "disabled_until_restart": "Wyłączony do ponownego uruchomienia", "disabled_until_x": "Wyłączony do {}", "next_break_at": "Następna przerwa o {}", - "software_required": "To enable this feature, please install {}" + "software_required": "Aby aktywować tę funkcję, zainstaluj {}" }, "ui_controls": { "about": "O programie", @@ -33,7 +33,7 @@ "cancel": "Anuluj", "close": "Zamknij", "disable": "Zatrzymaj Safe Eyes", - "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", + "disable_keyboard_shortcut": "Czas ignorowania skrótu klawiszowego zapobiegający niezamierzonemu pominięciu przerwy (w sekundach)", "enable": "Uruchom Safe Eyes", "enable_screen_lock": "Zablokuj ekran po każdej długiej przerwie", "for_x_hour": "Na {} godzinę", From 127cb284cb348b96d9b2cf1b990c9944c18d8a86 Mon Sep 17 00:00:00 2001 From: "yahoe.001" Date: Mon, 21 Aug 2017 09:47:48 -0400 Subject: [PATCH 40/40] Update the French translation --- safeeyes/config/lang/fr.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/safeeyes/config/lang/fr.json b/safeeyes/config/lang/fr.json index 4bb3ed8..4595909 100644 --- a/safeeyes/config/lang/fr.json +++ b/safeeyes/config/lang/fr.json @@ -18,13 +18,13 @@ "long_break_lean_back": "Adossez-vous à votre siège et relaxez-vous" }, "messages": { - "audible_alert_disabled": "Cannot enable audible notifications", + "audible_alert_disabled": "Impossible d'activer les notifications sonores", "ready_for_a_short_break": "Préparez-vous à une pause dans {} secondes", "ready_for_a_long_break": "Préparez-vous à une pause dans {} secondes", "disabled_until_restart": "Désactivé jusqu'au redémarrage", "disabled_until_x": "Désactivé jusqu'à {}", "next_break_at": "Prochaine pause à {}", - "software_required": "To enable this feature, please install {}" + "software_required": "Pour activer cette fonction, veuillez installer {}" }, "ui_controls": { "about": "À propos", @@ -33,7 +33,7 @@ "cancel": "Annuler", "close": "Fermer", "disable": "Désactiver Safe Eyes", - "disable_keyboard_shortcut": "Shortcut disabled period to prevent unintentional skip (in seconds)", + "disable_keyboard_shortcut": "Période de désactivation du raccourci pour empêcher d'ignorer involontairement (en secondes)", "enable": "Activer Safe Eyes", "enable_screen_lock": "Verrouiller l'écran après chaque pause longue", "for_x_hour": "Pendant {} heure", @@ -51,12 +51,12 @@ "save": "Enregistrer", "settings": "Paramètres", "short_break_duration": "Durée d'une pause courte (en secondes)", - "show_time_in_tray": "Show the next break time in system tray", + "show_time_in_tray": "Afficher la prochaine heure de pause dans la zone de notification ", "skip": "Ignorer", "strict_break": "Pause stricte (cacher le bouton Ignorer)", "system_language": "Langue du système ", - "time_to_prepare_for_break": "Temps de préparation à une pause (en secondes)", - "time_to_screen_lock": "Temps maximal pour ignorer, en passant outre le verrouillage (en secondes)", + "time_to_prepare_for_break": "Durée de préparation à une pause (en secondes)", + "time_to_screen_lock": "Durée maximale pour ignorer, en passant outre le verrouillage (en secondes)", "until_restart": "Jusqu'au redémarrage" } }