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():