diff --git a/build.sh b/build.sh index 84745960..efee7d6c 100755 --- a/build.sh +++ b/build.sh @@ -5,4 +5,6 @@ rm -rf build/ dist/ safeeyes.egg-info/ .eggs/ python3 setup.py sdist bdist_wheel twine upload --repository pypitest dist/safeeyes*.tar.gz clear >$(tty) -twine upload --repository pypitest dist/safeeyes*.whl \ No newline at end of file +twine upload --repository pypitest dist/safeeyes*.whl + +read x; \ No newline at end of file diff --git a/gitkraken.sh b/gitkraken.sh new file mode 100755 index 00000000..6e4bc575 --- /dev/null +++ b/gitkraken.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +gitkraken -p . \ No newline at end of file diff --git a/install in development mode and run.sh b/install in development mode and run.sh new file mode 100755 index 00000000..a81f5649 --- /dev/null +++ b/install in development mode and run.sh @@ -0,0 +1,36 @@ +#!/bin/bash + + +python3 -m pip install -e '/home/xy/workspace/Safeeyes fixálása/SafeEyes 2.1.6, fixálva 3 dologgal, lásd a git logot/' +# sleep 3 +# read x; +safeeyes & + + +# How to: https://packaging.python.org/en/latest/tutorials/installing-packages/ + +# Installing from a local src tree + +# Installing from local src in Development Mode, i.e. in such a way that the project appears to be installed, but yet is still editable from the src tree. +# Unix/macOS + +# python3 -m pip install -e + +# Windows + +# You can also install normally from src +# Unix/macOS + +# python3 -m pip install + + + +# Installing from VCS + +# Install a project from VCS in “editable” mode. For a full breakdown of the syntax, see pip’s section on VCS Support. +# Unix/macOS + +# python3 -m pip install -e SomeProject @ git+https://git.repo/some_pkg.git # from git +# python3 -m pip install -e SomeProject @ hg+https://hg.repo/some_pkg # from mercurial +# python3 -m pip install -e SomeProject @ svn+svn://svn.repo/some_pkg/trunk/ # from svn +# python3 -m pip install -e SomeProject @ git+https://git.repo/some_pkg.git@feature # from a branch diff --git a/run reset.sh b/run reset.sh new file mode 100755 index 00000000..c8ba9a25 --- /dev/null +++ b/run reset.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +safeeyes --reset +sleep 3 +read x; diff --git a/run.sh b/run.sh new file mode 100755 index 00000000..91e91483 --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +safeeyes & diff --git a/safeeyes/__main__.py b/safeeyes/__main__.py index 2eab4cd7..280d6916 100755 --- a/safeeyes/__main__.py +++ b/safeeyes/__main__.py @@ -107,6 +107,8 @@ def main(): group.add_argument('-t', '--take-break', help=_('Take a break now').lower(), action='store_true') parser.add_argument('--debug', help=_('start safeeyes in debug mode'), action='store_true') parser.add_argument('--status', help=_('print the status of running safeeyes instance and exit'), action='store_true') + parser.add_argument('--reset', help=_('Reset the scheduled time of the next break but not total break status like if a long break is due soon.'), action='store_true') + # sajt. Noh, sikerült implementálnom ezt a feature-t. Viszont nem jöttem rá arra, hogy hogyan kell úgy futtatni a programomat, hogy éljen is benne ez, mert még mindig a régi verzió működését kapom úgy látom. :/ a python3 -m safeeyes paranccsal futtattam és a --reset opciónak nyoma sehol. Mondjuk a smartpause plugin az meg átállt az új működésre szóval lehet h más a baj. parser.add_argument('--version', action='version', version='%(prog)s ' + SAFE_EYES_VERSION) args = parser.parse_args() @@ -135,6 +137,8 @@ def main(): rpc_client.take_break() elif args.status: print(rpc_client.status()) + elif args.reset: + rpc_client.reset() elif args.quit: rpc_client.quit() else: diff --git a/safeeyes/plugins/healthstats/plugin.py b/safeeyes/plugins/healthstats/plugin.py index e1cae38a..ad276c3e 100644 --- a/safeeyes/plugins/healthstats/plugin.py +++ b/safeeyes/plugins/healthstats/plugin.py @@ -55,7 +55,8 @@ def init(ctx, safeeyes_config, plugin_config): 'total_resets': 0, } - session = context['session']['plugin'].get('healthstats', {}) | defaults + session = context['session']['plugin'].get('healthstats', {}).copy() + session.update(defaults) # refactored to maintain compatibility with python3.8 on Ubuntu 20.04 LTS (dict | dict syntax was introduced in python3.9). if 'no_of_breaks' in session: # Ignore old format session. session = defaults diff --git a/safeeyes/plugins/mediacontrol/plugin.py b/safeeyes/plugins/mediacontrol/plugin.py index df471cd3..3f5faf23 100644 --- a/safeeyes/plugins/mediacontrol/plugin.py +++ b/safeeyes/plugins/mediacontrol/plugin.py @@ -23,6 +23,7 @@ import logging import os import dbus +import dbus.exceptions import re import gi from safeeyes.model import TrayAction @@ -41,11 +42,18 @@ def __active_players(): for service in bus.list_names(): if re.match('org.mpris.MediaPlayer2.', service): - player = bus.get_object(service, "/org/mpris/MediaPlayer2") - interface = dbus.Interface(player, 'org.freedesktop.DBus.Properties') - status = str(interface.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus')).lower() - if status == "playing": - players.append(player) + try: + player = bus.get_object(service, "/org/mpris/MediaPlayer2") + interface = dbus.Interface(player, 'org.freedesktop.DBus.Properties') + status = str(interface.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus')).lower() + if status == "playing": + players.append(player) + except dbus.exceptions.DBusException as e: + # Purpose of this: The Chromium snap (at least on ubuntu 20.04 LTS) forbids SafeEyes from sending dbus messages to Chromium and we must catch that exception and ignore that particular player. If we don't, the the method and plugin fails and the break itself fails to be called. With this fix, only impossible-to-reach players are ignored and all else works. + # The specific exception is (dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied) + # We don't care about logging the error but maybe we should log it in debug mode: + logging.debug(f"DBusException: {e}") + return players diff --git a/safeeyes/plugins/smartpause/config.json b/safeeyes/plugins/smartpause/config.json index 9ca35a69..a073b6b8 100644 --- a/safeeyes/plugins/smartpause/config.json +++ b/safeeyes/plugins/smartpause/config.json @@ -2,7 +2,7 @@ "meta": { "name": "Smart Pause", "description": "Pause Safe Eyes if the system is idle", - "version": "0.0.3" + "version": "0.0.3-adventuretc-2024-08-18" }, "dependencies": { "python_modules": [], @@ -20,6 +20,12 @@ "max": 3600, "min": 5 }, + { + "id": "interpret_idle_as_break", + "label": "Interpret idle time equivalent to upcoming break duration as a break", + "type": "BOOL", + "default": false + }, { "id": "postpone_if_active", "label": "Postpone the next break until the system becomes idle", diff --git a/safeeyes/plugins/smartpause/plugin.py b/safeeyes/plugins/smartpause/plugin.py index 296fe516..84b9cde5 100644 --- a/safeeyes/plugins/smartpause/plugin.py +++ b/safeeyes/plugins/smartpause/plugin.py @@ -43,6 +43,7 @@ next_break_duration = 0 short_break_interval = 0 waiting_time = 2 +interpret_idle_as_break = False is_wayland_and_gnome = False use_swayidle = False @@ -156,6 +157,7 @@ def init(ctx, safeeyes_config, plugin_config): global short_break_interval global long_break_duration global waiting_time + global interpret_idle_as_break global postpone_if_active global is_wayland_and_gnome global use_swayidle @@ -165,6 +167,7 @@ def init(ctx, safeeyes_config, plugin_config): disable_safeeyes = context['api']['disable_safeeyes'] postpone = context['api']['postpone'] idle_time = plugin_config['idle_time'] + interpret_idle_as_break = plugin_config['interpret_idle_as_break'] postpone_if_active = plugin_config['postpone_if_active'] short_break_interval = safeeyes_config.get( 'short_break_interval') * 60 # Convert to seconds @@ -194,14 +197,22 @@ def __start_idle_monitor(): smart_pause_activated = True idle_start_time = datetime.datetime.now() - datetime.timedelta(seconds=system_idle_time) logging.info('Pause Safe Eyes due to system idle') - disable_safeeyes(None, True) + info = _('Paused Safe Eyes due to system being idle') + disable_safeeyes(info, True) elif system_idle_time < idle_time and context['state'] == State.RESTING and idle_start_time is not None: + #2.1.4-ben ez a sor még más volt. Biztos, hogy jó most? "elif system_idle_time < idle_time and context['state'] == State.STOPPED and idle_start_time is not None:" logging.info('Resume Safe Eyes due to user activity') smart_pause_activated = False idle_period = (datetime.datetime.now() - idle_start_time) idle_seconds = idle_period.total_seconds() context['idle_period'] = idle_seconds - if idle_seconds < short_break_interval: + if interpret_idle_as_break and idle_seconds >= next_break_duration: + # User is idle for break duration and wants to consider it as a break + logging.debug("Idle for %d seconds; long breaks are %d seconds long", idle_seconds, long_break_duration) + enable_safeeyes(-1, idle_seconds >= long_break_duration) + elif idle_seconds < short_break_interval: + # Ja mostmár értem. Baszná meg. 2.1.4 és 2.1.6 közt azt változtatták meg ebben a pluginban, hogy nincs "interpret_idle_as_break" opció hanem az idle time-ot mindig csak úgy értemezi a program, hogy annyival kitolja a következő szünet esedékességi idejét és pause-ra teszi a safeeyes-t amíg nem ülsz a gépnél. De nekem nem ez kell hanem a interpret_idle_as_break működés. + # Ráadásul nem írta át a verziószámot amikor megváltoztatta a plugint. # Credit back the idle time if next_break_time is not None: # This method runs in a thread since the start. diff --git a/safeeyes/rpc.py b/safeeyes/rpc.py index ebb3686b..e3b53dc5 100644 --- a/safeeyes/rpc.py +++ b/safeeyes/rpc.py @@ -40,6 +40,7 @@ def __init__(self, port, context): self.__server.register_function(context['api']['disable_safeeyes'], 'disable_safeeyes') self.__server.register_function(context['api']['take_break'], 'take_break') self.__server.register_function(context['api']['status'], 'status') + self.__server.register_function(context['api']['reset'], 'reset') self.__server.register_function(context['api']['quit'], 'quit') def start(self): @@ -92,7 +93,7 @@ def disable_safeeyes(self): """ Disable Safe Eyes. """ - self.proxy.disable_safeeyes(None) + self.proxy.disable_safeeyes(None, False) def take_break(self): """ @@ -106,6 +107,12 @@ def status(self): """ return self.proxy.status() + def reset(self): + """ + Reset the scheduled time of the next break but not total break status like if a long break is due soon. + """ + return self.proxy.reset() + def quit(self): """ Quit Safe Eyes. diff --git a/safeeyes/safeeyes.py b/safeeyes/safeeyes.py index 0a7bcaea..97934306 100644 --- a/safeeyes/safeeyes.py +++ b/safeeyes/safeeyes.py @@ -71,9 +71,11 @@ def __init__(self, system_locale, config): self.show_about) self.context['api']['enable_safeeyes'] = lambda next_break_time=-1, reset_breaks=False: \ utility.execute_main_thread(self.enable_safeeyes, next_break_time, reset_breaks) - self.context['api']['disable_safeeyes'] = lambda status: utility.execute_main_thread( - self.disable_safeeyes, status) + self.context['api']['disable_safeeyes'] = lambda status, is_resting: \ + utility.execute_main_thread(self.disable_safeeyes, status, is_resting) + # fixed a bug. self.context['api']['status'] = self.status + self.context['api']['reset'] = self.reset self.context['api']['quit'] = lambda: utility.execute_main_thread( self.quit) if self.config.get('persist_state'): @@ -307,6 +309,32 @@ def status(self): """ return self._status + def reset(self): + """ + Reset the scheduled time of the next break but not total break status like if a long break is due soon. + """ + + # Stop the Safe Eyes core + if self.active: + self.plugins_manager.stop() + self.safe_eyes_core.stop() + + if self.rpc_server is None and self.config.get('use_rpc_server'): + # # RPC server wasn't running but now enabled + self.__start_rpc_server() + elif self.rpc_server is not None and not self.config.get('use_rpc_server'): + # # RPC server was running but now disabled + self.__stop_rpc_server() + + # Restart the core and initialize the components + self.safe_eyes_core.initialize(self.config) + self.break_screen.initialize(self.config) + self.plugins_manager.init(self.context, self.config) + if self.active and self.safe_eyes_core.has_breaks(): + # 1 sec delay is required to give enough time for core to be stopped + Timer(1.0, self.safe_eyes_core.start).start() + self.plugins_manager.start() + def persist_session(self): """ Save the session object to the session file.