diff --git a/README.md b/README.md index 3f38d94..6f9d160 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![PyPI version](https://badge.fury.io/py/safeeyes.svg)](https://badge.fury.io/py/safeeyes) [![Debian](https://badges.debian.net/badges/debian/unstable/safeeyes/version.svg)](https://packages.debian.org/unstable/safeeyes) [![AUR](https://img.shields.io/aur/version/safeeyes)](https://aur.archlinux.org/packages/safeeyes) +[![Flathub](https://img.shields.io/flathub/v/io.github.slgobinath.SafeEyes)](https://flathub.org/apps/details/io.github.slgobinath.SafeEyes) [![Translation status](https://hosted.weblate.org/widgets/safe-eyes/-/translations/svg-badge.svg)](https://hosted.weblate.org/engage/safe-eyes/?utm_source=widget) [![Awesome Humane Tech](https://raw.githubusercontent.com/humanetech-community/awesome-humane-tech/main/humane-tech-badge.svg?sanitize=true)](https://github.com/humanetech-community/awesome-humane-tech) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/slgobinath) @@ -84,6 +85,12 @@ sudo zypper install safeeyes sudo apk add safeeyes ``` +### Flatpak + +```bash +flatpak install flathub io.github.slgobinath.SafeEyes +``` + ### Other Linux & Run from source Ensure to meet the following dependencies: @@ -161,6 +168,22 @@ For more details, please check the issue: [#329](https://github.com/slgobinath/S Thirdparty plugins are available at another GitHub repository: [safeeyes-plugins](https://github.com/slgobinath/safeeyes-plugins). More details about how to write your own plugin and how to install third-party plugin are available there. +## How to Release? + +1. Checkout the latest commits from the `master` branch +2. Run `python3 -m safeeyes` to make sure nothing is broken +3. Update the Safe Eyes version in the following places (Open the project in VSCode and search for the current version): + - [setup.py](https://github.com/slgobinath/SafeEyes/blob/master/setup.py#L81) + - [setup.py](https://github.com/slgobinath/SafeEyes/blob/master/setup.py#L88) + - [safeeyes.py](https://github.com/slgobinath/SafeEyes/blob/master/safeeyes/safeeyes.py#L43) + - [io.github.slgobinath.SafeEyes.metainfo.xml](https://github.com/slgobinath/SafeEyes/blob/master/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml#L50) + - [about_dialog.glade](https://github.com/slgobinath/SafeEyes/blob/master/safeeyes/glade/about_dialog.glade#L74) +4. Update the [changelog](https://github.com/slgobinath/SafeEyes/blob/master/debian/changelog) (for Ubuntu release) +5. Commit the changes to `master` +6. Create a pull-request from `master` to `release` +7. Merge the PR to release **with merge commit** (Important to merge with merge commit) + + ## License GNU General Public License v3 diff --git a/debian/changelog b/debian/changelog index 1837ba4..27e607e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,6 @@ -safeeyes (2.1.5-0) lunar; urgency=high +safeeyes (2.1.6-0) lunar; urgency=high + * Support Python 3.11 + * Minor bug fixes * Fix the ecd ..rror if there is no long break diff --git a/debian/safeeyes.install b/debian/safeeyes.install index 0a32b7b..ebbb108 100644 --- a/debian/safeeyes.install +++ b/debian/safeeyes.install @@ -1,17 +1,17 @@ -safeeyes/platform/safeeyes.desktop usr/share/applications -safeeyes/platform/icons/hicolor/128x128/apps/safeeyes.png usr/share/icons/hicolor/128x128/apps -safeeyes/platform/icons/hicolor/16x16/apps/safeeyes.png usr/share/icons/hicolor/16x16/apps -safeeyes/platform/icons/hicolor/16x16/status/safeeyes_disabled.png usr/share/icons/hicolor/16x16/status -safeeyes/platform/icons/hicolor/16x16/status/safeeyes_enabled.png usr/share/icons/hicolor/16x16/status -safeeyes/platform/icons/hicolor/16x16/status/safeeyes_timer.png usr/share/icons/hicolor/16x16/status -safeeyes/platform/icons/hicolor/24x24/apps/safeeyes.png usr/share/icons/hicolor/24x24/apps -safeeyes/platform/icons/hicolor/24x24/status/safeeyes_disabled.png usr/share/icons/hicolor/24x24/status -safeeyes/platform/icons/hicolor/24x24/status/safeeyes_enabled.png usr/share/icons/hicolor/24x24/status -safeeyes/platform/icons/hicolor/24x24/status/safeeyes_timer.png usr/share/icons/hicolor/24x24/status -safeeyes/platform/icons/hicolor/32x32/apps/safeeyes.png usr/share/icons/hicolor/32x32/apps -safeeyes/platform/icons/hicolor/32x32/status/safeeyes_disabled.png usr/share/icons/hicolor/32x32/status -safeeyes/platform/icons/hicolor/32x32/status/safeeyes_enabled.png usr/share/icons/hicolor/32x32/status -safeeyes/platform/icons/hicolor/48x48/apps/safeeyes.png usr/share/icons/hicolor/48x48/apps -safeeyes/platform/icons/hicolor/48x48/status/safeeyes_disabled.png usr/share/icons/hicolor/48x48/status -safeeyes/platform/icons/hicolor/48x48/status/safeeyes_enabled.png usr/share/icons/hicolor/48x48/status -safeeyes/platform/icons/hicolor/64x64/apps/safeeyes.png usr/share/icons/hicolor/64x64/apps \ No newline at end of file +safeeyes/platform/io.github.slgobinath.SafeEyes.desktop usr/share/applications +safeeyes/platform/icons/hicolor/128x128/apps/io.github.slgobinath.SafeEyes.png usr/share/icons/hicolor/128x128/apps +safeeyes/platform/icons/hicolor/16x16/apps/io.github.slgobinath.SafeEyes.png usr/share/icons/hicolor/16x16/apps +safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-disabled.png usr/share/icons/hicolor/16x16/status +safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-enabled.png usr/share/icons/hicolor/16x16/status +safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-timer.png usr/share/icons/hicolor/16x16/status +safeeyes/platform/icons/hicolor/24x24/apps/io.github.slgobinath.SafeEyes.png usr/share/icons/hicolor/24x24/apps +safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-disabled.png usr/share/icons/hicolor/24x24/status +safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-enabled.png usr/share/icons/hicolor/24x24/status +safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-timer.png usr/share/icons/hicolor/24x24/status +safeeyes/platform/icons/hicolor/32x32/apps/io.github.slgobinath.SafeEyes.png usr/share/icons/hicolor/32x32/apps +safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-disabled.png usr/share/icons/hicolor/32x32/status +safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-enabled.png usr/share/icons/hicolor/32x32/status +safeeyes/platform/icons/hicolor/48x48/apps/io.github.slgobinath.SafeEyes.png usr/share/icons/hicolor/48x48/apps +safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-disabled.png usr/share/icons/hicolor/48x48/status +safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-enabled.png usr/share/icons/hicolor/48x48/status +safeeyes/platform/icons/hicolor/64x64/apps/io.github.slgobinath.SafeEyes.png usr/share/icons/hicolor/64x64/apps \ No newline at end of file diff --git a/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po index ce7dc7d..7b514a9 100644 --- a/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po +++ b/safeeyes/config/locale/de/LC_MESSAGES/safeeyes.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-03-07 09:50+0000\n" -"Last-Translator: J. Lavoie \n" +"PO-Revision-Date: 2023-07-04 20:53+0000\n" +"Last-Translator: Sebastian Pipping \n" "Language-Team: German \n" "Language: de\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.5.1\n" +"X-Generator: Weblate 5.0-dev\n" # Short break msgid "Tightly close your eyes" @@ -102,7 +102,10 @@ msgstr "Schließen" msgid "" "Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you " "to take breaks while you're working long hours at the computer" -msgstr "Beschreibung" +msgstr "" +"Safe Eyes schützt Ihre Augen vor Beschwerden (Asthenopie), indem es Sie " +"regelmäßig erinnert, Pausen zu machen, wenn Sie längere Zeit am Bildschirm " +"verbringen" # About dialog msgid "License" diff --git a/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po index 1428c69..1f1c877 100644 --- a/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po +++ b/safeeyes/config/locale/eu/LC_MESSAGES/safeeyes.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-09-28 22:17+0000\n" -"Last-Translator: Gontzal Manuel Pujana Onaindia \n" +"PO-Revision-Date: 2023-01-07 11:49+0000\n" +"Last-Translator: Porrumentzio \n" "Language-Team: Basque \n" "Language: eu\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.14.1\n" +"X-Generator: Weblate 4.15.1-dev\n" # Short break msgid "Tightly close your eyes" @@ -23,15 +23,15 @@ msgstr "Itxi begiak indarrez" # Short break msgid "Roll your eyes a few times to each side" -msgstr "Mugitu begiak alde bakoitzera pare bat aldiz" +msgstr "Mugitu begiak aldez alde" # Short break msgid "Rotate your eyes in clockwise direction" -msgstr "Biratu begiak erlojuaren noranzkoan" +msgstr "Biratu begiak erloju-orratzen noranzkoan" # Short break msgid "Rotate your eyes in counterclockwise direction" -msgstr "Biratu begiak erlojuaren aurkako noranzkoan" +msgstr "Biratu begiak erloju-orratzen kontrako noranzkoan" # Short break msgid "Blink your eyes" @@ -71,7 +71,7 @@ msgstr "itxi uneko safeeyes instantzia eta irten" # Commandline arg description msgid "show the settings dialog" -msgstr "erakutsi ezarpenen elkarrizketa-koadroa" +msgstr "erakutsi ezarpenak" # Commandline arg description msgid "start safeeyes in debug mode" @@ -90,8 +90,8 @@ msgid "" "Safe Eyes is running without an RPC server. Turn it on to use command-line " "arguments." msgstr "" -"Safe Eyes RPC zerbitzaririk gabe exekutatzen ari da. Piztu ezazu komando-" -"lerroko argumentuak erabiltzeko." +"RPC zerbitzaririk gabe ari da exekutatzen Safe Eyes. Piztu zerbitzaria " +"komando-lerroko argumentuak erabiltzeko." # About dialog msgid "Close" @@ -103,8 +103,8 @@ msgid "" "Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you " "to take breaks while you're working long hours at the computer" msgstr "" -"Safe Eyes-ek zure begiak begi-neketik (astenopia) babesten ditu " -"ordenagailuan ordu luzez zabiltzanean atsedenaldiak hartzeaz gogoraraziz" +"Safe Eyes-ek begi-neketik (astenopiatik) babesten zaitu ordenagailuan ordu " +"luzez zabiltzanean etenaldiak egiteko gogoraraziz" # About dialog msgid "License" @@ -120,19 +120,19 @@ msgstr "Atzeratu" # Settings dialog msgid "Break duration (in seconds)" -msgstr "Atsedenaldiaren iraupena (segundotan)" +msgstr "Etenaldiaren iraupena (segundotan)" # Settings dialog msgid "Interval between two breaks (in minutes)" -msgstr "Bi atsedenaldien arteko tartea (minututan)" +msgstr "Bi etenaldiren arteko tartea (minututan)" # Settings dialog msgid "Time to prepare for a break (in seconds)" -msgstr "Atsedenaldirako prestatzeko denbora (segundotan)" +msgstr "Etenaldirako prestatzeko denbora (segundotan)" # Settings dialog msgid "Keyboard shortcuts disabled period (in seconds)" -msgstr "Laster-teklak desgaitutako unea (segundotan)" +msgstr "Laster-teklak desgaitutako aldia (segundotan)" # Settings dialog msgid "Postponement duration (in minutes)" @@ -140,15 +140,15 @@ msgstr "Atzerapenaren iraupena (minututan)" # Settings dialog msgid "Show breaks in random order" -msgstr "Erakutsi atsedenaldiak ausazko ordenean" +msgstr "Erakutsi etenaldiak ausazko ordenan" # Settings dialog msgid "Strict break (No way to skip breaks)" -msgstr "Atsedenaldi zorrotza (saltatzeko modurik ez)" +msgstr "Etenaldi zorrotza (saltatzeko modurik ez)" # Settings dialog msgid "Allow postponing breaks" -msgstr "Baimendu atsedenaldiak atzeratzea" +msgstr "Baimendu etenaldiak atzeratzea" # Settings dialog msgid "Persist the internal state" @@ -164,7 +164,9 @@ msgstr "RPC zerbitzaririk gabe, komandu-lineako komanduek ez dute funtzionatuko" # Settings dialog msgid "Long break interval must be a multiple of short break interval" -msgstr "Atsedenaldik luzeak, motzen multzoa izan behar du" +msgstr "" +"Etenaldi luzeen arteko tarteak motzen arteko tartearen multiploa izan behar " +"du" # Settings dialog msgid "Reset" @@ -172,7 +174,7 @@ msgstr "Berrezarri" # Settings dialog msgid "Are you sure you want to reset all settings to default?" -msgstr "Ziur ezarpen guztiak lehenetsitakoetara berrezarri nahi dituzula?" +msgstr "Ziur ezarpen guztiak lehenetsietara berrezarri nahi dituzula?" # Settings dialog msgid "Options" @@ -180,11 +182,11 @@ msgstr "Aukerak" # Settings dialog msgid "Short Breaks" -msgstr "Atsedenaldi motzak" +msgstr "Etenaldi motzak" # Settings dialog msgid "Long Breaks" -msgstr "Atsedenaldi luzeak" +msgstr "Etenaldi luzeak" # Settings dialog msgid "Delete" @@ -192,7 +194,7 @@ msgstr "Ezabatu" # Settings dialog msgid "Are you sure you want to delete this break?" -msgstr "Ziur atsedenaldi hau ezabatu nahi duzula?" +msgstr "Ziur etenaldi hau ezabatu nahi duzula?" # Settings dialog msgid "You can't undo this action." @@ -200,11 +202,11 @@ msgstr "Ekintza hau ezin da desegin." # Settings dialog msgid "Break" -msgstr "Atsedenaldia" +msgstr "Etenaldia" # Settings dialog msgid "Breaks" -msgstr "Atsedenaldiak" +msgstr "Etenaldiak" # Settings dialog msgid "Plugins" @@ -256,7 +258,7 @@ msgstr "Denbora (minututan)" # Settings dialog msgid "Break Settings" -msgstr "Atsedenaldien ezarpenak" +msgstr "Etenaldien ezarpenak" # Settings dialog msgid "Plugin Settings" @@ -284,7 +286,7 @@ msgstr "Gehitu %(resource)s baliabidea %(config_resource)s direktorioan" # Settings dialog msgid "New Break" -msgstr "Atsedenaldi berria" +msgstr "Etenaldi berria" # Settings dialog msgid "Remove" @@ -304,15 +306,15 @@ msgstr "Abisu entzungarria" # plugin/audiblealert msgid "Play audible alert before and after breaks" -msgstr "Erreproduzitu abisu entzungarria atsedenaldien aurretik eta ondoren" +msgstr "Erreproduzitu abisu entzungarri bat etenaldien aurretik eta ondoren" # plugin/audiblealert msgid "Play audible alert before breaks" -msgstr "Erreproduzitu abisu entzungarria atsedenaldien aurretik" +msgstr "Erreproduzitu abisu entzungarria etenaldien aurretik" # plugin/audiblealert msgid "Play audible alert after breaks" -msgstr "Erreproduzitu abisu entzungarria atsedenaldien ondoren" +msgstr "Erreproduzitu abisu entzungarria etenaldien ondoren" # plugin/donotdisturb msgid "Do Not Disturb" @@ -320,11 +322,11 @@ msgstr "Ez molestatu" # plugin/donotdisturb msgid "Skip break if the active window is in fullscreen mode" -msgstr "Saltatu atsedenaldia uneko leihoa pantaila osoan badago" +msgstr "Saltatu etenaldia leiho aktiboa pantaila osoan badago" # plugin/donotdisturb msgid "Do not interrupt these windows anytime" -msgstr "Ez eten honako leihoetan edonola ere" +msgstr "Ez eten honako leihoetan inoiz ere" # plugin/donotdisturb msgid "Interrupt these windows regardless of their state" @@ -356,15 +358,15 @@ msgstr "Jakinarazpena" # plugin/notification msgid "Show a system notification before breaks" -msgstr "Erakutsi sistemako jakinarazpena atsedenaldien aurretik" +msgstr "Erakutsi sistemako jakinarazpen bat etenaldien aurretik" # plugin/notification msgid "Ready for a short break in %s seconds" -msgstr "Prestatu %s segundo barru atsedenaldi motza egiteko" +msgstr "Prestatu %s segundo barru etenaldi motza egiteko" # plugin/notification msgid "Ready for a long break in %s seconds" -msgstr "Prestatu %s segundo barru atsedenaldi luzea egiteko" +msgstr "Prestatu %s segundo barru etenaldi luzea egiteko" # plugin/screensaver msgid "Screensaver" @@ -373,7 +375,7 @@ msgstr "Pantaila babeslea" # plugin/screensaver msgid "Lock the screen after long breaks by starting screensaver" msgstr "" -"Blokeatu pantaila atsedenaldi luzeen ondoren pantaila-babeslea erakutsiz" +"Blokeatu pantaila etenaldi luzeen ondoren eta erakutsi pantaila-babeslea" # plugin/screensaver msgid "Custom screensaver command" @@ -381,7 +383,7 @@ msgstr "Pantaila-babeslearentzako komando pertsonalizatua" # plugin/screensaver msgid "Minimum seconds to skip without screensaver" -msgstr "Pantaila-babeslerik gabe saltatzeko gutxieneko segundoak" +msgstr "Pantaila-babesle erakutsi gabe saltatzeko segundoak" # plugin/screensaver msgid "Lock screen" @@ -397,17 +399,17 @@ msgstr "Pausatu Safe Eyes sistema inaktibo badago" # plugin/smartpause msgid "Minimum idle time to pause Safe Eyes (in seconds)" -msgstr "Safe Eyes pausatzeko gutxieneko denbora inaktiboa (segundotan)" +msgstr "Safe Eyes pausatzeko pasa behar den denbora inaktiboa (segundotan)" # plugin/smartpause msgid "Interpret idle time equivalent to upcoming break duration as a break" msgstr "" -"Interpretatu hurrengo atsedenaldiaren iraupenaren baliokidea den denbora " -"inaktiboa atsedenaldi gisa" +"Tratatu denbora inaktiboa etenaldi gisa, inaktibo emandako denbora datorren " +"etenaldiaren iraupen berekoa izan bada" # plugin/smartpause msgid "Postpone the next break until the system becomes idle" -msgstr "Atzeratu hurrengo atsedenaldia sistema inaktibo egon arte" +msgstr "Atzeratu hurrengo etenaldia sistema inaktibo egon arte" #: plugins/trayicon msgid "Tray Icon" @@ -419,7 +421,7 @@ msgstr "Erakutsi erretiluko ikonoa jakinarazpenen eremuan" #: plugins/trayicon msgid "Show next break time in tray icon" -msgstr "Erakutsi hurrengo atsedenaldia erretiluko ikonoan" +msgstr "Erakutsi hurrengo etenaldia erretiluko ikonoan" #: plugins/trayicon msgid "Allow disabling Safe Eyes" @@ -448,28 +450,28 @@ msgstr "Gaitu Safe Eyes" #: plugins/trayicon msgid "For %d Hour" msgid_plural "For %d Hours" -msgstr[0] "Ordu %derako" -msgstr[1] "%d ordurako" +msgstr[0] "Ordu %dez" +msgstr[1] "%d orduz" #: plugins/trayicon msgid "For %d Minute" msgid_plural "For %d Minutes" -msgstr[0] "Minutu %derako" -msgstr[1] "%d minuturako" +msgstr[0] "Minutu %dez" +msgstr[1] "%d minutuz" #: plugins/trayicon msgid "For %d Second" msgid_plural "For %d Seconds" -msgstr[0] "Segundo %derako" -msgstr[1] "%d segundorako" +msgstr[0] "Segundo %dez" +msgstr[1] "%d segundoz" #: plugins/trayicon msgid "Next break at %s" -msgstr "Hurrengo atsedenaldia: %s" +msgstr "Hurrengo etenaldia: %s" #: plugins/trayicon msgid "No Breaks Available" -msgstr "Atsedenaldirik ez erabilgarri" +msgstr "Etenaldirik ez erabilgarri" #: plugins/trayicon msgid "Settings" @@ -477,7 +479,7 @@ msgstr "Ezarpenak" #: plugins/trayicon msgid "Take a break now" -msgstr "Hartu atsedenaldia orain" +msgstr "Egin orain etenaldia" #: plugins/trayicon msgid "Until restart" @@ -485,7 +487,7 @@ msgstr "Berrabiarazi arte" #: plugins/trayicon msgid "Quit" -msgstr "Utzi" +msgstr "Irten" # plugin/mediacontrol msgid "Media Control" @@ -493,7 +495,7 @@ msgstr "Multimediaren kontrola" # plugin/mediacontrol msgid "Pause media players from the break screen" -msgstr "Pausatu multimedia erreproduzitzaileak atsedenaldiaren pantailatik" +msgstr "Pausatu multimedia etenaldiaren pantailatik" # plugin/mediacontrol msgid "Pause media" diff --git a/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po index 142e694..31dd539 100644 --- a/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po +++ b/safeeyes/config/locale/ko/LC_MESSAGES/safeeyes.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-02-24 07:50+0000\n" -"Last-Translator: Lee Yunseok \n" +"PO-Revision-Date: 2023-02-17 05:35+0000\n" +"Last-Translator: Yi Yunseok \n" "Language-Team: Korean \n" "Language: ko\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 4.5\n" +"X-Generator: Weblate 4.16-dev\n" # Short break msgid "Tightly close your eyes" @@ -346,7 +346,7 @@ msgstr "세이프 아이즈 사용에 기반한 통계 표시" # plugin/healthstats msgid "Statistics reset interval (cron expression)" -msgstr "통계 재설정 간격 (크론 표현식)" +msgstr "통계 초기화 간격 (크론 표현식)" # plugin/notification msgid "Notification" diff --git a/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po index e5c140c..17f57d1 100644 --- a/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po +++ b/safeeyes/config/locale/ru/LC_MESSAGES/safeeyes.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2022-12-21 05:47+0000\n" -"Last-Translator: Dmitriy Q \n" +"PO-Revision-Date: 2023-03-22 16:41+0000\n" +"Last-Translator: AHOHNMYC \n" "Language-Team: Russian \n" "Language: ru\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 4.15.1-dev\n" +"X-Generator: Weblate 4.16.2-dev\n" # Short break msgid "Tightly close your eyes" @@ -157,11 +157,11 @@ msgstr "Сохранять внутреннее состояние" # Settings dialog msgid "Use RPC server to receive runtime commands" -msgstr "Использовать RPC-сервер для получения запущенных команд" +msgstr "Используйте RPC сервер для получения команд во время работы приложения" # Settings dialog msgid "Without the RPC server, command-line commands may not work" -msgstr "Без RPC сервера команды из командной строки могут не работать" +msgstr "Без RPC сервера команды из командной строки могут не сработать" # Settings dialog msgid "Long break interval must be a multiple of short break interval" diff --git a/safeeyes/config/locale/safeeyes.pot b/safeeyes/config/locale/safeeyes.pot index 6352149..aea416e 100644 --- a/safeeyes/config/locale/safeeyes.pot +++ b/safeeyes/config/locale/safeeyes.pot @@ -456,6 +456,18 @@ msgstr "" msgid "Take a break now" msgstr "" +#: plugins/trayicon +msgid "Any break" +msgstr "" + +#: plugins/trayicon +msgid "Short break" +msgstr "" + +#: plugins/trayicon +msgid "Long break" +msgstr "" + #: plugins/trayicon msgid "Until restart" msgstr "" diff --git a/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po b/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po index 03aa466..fc4d298 100644 --- a/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po +++ b/safeeyes/config/locale/sv/LC_MESSAGES/safeeyes.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2021-08-18 00:37+0000\n" +"PO-Revision-Date: 2023-02-11 11:39+0000\n" "Last-Translator: Luna Jernberg \n" "Language-Team: Swedish \n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.8-dev\n" +"X-Generator: Weblate 4.16-dev\n" # Short break msgid "Tightly close your eyes" @@ -138,7 +138,7 @@ msgstr "Uppskjutningsvaraktighet (i minuter)" # Settings dialog msgid "Show breaks in random order" -msgstr "" +msgstr "Visa avbrott i slumpmässig ordning" # Settings dialog msgid "Strict break (No way to skip breaks)" diff --git a/safeeyes/core.py b/safeeyes/core.py index f51a8c0..00a7f98 100644 --- a/safeeyes/core.py +++ b/safeeyes/core.py @@ -131,7 +131,7 @@ class SafeEyesCore: logging.debug("Postpone the break for %d seconds", self.postpone_duration) self.context['postponed'] = True - def take_break(self): + def take_break(self, break_type = None): """ Calling this method stops the scheduler and show the next break screen """ @@ -139,15 +139,15 @@ class SafeEyesCore: return if not self.context['state'] == State.WAITING: return - utility.start_thread(self.__take_break) + utility.start_thread(self.__take_break, break_type=break_type) - def has_breaks(self): + def has_breaks(self, break_type = None): """ - Check whether Safe Eyes has breaks or not. + Check whether Safe Eyes has breaks or not. Use the break_type to check for either short or long break. """ - return not self.break_queue.is_empty() + return not self.break_queue.is_empty(break_type) - def __take_break(self): + def __take_break(self, break_type = None): """ Show the next break screen """ @@ -167,6 +167,8 @@ class SafeEyesCore: time.sleep(1) # Wait for 1 sec to ensure the sceduler is dead self.running = True + if break_type is not None and self.break_queue.get_break().type != break_type: + self.break_queue.next(break_type) utility.execute_main_thread(self.__fire_start_break) def __scheduler_job(self): @@ -244,8 +246,9 @@ class SafeEyesCore: utility.execute_main_thread(self.__fire_start_break) def __fire_start_break(self): + break_obj = self.break_queue.get_break() # Show the break screen - if not self.on_start_break.fire(self.break_queue.get_break()): + if not self.on_start_break.fire(break_obj): # Plugins want to ignore this break self.__start_next_break() return @@ -258,7 +261,7 @@ class SafeEyesCore: # Wait in user thread utility.start_thread(self.__postpone_break) else: - self.start_break.fire(self.break_queue.get_break()) + self.start_break.fire(break_obj) utility.start_thread(self.__start_break) def __start_break(self): diff --git a/safeeyes/model.py b/safeeyes/model.py index cbd5590..63c88e8 100644 --- a/safeeyes/model.py +++ b/safeeyes/model.py @@ -84,7 +84,6 @@ class BreakQueue: self.__current_break = None self.__current_long = 0 self.__current_short = 0 - self.__shorts_taken = 0 self.__short_break_time = config.get('short_break_interval') self.__long_break_time = config.get('long_break_interval') self.__is_random_order = config.get('random_order') @@ -113,19 +112,39 @@ class BreakQueue: while brk != current_break and brk.name != last_break: brk = self.next() - def get_break(self): + def get_break(self, break_type = None): if self.__current_break is None: self.__current_break = self.next() - return self.__current_break + + if break_type is None or self.__current_break.type == break_type: + return self.__current_break + + if break_type == BreakType.LONG_BREAK: + return self.__long_queue[self.__current_long] + + return self.__short_queue[self.__current_short] def is_long_break(self): return self.__current_break is not None and self.__current_break.type == BreakType.LONG_BREAK - def next(self): + def next(self, break_type = None): break_obj = None shorts = self.__short_queue longs = self.__long_queue + # Reset break that has just ended + if self.is_long_break(): + self.__current_break.time = self.__long_break_time + if self.__current_long == 0 and self.__is_random_order: + # Shuffle queue + self.__build_longs() + elif self.__current_break: + # Reduce the break time from the next long break (default) + if longs: + longs[self.__current_long].time -= shorts[self.__current_short].time + if self.__current_short == 0 and self.__is_random_order: + self.__build_shorts() + if self.is_empty(): return None @@ -133,27 +152,11 @@ class BreakQueue: break_obj = self.__next_long() elif longs is None: break_obj = self.__next_short() - elif longs[self.__current_long].time <= shorts[self.__current_short].time: + elif break_type == BreakType.LONG_BREAK or longs[self.__current_long].time <= shorts[self.__current_short].time: break_obj = self.__next_long() else: break_obj = self.__next_short() - # Shorts and longs exist -> set cycle on every long - if break_obj.type == BreakType.LONG_BREAK: - self.context['new_cycle'] = True - self.__shorts_taken = 0 - # Only shorts exist -> set cycle when enough short breaks pass - elif self.__shorts_taken == self.__cycle_len: - self.context['new_cycle'] = True - self.__shorts_taken = 0 - else: - self.context['new_cycle'] = False - - if self.__current_break is not None: - # Reset the time of long breaks - if self.__current_break.type == BreakType.LONG_BREAK: - self.__current_break.time = self.__long_break_time - self.__current_break = break_obj self.context['session']['break'] = self.__current_break.name @@ -162,30 +165,30 @@ class BreakQueue: def reset(self): for break_object in self.__short_queue: break_object.time = self.__short_break_time - + for break_object in self.__long_queue: break_object.time = self.__long_break_time - def is_empty(self): - return self.__short_queue is None and self.__long_queue is None + def is_empty(self, break_type = None): + """ + Check if the given break type is empty or not. If the break_type is None, check for both short and long breaks. + """ + if break_type == BreakType.SHORT_BREAK: + return self.__short_queue is None + elif break_type == BreakType.LONG_BREAK: + return self.__long_queue is None + else: + return self.__short_queue is None and self.__long_queue is None def __next_short(self): longs = self.__long_queue shorts = self.__short_queue break_obj = shorts[self.__current_short] self.context['break_type'] = 'short' - # Reduce the break time from the next long break (default) - if longs: - longs[self.__current_long].time -= shorts[self.__current_short].time # Update the index to next self.__current_short = (self.__current_short + 1) % len(shorts) - # Shuffle queue - if self.__current_short == 0 and self.__is_random_order: - self.__build_shorts() - - self.__shorts_taken += 1 return break_obj def __next_long(self): @@ -196,10 +199,6 @@ class BreakQueue: # Update the index to next self.__current_long = (self.__current_long + 1) % len(longs) - # Shuffle queue - if self.__current_long == 0 and self.__is_random_order: - self.__build_longs() - return break_obj def __build_queue(self, break_type, break_configs, break_time, break_duration): diff --git a/safeeyes/platform/icons/hicolor/128x128/apps/safeeyes.png b/safeeyes/platform/icons/hicolor/128x128/apps/io.github.slgobinath.SafeEyes.png similarity index 100% rename from safeeyes/platform/icons/hicolor/128x128/apps/safeeyes.png rename to safeeyes/platform/icons/hicolor/128x128/apps/io.github.slgobinath.SafeEyes.png diff --git a/safeeyes/platform/icons/hicolor/16x16/apps/safeeyes.png b/safeeyes/platform/icons/hicolor/16x16/apps/io.github.slgobinath.SafeEyes.png similarity index 100% rename from safeeyes/platform/icons/hicolor/16x16/apps/safeeyes.png rename to safeeyes/platform/icons/hicolor/16x16/apps/io.github.slgobinath.SafeEyes.png diff --git a/safeeyes/platform/icons/hicolor/16x16/status/safeeyes_disabled.png b/safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-disabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/16x16/status/safeeyes_disabled.png rename to safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-disabled.png diff --git a/safeeyes/platform/icons/hicolor/16x16/status/safeeyes_enabled.png b/safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-enabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/16x16/status/safeeyes_enabled.png rename to safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-enabled.png diff --git a/safeeyes/platform/icons/hicolor/16x16/status/safeeyes_timer.png b/safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-timer.png similarity index 100% rename from safeeyes/platform/icons/hicolor/16x16/status/safeeyes_timer.png rename to safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-timer.png diff --git a/safeeyes/platform/icons/hicolor/24x24/apps/safeeyes.png b/safeeyes/platform/icons/hicolor/24x24/apps/io.github.slgobinath.SafeEyes.png similarity index 100% rename from safeeyes/platform/icons/hicolor/24x24/apps/safeeyes.png rename to safeeyes/platform/icons/hicolor/24x24/apps/io.github.slgobinath.SafeEyes.png diff --git a/safeeyes/platform/icons/hicolor/24x24/status/safeeyes_disabled.png b/safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-disabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/24x24/status/safeeyes_disabled.png rename to safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-disabled.png diff --git a/safeeyes/platform/icons/hicolor/24x24/status/safeeyes_enabled.png b/safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-enabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/24x24/status/safeeyes_enabled.png rename to safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-enabled.png diff --git a/safeeyes/platform/icons/hicolor/24x24/status/safeeyes_timer.png b/safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-timer.png similarity index 100% rename from safeeyes/platform/icons/hicolor/24x24/status/safeeyes_timer.png rename to safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-timer.png diff --git a/safeeyes/platform/icons/hicolor/32x32/apps/safeeyes.png b/safeeyes/platform/icons/hicolor/32x32/apps/io.github.slgobinath.SafeEyes.png similarity index 100% rename from safeeyes/platform/icons/hicolor/32x32/apps/safeeyes.png rename to safeeyes/platform/icons/hicolor/32x32/apps/io.github.slgobinath.SafeEyes.png diff --git a/safeeyes/platform/icons/hicolor/32x32/status/safeeyes_disabled.png b/safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-disabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/32x32/status/safeeyes_disabled.png rename to safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-disabled.png diff --git a/safeeyes/platform/icons/hicolor/32x32/status/safeeyes_enabled.png b/safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-enabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/32x32/status/safeeyes_enabled.png rename to safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-enabled.png diff --git a/safeeyes/platform/icons/hicolor/48x48/apps/safeeyes.png b/safeeyes/platform/icons/hicolor/48x48/apps/io.github.slgobinath.SafeEyes.png similarity index 100% rename from safeeyes/platform/icons/hicolor/48x48/apps/safeeyes.png rename to safeeyes/platform/icons/hicolor/48x48/apps/io.github.slgobinath.SafeEyes.png diff --git a/safeeyes/platform/icons/hicolor/48x48/status/safeeyes_disabled.png b/safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-disabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/48x48/status/safeeyes_disabled.png rename to safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-disabled.png diff --git a/safeeyes/platform/icons/hicolor/48x48/status/safeeyes_enabled.png b/safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-enabled.png similarity index 100% rename from safeeyes/platform/icons/hicolor/48x48/status/safeeyes_enabled.png rename to safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-enabled.png diff --git a/safeeyes/platform/icons/hicolor/64x64/apps/safeeyes.png b/safeeyes/platform/icons/hicolor/64x64/apps/io.github.slgobinath.SafeEyes.png similarity index 100% rename from safeeyes/platform/icons/hicolor/64x64/apps/safeeyes.png rename to safeeyes/platform/icons/hicolor/64x64/apps/io.github.slgobinath.SafeEyes.png diff --git a/safeeyes/platform/safeeyes.desktop b/safeeyes/platform/io.github.slgobinath.SafeEyes.desktop old mode 100755 new mode 100644 similarity index 97% rename from safeeyes/platform/safeeyes.desktop rename to safeeyes/platform/io.github.slgobinath.SafeEyes.desktop index 9d1ecbb..5d88bb9 --- a/safeeyes/platform/safeeyes.desktop +++ b/safeeyes/platform/io.github.slgobinath.SafeEyes.desktop @@ -25,7 +25,7 @@ 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 +Icon=io.github.slgobinath.SafeEyes Terminal=false Type=Application Categories=Utility; diff --git a/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml b/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml new file mode 100644 index 0000000..0aa25a6 --- /dev/null +++ b/safeeyes/platform/io.github.slgobinath.SafeEyes.metainfo.xml @@ -0,0 +1,55 @@ + + + io.github.slgobinath.SafeEyes + + Safe Eyes + Gobinath + A Free and Open Source tool for Linux users to reduce and prevent repetitive strain + injury (RSI). + + CC0-1.0 + GPL-3.0 + + + Utility + Accessibility + + + +

+ Protect your eyes from eye strain using this simple and beautiful, yet extensible break + reminder +

+

+ Features: +

+

+ Remind you to take breaks with exercises to reduce RSI, Disable keyboard during breaks, + Notification before and after breaks, Smart pause if system is idle, Multi-screen + support, Customizable user interface, RPC API to control externally, Command-line + arguments to control the running instance, Customizable using plug-ins +

+
+ + io.github.slgobinath.SafeEyes.desktop + + + https://slgobinath.github.io/SafeEyes/assets/screenshots/safeeyes_1.png + + + https://slgobinath.github.io/SafeEyes/assets/screenshots/safeeyes_3.png + + + https://slgobinath.github.io/SafeEyes/assets/screenshots/safeeyes_6.png + + + + https://slgobinath.github.io/SafeEyes/ + + + + + + + +
\ No newline at end of file diff --git a/safeeyes/plugin_manager.py b/safeeyes/plugin_manager.py index 4127872..6dfaa7a 100644 --- a/safeeyes/plugin_manager.py +++ b/safeeyes/plugin_manager.py @@ -84,8 +84,12 @@ class PluginManager: for plugin in config.get('plugins'): try: self.__load_plugin(plugin) - except BaseException: - logging.error('Error in loading the plugin: %s', plugin['id']) + except BaseException as e: + traceback_wanted = logging.getLogger().getEffectiveLevel() == logging.DEBUG + if traceback_wanted: + import traceback + traceback.print_exc() + logging.error('Error in loading the plugin %s: %s', plugin['id'], e) continue # Initialize the plugins for plugin in self.__plugins_on_init: diff --git a/safeeyes/plugins/healthstats/plugin.py b/safeeyes/plugins/healthstats/plugin.py index d66c9ae..041bf98 100644 --- a/safeeyes/plugins/healthstats/plugin.py +++ b/safeeyes/plugins/healthstats/plugin.py @@ -27,7 +27,6 @@ import logging context = None no_of_skipped_breaks = 0 no_of_breaks = 0 -no_of_cycles = -1 session = None safe_eyes_start_time = datetime.datetime.now() total_idle_time = 0 @@ -46,7 +45,6 @@ def init(ctx, safeeyes_config, plugin_config): global session global no_of_skipped_breaks global no_of_breaks - global no_of_cycles global statistics_reset_cron global safe_eyes_start_time global total_idle_time @@ -71,7 +69,6 @@ def init(ctx, safeeyes_config, plugin_config): if session is None: session = {'no_of_skipped_breaks': 0, 'no_of_breaks': 0, - 'no_of_cycles': -1, 'safe_eyes_start_time': safe_eyes_start_time.strftime("%Y-%m-%d %H:%M:%S"), 'total_idle_time': 0, 'last_screen_time': -1, @@ -79,7 +76,6 @@ def init(ctx, safeeyes_config, plugin_config): context['session']['plugin']['healthstats'] = session no_of_skipped_breaks = session.get('no_of_skipped_breaks', 0) no_of_breaks = session.get('no_of_breaks', 0) - no_of_cycles = session.get('no_of_cycles', -1) total_idle_time = session.get('total_idle_time', 0) last_screen_time = session.get('last_screen_time', -1) str_time = session.get('safe_eyes_start_time', None) @@ -115,12 +111,8 @@ def get_widget_title(break_obj): return "" global no_of_breaks - global no_of_cycles no_of_breaks += 1 - if context['new_cycle']: - no_of_cycles += 1 session['no_of_breaks'] = no_of_breaks - session['no_of_cycles'] = no_of_cycles session['safe_eyes_start_time'] = safe_eyes_start_time.strftime("%Y-%m-%d %H:%M:%S") session['total_idle_time'] = total_idle_time session['last_screen_time'] = last_screen_time @@ -129,7 +121,6 @@ def get_widget_title(break_obj): def _reset_stats(): global no_of_breaks - global no_of_cycles global safe_eyes_start_time global total_idle_time global no_of_skipped_breaks @@ -154,10 +145,8 @@ def _reset_stats(): last_screen_time = round((total_duration_sec - total_idle_time) / 60) total_idle_time = 0 no_of_breaks = 0 - no_of_cycles = 0 no_of_skipped_breaks = 0 session['no_of_breaks'] = 0 - session['no_of_cycles'] = 0 session['no_of_skipped_breaks'] = 0 session['safe_eyes_start_time'] = safe_eyes_start_time.strftime("%Y-%m-%d %H:%M:%S") session['total_idle_time'] = total_idle_time @@ -195,7 +184,7 @@ def get_widget_content(break_obj): elif screen_time < last_screen_time: symbol = '-' screen_time_diff = ' ( {}{:02d}:{:02d} )'.format(symbol, hrs_diff, mins_diff) - return "{}\tBREAKS: {}\tSKIPPED: {}\tCYCLES: {}\tSCREEN TIME: {}{}".format(heart, no_of_breaks, no_of_skipped_breaks, no_of_cycles, time_format, screen_time_diff) + return "{}\tBREAKS: {}\tSKIPPED: {}\tSCREEN TIME: {}{}".format(heart, no_of_breaks, no_of_skipped_breaks, time_format, screen_time_diff) def on_start(): diff --git a/safeeyes/plugins/notification/plugin.py b/safeeyes/plugins/notification/plugin.py index 8dac053..ed4a0e8 100644 --- a/safeeyes/plugins/notification/plugin.py +++ b/safeeyes/plugins/notification/plugin.py @@ -60,7 +60,7 @@ def on_pre_break(break_obj): else: message += (_('Ready for a long break in %s seconds') % warning_time) - notification = Notify.Notification.new('Safe Eyes', message, icon='safeeyes_enabled') + notification = Notify.Notification.new('Safe Eyes', message, icon='io.github.slgobinath.SafeEyes-enabled') try: notification.show() except BaseException: diff --git a/safeeyes/plugins/trayicon/plugin.py b/safeeyes/plugins/trayicon/plugin.py index 9fb3b48..061535a 100644 --- a/safeeyes/plugins/trayicon/plugin.py +++ b/safeeyes/plugins/trayicon/plugin.py @@ -17,6 +17,7 @@ # along with this program. If not, see . import datetime +from safeeyes.model import BreakType import gi gi.require_version('Gtk', '3.0') try: @@ -67,7 +68,7 @@ class TrayIcon: # Construct the tray icon self.indicator = appindicator.Indicator.new( - APPINDICATOR_ID, "safeeyes_enabled", appindicator.IndicatorCategory.APPLICATION_STATUS) + APPINDICATOR_ID, "io.github.slgobinath.SafeEyes-enabled", appindicator.IndicatorCategory.APPLICATION_STATUS) self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE) # Construct the context menu @@ -76,7 +77,7 @@ class TrayIcon: # Next break info menu item self.item_info = Gtk.ImageMenuItem() img_timer = Gtk.Image() - img_timer.set_from_icon_name("safeeyes_timer", 16) + img_timer.set_from_icon_name("io.github.slgobinath.SafeEyes-timer", 16) self.item_info.set_image(img_timer) self.item_separator = Gtk.SeparatorMenuItem() @@ -85,10 +86,8 @@ class TrayIcon: self.item_enable.connect('activate', self.on_enable_clicked) self.item_disable = Gtk.MenuItem() - self.item_disable.connect('activate', self.on_disable_clicked) - self.sub_menu_disable = Gtk.Menu() - self.sub_menu_items = [] + self.sub_menu_disable_items = [] # Read disable options and build the sub menu for disable_option in plugin_config['disable_options']: @@ -116,7 +115,7 @@ class TrayIcon: # Create submenu sub_menu_item = Gtk.MenuItem() sub_menu_item.connect('activate', self.on_disable_clicked, time_in_minutes) - self.sub_menu_items.append([sub_menu_item, label, disable_option['time']]) + self.sub_menu_disable_items.append([sub_menu_item, label, disable_option['time']]) self.sub_menu_disable.append(sub_menu_item) # Disable until restart submenu @@ -129,7 +128,19 @@ class TrayIcon: # Settings menu item self.item_manual_break = Gtk.MenuItem() - self.item_manual_break.connect('activate', self.on_manual_break_clicked) + + self.sub_menu_manual_next_break = Gtk.MenuItem() + self.sub_menu_manual_next_break.connect('activate', self.on_manual_break_clicked, None) + self.sub_menu_manual_next_short_break = Gtk.MenuItem() + self.sub_menu_manual_next_short_break.connect('activate', self.on_manual_break_clicked, BreakType.SHORT_BREAK) + self.sub_menu_manual_next_long_break = Gtk.MenuItem() + self.sub_menu_manual_next_long_break.connect('activate', self.on_manual_break_clicked, BreakType.LONG_BREAK) + + self.sub_menu_manual_break = Gtk.Menu() + self.sub_menu_manual_break.append(self.sub_menu_manual_next_break) + self.sub_menu_manual_break.append(self.sub_menu_manual_next_short_break) + self.sub_menu_manual_break.append(self.sub_menu_manual_next_long_break) + self.item_manual_break.set_submenu(self.sub_menu_manual_break) # Settings menu item self.item_settings = Gtk.MenuItem() @@ -182,7 +193,7 @@ class TrayIcon: """ Update the text of menu items based on the selected language. """ - for entry in self.sub_menu_items: + for entry in self.sub_menu_disable_items: # print(self.context['locale'].ngettext('For %d Hour', 'For %d Hours', 1) % 1) entry[0].set_label(self.context['locale'].ngettext(entry[1][0], entry[1][1], entry[2]) % entry[2]) @@ -195,24 +206,27 @@ class TrayIcon: if self.active: if self.date_time: self.__set_next_break_info() - self.indicator.set_icon("safeeyes_enabled") + self.indicator.set_icon("io.github.slgobinath.SafeEyes-enabled") else: if self.wakeup_time: self.item_info.set_label(_('Disabled until %s') % utility.format_time(self.wakeup_time)) else: self.item_info.set_label(_('Disabled until restart')) self.indicator.set_label('', '') - self.indicator.set_icon("safeeyes_disabled") + self.indicator.set_icon("io.github.slgobinath.SafeEyes-disabled") else: self.item_info.set_label(_('No Breaks Available')) self.indicator.set_label('', '') - self.indicator.set_icon("safeeyes_disabled") + self.indicator.set_icon("io.github.slgobinath.SafeEyes-disabled") self.item_info.set_sensitive(breaks_found and self.active) self.item_enable.set_sensitive(breaks_found and not self.active) self.item_disable.set_sensitive(breaks_found and self.active) self.item_manual_break.set_sensitive(breaks_found and self.active) self.item_manual_break.set_label(_('Take a break now')) + self.sub_menu_manual_next_break.set_label(_('Any break')) + self.sub_menu_manual_next_short_break.set_label(_('Short break')) + self.sub_menu_manual_next_long_break.set_label(_('Long break')) self.item_settings.set_label(_('Settings')) self.item_about.set_label(_('About')) self.item_quit.set_label(_('Quit')) @@ -282,7 +296,11 @@ class TrayIcon: """ Trigger a break manually. """ - self.take_break() + if len(args) > 1: + break_type = args[1] + self.take_break(break_type) + else: + self.take_break() def on_enable_clicked(self, *args): """ @@ -342,7 +360,7 @@ class TrayIcon: if self.active: logging.info('Disable Safe Eyes') self.active = False - self.indicator.set_icon("safeeyes_disabled") + self.indicator.set_icon("io.github.slgobinath.SafeEyes-disabled") self.item_info.set_label(_('Disabled until restart')) self.indicator.set_label('', '') self.item_info.set_sensitive(False) @@ -357,7 +375,7 @@ class TrayIcon: if not self.active: logging.info('Enable Safe Eyes') self.active = True - self.indicator.set_icon("safeeyes_enabled") + self.indicator.set_icon("io.github.slgobinath.SafeEyes-enabled") self.item_info.set_sensitive(True) self.item_enable.set_sensitive(False) self.item_disable.set_sensitive(True) @@ -378,9 +396,9 @@ class TrayIcon: def start_animation(self): if not self.active or not self.animate: return - utility.execute_main_thread(lambda: self.indicator.set_icon("safeeyes_disabled")) + utility.execute_main_thread(lambda: self.indicator.set_icon("io.github.slgobinath.SafeEyes-disabled")) time.sleep(0.5) - utility.execute_main_thread(lambda: self.indicator.set_icon("safeeyes_enabled")) + utility.execute_main_thread(lambda: self.indicator.set_icon("io.github.slgobinath.SafeEyes-enabled")) if self.animate and self.active: time.sleep(0.5) if self.animate and self.active: @@ -389,9 +407,9 @@ class TrayIcon: def stop_animation(self): self.animate = False if self.active: - utility.execute_main_thread(lambda: self.indicator.set_icon("safeeyes_enabled")) + utility.execute_main_thread(lambda: self.indicator.set_icon("io.github.slgobinath.SafeEyes-enabled")) else: - utility.execute_main_thread(lambda: self.indicator.set_icon("safeeyes_disabled")) + utility.execute_main_thread(lambda: self.indicator.set_icon("io.github.slgobinath.SafeEyes-disabled")) def init(ctx, safeeyes_cfg, plugin_config): """ diff --git a/safeeyes/safeeyes.py b/safeeyes/safeeyes.py index 9ce47eb..7b88553 100644 --- a/safeeyes/safeeyes.py +++ b/safeeyes/safeeyes.py @@ -40,7 +40,7 @@ from safeeyes.ui.settings_dialog import SettingsDialog gi.require_version('Gtk', '3.0') from gi.repository import Gtk -SAFE_EYES_VERSION = "2.1.5" +SAFE_EYES_VERSION = "2.1.6" class SafeEyes: @@ -93,8 +93,7 @@ class SafeEyes: self.safe_eyes_core.on_stop_break += self.stop_break self.safe_eyes_core.on_update_next_break += self.update_next_break self.safe_eyes_core.initialize(self.config) - self.context['api']['take_break'] = lambda: utility.execute_main_thread( - self.safe_eyes_core.take_break) + self.context['api']['take_break'] = self.take_break self.context['api']['has_breaks'] = self.safe_eyes_core.has_breaks self.context['api']['postpone'] = self.safe_eyes_core.postpone self.plugins_manager.init(self.context, self.config) @@ -295,11 +294,11 @@ class SafeEyes: self.plugins_manager.stop_break() return True - def take_break(self): + def take_break(self, break_type = None): """ Take a break now. """ - self.safe_eyes_core.take_break() + utility.execute_main_thread(self.safe_eyes_core.take_break, break_type) def status(self): """ diff --git a/safeeyes/utility.py b/safeeyes/utility.py index bf2dede..76803e5 100644 --- a/safeeyes/utility.py +++ b/safeeyes/utility.py @@ -51,10 +51,11 @@ BIN_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) HOME_DIRECTORY = os.environ.get('HOME') or os.path.expanduser('~') CONFIG_DIRECTORY = os.path.join(os.environ.get( 'XDG_CONFIG_HOME') or os.path.join(HOME_DIRECTORY, '.config'), 'safeeyes') +STYLE_SHEET_DIRECTORY = os.path.join(CONFIG_DIRECTORY, 'style') CONFIG_FILE_PATH = os.path.join(CONFIG_DIRECTORY, 'safeeyes.json') CONFIG_RESOURCE = os.path.join(CONFIG_DIRECTORY, 'resource') SESSION_FILE_PATH = os.path.join(CONFIG_DIRECTORY, 'session.json') -STYLE_SHEET_PATH = os.path.join(CONFIG_DIRECTORY, 'style/safeeyes_style.css') +STYLE_SHEET_PATH = os.path.join(STYLE_SHEET_DIRECTORY, '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") @@ -62,7 +63,7 @@ LOG_FILE_PATH = os.path.join(HOME_DIRECTORY, 'safeeyes.log') SYSTEM_PLUGINS_DIR = os.path.join(BIN_DIRECTORY, 'plugins') USER_PLUGINS_DIR = os.path.join(CONFIG_DIRECTORY, 'plugins') LOCALE_PATH = os.path.join(BIN_DIRECTORY, 'config/locale') -SYSTEM_DESKTOP_FILE = os.path.join(BIN_DIRECTORY, "platform/safeeyes.desktop") +SYSTEM_DESKTOP_FILE = os.path.join(BIN_DIRECTORY, "platform/io.github.slgobinath.SafeEyes.desktop") SYSTEM_ICONS = os.path.join(BIN_DIRECTORY, "platform/icons") DESKTOP_ENVIRONMENT = None IS_WAYLAND = False @@ -371,17 +372,15 @@ def merge_configs(new_config, old_config): def initialize_safeeyes(): """ - Create the config file and style sheet in ~/.config/safeeyes directory. + Create the config file and style sheet in XDG_CONFIG_HOME(or ~/.config)/safeeyes directory. """ - logging.info('Copy the config files to ~/.config/safeeyes') - - style_dir_path = os.path.join(HOME_DIRECTORY, '.config/safeeyes/style') + logging.info('Copy the config files to XDG_CONFIG_HOME(or ~/.config)/safeeyes') # Remove the ~/.config/safeeyes/safeeyes.json file delete(CONFIG_FILE_PATH) - # Create the ~/.config/safeeyes/style directory - mkdir(style_dir_path) + # Create the XDG_CONFIG_HOME(or ~/.config)/safeeyes/style directory + mkdir(STYLE_SHEET_DIRECTORY) # Copy the safeeyes.json shutil.copy2(SYSTEM_CONFIG_FILE_PATH, CONFIG_FILE_PATH) @@ -400,7 +399,7 @@ def create_startup_entry(): Create start up entry. """ startup_dir_path = os.path.join(HOME_DIRECTORY, '.config/autostart') - startup_entry = os.path.join(startup_dir_path, 'safeeyes.desktop') + startup_entry = os.path.join(startup_dir_path, 'io.github.slgobinath.SafeEyes.desktop') # Create the folder if not exist mkdir(startup_dir_path) @@ -423,13 +422,13 @@ def initialize_platform(): applications_dir_path = os.path.join(HOME_DIRECTORY, '.local/share/applications') icons_dir_path = os.path.join(HOME_DIRECTORY, '.local/share/icons') - desktop_entry = os.path.join(applications_dir_path, 'safeeyes.desktop') + desktop_entry = os.path.join(applications_dir_path, 'io.github.slgobinath.SafeEyes.desktop') # Create the folder if not exist mkdir(icons_dir_path) # Create a desktop entry - if not os.path.exists(os.path.join(sys.prefix, "share/applications/safeeyes.desktop")): + if not os.path.exists(os.path.join(sys.prefix, "share/applications/io.github.slgobinath.SafeEyes.desktop")): # Create the folder if not exist mkdir(applications_dir_path) @@ -666,7 +665,7 @@ 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.getargspec(getattr(module, method_name)).args) == no_of_args: + if len(inspect.getfullargspec(getattr(module, method_name)).args) == no_of_args: return True return False diff --git a/setup.py b/setup.py index d04e820..c7bc490 100644 --- a/setup.py +++ b/setup.py @@ -41,17 +41,17 @@ def __data_files(): Collect the data files. """ root_dir = sys.prefix - return [(os.path.join(root_dir, "share/applications"), ["safeeyes/platform/safeeyes.desktop"]), - (os.path.join(root_dir, "share/icons/hicolor/24x24/status"), ["safeeyes/platform/icons/hicolor/24x24/status/safeeyes_disabled.png", "safeeyes/platform/icons/hicolor/24x24/status/safeeyes_enabled.png", "safeeyes/platform/icons/hicolor/24x24/status/safeeyes_timer.png"]), - (os.path.join(root_dir, "share/icons/hicolor/24x24/apps"), ["safeeyes/platform/icons/hicolor/24x24/apps/safeeyes.png"]), - (os.path.join(root_dir, "share/icons/hicolor/16x16/status"), ["safeeyes/platform/icons/hicolor/16x16/status/safeeyes_disabled.png", "safeeyes/platform/icons/hicolor/16x16/status/safeeyes_enabled.png", "safeeyes/platform/icons/hicolor/16x16/status/safeeyes_timer.png"]), - (os.path.join(root_dir, "share/icons/hicolor/16x16/apps"), ["safeeyes/platform/icons/hicolor/16x16/apps/safeeyes.png"]), - (os.path.join(root_dir, "share/icons/hicolor/32x32/status"), ["safeeyes/platform/icons/hicolor/32x32/status/safeeyes_disabled.png", "safeeyes/platform/icons/hicolor/32x32/status/safeeyes_enabled.png"]), - (os.path.join(root_dir, "share/icons/hicolor/32x32/apps"), ["safeeyes/platform/icons/hicolor/32x32/apps/safeeyes.png"]), - (os.path.join(root_dir, "share/icons/hicolor/64x64/apps"), ["safeeyes/platform/icons/hicolor/64x64/apps/safeeyes.png"]), - (os.path.join(root_dir, "share/icons/hicolor/128x128/apps"), ["safeeyes/platform/icons/hicolor/128x128/apps/safeeyes.png"]), - (os.path.join(root_dir, "share/icons/hicolor/48x48/status"), ["safeeyes/platform/icons/hicolor/48x48/status/safeeyes_disabled.png", "safeeyes/platform/icons/hicolor/48x48/status/safeeyes_enabled.png"]), - (os.path.join(root_dir, "share/icons/hicolor/48x48/apps"), ["safeeyes/platform/icons/hicolor/48x48/apps/safeeyes.png"]),] + return [(os.path.join(root_dir, "share/applications"), ["safeeyes/platform/io.github.slgobinath.SafeEyes.desktop"]), + (os.path.join(root_dir, "share/icons/hicolor/24x24/status"), ["safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-disabled.png", "safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-enabled.png", "safeeyes/platform/icons/hicolor/24x24/status/io.github.slgobinath.SafeEyes-timer.png"]), + (os.path.join(root_dir, "share/icons/hicolor/24x24/apps"), ["safeeyes/platform/icons/hicolor/24x24/apps/io.github.slgobinath.SafeEyes.png"]), + (os.path.join(root_dir, "share/icons/hicolor/16x16/status"), ["safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-disabled.png", "safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-enabled.png", "safeeyes/platform/icons/hicolor/16x16/status/io.github.slgobinath.SafeEyes-timer.png"]), + (os.path.join(root_dir, "share/icons/hicolor/16x16/apps"), ["safeeyes/platform/icons/hicolor/16x16/apps/io.github.slgobinath.SafeEyes.png"]), + (os.path.join(root_dir, "share/icons/hicolor/32x32/status"), ["safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-disabled.png", "safeeyes/platform/icons/hicolor/32x32/status/io.github.slgobinath.SafeEyes-enabled.png"]), + (os.path.join(root_dir, "share/icons/hicolor/32x32/apps"), ["safeeyes/platform/icons/hicolor/32x32/apps/io.github.slgobinath.SafeEyes.png"]), + (os.path.join(root_dir, "share/icons/hicolor/64x64/apps"), ["safeeyes/platform/icons/hicolor/64x64/apps/io.github.slgobinath.SafeEyes.png"]), + (os.path.join(root_dir, "share/icons/hicolor/128x128/apps"), ["safeeyes/platform/icons/hicolor/128x128/apps/io.github.slgobinath.SafeEyes.png"]), + (os.path.join(root_dir, "share/icons/hicolor/48x48/status"), ["safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-disabled.png", "safeeyes/platform/icons/hicolor/48x48/status/io.github.slgobinath.SafeEyes-enabled.png"]), + (os.path.join(root_dir, "share/icons/hicolor/48x48/apps"), ["safeeyes/platform/icons/hicolor/48x48/apps/io.github.slgobinath.SafeEyes.png"]),] def __package_files(directory): @@ -78,14 +78,14 @@ def __package_data(): setuptools.setup( name="safeeyes", - version="2.1.5", + version="2.1.6", description="Protect your eyes from eye strain using this continuous breaks reminder.", long_description=long_description, long_description_content_type="text/markdown", author="Gobinath Loganathan", author_email="slgobinath@gmail.com", url="https://github.com/slgobinath/SafeEyes", - download_url="https://github.com/slgobinath/SafeEyes/archive/v2.1.5.tar.gz", + download_url="https://github.com/slgobinath/SafeEyes/archive/v2.1.6.tar.gz", packages=setuptools.find_packages(), package_data={'safeeyes': __package_data()}, data_files=__data_files(),