Fix mypy errors

This commit is contained in:
Gobinath 2021-06-12 18:34:53 -04:00
parent fe4e33da0b
commit 74680075e2
32 changed files with 186 additions and 146 deletions

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -19,6 +18,7 @@
import datetime
import logging
from typing import Optional
from safeeyes import utility
from safeeyes.breaks.store import BreaksStore
@ -28,6 +28,7 @@ from safeeyes.spi.api import BreakAPI
from safeeyes.spi.breaks import BreakType, Break
from safeeyes.spi.state import State
from safeeyes.thread import Heartbeat, ThreadCondition, Timer, worker
from safeeyes.util.locale import _
class BreakScheduler(BreakAPI):
@ -43,21 +44,8 @@ class BreakScheduler(BreakAPI):
self.__postponed: bool = False
def start(self, next_break_time: datetime.datetime = None):
if self.__breaks_store.is_empty():
return
self.__reset_stop_flags()
current_break = self.__breaks_store.get_break()
if current_break is None:
# This check is unnecessary
return
if next_break_time is None:
current_time = datetime.datetime.now()
waiting_time = current_break.waiting_time * 60
next_break_time = current_time + datetime.timedelta(seconds=waiting_time)
self.schedule(next_break_time)
self.__start(next_break_time)
def stop(self):
self.__condition.release_all()
@ -78,7 +66,7 @@ class BreakScheduler(BreakAPI):
def next_break(self):
self.__breaks_store.next()
self.start()
self.__start()
def skip(self):
self.__skipped = True
@ -89,6 +77,23 @@ class BreakScheduler(BreakAPI):
next_break_time = datetime.datetime.now() + datetime.timedelta(seconds=duration)
self.schedule(next_break_time)
def __start(self, next_break_time: datetime.datetime = None):
if self.__breaks_store.is_empty():
return
current_break = self.__breaks_store.get_break()
if current_break is None:
# This check is unnecessary
return
if next_break_time is None:
current_time = datetime.datetime.now()
waiting_time = current_break.waiting_time * 60
next_break_time = current_time + datetime.timedelta(seconds=waiting_time)
self.schedule(next_break_time)
def schedule(self, next_break_time: datetime.datetime):
if self.__breaks_store.is_empty():
return
@ -97,14 +102,18 @@ class BreakScheduler(BreakAPI):
self.stop()
next_break = self.__breaks_store.peek()
short_break_time = next_break_time
long_break_time = next_break_time
if next_break is None:
return
short_break_time: Optional[datetime.datetime] = None
long_break_time: Optional[datetime.datetime] = None
if next_break.is_long_break():
short_break_time = next_break_time + datetime.timedelta(
minutes=self.__breaks_store.peek(BreakType.SHORT).waiting_time)
next_short_break = self.__breaks_store.peek(BreakType.SHORT)
if next_short_break:
short_break_time = next_break_time + datetime.timedelta(minutes=next_short_break.waiting_time)
else:
long_break_time = next_break_time + datetime.timedelta(
minutes=self.__breaks_store.peek(BreakType.LONG).waiting_time)
next_long_break = self.__breaks_store.peek(BreakType.LONG)
if next_long_break:
long_break_time = next_break_time + datetime.timedelta(minutes=next_long_break.waiting_time)
self.__context.core_api.set_status(_('Next break at %s') % (utility.format_time(next_break_time)))
self.__plugins.update_next_break(next_break, short_break_time, long_break_time)

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -22,6 +21,7 @@ from typing import Optional
from safeeyes.breaks.queue import Queue
from safeeyes.context import Context, SESSION_KEY_BREAK, SESSION_KEY_BREAK_TYPE
from safeeyes.spi.breaks import Break, BreakType
from safeeyes.util.locale import _
class BreaksStore:
@ -60,22 +60,32 @@ class BreaksStore:
"""
Select the next break. If the queue is empty, return None.
"""
break_obj = None
break_obj: Optional[Break] = None
if self.is_empty():
return break_obj
if self.__short_queue.is_empty():
if self.__short_queue.is_empty() or break_type == BreakType.LONG:
break_obj = self.__next_long()
elif self.__long_queue.is_empty():
elif self.__long_queue.is_empty() or break_type == BreakType.SHORT:
break_obj = self.__next_short()
elif break_type == BreakType.LONG or self.__long_queue.peek().waiting_time <= self.__short_queue.peek().waiting_time:
break_obj = self.__next_long()
else:
break_obj = self.__next_short()
# break_type is not specified and the queue is not empty
next_long_break = self.__long_queue.peek()
next_short_break = self.__short_queue.peek()
if next_long_break and next_short_break and next_long_break.waiting_time <= next_short_break.waiting_time:
break_obj = self.__next_long()
else:
break_obj = self.__next_short()
break_obj.reset_time()
self.__current_break = break_obj
self.__context.session.set(SESSION_KEY_BREAK, self.__current_break.name)
if self.__current_break:
# Reset the last break time
self.__current_break.reset_time()
if break_obj:
self.__current_break = break_obj
self.__context.session.set(SESSION_KEY_BREAK, break_obj.name)
else:
self.__current_break = None
return break_obj
@ -116,11 +126,10 @@ class BreaksStore:
def __restore_last_break(self, last_break: str) -> None:
if not self.is_empty() and last_break is not None:
current_break = self.get_break()
if last_break != current_break.name:
if current_break is not None and last_break != current_break.name:
next_break = self.next()
if next_break is not None:
while next_break != current_break and next_break.name != last_break:
next_break = self.next()
while next_break is not None and next_break != current_break and next_break.name != last_break:
next_break = self.next()
def __build_shorts(self) -> Queue:
return BreaksStore.__build_queue(BreakType.SHORT,

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -61,11 +60,11 @@ class Context:
self.state = State.START
self.__settings_dialog_visible = False
self.env: DesktopEnvironment = DesktopEnvironment.get_env()
self.core_api: CoreAPI = None
self.thread_api: ThreadAPI = None
self.break_api: BreakAPI = None
self.window_api: WindowAPI = None
self.plugin_api: PluginAPI = None
self.core_api: CoreAPI
self.thread_api: ThreadAPI
self.break_api: BreakAPI
self.window_api: WindowAPI
self.plugin_api: PluginAPI
def set_apis(self, core_api: CoreAPI,
thread_api: ThreadAPI,

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -17,6 +16,7 @@ import logging
import os
import re
import subprocess
from typing import Optional
class DesktopEnvironment:
@ -40,10 +40,11 @@ class DesktopEnvironment:
"""
Detect the desktop environment.
"""
desktop_session = os.environ.get('DESKTOP_SESSION')
current_desktop = os.environ.get('XDG_CURRENT_DESKTOP')
desktop_session: Optional[str] = os.environ.get('DESKTOP_SESSION')
current_desktop: Optional[str] = os.environ.get('XDG_CURRENT_DESKTOP')
env = 'unknown'
if desktop_session is not None:
gnome_session_id: Optional[str] = os.environ.get('GNOME_DESKTOP_SESSION_ID')
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']:
@ -55,8 +56,7 @@ class DesktopEnvironment:
elif 'plasma' in desktop_session or desktop_session.startswith('kubuntu') or os.environ.get(
'KDE_FULL_SESSION') == 'true':
env = 'kde'
elif (os.environ.get('GNOME_DESKTOP_SESSION_ID') is not None) and (
'deprecated' not in os.environ.get('GNOME_DESKTOP_SESSION_ID')):
elif (gnome_session_id is not None) and ('deprecated' not in gnome_session_id):
env = 'gnome'
elif desktop_session.startswith('ubuntu'):
env = 'unity'

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -14,17 +13,18 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
import importlib
import inspect
import logging
import os
import sys
from typing import List, Any, Dict
from typing import List, Any, Dict, Optional
from safeeyes import utility, SAFE_EYES_HOME_DIR, SAFE_EYES_CONFIG_DIR
from safeeyes.config import Config
from safeeyes.context import Context
from safeeyes.env import system
from safeeyes.plugin_utils.proxy import PluginProxy
from safeeyes.plugin_utils.plugin import Validator
from safeeyes.plugin_utils.proxy import PluginProxy, ValidatorProxy
from safeeyes.util.locale import _
from safeeyes.utility import DESKTOP_ENVIRONMENT, CONFIG_RESOURCE
sys.path.append(os.path.abspath(utility.SYSTEM_PLUGINS_DIR))
@ -54,11 +54,12 @@ class PluginLoader:
"""
Load the given plugin.
"""
plugin_obj: PluginProxy
plugin_id = plugin['id']
plugin_enabled = plugin['enabled']
if plugin_id in self.__plugins and not plugin_enabled:
# Loading a disabled plugin but it was loaded earlier
plugin_obj: PluginProxy = self.__plugins[plugin_id]
plugin_obj = self.__plugins[plugin_id]
plugin_obj.disable()
if not plugin_obj.can_breaks_override():
# Plugin is disabled and breaks cannot override it
@ -90,7 +91,7 @@ class PluginLoader:
if plugin_enabled or plugin_config.get('break_override_allowed', False):
if plugin_id in self.__plugins:
# The plugin is already enabled or partially loaded due to break_override_allowed
plugin_obj: PluginProxy = self.__plugins[plugin_id]
plugin_obj = self.__plugins[plugin_id]
# Validate the dependencies again
if PluginLoader.__check_plugin_dependencies(context, plugin_id, plugin_config,
plugin.get('settings', {}), plugin_path):
@ -120,11 +121,11 @@ class PluginLoader:
plugin_obj.enable()
@staticmethod
def load_plugins_config(context: Context, config: Config):
def load_plugins_config(context: Context, config: Config) -> List[dict]:
"""
Load all the plugins from the given directory.
"""
configs = []
configs: List[dict] = []
for plugin in config.get('plugins'):
plugin_path = os.path.join(SYSTEM_PLUGINS_DIR, plugin['id'])
if not os.path.isdir(plugin_path):
@ -134,30 +135,30 @@ class PluginLoader:
plugin_icon_path = os.path.join(plugin_path, 'icon.png')
plugin_module_path = os.path.join(plugin_path, 'plugin.py')
if not os.path.isfile(plugin_module_path):
return
return []
icon = None
if os.path.isfile(plugin_icon_path):
icon = plugin_icon_path
else:
icon = system.get_resource_path('ic_plugin.png')
config = utility.load_json(plugin_config_path)
if config is None:
plugin_config = utility.load_json(plugin_config_path)
if plugin_config is None:
continue
dependency_description = PluginLoader.__check_plugin_dependencies(context, plugin['id'], config,
dependency_description = PluginLoader.__check_plugin_dependencies(context, plugin['id'], plugin_config,
plugin.get('settings', {}), plugin_path)
if dependency_description:
plugin['enabled'] = False
config['error'] = True
config['meta']['description'] = dependency_description
plugin_config['error'] = True
plugin_config['meta']['description'] = dependency_description
icon = system.get_resource_path('ic_warning.png')
else:
config['error'] = False
config['id'] = plugin['id']
config['icon'] = icon
config['enabled'] = plugin['enabled']
for setting in config['settings']:
plugin_config['error'] = False
plugin_config['id'] = plugin['id']
plugin_config['icon'] = icon
plugin_config['enabled'] = plugin['enabled']
for setting in plugin_config['settings']:
setting['safeeyes_config'] = plugin['settings']
configs.append(config)
configs.append(plugin_config)
return configs
@staticmethod
@ -170,7 +171,7 @@ class PluginLoader:
@staticmethod
def __check_plugin_dependencies(context: Context, plugin_id: str, plugin_config: dict, plugin_settings: dict,
plugin_path: str):
plugin_path: str) -> Optional[str]:
"""
Check the plugin dependencies.
"""
@ -196,11 +197,16 @@ class PluginLoader:
return _('Please add the resource %(resource)s to %(config_resource)s directory') % {
'resource': resource, 'config_resource': CONFIG_RESOURCE}
plugin_dependency_checker = os.path.join(plugin_path, 'dependency_checker.py')
if os.path.isfile(plugin_dependency_checker):
dependency_checker = importlib.import_module((plugin_id + '.dependency_checker'))
if dependency_checker and hasattr(dependency_checker, "validate") and len(
inspect.getfullargspec(getattr(dependency_checker, "validate")).args) == 3:
return dependency_checker.validate(context, plugin_config, plugin_settings)
validator = PluginLoader.__get_validator(plugin_id, plugin_path)
if validator:
return validator.validate(context, plugin_config, plugin_settings)
return None
@staticmethod
def __get_validator(plugin_id: str, plugin_path: str) -> Optional[Validator]:
plugin_validator = os.path.join(plugin_path, 'validator.py')
if os.path.isfile(plugin_validator):
validator = importlib.import_module((plugin_id + '.validator'))
return ValidatorProxy(validator)
return None

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -13,8 +12,8 @@
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
import datetime
from typing import List
from datetime import datetime
from typing import List, Optional
from safeeyes.context import Context
from safeeyes.plugin_utils.proxy import PluginProxy
@ -87,7 +86,7 @@ class PluginManager(PluginAPI):
for plugin in self.__plugins:
plugin.on_exit()
def update_next_break(self, break_obj: Break, next_short_break: datetime.datetime,
next_long_break: datetime.datetime) -> None:
def update_next_break(self, break_obj: Break, next_short_break: Optional[datetime],
next_long_break: Optional[datetime]) -> None:
for plugin in self.__plugins:
plugin.update_next_break(break_obj, next_short_break, next_long_break)

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -95,8 +94,15 @@ class Plugin(abc.ABC):
"""
pass
def update_next_break(self, break_obj: Break, next_short_break: datetime, next_long_break: datetime) -> None:
def update_next_break(self, break_obj: Break, next_short_break: Optional[datetime],
next_long_break: Optional[datetime]) -> None:
"""
Called when the next break is scheduled.
"""
pass
class Validator(abc.ABC):
def validate(self, context: Context, plugin_config: dict, plugin_settings: dict) -> Optional[str]:
pass

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -18,11 +17,23 @@ from datetime import datetime
from typing import Optional, Any
from safeeyes.context import Context
from safeeyes.plugin_utils.plugin import Plugin
from safeeyes.plugin_utils.plugin import Plugin, Validator
from safeeyes.spi.breaks import Break
from safeeyes.spi.plugin import Widget, TrayAction, BreakAction
class ModuleUtil:
@staticmethod
def has_method(module, method_name, no_of_args=0):
"""
Check whether the given function is defined in the module or not.
"""
if hasattr(module, method_name):
if len(inspect.getfullargspec(getattr(module, method_name)).args) == no_of_args:
return True
return False
class PluginProxy(Plugin):
"""
A proxy class representing the actual plugin object.
@ -50,13 +61,13 @@ class PluginProxy(Plugin):
def disable(self) -> None:
if self.__enabled:
self.__enabled = False
if PluginProxy.__has_method(self.__plugin, 'disable', 0):
if ModuleUtil.has_method(self.__plugin, 'disable', 0):
return self.__plugin.disable()
def enable(self) -> None:
if not self.__enabled:
self.__enabled = True
if PluginProxy.__has_method(self.__plugin, 'enable', 0):
if ModuleUtil.has_method(self.__plugin, 'enable', 0):
return self.__plugin.enable()
def update_settings(self, plugin_settings: dict) -> None:
@ -66,14 +77,14 @@ class PluginProxy(Plugin):
"""
This function is called to initialize the plugin.
"""
if PluginProxy.__has_method(self.__plugin, 'init', 2):
if ModuleUtil.has_method(self.__plugin, 'init', 2):
self.__plugin.init(context, self.__settings)
def get_break_action(self, break_obj: Break) -> Optional[BreakAction]:
"""
This function is called before on_pre_break and on_start_break.
"""
if PluginProxy.__has_method(self.__plugin, 'get_break_action', 1):
if ModuleUtil.has_method(self.__plugin, 'get_break_action', 1):
return self.__plugin.get_break_action(break_obj)
return BreakAction.allow()
@ -82,35 +93,35 @@ class PluginProxy(Plugin):
Called some time before starting the break to prepare the plugins. For example, the notification plugin will
show a notification during this method call.
"""
if self.__is_supported(break_obj) and PluginProxy.__has_method(self.__plugin, 'on_pre_break', 1):
if self.__is_supported(break_obj) and ModuleUtil.has_method(self.__plugin, 'on_pre_break', 1):
self.__plugin.on_pre_break(break_obj)
def on_start_break(self, break_obj: Break) -> None:
"""
Called when starting a break.
"""
if self.__is_supported(break_obj) and PluginProxy.__has_method(self.__plugin, 'on_start_break', 1):
if self.__is_supported(break_obj) and ModuleUtil.has_method(self.__plugin, 'on_start_break', 1):
self.__plugin.on_start_break(break_obj)
def on_count_down(self, break_obj: Break, countdown: int, seconds: int) -> None:
"""
Called during a break.
"""
if self.__is_supported(break_obj) and PluginProxy.__has_method(self.__plugin, 'on_count_down', 3):
if self.__is_supported(break_obj) and ModuleUtil.has_method(self.__plugin, 'on_count_down', 3):
self.__plugin.on_count_down(break_obj, countdown, seconds)
def on_stop_break(self, break_obj: Break, skipped: bool, postponed: bool) -> None:
"""
Called when a break is stopped.
"""
if self.__is_supported(break_obj) and PluginProxy.__has_method(self.__plugin, 'on_stop_break', 3):
if self.__is_supported(break_obj) and ModuleUtil.has_method(self.__plugin, 'on_stop_break', 3):
self.__plugin.on_stop_break(break_obj, skipped, postponed)
def get_widget(self, break_obj: Break) -> Optional[Widget]:
"""
Return an optional break screen widget.
"""
if self.__is_supported(break_obj) and PluginProxy.__has_method(self.__plugin, 'get_widget', 1):
if self.__is_supported(break_obj) and ModuleUtil.has_method(self.__plugin, 'get_widget', 1):
return self.__plugin.get_widget(break_obj)
return None
@ -118,7 +129,7 @@ class PluginProxy(Plugin):
"""
Return an optional break screen widget.
"""
if self.__is_supported(break_obj) and PluginProxy.__has_method(self.__plugin, 'get_tray_action', 1):
if self.__is_supported(break_obj) and ModuleUtil.has_method(self.__plugin, 'get_tray_action', 1):
return self.__plugin.get_tray_action(break_obj)
return None
@ -126,36 +137,38 @@ class PluginProxy(Plugin):
"""
Called when Safe Eyes is started.
"""
if self.__enabled and PluginProxy.__has_method(self.__plugin, 'on_start', 0):
if self.__enabled and ModuleUtil.has_method(self.__plugin, 'on_start', 0):
self.__plugin.on_start()
def on_stop(self) -> None:
"""
Called when Safe Eyes is stopped.
"""
if self.__enabled and PluginProxy.__has_method(self.__plugin, 'on_stop', 0):
if self.__enabled and ModuleUtil.has_method(self.__plugin, 'on_stop', 0):
self.__plugin.on_stop()
def on_exit(self) -> None:
"""
Called when Safe Eyes is closed.
"""
if self.__enabled and PluginProxy.__has_method(self.__plugin, 'on_exit', 0):
if self.__enabled and ModuleUtil.has_method(self.__plugin, 'on_exit', 0):
self.__plugin.on_exit()
def update_next_break(self, break_obj: Break, next_short_break: datetime, next_long_break: datetime) -> None:
def update_next_break(self, break_obj: Break, next_short_break: Optional[datetime],
next_long_break: Optional[datetime]) -> None:
"""
Called when the next break is scheduled.
"""
if self.__is_supported(break_obj) and PluginProxy.__has_method(self.__plugin, 'update_next_break', 3):
if self.__is_supported(break_obj) and ModuleUtil.has_method(self.__plugin, 'update_next_break', 3):
self.__plugin.update_next_break(break_obj, next_short_break, next_long_break)
@staticmethod
def __has_method(module, method_name, no_of_args=0):
"""
Check whether the given function is defined in the module or not.
"""
if hasattr(module, method_name):
if len(inspect.getfullargspec(getattr(module, method_name)).args) == no_of_args:
return True
return False
class ValidatorProxy(Validator):
def __init__(self, module: Any):
self.__validator = module
def validate(self, context: Context, plugin_config: dict, plugin_settings: dict) -> Optional[str]:
if ModuleUtil.has_method(self.__validator, "validate", 3):
return self.__validator.validate(context, plugin_config, plugin_settings)
return None

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -69,7 +68,7 @@ class BreakScreen:
"""
logging.info("User skipped the break")
# Must call on_skip before close to lock screen before closing the break screen
self.__context.break_api.next_break()
self.__context.break_api.skip()
self.close()
def postpone_break(self):

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -15,12 +15,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
from safeeyes import utility
from safeeyes.context import Context
def validate(ctx: Context, plugin_config: dict, plugin_settings: dict):
def validate(ctx: Context, plugin_config: dict, plugin_settings: dict) -> Optional[str]:
command = "wlrctl" if ctx.env.is_wayland() else "xprop"
if not utility.command_exist(command):
return _("Please install the command-line tool '%s'") % command

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
from safeeyes.context import Context
from safeeyes.env import system
@ -30,7 +31,7 @@ def __is_valid_cron(expr: str) -> bool:
return False
def validate(ctx: Context, plugin_config: dict, plugin_settings: dict):
def validate(ctx: Context, plugin_config: dict, plugin_settings: dict) -> Optional[str]:
if not system.module_exists("croniter"):
return _("Please install the Python module 'croniter'")

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -212,13 +212,18 @@ def on_stop():
smart_pause.stop()
def update_next_break(break_obj: Break, next_short_break: datetime.datetime,
next_long_break: datetime.datetime) -> None:
def update_next_break(break_obj: Break, next_short_break_time: Optional[datetime.datetime],
next_long_break_time: Optional[datetime.datetime]) -> None:
"""
Update the next break time.
"""
date_time = next_short_break if next_short_break < next_long_break else next_long_break
smart_pause.set_next_break(break_obj, date_time)
next_break_time: Optional[datetime.datetime] = None
if next_short_break_time is not None:
next_break_time = next_short_break_time if next_long_break_time is None or next_short_break_time < next_long_break_time else next_long_break_time
elif next_long_break_time is not None:
next_break_time = next_long_break_time if next_short_break_time is None or next_long_break_time < next_short_break_time else next_short_break_time
if next_break_time:
smart_pause.set_next_break(break_obj, next_break_time)
def get_break_action(break_obj: Break) -> Optional[BreakAction]:

View File

@ -15,16 +15,15 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Optional
from safeeyes import utility
from safeeyes.context import Context
from safeeyes.util.locale import _
def validate(plugin_config, plugin_settings):
command = None
if utility.DESKTOP_ENVIRONMENT == "gnome" and utility.IS_WAYLAND:
command = "dbus-send"
else:
command = "xprintidle"
def validate(ctx: Context, plugin_config: dict, plugin_settings: dict) -> Optional[str]:
command = "dbus-send" if ctx.env.name == "gnome" and ctx.env.is_wayland() else "xprintidle"
if not utility.command_exist(command):
return _("Please install the command-line tool '%s'") % command
else:

View File

@ -17,7 +17,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
from typing import Dict
from typing import Dict, Optional
import gi
@ -435,12 +435,19 @@ def init(ctx: Context, plugin_config: dict):
tray_icon.initialize(plugin_config)
def update_next_break(break_obj, next_short_break_time, next_long_break_time):
def update_next_break(break_obj, next_short_break_time: Optional[datetime.datetime],
next_long_break_time: Optional[datetime.datetime]):
"""
Update the next break time.
"""
next_break_time = next_short_break_time if next_short_break_time < next_long_break_time else next_long_break_time
tray_icon.next_break_time(next_break_time)
next_break_time: Optional[datetime.datetime] = None
if next_short_break_time is not None:
next_break_time = next_short_break_time if next_long_break_time is None or next_short_break_time < next_long_break_time else next_long_break_time
elif next_long_break_time is not None:
next_break_time = next_long_break_time if next_short_break_time is None or next_long_break_time < next_short_break_time else next_short_break_time
if next_break_time:
tray_icon.next_break_time(next_break_time)
def on_pre_break(break_obj):

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,8 +1,7 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
# Copyright (C) 2021 Gobinath
# Copyright (C) 2017 Gobinath
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -16,9 +15,8 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import abc
import datetime
from datetime import datetime
from typing import List
from safeeyes.spi.breaks import BreakType, Break

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.

View File

@ -10,3 +10,7 @@ def init_locale():
system_locale.install()
locale.bindtextdomain('safeeyes', utility.LOCALE_PATH)
return system_locale
def _(message: str) -> str:
return gettext.gettext(message)

View File

@ -1,4 +1,3 @@
#!/usr/bin/env python
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
@ -31,6 +30,7 @@ import sys
from distutils.version import LooseVersion
from logging.handlers import RotatingFileHandler
from pathlib import Path
from typing import Optional
import babel.core
import babel.dates
@ -123,7 +123,7 @@ def mkdir(path):
raise
def load_json(json_path):
def load_json(json_path) -> Optional[dict]:
"""
Load the JSON file from the given path.
"""