Compare commits

...

100 Commits

Author SHA1 Message Date
aerowolf 00c33908a3
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/zh_Hans/
2024-02-21 11:01:57 +01:00
Сергій 766e9a9795
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/uk/
2024-02-15 14:01:56 +01:00
Salif Mehmed 4f7cbc4d93
Translated using Weblate (Bulgarian)
Currently translated at 37.0% (43 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/bg/
2024-02-07 06:56:10 +01:00
Hosted Weblate c8f815345d
Merge branch 'origin/master' into Weblate. 2024-01-30 15:01:51 +01:00
麋悟BigELK176 a59f3770dc
Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/zh_Hant/
2024-01-30 15:01:49 +01:00
AdamPS 3e89aa4fcf Improvements to "interpret idle as break" #551 (correction) 2023-12-20 20:08:11 +00:00
AdamPS 903d407faf Improvements to "interpret idle as break" #551 2023-11-30 18:04:44 +00:00
Alyssa Rosenzweig 777d48603d
Fix with python3.12 (#544)
imp is deprecated in 3.4 and removed in 3.12. this caused safe eyes to
break on upgrading to fedora 39

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
2023-11-30 18:01:58 +00:00
AdamPS cbfc0cc133 Local function names should match #550 2023-11-30 14:57:37 +00:00
AdamPS edb5b70b53 Improvements to health statistics #549 2023-11-29 14:00:29 +00:00
AdamPS dd190d0543 Update comment with list of methods 2023-11-29 14:00:29 +00:00
AdamPS 9d30def057 Display next long break #374 2023-11-29 14:00:29 +00:00
Almaz Mannanov 0cce71070b
Translated using Weblate (Russian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ru/
2023-11-26 00:02:15 +00:00
Hosted Weblate e8bf389da8
Merge branch 'origin/master' into Weblate. 2023-10-31 16:04:52 +00:00
Eryk Michalak e8a254d74e
Translated using Weblate (Polish)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/pl/
2023-10-31 16:04:50 +00:00
Kryštof Jelínek c37e9db6db
Translated using Weblate (Czech)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/cs/
2023-10-31 16:04:49 +00:00
akhil_s 776a8b81de Fix 'initialize_logging' function spelling 2023-10-16 10:17:56 -04:00
Hosted Weblate c4675b743d
Merge branch 'origin/master' into Weblate. 2023-10-13 04:15:40 +00:00
Novak Urosevic a33f317241
Translated using Weblate (Serbian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/sr/
2023-10-13 06:15:38 +02:00
Ilario Gelmetti 5a993a4d60
Fix broken startup symlinks (#531)
* utility: create_startup_entry check link health

* model: init always run create_startup_entry

* utility: initialize_safeeyes don't call create_startup_entry

* utility: add force option to create_startup_entry

* model: do not create autostart, only repair broken

* utility: fix comment
2023-08-18 11:15:30 -04:00
Milan Šalka 068771d5fd
Translated using Weblate (Slovak)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/sk/
2023-08-10 21:53:26 +02:00
Hosted Weblate 20db0432b9
Merge branch 'origin/master' into Weblate. 2023-08-05 20:48:06 +02:00
Salif Mehmed b04d49ed34
Translated using Weblate (Bulgarian)
Currently translated at 7.7% (9 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/bg/
2023-08-05 20:48:05 +02:00
Sebastian Pipping dc0a470c34
Make GitHub Actions check translation files (#534)
* validate_po.py: Fix typo "varialbes"

* validate_po.py: Exit with code 1 on error

* validate_po.py: Process locales in alphabetical order

* validate_po.py: Report on progress

* Make GitHub Actions check translation files
2023-08-03 11:16:06 -04:00
Hosted Weblate e6112a87a9
Merge branch 'origin/master' into Weblate. 2023-07-08 20:48:00 +02:00
Dmitriy Q b838f3c5fe
Translated using Weblate (Russian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ru/
2023-07-08 20:47:58 +02:00
Gobinath ae88ad3386
Merge pull request #529 from slgobinath/master
Release 2.1.6
2023-07-04 20:10:57 -04:00
Gobinath Loganathan bd18d33c90 Prepare v2.1.6 2023-07-04 20:09:53 -04:00
Hosted Weblate 1a9ebfb2db
Merge branch 'origin/master' into Weblate. 2023-07-04 22:53:46 +02:00
Sebastian Pipping f26bcc5af2
Translated using Weblate (German)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/de/
2023-07-04 22:53:44 +02:00
Onur Alp Akin 684d16265a
Reverse-DNS scheme for icons & Broken initialize logic fix & Add appstream (#519)
* Add appstream

* rename platform files reverse-dns format

* rename debian install file reverse-dns format

* rename usages reverse-dns format

* Respect XDG_CONFIG while initializing safeeyes

Instead of using custom variable to define target; Continue respecting XDG specs
https://github.com/slgobinath/SafeEyes/issues/432#issuecomment-883829334

* move appstream under platform

* add flathub badge

* update flathub badge & flatpak installation
2023-05-10 05:45:38 -04:00
Sebastian Pipping 45a633d31f
Display a traceback of plugin loading errors when --debug is given (#506) 2023-04-17 20:06:26 -04:00
Sebastian Pipping 06d8f491c4
Fix support for Python 3.11 (fixes #491) (#505)
Co-authored-by: tibequadorian <tibequadorian@posteo.de>
2023-04-17 20:06:11 -04:00
Ilario Gelmetti 682a027d04
Remove executable permission from safeeyes.desktop (#512) 2023-04-17 20:02:26 -04:00
AHOHNMYC cae19b0f28
Translated using Weblate (Russian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ru/
2023-03-22 17:41:13 +01:00
Yi Yunseok 0874be58c2
Translated using Weblate (Korean)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ko/
2023-02-17 06:35:26 +01:00
Luna Jernberg d1a9f7d0b5
Translated using Weblate (Swedish)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/sv/
2023-02-11 12:39:43 +01:00
Hosted Weblate 339ed40f4a
Merge branch 'origin/master' into Weblate. 2023-02-03 07:02:34 +01:00
Yi Yunseok 7bde5d0368
Translated using Weblate (Korean)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ko/
2023-02-03 07:02:32 +01:00
AdamPS 201e6d2982
Fix incorrectly skipped long breaks #443 (#444)
* Improve error message to include information from the exception

* #347 Take short or long breaks from tray

Correction: get_break() should not alter the break queue.

* Fix incorrectly skipped long breaks
2023-01-24 17:22:51 +00:00
AdamPS 9a76aa4211 #347 Take short or long breaks from tray
Correction: get_break() should not alter the break queue.
2023-01-24 16:49:30 +00:00
AdamPS 788e2b43af Improve error message to include information from the exception 2023-01-23 15:51:52 +00:00
AdamPS d20894a7c4
Merge pull request #504 from slgobinath/feature-long-break-friendly-tray-icon
#347 Take short or long breaks from tray
2023-01-23 15:46:53 +00:00
Gobinath 9e64e65fce Add sub-menu to take any, short or long breaks 2023-01-23 15:28:57 +00:00
Hosted Weblate b90349ab10
Merge branch 'origin/master' into Weblate. 2023-01-07 12:49:30 +01:00
Porrumentzio a158587311
Translated using Weblate (Basque)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/eu/
2023-01-07 12:49:28 +01:00
Gobinath Loganathan 4799518354 Install wheel in dependencies 2023-01-05 19:18:51 -05:00
Gobinath e495bf5652
Merge pull request #501 from slgobinath/master
Release 2.1.5
2023-01-05 19:15:48 -05:00
Gobinath Loganathan e79444c699 Fix GH secret 2023-01-05 19:15:26 -05:00
Gobinath Loganathan 95da9334e0 Update GH workflow to synchronize after release 2023-01-05 19:13:58 -05:00
Gobinath Loganathan 375bd9d737 Bump the version to 2.1.5 2023-01-05 19:11:06 -05:00
Gobinath Loganathan d6a3596faa Add CICD to automatic release 2023-01-05 19:08:29 -05:00
meztihn bcecc016dd DND: Fix window class matching for names with spaces 2023-01-05 19:02:54 -05:00
Dmitriy Q 32cfc401f3
Translated using Weblate (Russian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ru/
2022-12-21 06:47:11 +01:00
Hosted Weblate 9123562d5e
Merge branch 'origin/master' into Weblate. 2022-11-27 00:54:41 +01:00
Minh P 06d4aa5afe
Translated using Weblate (Vietnamese)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/vi/
2022-11-27 00:54:37 +01:00
Gobinath Loganathan 5e844553dd Change release target to Ubuntu lunar 2022-11-20 18:54:43 -05:00
Gobinath Loganathan b89fd61cdf Fix deb build 2022-11-20 17:53:33 -05:00
Gobinath Loganathan 7f17dabbfe Bump version to 2.1.4 2022-11-20 17:22:47 -05:00
Anjan Momi 44e4a0a6ac
README: add alpine package (#486) 2022-10-13 11:56:00 -04:00
Anjan Momi d3594bdb8f
Do not fail if gettext.bindtextdomain not working (#485) 2022-10-13 11:53:26 -04:00
Anjan Momi dd16395471
Check if using wayland via WAYLAND_DISPLAY env variable (#484)
My distro does not install loginctl. I have implemented another easy
condition for wayland.

https://stackoverflow.com/questions/45536141/how-i-can-find-out-if-a-linux-system-uses-wayland-or-x11/45537237#45537237
2022-10-13 11:52:47 -04:00
Gontzal Manuel Pujana Onaindia 29a1e15192
Translated using Weblate (Basque)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/eu/
2022-09-29 00:17:19 +02:00
Dmitriy Q 6ac60ec17c
Translated using Weblate (Russian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ru/
2022-09-08 06:17:43 +02:00
calbasi 2f83647d74
Translated using Weblate (Catalan)
Currently translated at 60.3% (70 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ca/
2022-08-08 23:25:26 +02:00
Danial Behzadi 71df387773
Translated using Weblate (Persian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/fa/
2022-07-07 12:18:56 +02:00
AHOHNMYC 6d66941058
Translated using Weblate (Russian)
Currently translated at 99.1% (115 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ru/
2022-06-01 14:19:39 +02:00
Mohamed Omran 01f247328e
Translated using Weblate (Arabic)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ar/
2022-05-24 19:15:11 +02:00
Mohamed Omran c04a2d2009
Translated using Weblate (Arabic)
Currently translated at 83.6% (97 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ar/
2022-05-23 18:19:42 +02:00
Hosted Weblate 43ed01d3e4
Merge branch 'origin/master' into Weblate. 2022-04-17 18:06:45 +02:00
menom cdcf5d7918
Translated using Weblate (Slovak)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/sk/
2022-04-17 18:06:44 +02:00
Karl-Philipp Richter 292ad62729
Use HTTPS where users potentially open the URL in a browser (#475) 2022-04-01 09:23:36 -04:00
Pavel Borecki ed69ddde36
Translated using Weblate (Czech)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/cs/
2022-03-06 21:59:25 +01:00
Danial Behzadi 4b318e4895
Translated using Weblate (Persian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/fa/
2022-01-21 09:56:33 +01:00
albanobattistella 8483a3db87
Translated using Weblate (Italian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/it/
2022-01-16 13:55:20 +01:00
AO Localisation Lab 08dc41f352
Translated using Weblate (French)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/fr/
2022-01-11 16:55:08 +01:00
albanobattistella 7ef644e6a2
Translated using Weblate (Italian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/it/
2022-01-02 17:53:28 +01:00
Hosted Weblate 5489d952cf
Merge branch 'origin/master' into Weblate. 2021-11-26 02:51:35 +01:00
Gralias 846022b8e2
Translated using Weblate (Vietnamese)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/vi/
2021-11-26 02:51:33 +01:00
Ankit Raj Pandey ed60dd1970
Directly track running swayidle process (#470)
We actually don't need to use a separate variable to track the status of
the spawned swayidle process, since we can poll the status directly from
the process object. This increases robustness against e.g. a killed
swayidle process, which would cause safeeyes to be permanently disabled
until a restart.
2021-11-16 08:52:12 -05:00
Itrych 2e7df5c880
Translated using Weblate (Russian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/ru/
2021-11-03 15:15:27 +01:00
Hosted Weblate b673752f8b
Merge branch 'origin/master' into Weblate. 2021-10-10 07:05:36 +02:00
Frank.wu b70241ddda
Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/zh_Hans/
2021-10-10 07:05:35 +02:00
Ankit Raj Pandey ad041c7855
Add smartpause support for swaywm (#464)
If the current desktop environment is sway, the smartpause plugin will
spawn a swayidle process that outputs the current time on idle and
resume. Using that info, we can determine:

1. Whether the system is currently idle (idle timestamp > active timestamp)
2. How many seconds the system has been idle (current timestamp - idle timestamp)

Since swayidle uses the KDE idle protocol, it might be possible to
extend this to Wayland KDE as well.
2021-09-29 07:53:08 -04:00
mullerdavid c784000e69
Fix broken tray icon on Debian 11 (#461)
* Tryicon plugin Ayatana library fallback

* Updating debian dependencies

* Updated readme, adding Ayataha Appindicator
2021-09-21 08:20:23 -04:00
Federico Ceratto 8f4b9f2b10
Simplify Debian installation instructions (#460) 2021-09-04 15:37:38 -04:00
Luna Jernberg a257c0993d
Translated using Weblate (Swedish)
Currently translated at 99.1% (115 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/sv/
2021-08-18 02:37:20 +02:00
Tymofii Lytvynenko c61da87600
Translated using Weblate (Ukrainian)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/uk/
2021-08-18 02:37:19 +02:00
Tymofii Lytvynenko 583471c9a0
Translated using Weblate (Ukrainian)
Currently translated at 97.4% (113 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/uk/
2021-08-16 00:33:21 +02:00
Yogesh 541f39fdc0
Translated using Weblate (Kannada)
Currently translated at 16.3% (19 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/kn/
2021-07-30 19:35:18 +02:00
Allan Nordhøy 858e8288df
Translated using Weblate (Norwegian Bokmål)
Currently translated at 96.5% (112 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/nb_NO/
2021-07-30 19:35:18 +02:00
Hosted Weblate cbc29334ac
Merge branch 'origin/master' into Weblate. 2021-07-04 09:32:42 +02:00
J. Lavoie 330e343a04
Translated using Weblate (English (United States))
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/en_US/
2021-07-04 09:32:41 +02:00
Gobinath 4638e075ca
Create FUNDING.yml 2021-05-28 08:07:59 -04:00
Gobinath 5c0c92a8f3 Update issue templates 2021-05-26 17:18:27 -04:00
Yaron Shahrabani f26fb07ffc
Translated using Weblate (Hebrew)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/he/
2021-05-23 11:32:10 +02:00
Hosted Weblate 54eab4eba0
Merge branch 'origin/master' into Weblate. 2021-05-21 17:32:51 +02:00
Jorge Maldonado Ventura e65426ece4
Translated using Weblate (Esperanto)
Currently translated at 100.0% (116 of 116 strings)

Translation: Safe Eyes/Translations
Translate-URL: https://hosted.weblate.org/projects/safe-eyes/translations/eo/
2021-05-21 17:32:49 +02:00
Porrumentzio 90458a8ce4
Add parameters on Basque translation (#447)
fixes #441
2021-05-17 07:22:32 -04:00
Gobinath b72ccaa2ea Add a script to validate po files before release 2021-05-10 07:26:30 -04:00
75 changed files with 1428 additions and 992 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: slgobinath
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: 'https://www.paypal.com/paypalme/slgobinath'

32
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,32 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Desktop (please complete the following information):**
- OS: [e.g. Ubuntu 20.04, Manjaro]
- Desktop Env [e.g. Gnome, KDE]
- Version [e.g. 2.0.3]
**Debug Log**
Run the Safe Eyes using `safeeyes --debug` command attach the ~/safeeyes.log` file.
**Screenshots**
If applicable, add screenshots to help explain your problem.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -0,0 +1,20 @@
---
name: Plugin request
about: Suggest an idea for a plugin
title: ''
labels: plugin
assignees: ''
---
**Is your plugin request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the plugin you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

68
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,68 @@
name: Release
on:
push:
branches: [ release ]
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
token: ${{ secrets.GH_API_SECRET }}
- name: Set up Python 3.10
uses: actions/setup-python@v3
with:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
pip install wheel
- name: Get Current Version
run: |
project_version=$(python3 setup.py --version)
echo "project_version=$project_version" >> $GITHUB_OUTPUT
id: get_current_version
- name: Create Tag
uses: mathieudutour/github-tag-action@v6.1
with:
custom_tag: "v${{steps.get_current_version.outputs.project_version}}"
github_token: ${{ secrets.GH_API_SECRET }}
- name: Build Changelog
id: build_changelog
uses: mikepenz/release-changelog-builder-action@v3.4.0
env:
GITHUB_TOKEN: ${{ secrets.GH_API_SECRET }}
- name: Create Release
uses: softprops/action-gh-release@v1
with:
tag_name: 'v${{steps.get_current_version.outputs.project_version}}'
body: ${{steps.build_changelog.outputs.changelog}}
token: ${{ secrets.GH_API_SECRET }}
- name: Build Python Package
run: rm -Rf build *.egg-info/ && python3 setup.py sdist bdist_wheel
- name: Publish to PyPi
uses: pypa/gh-action-pypi-publish@v1.6.4
with:
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Sync Release with Master
run: |
git fetch origin
git checkout release
git pull origin release
git checkout master
git pull origin master
git merge release --ff-only
git push origin master

31
.github/workflows/translations.yml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Check translations
# Drop permissions to minimum for security
permissions:
contents: read
on:
pull_request:
push:
workflow_dispatch:
jobs:
check_translations:
name: Check translations
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Install runtime dependencies
run: |
python3 -m pip install --upgrade pip setuptools wheel
python3 -m pip install polib
- name: Check translations
run: |
python3 validate_po.py

View File

@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@ -645,7 +645,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
@ -664,11 +664,11 @@ might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
<https://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@ -4,13 +4,14 @@
[![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)
Protect your eyes from eye strain using this simple and beautiful, yet extensible break reminder.
Visit the official site: http://slgobinath.github.io/SafeEyes/ for more details.
Visit the official site: https://slgobinath.github.io/SafeEyes/ for more details.
## Safe Eyes command-line arguments
@ -59,14 +60,6 @@ sudo emerge -av x11-misc/safeeyes
### Debian
```bash
sudo apt-get install gir1.2-appindicator3-0.1 gir1.2-notify-0.7 python3-psutil python3-xlib xprintidle python3-pip python3-babel python3-croniter
sudo pip3 install safeeyes
sudo update-icon-caches /usr/share/icons/hicolor
```
People using unstable/testing Debian can install Safe Eyes from the official repository using the following command:
```bash
sudo apt-get install safeeyes
```
@ -86,11 +79,23 @@ sudo zypper refresh
sudo zypper install safeeyes
```
### Alpine Linux
```bash
sudo apk add safeeyes
```
### Flatpak
```bash
flatpak install flathub io.github.slgobinath.SafeEyes
```
### Other Linux & Run from source
Ensure to meet the following dependencies:
- gir1.2-appindicator3-0.1
- gir1.2-appindicator3-0.1 or gir1.2-ayatanaappindicator3-0.1
- gir1.2-notify-0.7
- libappindicator-gtk3
- python3-psutil
@ -163,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

8
debian/changelog vendored
View File

@ -1,5 +1,9 @@
safeeyes (2.1.3-1) xenial; urgency=high
* Fix the error if there is no long break
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
* Add wayland support for do not disturb me plugin

2
debian/compat vendored
View File

@ -1 +1 @@
9
10

4
debian/control vendored
View File

@ -2,14 +2,14 @@ Source: safeeyes
Section: utils
Priority: optional
Maintainer: Gobinath Loganathan <slgobinath@gmail.com>
Build-Depends: debhelper (>= 9), python3, python3-setuptools
Build-Depends: debhelper (>= 10), dh-python, python3, python3-setuptools
Standards-Version: 3.9.6
X-Python3-Version: >= 3.5
Homepage: https://github.com/slgobinath/SafeEyes/
Package: safeeyes
Architecture: all
Depends: ${misc:Depends}, ${python3:Depends}, gir1.2-appindicator3-0.1, python3 (>= 3.5.0), python3-xlib, python3-dbus, gir1.2-notify-0.7, python3-babel, x11-utils, xprintidle, alsa-utils, python3-psutil, python3-croniter
Depends: ${misc:Depends}, ${python3:Depends}, gir1.2-ayatanaappindicator3-0.1, python3 (>= 3.5.0), python3-xlib, python3-dbus, gir1.2-notify-0.7, python3-babel, x11-utils, xprintidle, alsa-utils, python3-psutil, python3-croniter
Description: Safe Eyes
Safe Eyes is a simple tool to remind you to take periodic breaks for your eyes. This is essential for anyone spending more time on the computer to avoid eye strain and other physical problems.
.

View File

@ -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
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

View File

@ -90,9 +90,12 @@ def main():
"""
system_locale = gettext.translation('safeeyes', localedir=utility.LOCALE_PATH, languages=[utility.system_locale(), 'en_US'], fallback=True)
system_locale.install()
# locale.bindtextdomain is required for Glade files
# gettext.bindtextdomain(gettext.textdomain(), Utility.LOCALE_PATH)
locale.bindtextdomain('safeeyes', utility.LOCALE_PATH)
try:
# locale.bindtextdomain is required for Glade files
locale.bindtextdomain('safeeyes', utility.LOCALE_PATH)
except AttributeError:
logging.warning('installed python\'s gettext module does not support locale.bindtextdomain. locale.bindtextdomain is required for Glade files')
parser = argparse.ArgumentParser(prog='safeeyes', description=_('description'))
group = parser.add_mutually_exclusive_group()
@ -108,7 +111,7 @@ def main():
args = parser.parse_args()
# Initialize the logging
utility.intialize_logging(args.debug)
utility.initialize_logging(args.debug)
utility.initialize_platform()
config = Config()

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2020-12-23 11:29+0000\n"
"Last-Translator: Muhammad Hegab <mhegab@hotmail.com>\n"
"PO-Revision-Date: 2022-05-24 17:15+0000\n"
"Last-Translator: Mohamed Omran <mohamedgomran@gmail.com>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/safe-eyes/"
"translations/ar/>\n"
"Language: ar\n"
@ -16,7 +16,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
"X-Generator: Weblate 4.4.1-dev\n"
"X-Generator: Weblate 4.13-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -72,7 +72,7 @@ msgstr "غادر برنامج safeeyes المشتغل حاليّا"
# Commandline arg description
msgid "show the settings dialog"
msgstr "أظهر مربع الإعدادات"
msgstr "إظهار لوحة اﻹعدادات"
# Commandline arg description
msgid "start safeeyes in debug mode"
@ -84,7 +84,7 @@ msgstr "أظهر حالة برنامج safeeyes المشتغل حاليا و أ
# Status message
msgid "Safe Eyes is not running"
msgstr "SafeEyes غير مشغل"
msgstr "SafeEyes لا يعمل"
# RPC not enabled message
msgid ""
@ -137,7 +137,7 @@ msgstr "مدة التأخير (دقائق)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "اظهِّر الاستراحات بترتيب عشوائي"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
@ -274,7 +274,7 @@ msgstr "من فضلك ثبّت أداة سطر الأوامر '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "تعبير الوظيفة المجدولة غير صحيح '%s'"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -290,7 +290,7 @@ msgstr "إزالة"
# Settings dialog
msgid "Discard"
msgstr "اترك"
msgstr "تجاهل"
# Settings dialog
msgid "Save"
@ -298,7 +298,7 @@ msgstr "احفظ"
# plugin/audiblealert
msgid "Audible Alert"
msgstr "تنبيه مسموع"
msgstr "إنذار مسموع"
# plugin/audiblealert
msgid "Play audible alert before and after breaks"
@ -346,7 +346,7 @@ msgstr "أظهر الإحصاءات بناءً على كيفية استخدام
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "فاصل إعادة ضبط الإحصائيات (تعبير وظيفة مجدولة)"
# plugin/notification
msgid "Notification"
@ -366,55 +366,55 @@ msgstr "استعد لراحة طويلة بعد %s من الثواني"
# plugin/screensaver
msgid "Screensaver"
msgstr ""
msgstr "شاشة التوقف"
# plugin/screensaver
msgid "Lock the screen after long breaks by starting screensaver"
msgstr ""
msgstr "اغلق الشاشة بعد فترة استراحة طويلة عن طريق بدأ شاشة التوقف"
# plugin/screensaver
msgid "Custom screensaver command"
msgstr ""
msgstr "أمر شاشة التوقف مخصص"
# plugin/screensaver
msgid "Minimum seconds to skip without screensaver"
msgstr ""
msgstr "أقل عدد ثواني للتخطي بدون شاشة التوقف"
# plugin/screensaver
msgid "Lock screen"
msgstr ""
msgstr "اغلق الشاشة"
# plugin/smartpause
msgid "Smart Pause"
msgstr ""
msgstr "التوقف الذكي"
# plugin/smartpause
msgid "Pause Safe Eyes if the system is idle"
msgstr ""
msgstr "اوقف Safe Eyes إذا كان النظام خاملاً"
# plugin/smartpause
msgid "Minimum idle time to pause Safe Eyes (in seconds)"
msgstr ""
msgstr "أقل مدة خمول لإيقاف Safe Eyes (بالثوان)"
# plugin/smartpause
msgid "Interpret idle time equivalent to upcoming break duration as a break"
msgstr ""
msgstr "تفسير وقت الخمول المكافئ لفترة الاستراحة القادمة على أنه استراحة"
# plugin/smartpause
msgid "Postpone the next break until the system becomes idle"
msgstr ""
msgstr "اجًّل فترة الاستراحة القادمة حتى يصبح النظام خاملاً"
#: plugins/trayicon
msgid "Tray Icon"
msgstr ""
msgstr "الأيقونة"
#: plugins/trayicon
msgid "Show a tray icon in the notification area"
msgstr ""
msgstr "أظهِّر الأيقونة في منطقة الإشعارات"
#: plugins/trayicon
msgid "Show next break time in tray icon"
msgstr ""
msgstr "أظهِّر وقت الاستراحة القادمة في درج الأيقونة"
#: plugins/trayicon
msgid "Allow disabling Safe Eyes"
@ -443,68 +443,68 @@ msgstr "فعِّل Safe Eyes"
#: plugins/trayicon
msgid "For %d Hour"
msgid_plural "For %d Hours"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
msgstr[0] "لمدة %d ساعة"
msgstr[1] "لمدة ساعة"
msgstr[2] "لمدة ساعتين"
msgstr[3] "لمدة %d ساعات"
msgstr[4] "لمدة %d ساعة"
msgstr[5] "لمدة %d ساعة"
#: plugins/trayicon
msgid "For %d Minute"
msgid_plural "For %d Minutes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
msgstr[0] "لمدة %d دقيقة"
msgstr[1] "لمدة دقيقة"
msgstr[2] "لمدة دقيقتين"
msgstr[3] "لمدة %d دقائق"
msgstr[4] "لمدة %d دقيقة"
msgstr[5] "لمدة %d دقيقة"
#: plugins/trayicon
msgid "For %d Second"
msgid_plural "For %d Seconds"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
msgstr[0] "لمدة %d ثانية"
msgstr[1] "لمدة ثانية"
msgstr[2] "لمدة ثانيتين"
msgstr[3] "لمدة %d ثوان"
msgstr[4] "لمدة %d ثانية"
msgstr[5] "لمدة %d ثانية"
#: plugins/trayicon
msgid "Next break at %s"
msgstr ""
msgstr "فترة الاستراحة القادمة بعد %s"
#: plugins/trayicon
msgid "No Breaks Available"
msgstr ""
msgstr "لا يوجد فترات استراحة متاحة"
#: plugins/trayicon
msgid "Settings"
msgstr ""
msgstr "الإعدادات"
#: plugins/trayicon
msgid "Take a break now"
msgstr ""
msgstr "خُذ استراحة الآن"
#: plugins/trayicon
msgid "Until restart"
msgstr ""
msgstr "حتى إعادة التشغيل"
#: plugins/trayicon
msgid "Quit"
msgstr ""
msgstr "اخرج"
# plugin/mediacontrol
msgid "Media Control"
msgstr ""
msgstr "تحكم الوسائط"
# plugin/mediacontrol
msgid "Pause media players from the break screen"
msgstr ""
msgstr "أوقِف مشغلات الوسائط في شاشة فترة الاستراحة"
# plugin/mediacontrol
msgid "Pause media"
msgstr ""
msgstr "أوقِف الوسائط"
# plugin/healthstats
#~ msgid "Interval to reset statistics (in hours)"

View File

@ -6,51 +6,52 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"PO-Revision-Date: 2024-02-07 05:56+0000\n"
"Last-Translator: Salif Mehmed <mail@salif.eu>\n"
"Language-Team: Bulgarian <https://hosted.weblate.org/projects/safe-eyes/"
"translations/bg/>\n"
"Language: bg\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.8.7.1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.4-dev\n"
# Short break
msgid "Tightly close your eyes"
msgstr ""
msgstr "Затворете плътно очи"
# Short break
msgid "Roll your eyes a few times to each side"
msgstr ""
msgstr "Завъртете очи няколко пъти на всяка страна"
# Short break
msgid "Rotate your eyes in clockwise direction"
msgstr ""
msgstr "Завъртете очите си по посока на часовниковата стрелка"
# Short break
msgid "Rotate your eyes in counterclockwise direction"
msgstr ""
msgstr "Завъртете очите си обратно на часовниковата стрелка"
# Short break
msgid "Blink your eyes"
msgstr ""
msgstr "Мигайте с очи"
# Short break
msgid "Focus on a point in the far distance"
msgstr ""
msgstr "Фокусирайте се върху точка в далечината"
# Short break
msgid "Have some water"
msgstr ""
msgstr "Пийте вода"
# Long break
msgid "Walk for a while"
msgstr ""
msgstr "Разходете се известно време"
# Long break
msgid "Lean back at your seat and relax"
msgstr ""
msgstr "Облегнете се и се отпуснете"
# Commandline arg description
msgid "show the about dialog"
@ -92,7 +93,7 @@ msgstr ""
# About dialog
msgid "Close"
msgstr ""
msgstr "Затваряне"
# Description in about dialog
# Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you to take breaks while you're working long hours at the computer
@ -103,23 +104,23 @@ msgstr ""
# About dialog
msgid "License"
msgstr ""
msgstr "Лиценз"
# Break screen
msgid "Skip"
msgstr ""
msgstr "Пропускане"
# Break screen
msgid "Postpone"
msgstr ""
msgstr "Отлагане"
# Settings dialog
msgid "Break duration (in seconds)"
msgstr ""
msgstr "Продължителност на почивките (в секунди)"
# Settings dialog
msgid "Interval between two breaks (in minutes)"
msgstr ""
msgstr "Интервал между две почивки (в минути)"
# Settings dialog
msgid "Time to prepare for a break (in seconds)"
@ -171,19 +172,19 @@ msgstr ""
# Settings dialog
msgid "Options"
msgstr ""
msgstr "Опции"
# Settings dialog
msgid "Short Breaks"
msgstr ""
msgstr "Кратки почивки"
# Settings dialog
msgid "Long Breaks"
msgstr ""
msgstr "Дълги почивки"
# Settings dialog
msgid "Delete"
msgstr ""
msgstr "Изтриване"
# Settings dialog
msgid "Are you sure you want to delete this break?"
@ -195,11 +196,11 @@ msgstr ""
# Settings dialog
msgid "Break"
msgstr ""
msgstr "Почивка"
# Settings dialog
msgid "Breaks"
msgstr ""
msgstr "Почивки"
# Settings dialog
msgid "Plugins"
@ -243,11 +244,11 @@ msgstr ""
# Settings dialog
msgid "Time (in seconds)"
msgstr ""
msgstr "Време (в секунди)"
# Settings dialog
msgid "Time (in minutes)"
msgstr ""
msgstr "Време (в минути)"
# Settings dialog
msgid "Break Settings"
@ -279,19 +280,19 @@ msgstr ""
# Settings dialog
msgid "New Break"
msgstr ""
msgstr "Нова почивка"
# Settings dialog
msgid "Remove"
msgstr ""
msgstr "Премахване"
# Settings dialog
msgid "Discard"
msgstr ""
msgstr "Отхвърляне"
# Settings dialog
msgid "Save"
msgstr ""
msgstr "Запазване"
# plugin/audiblealert
msgid "Audible Alert"
@ -311,7 +312,7 @@ msgstr ""
# plugin/donotdisturb
msgid "Do Not Disturb"
msgstr ""
msgstr "Не безпокой"
# plugin/donotdisturb
msgid "Skip break if the active window is in fullscreen mode"
@ -347,7 +348,7 @@ msgstr ""
# plugin/notification
msgid "Notification"
msgstr ""
msgstr "Известие"
# plugin/notification
msgid "Show a system notification before breaks"
@ -419,65 +420,65 @@ msgstr ""
#: plugins/trayicon
msgid "About"
msgstr ""
msgstr "Относно"
#: plugins/trayicon
msgid "Disable Safe Eyes"
msgstr ""
msgstr "Изключване на Safe Eyes"
#: plugins/trayicon
msgid "Disabled until %s"
msgstr ""
msgstr "Изключено до %s"
#: plugins/trayicon
msgid "Disabled until restart"
msgstr ""
msgstr "Изключено до рестартиране"
#: plugins/trayicon
msgid "Enable Safe Eyes"
msgstr ""
msgstr "Включване на Safe Eyes"
#: plugins/trayicon
msgid "For %d Hour"
msgid_plural "For %d Hours"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "За %d Час"
msgstr[1] "За %d Часа"
#: plugins/trayicon
msgid "For %d Minute"
msgid_plural "For %d Minutes"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "За %d Минута"
msgstr[1] "За %d Минути"
#: plugins/trayicon
msgid "For %d Second"
msgid_plural "For %d Seconds"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "За %d Секунда"
msgstr[1] "За %d Секунди"
#: plugins/trayicon
msgid "Next break at %s"
msgstr ""
msgstr "Следваща почивка в %s"
#: plugins/trayicon
msgid "No Breaks Available"
msgstr ""
msgstr "Няма налични почивки"
#: plugins/trayicon
msgid "Settings"
msgstr ""
msgstr "Настройки"
#: plugins/trayicon
msgid "Take a break now"
msgstr ""
msgstr "Направете почивка сега"
#: plugins/trayicon
msgid "Until restart"
msgstr ""
msgstr "До рестартиране"
#: plugins/trayicon
msgid "Quit"
msgstr ""
msgstr "Изход"
# plugin/mediacontrol
msgid "Media Control"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2018-02-01 11:34+0000\n"
"Last-Translator: Joan Montané <joan@montane.cat>\n"
"PO-Revision-Date: 2022-08-08 21:25+0000\n"
"Last-Translator: calbasi <joan@calbasi.net>\n"
"Language-Team: Catalan <https://hosted.weblate.org/projects/safe-eyes/"
"translations/ca/>\n"
"Language: ca\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 2.19-dev\n"
"X-Generator: Weblate 4.14-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -55,31 +55,31 @@ msgstr "Reclineu-vos sobre la cadira i relaxeu-vos"
# Commandline arg description
msgid "show the about dialog"
msgstr ""
msgstr "Mostra la informació Naltros"
# Commandline arg description
msgid "disable the currently running safeeyes instance"
msgstr ""
msgstr "Inhabilita la instància de safeeyes en funcionament"
# Commandline arg description
msgid "enable the currently running safeeyes instance"
msgstr ""
msgstr "Habilita la instància de safeeyes en funcionament"
# Commandline arg description
msgid "quit the running safeeyes instance and exit"
msgstr ""
msgstr "Tanca de la instància de safeeyes en funcionament i surt"
# Commandline arg description
msgid "show the settings dialog"
msgstr ""
msgstr "Mostra la finestra de preferències"
# Commandline arg description
msgid "start safeeyes in debug mode"
msgstr ""
msgstr "Inicia safeeyes en mode de depuració"
# Commandline arg description
msgid "print the status of running safeeyes instance and exit"
msgstr ""
msgstr "Mostra l'estat de la instància de safeeyes en funcionament i surt"
# Status message
msgid "Safe Eyes is not running"
@ -139,11 +139,11 @@ msgstr "Durada d'una posposició (en minuts)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "Mostra les pauses en ordre aleatori"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
msgstr ""
msgstr "Pauses estrictes (sense possibilitat de saltar-se-les)"
# Settings dialog
msgid "Allow postponing breaks"
@ -167,99 +167,99 @@ msgstr ""
# Settings dialog
msgid "Reset"
msgstr ""
msgstr "Restablir"
# Settings dialog
msgid "Are you sure you want to reset all settings to default?"
msgstr ""
msgstr "De veritat que voleu restablir les preferències als valors per defecte?"
# Settings dialog
msgid "Options"
msgstr ""
msgstr "Opcions"
# Settings dialog
msgid "Short Breaks"
msgstr ""
msgstr "Pauses curtes"
# Settings dialog
msgid "Long Breaks"
msgstr ""
msgstr "Pauses llargues"
# Settings dialog
msgid "Delete"
msgstr ""
msgstr "Suprimeix"
# Settings dialog
msgid "Are you sure you want to delete this break?"
msgstr ""
msgstr "De veritat que voleu suprimir aquesta pausa?"
# Settings dialog
msgid "You can't undo this action."
msgstr ""
msgstr "Aquesta acció no podrà revertir-se."
# Settings dialog
msgid "Break"
msgstr ""
msgstr "Pausa"
# Settings dialog
msgid "Breaks"
msgstr ""
msgstr "Pauses"
# Settings dialog
msgid "Plugins"
msgstr ""
msgstr "Complements"
# Settings dialog
msgid "Type"
msgstr ""
msgstr "Tipus"
# Settings dialog
msgid "Short"
msgstr ""
msgstr "Curta"
# Settings dialog
msgid "Long"
msgstr ""
msgstr "Llarga"
# Settings dialog
msgid "Image"
msgstr ""
msgstr "Imatge"
# Settings dialog
msgid "Select"
msgstr ""
msgstr "Trieu"
# Settings dialog
msgid "Please select an image"
msgstr ""
msgstr "Si us plau, trieu una imatge"
# Settings dialog
msgid "Duration"
msgstr ""
msgstr "Durada"
# Settings dialog
msgid "Time to wait"
msgstr ""
msgstr "Temps d'espera"
# Settings dialog
msgid "Override"
msgstr ""
msgstr "Sobreescriu"
# Settings dialog
msgid "Time (in seconds)"
msgstr ""
msgstr "Temps (en segons)"
# Settings dialog
msgid "Time (in minutes)"
msgstr ""
msgstr "Temps (en minuts)"
# Settings dialog
msgid "Break Settings"
msgstr ""
msgstr "Preferències de la pausa"
# Settings dialog
msgid "Plugin Settings"
msgstr ""
msgstr "Preferències del complement"
# Settings dialog
msgid "Plugin does not support %s desktop environment"
@ -283,15 +283,15 @@ msgstr ""
# Settings dialog
msgid "New Break"
msgstr ""
msgstr "Nova Pausa"
# Settings dialog
msgid "Remove"
msgstr ""
msgstr "Suprimeix"
# Settings dialog
msgid "Discard"
msgstr ""
msgstr "Descarta-ho"
# Settings dialog
msgid "Save"
@ -299,7 +299,7 @@ msgstr "Desa"
# plugin/audiblealert
msgid "Audible Alert"
msgstr ""
msgstr "Alerta audible"
# plugin/audiblealert
msgid "Play audible alert before and after breaks"
@ -315,7 +315,7 @@ msgstr ""
# plugin/donotdisturb
msgid "Do Not Disturb"
msgstr ""
msgstr "No molesteu"
# plugin/donotdisturb
msgid "Skip break if the active window is in fullscreen mode"
@ -339,7 +339,7 @@ msgstr ""
# plugin/healthstats
msgid "Health Statistics"
msgstr ""
msgstr "Estadístiques de salut"
# plugin/healthstats
msgid "Show statistics based on how you use Safe Eyes"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2019-11-26 16:05+0000\n"
"Last-Translator: Pavel Borecki <pavel.borecki@gmail.com>\n"
"PO-Revision-Date: 2023-10-31 16:04+0000\n"
"Last-Translator: Kryštof Jelínek <krystof186@gmail.com>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/safe-eyes/"
"translations/cs/>\n"
"Language: cs\n"
@ -15,7 +15,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 3.10-dev\n"
"X-Generator: Weblate 5.2-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -23,15 +23,15 @@ msgstr "Zavřete oči"
# Short break
msgid "Roll your eyes a few times to each side"
msgstr "Zakroete očima (několikrát na každou stranu)"
msgstr "Zakružte očima (několikrát na každou stranu)"
# Short break
msgid "Rotate your eyes in clockwise direction"
msgstr "Zakroete očima ve směru hodinových ručiček"
msgstr "Zakružte očima ve směru hodinových ručiček"
# Short break
msgid "Rotate your eyes in counterclockwise direction"
msgstr "Zakroete očima proti směru hodinových ručiček"
msgstr "Zakružte očima proti směru hodinových ručiček"
# Short break
msgid "Blink your eyes"
@ -140,7 +140,7 @@ msgstr "Odložit trvání (v minutách)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "Zobrazovat přestávky v náhodném pořadí"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
@ -276,7 +276,7 @@ msgstr "Nainstalujte si nástroj pro příkazový řádek „%s“"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "Neplatný výraz pro plánovač (cron) „%s“"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -349,7 +349,7 @@ msgstr "Zobrazit zdravotní statistiky založené na používání Safe Eyes"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "Interval vynulování statistik (výraz pro plánovač cron)"
# plugin/notification
msgid "Notification"

View File

@ -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 <j.lavoie@net-c.ca>\n"
"PO-Revision-Date: 2023-07-04 20:53+0000\n"
"Last-Translator: Sebastian Pipping <sebastian@pipping.org>\n"
"Language-Team: German <https://hosted.weblate.org/projects/safe-eyes/"
"translations/de/>\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"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2017-09-17 07:59-0400\n"
"PO-Revision-Date: 2020-06-17 18:41+0000\n"
"Last-Translator: Aanand Kainth <akainth015@gmail.com>\n"
"PO-Revision-Date: 2021-07-04 07:32+0000\n"
"Last-Translator: J. Lavoie <j.lavoie@net-c.ca>\n"
"Language-Team: English (United States) <https://hosted.weblate.org/projects/"
"safe-eyes/translations/en_US/>\n"
"Language: en_US\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.1.1-dev\n"
"X-Generator: Weblate 4.8-dev\n"
"Generated-By: pygettext.py 1.5\n"
# Short break
@ -277,7 +277,7 @@ msgstr "Please install the command-line tool '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "Invalid cron expression “%s”"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2017-09-17 07:59-0400\n"
"PO-Revision-Date: 2021-02-10 15:50+0000\n"
"PO-Revision-Date: 2021-05-21 15:32+0000\n"
"Last-Translator: Jorge Maldonado Ventura <jorgesumle@freakspot.net>\n"
"Language-Team: Esperanto <https://hosted.weblate.org/projects/safe-eyes/"
"translations/eo/>\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-dev\n"
"X-Generator: Weblate 4.7-dev\n"
"Generated-By: pygettext.py 1.5\n"
# Short break
@ -44,7 +44,7 @@ msgstr "Fokusu malfermegan punkton"
# Short break
msgid "Have some water"
msgstr "Trinku kelke da akvon"
msgstr "Trinku kelke da akvo"
# Long break
msgid "Walk for a while"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-04-15 12:26+0000\n"
"PO-Revision-Date: 2023-01-07 11:49+0000\n"
"Last-Translator: Porrumentzio <porrumentzio@riseup.net>\n"
"Language-Team: Basque <https://hosted.weblate.org/projects/safe-eyes/"
"translations/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.6-dev\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,18 +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
#, fuzzy
msgid "Interpret idle time equivalent to upcoming break duration as a break"
msgstr ""
"Interpretatu denbora inaktiboa hurrengo atsedenaldiaren iraupenaren "
"baliokide, 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"
@ -420,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"
@ -449,28 +450,28 @@ msgstr "Gaitu Safe Eyes"
#: plugins/trayicon
msgid "For %d Hour"
msgid_plural "For %d Hours"
msgstr[0] "Ordubeterako"
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 baterako"
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 baterako"
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"
@ -478,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"
@ -486,7 +487,7 @@ msgstr "Berrabiarazi arte"
#: plugins/trayicon
msgid "Quit"
msgstr "Utzi"
msgstr "Irten"
# plugin/mediacontrol
msgid "Media Control"
@ -494,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"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2020-10-23 17:20+0000\n"
"Last-Translator: mohammadbagher fakouri <mbfakourii@gmail.com>\n"
"PO-Revision-Date: 2022-07-07 10:18+0000\n"
"Last-Translator: Danial Behzadi <dani.behzi@ubuntu.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/safe-eyes/"
"translations/fa/>\n"
"Language: fa\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.3.1\n"
"X-Generator: Weblate 4.13.1-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -27,11 +27,11 @@ msgstr "چندبار چشمانتان را به اطراف بچرخانید"
# Short break
msgid "Rotate your eyes in clockwise direction"
msgstr "چشمان خود را در جهت عقربه های ساعت بچرخانید"
msgstr "چشمانتان را ساعتگرد بچرخانید"
# Short break
msgid "Rotate your eyes in counterclockwise direction"
msgstr "چشم هایتان را در خلاف جهت عقربه های ساعت بچرخانید"
msgstr "چشمانتان را پادساعتگرد بچرخانید"
# Short break
msgid "Blink your eyes"
@ -59,39 +59,39 @@ msgstr "نشان دادن پنجره درباره"
# Commandline arg description
msgid "disable the currently running safeeyes instance"
msgstr "غیرفعال کردن نمونه safeeyes درحال اجرا"
msgstr "از کار انداختن نمونهٔ محافظ چشم در حال اجرا"
# Commandline arg description
msgid "enable the currently running safeeyes instance"
msgstr "فعال کردن نمونه safeeyes درحال اجرا"
msgstr "به کار انداختن نمونهٔ محافظ چشم در حال اجرا"
# Commandline arg description
msgid "quit the running safeeyes instance and exit"
msgstr "بستن و خروج از safeeyes در حال اجرا"
msgstr "بستن و خروج از نمونهٔ محافظ چشم در حال اجرا"
# Commandline arg description
msgid "show the settings dialog"
msgstr "نشان دادن پنجره تنظیمات"
msgstr "نمایش گفت‌وگوی تنظیمات"
# Commandline arg description
msgid "start safeeyes in debug mode"
msgstr "اجرا کردن safeeyes در حالت دیباگ"
msgstr "اجرای محافظ چشم در حالت رفع اشکال"
# Commandline arg description
msgid "print the status of running safeeyes instance and exit"
msgstr "وضعیت اجرای safeeyes را چاپ کرده و از آن خارج شوید"
msgstr "چاپ وضعیت نمونهٔ محافظ چشم در جال اجرا و خروج"
# Status message
msgid "Safe Eyes is not running"
msgstr "محافظ چشم در حال اجرا نیست"
msgstr "محافظ چشم اجرا نمی‌شود"
# RPC not enabled message
msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr ""
"Safe Eyes بدون سرور RPC در حال اجرا است. برای استفاده از آرگومان های خط "
"فرمان آن را روشن کنید."
"محافظ چشم دارد بدون کارساز RPC اجرا می‌شود. برای استفاده از آرگومان‌های خط "
"فرمان، روشنش کنید."
# About dialog
msgid "Close"
@ -102,19 +102,21 @@ msgstr "بستن"
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 "شرح"
msgstr ""
"محافظ چشم با یادآوردی استراحت هنگام کار طولانی با رایانه، از چشمانتان در "
"برابر خشتگی جشم (استنوپیا) محافظت می‌کند"
# About dialog
msgid "License"
msgstr "مجوز"
msgstr "پروانه"
# Break screen
msgid "Skip"
msgstr "رد کردن"
msgstr "پرش"
# Break screen
msgid "Postpone"
msgstr "بعدا"
msgstr "تعویق"
# Settings dialog
msgid "Break duration (in seconds)"
@ -122,31 +124,31 @@ msgstr "زمان استراحت (به ثانیه)"
# Settings dialog
msgid "Interval between two breaks (in minutes)"
msgstr "بازه بین دو استراحت (به دقیقه)"
msgstr "بازهٔ بین دو استراحت (به دقیقه)"
# Settings dialog
msgid "Time to prepare for a break (in seconds)"
msgstr "زمان آماده شدن برای استراحت (در چند ثانیه)"
msgstr "زمان آمادگی برای استراحت (به ثانیه)"
# Settings dialog
msgid "Keyboard shortcuts disabled period (in seconds)"
msgstr "میانبرهای صفحه کلید دوره غیرفعال شده (در چند ثانیه)"
msgstr "دورهٔ از کار افتادن میان‌برهای صفحه کلید (به ثانیه)"
# Settings dialog
msgid "Postponement duration (in minutes)"
msgstr "به تعویق انداختن مدت زمان (در چند دقیقه)"
msgstr "زمان تعویق (به دقیقه)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "نمایش استراحت‌ها به ترتیب کاتوره‌ای"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
msgstr "استراحت سخت (راهی برای جستجوی وقفه وجود ندارد)"
msgstr "استراحت قاطع ( بدون راهی برای پرش از استراحت)"
# Settings dialog
msgid "Allow postponing breaks"
msgstr "به تعویق انداختن وقفه ها اجازه دهید"
msgstr "اجازه به تعویق استراحت‌ها"
# Settings dialog
msgid "Persist the internal state"
@ -154,36 +156,35 @@ 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"
msgstr "فاصله زمانی طولانی باید مضربی از وقفه کوتاه باشد"
msgstr "دورهٔ استراحت طولانی باید مضربی از دوره‌های استراحت کوتاه باشد"
# Settings dialog
msgid "Reset"
msgstr "تنظیم مجدد"
msgstr "بازنشانی"
# Settings dialog
msgid "Are you sure you want to reset all settings to default?"
msgstr ""
"آیا مطمئن هستید که می خواهید همه تنظیمات را به حالت پیش فرض بازنشانی کنید؟"
msgstr "مطمئنید که می‌خواهید تمامی تنظیمات را به پیش‌گزیده بازنشانی کنید؟"
# Settings dialog
msgid "Options"
msgstr "گزینه ها"
msgstr "گزینهها"
# Settings dialog
msgid "Short Breaks"
msgstr "وقفه های کوتاه"
msgstr "استراحت‌های کوتاه"
# Settings dialog
msgid "Long Breaks"
msgstr "وقفه های طولانی"
msgstr "استراحت‌های طولانی"
# Settings dialog
msgid "Delete"
@ -191,7 +192,7 @@ msgstr "حذف"
# Settings dialog
msgid "Are you sure you want to delete this break?"
msgstr "آیا مطمئن هستید که می خواهید این وقفه را حذف کنید؟"
msgstr "مطمئنید که می‌خواهید این استراحت را حذف کنید؟"
# Settings dialog
msgid "You can't undo this action."
@ -203,15 +204,15 @@ msgstr "استراحت"
# Settings dialog
msgid "Breaks"
msgstr "می شکند"
msgstr "استراحت‌ها"
# Settings dialog
msgid "Plugins"
msgstr "پلاگین ها"
msgstr "افزایه‌ها"
# Settings dialog
msgid "Type"
msgstr "نوع"
msgstr "گونه"
# Settings dialog
msgid "Short"
@ -227,59 +228,59 @@ msgstr "تصویر"
# Settings dialog
msgid "Select"
msgstr "انتخاب کنید"
msgstr "گزینش"
# Settings dialog
msgid "Please select an image"
msgstr "لطفاً تصویری انتخاب کنید"
msgstr "لطفاً تصویری برگزینید"
# Settings dialog
msgid "Duration"
msgstr "مدت زمان"
msgstr "طول"
# Settings dialog
msgid "Time to wait"
msgstr "وقت انتظار است"
msgstr "زمان انتظار"
# Settings dialog
msgid "Override"
msgstr "لغو کردن"
msgstr "پایمالی"
# Settings dialog
msgid "Time (in seconds)"
msgstr "زمان (در چند ثانیه)"
msgstr "زمان (به ثانیه)"
# Settings dialog
msgid "Time (in minutes)"
msgstr "زمان (در چند دقیقه)"
msgstr "زمان (به دقیقه)"
# Settings dialog
msgid "Break Settings"
msgstr "شکستن تنظیمات"
msgstr "تنظیمات استراحت"
# Settings dialog
msgid "Plugin Settings"
msgstr "تنظیمات پلاگین"
msgstr "تنظیمات افزایه"
# Settings dialog
msgid "Plugin does not support %s desktop environment"
msgstr "پلاگین پشتیبانی نمی کند %s محیط دسک تاپ"
msgstr "افزایه از محیط میزکار %s پشتیبانی نمی‌کند"
# Settings dialog
msgid "Please install the Python module '%s'"
msgstr "لطفاً ماژول پایتون را نصب کنید '%s'"
msgstr "لطفاً پیمانهٔ %s پایتون را نصب کنید"
# Settings dialog
msgid "Please install the command-line tool '%s'"
msgstr "لطفاً ابزار خط فرمان را نصب کنید '%s'"
msgstr "لطفاً ابزار خط فرمان %s را نصب کنید"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "عبارت کرون نامعتبر «%s»"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
msgstr "لطفا منبع را اضافه کنید %(resource) در %(config_resource)پوشه ها"
msgstr "لطفا منبع %(resource)s را به شاخهٔ %(config_resource)s بیفزایید"
# Settings dialog
msgid "New Break"
@ -303,15 +304,15 @@ msgstr "هشدار شنیدنی"
# plugin/audiblealert
msgid "Play audible alert before and after breaks"
msgstr "هشدار صوتی را قبل و بعد از وقفه پخش کنید"
msgstr "پخش هشدار صوتی پیش و پس از استراحت‌ها"
# plugin/audiblealert
msgid "Play audible alert before breaks"
msgstr "هشدار صوتی را قبل از وقفه پخش کنید"
msgstr "پخش هشدار صوتی پیش از استراحت‌ها"
# plugin/audiblealert
msgid "Play audible alert after breaks"
msgstr "بعد از وقفه هشدار صوتی را پخش کنید"
msgstr "پخش هشدار صوتی پس از استراحت‌ها"
# plugin/donotdisturb
msgid "Do Not Disturb"
@ -323,15 +324,15 @@ msgstr "اگر پنجره فعال در حالت تمام صفحه است ، ا
# plugin/donotdisturb
msgid "Do not interrupt these windows anytime"
msgstr "هر وقت بخواهید این پنجره ها را قطع نکنید"
msgstr "این پنجره‌ها هرگز دچار وقفه نشوند"
# plugin/donotdisturb
msgid "Interrupt these windows regardless of their state"
msgstr "قطع این پنجره ها بدون توجه به وضعیت آنها"
msgstr "وقفه دادن این پنجره‌ها فارغ از وضعیتشان"
# plugin/donotdisturb
msgid "Switch the interruptible windows to normal mode"
msgstr "پنجره های قطع شونده را به حالت عادی تغییر دهید"
msgstr "تغییر پنچره‌های وقفه‌پذیر به حالت عادی"
# plugin/donotdisturb
msgid "Do not disturb while on battery"
@ -339,31 +340,31 @@ msgstr "در هنگام شارژ باتری مزاحم نشوید"
# plugin/healthstats
msgid "Health Statistics"
msgstr "آمار بهداشت"
msgstr "آمار سلامتی"
# plugin/healthstats
msgid "Show statistics based on how you use Safe Eyes"
msgstr "آماری را براساس نحوه استفاده از Safe Eyes نشان دهید"
msgstr "نمایش آماری بر پایهٔ چگونگی استفاده‌تان از محافظ چشم"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "بازهٔ بازنشانی آمار (عبارت کرون)"
# plugin/notification
msgid "Notification"
msgstr "اطلاع"
msgstr "آگاهی"
# plugin/notification
msgid "Show a system notification before breaks"
msgstr "قبل از وقفه یک اعلان سیستم را نشان دهید"
msgstr "نمایش یک آگاهی سامانه پیش از استراحت‌ها"
# plugin/notification
msgid "Ready for a short break in %s seconds"
msgstr "آماده برای یک استراحت کوتاه در %s ثانیه"
msgstr "آماده برای استراحتی کوتاه در %s ثانیه"
# plugin/notification
msgid "Ready for a long break in %s seconds"
msgstr "آماده برای یک استراحت طولانی در %s ثانیه"
msgstr "آماده برای استراحتی طولانی در %s ثانیه"
# plugin/screensaver
msgid "Screensaver"
@ -371,7 +372,7 @@ msgstr "محافظ صفحه"
# plugin/screensaver
msgid "Lock the screen after long breaks by starting screensaver"
msgstr "با اسکرین سیور ، صفحه را پس از وقفه های طولانی قفل کن"
msgstr "قفل صفحه پس از استراحت‌های طولانی با آغاز محافظ صفحه"
# plugin/screensaver
msgid "Custom screensaver command"
@ -379,7 +380,7 @@ msgstr "دستور محافظ صفحه نمایش سفارشی"
# plugin/screensaver
msgid "Minimum seconds to skip without screensaver"
msgstr "حداقل ثانیه برای پرش بدون محافظ صفحه نمایش"
msgstr "کمینهٔ ثانیه‌ها برای پرش بدون محافظ صفحه"
# plugin/screensaver
msgid "Lock screen"
@ -391,73 +392,73 @@ msgstr "مکث هوشمند"
# plugin/smartpause
msgid "Pause Safe Eyes if the system is idle"
msgstr "اگر سیستم بیکار است ، Safe Eyes را مکث کنید"
msgstr "مکث محافظ چشم در صورت بی‌کاری سامانه"
# plugin/smartpause
msgid "Minimum idle time to pause Safe Eyes (in seconds)"
msgstr "حداقل زمان بیکار برای مکث ایمن چشم ها (در چند ثانیه)"
msgstr "کمینهٔ زمان بیکاری برای مکث محافظ چشم (به ثانیه)"
# plugin/smartpause
msgid "Interpret idle time equivalent to upcoming break duration as a break"
msgstr "زمان بیکار معادل مدت وقفه آینده را به عنوان یک استراحت تفسیر کنید"
msgstr "وقفهٔ زمان بیکاری معادل زمان استراحت پیش رو به عنوان یک استراحت"
# plugin/smartpause
msgid "Postpone the next break until the system becomes idle"
msgstr "وقفه بعدی را به تأخیر بیندازید تا سیستم بیکار شود"
msgstr "تعویق استراحت بعدی تا زمان بیکار شدن سامانه"
#: plugins/trayicon
msgid "Tray Icon"
msgstr "Tray Icon"
msgstr "نقشک سینی"
#: plugins/trayicon
msgid "Show a tray icon in the notification area"
msgstr "نماد تلاش مجدد را در قسمت اعلان نشان دهید"
msgstr "نمایش نقشک سینی در ناحیهٔ آگاهی"
#: plugins/trayicon
msgid "Show next break time in tray icon"
msgstr "زمان استراحت بعدی را در نماد تلاش مجدد نشان دهید"
msgstr "نمایش زمان استراحت بعدی در نقشک سینی"
#: plugins/trayicon
msgid "Allow disabling Safe Eyes"
msgstr "اجازه دادن به غیرفعال کردن ایمن چشم ها"
msgstr "اجازه به از کار انداختن محافظ چشم"
#: plugins/trayicon
msgid "About"
msgstr "در باره"
msgstr "درباره"
#: plugins/trayicon
msgid "Disable Safe Eyes"
msgstr "غیر فعال سازی Safe Eyes"
msgstr "از کار انداختن محافظ چشم"
#: plugins/trayicon
msgid "Disabled until %s"
msgstr "غیرفعال تا %s"
msgstr "از کار افتاده تا %s"
#: plugins/trayicon
msgid "Disabled until restart"
msgstr "غیرفعال است تا راه اندازی مجدد"
msgstr "از کار افتاده تا آغاز دوباره"
#: plugins/trayicon
msgid "Enable Safe Eyes"
msgstr "فعال سازی Safe Eyes"
msgstr "به کار انداختن محافظ چشم"
#: plugins/trayicon
msgid "For %d Hour"
msgid_plural "For %d Hours"
msgstr[0] "به مدت %d ساعت ها"
msgstr[1] "به مدت %d ساعت"
msgstr[0] "برای ۱ ساعت"
msgstr[1] "برای %Id ساعت"
#: plugins/trayicon
msgid "For %d Minute"
msgid_plural "For %d Minutes"
msgstr[0] "برای %d دقیقه"
msgstr[1] "برای %d دقیقه ها"
msgstr[0] "برای ۱ دقیقه"
msgstr[1] "برای %Id دقیقه"
#: plugins/trayicon
msgid "For %d Second"
msgid_plural "For %d Seconds"
msgstr[0] "برای %d ثانیه"
msgstr[1] "برای %d ثانیه ها"
msgstr[0] "برای ۱ ثانیه"
msgstr[1] "برای %dI ثانیه"
#: plugins/trayicon
msgid "Next break at %s"
@ -465,7 +466,7 @@ msgstr "استراحت بعدی در %s"
#: plugins/trayicon
msgid "No Breaks Available"
msgstr "هیچ وقفه ای موجود نیست"
msgstr "هیچ استراحتی موجود نیست"
#: plugins/trayicon
msgid "Settings"
@ -473,23 +474,23 @@ msgstr "تنظیمات"
#: plugins/trayicon
msgid "Take a break now"
msgstr "کمی استراحت کن"
msgstr "اکنون استراحت کنید"
#: plugins/trayicon
msgid "Until restart"
msgstr "تا راه اندازی مجدد"
msgstr "تا آغاز دوباره"
#: plugins/trayicon
msgid "Quit"
msgstr "ترک کن"
msgstr "خروج"
# plugin/mediacontrol
msgid "Media Control"
msgstr "کنترل رسانه"
msgstr "واپایش رسانه"
# plugin/mediacontrol
msgid "Pause media players from the break screen"
msgstr "توقف پخش کننده رسانه در توقف صفحه"
msgstr "مکث پخش‌کننده‌های رسانه در صفحهٔ استراحت"
# plugin/mediacontrol
msgid "Pause media"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-02-10 15:50+0000\n"
"PO-Revision-Date: 2022-01-11 15:55+0000\n"
"Last-Translator: AO Localisation Lab <ao@localizationlab.org>\n"
"Language-Team: French <https://hosted.weblate.org/projects/safe-eyes/"
"translations/fr/>\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-dev\n"
"X-Generator: Weblate 4.10.1\n"
# Short break
msgid "Tightly close your eyes"
@ -59,7 +59,7 @@ msgstr "afficher la boîte de dialogue À propos"
# Commandline arg description
msgid "disable the currently running safeeyes instance"
msgstr "désactiver linstance de safeyes en cours"
msgstr "désactiver linstance de safeeyes en cours"
# Commandline arg description
msgid "enable the currently running safeeyes instance"
@ -67,7 +67,7 @@ msgstr "activer linstance de safeyes en cours"
# Commandline arg description
msgid "quit the running safeeyes instance and exit"
msgstr "fermer linstance de safeyes en cours et sortir"
msgstr "fermer linstance de safeyes en cours et fermer"
# Commandline arg description
msgid "show the settings dialog"
@ -79,7 +79,7 @@ msgstr "démarrer safeeyes en mode de débogage"
# Commandline arg description
msgid "print the status of running safeeyes instance and exit"
msgstr "imprimer létat de linstance safeeyes en cours et sortir"
msgstr "imprimer létat de linstance safeeyes en cours et fermer"
# Status message
msgid "Safe Eyes is not running"
@ -103,7 +103,7 @@ 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 protège vos yeux contre la fatigue de l'œil (asthénopie) en vous "
"Safe Eyes protège vos yeux contre la fatigue de lœil (asthénopie) en vous "
"rappelant de prendre des pauses lors de vos longues heures de travail sur un "
"ordinateur"
@ -203,7 +203,7 @@ msgstr "Voulez-vous vraiment supprimer cette pause?"
# Settings dialog
msgid "You can't undo this action."
msgstr "Vous ne pouvez-pas annuler cette action."
msgstr "Vous ne pouvez pas annuler cette action."
# Settings dialog
msgid "Break"
@ -235,11 +235,11 @@ msgstr "Image"
# Settings dialog
msgid "Select"
msgstr "Choisir"
msgstr "Sélectionner"
# Settings dialog
msgid "Please select an image"
msgstr "Veuillez choisir une image"
msgstr "Veuillez sélectionner une image"
# Settings dialog
msgid "Duration"
@ -352,7 +352,7 @@ msgstr "Statistiques de santé"
# plugin/healthstats
msgid "Show statistics based on how you use Safe Eyes"
msgstr "Afficher des statistiques basées sur votre utilisation de Safe Eyes"
msgstr "Afficher des statistiques daprès votre utilisation de Safe Eyes"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
@ -376,7 +376,7 @@ msgstr "Préparez-vous à une pause longue dans %s secondes"
# plugin/screensaver
msgid "Screensaver"
msgstr "Économiseur d'écran"
msgstr "Économiseur décran"
# plugin/screensaver
msgid "Lock the screen after long breaks by starting screensaver"
@ -407,7 +407,7 @@ msgstr "Mettre Safe Eyes en pause si le système est inactif"
# plugin/smartpause
msgid "Minimum idle time to pause Safe Eyes (in seconds)"
msgstr ""
"Durée d'inactivité minimale pour mettre Safe Eyes en pause (en secondes)"
"Durée dinactivité minimale pour mettre Safe Eyes en pause (en secondes)"
# plugin/smartpause
msgid "Interpret idle time equivalent to upcoming break duration as a break"
@ -479,7 +479,7 @@ msgstr "Prochaine pause à %s"
#: plugins/trayicon
msgid "No Breaks Available"
msgstr "Aucune pause n'est prévue"
msgstr "Aucune pause n'est proposée"
#: plugins/trayicon
msgid "Settings"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2020-10-13 15:27+0000\n"
"PO-Revision-Date: 2021-05-23 09:32+0000\n"
"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/safe-eyes/"
"translations/he/>\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.3-dev\n"
"X-Generator: Weblate 4.7-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -138,7 +138,7 @@ msgstr "משך עיכוב (בשניות)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "להציג הפסקות בסדר אקראי"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
@ -274,7 +274,7 @@ msgstr "נא להתקין את כלי שורת הפקודה %s"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "ביטוי cron שגוי %s"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -346,7 +346,7 @@ msgstr "להציג סטטיסטיקה על אופן השימוש שלך בהגנ
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "הפרשים בין איפוסי סטטיסטיקה (ביטוי cron)"
# plugin/notification
msgid "Notification"

View File

@ -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: bortox <broto777@zoho.com>\n"
"PO-Revision-Date: 2022-01-16 12:55+0000\n"
"Last-Translator: albanobattistella <albano_battistella@hotmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/safe-eyes/"
"translations/it/>\n"
"Language: it\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\n"
"X-Generator: Weblate 4.10.1\n"
# Short break
msgid "Tightly close your eyes"
@ -90,8 +90,8 @@ msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr ""
"Safe Eyes funziona senza un server RPC. Attivalo per utilizzare gli "
"argomenti della riga di comando."
"Safe Eyes è in esecuzione senza un server RPC. Apri Safe Eyes per utilizzare "
"la linea di comando."
# About dialog
msgid "Close"
@ -388,7 +388,7 @@ msgstr "Tempo minimo per il salto senza salvaschermo (in secondi)"
# plugin/screensaver
msgid "Lock screen"
msgstr "Schermo bloccato"
msgstr "Blocca schermo"
# plugin/smartpause
msgid "Smart Pause"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2020-12-23 11:29+0000\n"
"PO-Revision-Date: 2021-07-30 17:35+0000\n"
"Last-Translator: Yogesh <yogesh@karnatakaeducation.org.in>\n"
"Language-Team: Kannada <https://hosted.weblate.org/projects/safe-eyes/"
"translations/kn/>\n"
@ -15,11 +15,11 @@ 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.4.1-dev\n"
"X-Generator: Weblate 4.7.2-dev\n"
# Short break
msgid "Tightly close your eyes"
msgstr ""
msgstr "ಕಣ್ಣನ್ನು ಗಟ್ಟಿಯಾಗಿ ಮುಚ್ಚಿರಿ"
# Short break
msgid "Roll your eyes a few times to each side"
@ -35,7 +35,7 @@ msgstr ""
# Short break
msgid "Blink your eyes"
msgstr ""
msgstr "ಕಣ್ಣನ್ನು ಮಿಟುಕಿಸಿ"
# Short break
msgid "Focus on a point in the far distance"
@ -43,35 +43,35 @@ msgstr ""
# Short break
msgid "Have some water"
msgstr ""
msgstr "ಸ್ವಲ್ಪ ನೀರನ್ನು ಕುಡಿಯಿರಿ"
# Long break
msgid "Walk for a while"
msgstr ""
msgstr "ಕೆಲ ಸಮಯ ನಡೆದಾಡಿ"
# Long break
msgid "Lean back at your seat and relax"
msgstr ""
msgstr "ನಿಮ್ಮ ಆಸನದ ಹಿಂಬದಿಗೆ ಹೊರಗಿ ವಿಶ್ರಮಿಸಿ"
# Commandline arg description
msgid "show the about dialog"
msgstr ""
msgstr "ಇದರ ಬಗ್ಗೆ ತೋರಿಸು"
# Commandline arg description
msgid "disable the currently running safeeyes instance"
msgstr ""
msgstr "ನೆಡುಯುತ್ತಿರುವ ಸೇಫ್‌ಐಸ್ಅನ್ನು ನಿಶ್ಕ್ರಿಯ ಗೊಳಿಸು"
# Commandline arg description
msgid "enable the currently running safeeyes instance"
msgstr ""
msgstr "ನೆಡುಯುತ್ತಿರುವ ಸೇಫ್‌ಐಸ್ಅನ್ನು ಸಕ್ರಿಯ ಗೊಳಿಸು"
# Commandline arg description
msgid "quit the running safeeyes instance and exit"
msgstr ""
msgstr "ನೆಡುಯುತ್ತಿರುವ ಸೇಫ್‌ಐಸ್ಅನ್ನು ತ್ಯಜಿಸು"
# Commandline arg description
msgid "show the settings dialog"
msgstr ""
msgstr "ಸಿದ್ಧತೆಗಳನ್ನು ತೋರಿಸು"
# Commandline arg description
msgid "start safeeyes in debug mode"
@ -83,7 +83,7 @@ msgstr "ಚಾಲನೆಯಲ್ಲಿರುವ ಸೇಫ್ಐಸ್ ಸ್ಥ
# Status message
msgid "Safe Eyes is not running"
msgstr ""
msgstr "ಸೇಫ್‌ಐಸ್ ನೆಡುಯುತ್ತಿಲ್ಲ"
# RPC not enabled message
msgid ""
@ -95,7 +95,7 @@ msgstr ""
# About dialog
msgid "Close"
msgstr ""
msgstr "ಮುಚ್ಚಿರಿ"
# Description in about dialog
# Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you to take breaks while you're working long hours at the computer

View File

@ -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 <ironyunseok@protonmail.com>\n"
"PO-Revision-Date: 2023-02-17 05:35+0000\n"
"Last-Translator: Yi Yunseok <ironyunseok@protonmail.com>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/safe-eyes/"
"translations/ko/>\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"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-02-10 15:50+0000\n"
"PO-Revision-Date: 2021-07-30 17:35+0000\n"
"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/"
"safe-eyes/translations/nb_NO/>\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-dev\n"
"X-Generator: Weblate 4.7.2-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -163,7 +163,7 @@ msgstr "Uten RPC-tjeneren, vil ikke kommandolinje-argumenter virke"
# Settings dialog
msgid "Long break interval must be a multiple of short break interval"
msgstr "Tiden mellom lange pauser må være være en inndeling av de små pausene"
msgstr "Tiden mellom lange pauser må være en inndeling av de små pausene"
# Settings dialog
msgid "Reset"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2020-04-03 10:36+0000\n"
"Last-Translator: Michal Biesiada <blade-14@o2.pl>\n"
"PO-Revision-Date: 2023-10-31 16:04+0000\n"
"Last-Translator: Eryk Michalak <gnu.ewm@protonmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/safe-eyes/"
"translations/pl/>\n"
"Language: pl\n"
@ -16,7 +16,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
"X-Generator: Weblate 4.0-dev\n"
"X-Generator: Weblate 5.2-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -141,7 +141,7 @@ msgstr "Czas przełożenia (w minutach)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "Wyświetlaj przerwy w losowej kolejności"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
@ -169,11 +169,11 @@ msgstr "Długa przerwa musi być poprzedzona kilkoma krótkimi"
# Settings dialog
msgid "Reset"
msgstr "Zresetuj ustawienia"
msgstr "Resetuj"
# Settings dialog
msgid "Are you sure you want to reset all settings to default?"
msgstr "Czy jesteś pewien, że chcesz przywrócić ustawienia domyślne?"
msgstr "Czy chcesz przywrócić ustawienia domyślne?"
# Settings dialog
msgid "Options"
@ -193,11 +193,11 @@ msgstr "Usuń"
# Settings dialog
msgid "Are you sure you want to delete this break?"
msgstr "Czy jesteś pewien, że chcesz usunąć tę przerwę?"
msgstr "Czy na pewno chcesz usunąć tę przerwę?"
# Settings dialog
msgid "You can't undo this action."
msgstr "Nie możesz cofnąć tej akcji."
msgstr "Nie można cofnąć tej operacji."
# Settings dialog
msgid "Break"
@ -277,7 +277,7 @@ msgstr "Proszę zainstalować wiersz poleceń '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "Nieprawidłowe wyrażenie cron '%s'"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -349,7 +349,7 @@ msgstr "Pokaż statystyki oparte o Safe Eyes"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "Okres resetowania statystyk (wyrażenie cron)"
# plugin/notification
msgid "Notification"
@ -480,7 +480,7 @@ msgstr "Ustawienia"
#: plugins/trayicon
msgid "Take a break now"
msgstr "Przerwa"
msgstr "Zrób sobie teraz przerwę"
#: plugins/trayicon
msgid "Until restart"

View File

@ -6,17 +6,17 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-03-11 12:02+0000\n"
"Last-Translator: Dmitriy Q <krotesk@mail.ru>\n"
"PO-Revision-Date: 2023-11-26 00:02+0000\n"
"Last-Translator: Almaz Mannanov <AlmazWorks@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/safe-eyes/"
"translations/ru/>\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"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.5.2-dev\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 5.2.1-rc\n"
# Short break
msgid "Tightly close your eyes"
@ -56,15 +56,15 @@ msgstr "Откиньтесь на спинку стула и расслабьт
# Commandline arg description
msgid "show the about dialog"
msgstr "О программе"
msgstr "показать окно \"о программе\""
# Commandline arg description
msgid "disable the currently running safeeyes instance"
msgstr "Отключить Safe Eyes"
msgstr "отключить текущий запущенный экземпляр Safe Eyes"
# Commandline arg description
msgid "enable the currently running safeeyes instance"
msgstr "Активировать Safe Eyes"
msgstr "активировать текущий запущенный экземпляр Safe Eyes"
# Commandline arg description
msgid "quit the running safeeyes instance and exit"
@ -72,7 +72,7 @@ msgstr "Закрыть Safe Eyes и выйти"
# Commandline arg description
msgid "show the settings dialog"
msgstr "Настройки"
msgstr "показать окно настроек"
# Commandline arg description
msgid "start safeeyes in debug mode"
@ -91,8 +91,8 @@ msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr ""
"Safe Eyes работает без RPC-сервера. Включите его чтобы использовать "
"аргументы командной строки."
"Программа Safe Eyes запущена без RPC сервера. Для использования аргументов "
"командной строки запустите RPC сервер."
# About dialog
msgid "Close"
@ -103,7 +103,9 @@ msgstr "Закрыть"
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 "Описание"
msgstr ""
"Safe Eyes защищает ваши глаза от перенапряжения (астенопии), напоминая о "
"необходимости сделать перерыв во время долгих часов за ПК"
# About dialog
msgid "License"
@ -143,7 +145,7 @@ msgstr "Показывать перерывы в случайном порядк
# Settings dialog
msgid "Strict break (No way to skip breaks)"
msgstr "Обязательный перерыв (Невозможно отменить перерывы)"
msgstr "Обязательный перерыв (без возможности пропуска)"
# Settings dialog
msgid "Allow postponing breaks"
@ -155,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"
@ -232,7 +234,7 @@ msgstr "Выбрать"
# Settings dialog
msgid "Please select an image"
msgstr "Пожалуйста выберите изображение"
msgstr "Пожалуйста, выберите изображение"
# Settings dialog
msgid "Duration"
@ -268,11 +270,11 @@ msgstr "Дополнение не поддерживает окружение р
# Settings dialog
msgid "Please install the Python module '%s'"
msgstr "Пожалуйста установите модуль Python: %s"
msgstr "Пожалуйста, установите модуль Python: %s"
# Settings dialog
msgid "Please install the command-line tool '%s'"
msgstr "Пожалуйста установите инструмент командной строки '%s'"
msgstr "Пожалуйста, установите инструмент командной строки '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
@ -280,7 +282,7 @@ msgstr "Недопустимое выражение cron '%s'"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
msgstr "Пожалуйста добавьте источник %(resource)s в папку %(config_resource)"
msgstr "Пожалуйста, добавьте источник %(resource)s в папку %(config_resource)"
# Settings dialog
msgid "New Break"
@ -288,7 +290,7 @@ msgstr "Новый перерыв"
# Settings dialog
msgid "Remove"
msgstr "Удалить"
msgstr "Стереть"
# Settings dialog
msgid "Discard"
@ -320,7 +322,7 @@ msgstr "Не беспокоить"
# plugin/donotdisturb
msgid "Skip break if the active window is in fullscreen mode"
msgstr "Пропустить перерыв, если активое окно в полнооконном режиме"
msgstr "Пропустить перерыв, если активное окно в полноэкранном режиме"
# plugin/donotdisturb
msgid "Do not interrupt these windows anytime"
@ -336,7 +338,7 @@ msgstr "Переключать прерываемые окна в нормаль
# plugin/donotdisturb
msgid "Do not disturb while on battery"
msgstr "Не прерывать на автономном питании"
msgstr "Не беспокоить при работе от батареи"
# plugin/healthstats
msgid "Health Statistics"
@ -344,7 +346,7 @@ msgstr "Статистика здоровья"
# plugin/healthstats
msgid "Show statistics based on how you use Safe Eyes"
msgstr "Показывать статистику основанную на использовании Safe Eyes"
msgstr "Показывать статистику, основанную на использовании Safe Eyes"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
@ -401,8 +403,8 @@ msgstr "Минимальное время простоя для приостан
# plugin/smartpause
msgid "Interpret idle time equivalent to upcoming break duration as a break"
msgstr ""
"Интерпретировать время простоя равное продолжительности предстоящего "
"перерыва как перерыв"
"Интерпретировать время простоя, равное продолжительности предстоящего "
"перерыва, как перерыв"
# plugin/smartpause
msgid "Postpone the next break until the system becomes idle"
@ -422,7 +424,7 @@ msgstr "Показывать время до следующего перерыв
#: plugins/trayicon
msgid "Allow disabling Safe Eyes"
msgstr "Разрешить запрет Safe Eyes"
msgstr "Разрешить выключение Safe Eyes"
#: plugins/trayicon
msgid "About"

View File

@ -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 ""

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2019-02-17 23:26+0000\n"
"Last-Translator: Jose Riha <jose1711@gmail.com>\n"
"PO-Revision-Date: 2023-08-10 19:53+0000\n"
"Last-Translator: Milan Šalka <salka.milan@googlemail.com>\n"
"Language-Team: Slovak <https://hosted.weblate.org/projects/safe-eyes/"
"translations/sk/>\n"
"Language: sk\n"
@ -15,7 +15,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
"X-Generator: Weblate 3.5-dev\n"
"X-Generator: Weblate 5.0-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -90,6 +90,8 @@ msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr ""
"Safe Eyes je spustený bez RPC serveru. Zapnite ho pre použitie argumentov v "
"príkazovom riadku."
# About dialog
msgid "Close"
@ -103,7 +105,7 @@ msgid ""
msgstr ""
"Safe Eyes vám pripomenie, aby ste si urobili prestávku počas dlhých hodín "
"stravených za počítačom. Chráni tak vaše oči pred prílišným namáhaním "
"(asthenopiou)."
"(asthenopiou)"
# About dialog
msgid "License"
@ -139,7 +141,7 @@ msgstr "Odložiť o (v minútach)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "Ukazovať prestávky v náhodnom poradí"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
@ -155,11 +157,11 @@ msgstr "Zachovať vnútorný stav"
# Settings dialog
msgid "Use RPC server to receive runtime commands"
msgstr ""
msgstr "Použiť RPC server na prijatie spúšťacích príkazov"
# Settings dialog
msgid "Without the RPC server, command-line commands may not work"
msgstr ""
msgstr "Bez RPC serveru príkazy v príkazovom riadku nemusia fungovať"
# Settings dialog
msgid "Long break interval must be a multiple of short break interval"
@ -275,7 +277,7 @@ msgstr "Prosím nainštalujte si nástroj '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "Neplatný výraz pre cron '%s'"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -347,7 +349,7 @@ msgstr "Zobraziť štatistiky o tom, ako používate Safe Eyes"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "Interval vynulovania štatistík (výraz pre plánovač cron)"
# plugin/notification
msgid "Notification"
@ -403,7 +405,7 @@ msgstr "Započítaj čas, kedy počítač nie je používaný, do prestávky"
# plugin/smartpause
msgid "Postpone the next break until the system becomes idle"
msgstr ""
msgstr "Odložiť ďalšiu prestávku až dokiaľ bude systém nečinný"
#: plugins/trayicon
msgid "Tray Icon"
@ -419,7 +421,7 @@ msgstr "Zobraziť čas nasledujúcej prestávku v ikone"
#: plugins/trayicon
msgid "Allow disabling Safe Eyes"
msgstr ""
msgstr "Povoliť vypnutie Safe Eyes"
#: plugins/trayicon
msgid "About"
@ -488,12 +490,12 @@ msgstr "Koniec"
# plugin/mediacontrol
msgid "Media Control"
msgstr ""
msgstr "Ovládanie médií"
# plugin/mediacontrol
msgid "Pause media players from the break screen"
msgstr ""
msgstr "Pozastaviť prehrávače médií z obrazovky prestávky"
# plugin/mediacontrol
msgid "Pause media"
msgstr ""
msgstr "Pozastaviť média"

View File

@ -6,94 +6,97 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"PO-Revision-Date: 2023-10-13 04:15+0000\n"
"Last-Translator: Novak Urosevic <novak_urosevic@yahoo.com>\n"
"Language-Team: Serbian <https://hosted.weblate.org/projects/safe-eyes/"
"translations/sr/>\n"
"Language: sr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.3\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\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 5.1-dev\n"
# Short break
msgid "Tightly close your eyes"
msgstr ""
msgstr "Чврсто затворите очи"
# Short break
msgid "Roll your eyes a few times to each side"
msgstr ""
msgstr "Колутајте очима „исцртавајући“ број 8 неколико пута"
# Short break
msgid "Rotate your eyes in clockwise direction"
msgstr ""
msgstr "Колутајте очи у круг у смеру казаљке на сату"
# Short break
msgid "Rotate your eyes in counterclockwise direction"
msgstr ""
msgstr "Колутајте очи у круг у смеру супротном од казаљке на сату"
# Short break
msgid "Blink your eyes"
msgstr ""
msgstr "Трепћите очима"
# Short break
msgid "Focus on a point in the far distance"
msgstr ""
msgstr "Усмерите поглед на тачку у даљини"
# Short break
msgid "Have some water"
msgstr ""
msgstr "Попијте воду"
# Long break
msgid "Walk for a while"
msgstr ""
msgstr "Протегните се"
# Long break
msgid "Lean back at your seat and relax"
msgstr ""
msgstr "Завалите се у фотељу и опустите се"
# Commandline arg description
msgid "show the about dialog"
msgstr ""
msgstr "Прикажи о нама прозор"
# Commandline arg description
msgid "disable the currently running safeeyes instance"
msgstr ""
msgstr "Онемогућите тренутну сесију safeeyes-a"
# Commandline arg description
msgid "enable the currently running safeeyes instance"
msgstr ""
msgstr "Омогућите тренутну сесију safeeyes-a"
# Commandline arg description
msgid "quit the running safeeyes instance and exit"
msgstr ""
msgstr "Искључите тренутну сесију safeeyes-а и затворите програм"
# Commandline arg description
msgid "show the settings dialog"
msgstr ""
msgstr "Прикажи прозор са подешавањима"
# Commandline arg description
msgid "start safeeyes in debug mode"
msgstr ""
msgstr "Покрените safeeyes у режиму за исправљање грешака"
# Commandline arg description
msgid "print the status of running safeeyes instance and exit"
msgstr ""
msgstr "Одштампајте статус тренутне сесије safeeyes-a и напустите"
# Status message
msgid "Safe Eyes is not running"
msgstr ""
msgstr "Safe Eyes није укључен"
# RPC not enabled message
msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr ""
"Safe Eyes ради без RPC (Remote Procedure Call) сервера. Укључите га како "
"бисте користили командне-линије."
# About dialog
msgid "Close"
msgstr ""
msgstr "Затворите"
# Description in about dialog
# Safe Eyes protects your eyes from eye strain (asthenopia) by reminding you to take breaks while you're working long hours at the computer
@ -101,396 +104,405 @@ 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 штити Ваше очи од напрезања (astenopija) подсећајући Вас да "
"правите паузе током вишесатне употребе компјутера"
# About dialog
msgid "License"
msgstr ""
msgstr "Лиценца"
# Break screen
msgid "Skip"
msgstr ""
msgstr "Прескочите"
# Break screen
msgid "Postpone"
msgstr ""
msgstr "Одложите"
# Settings dialog
msgid "Break duration (in seconds)"
msgstr ""
msgstr "Време трајања паузе (у секундама)"
# Settings dialog
msgid "Interval between two breaks (in minutes)"
msgstr ""
msgstr "Временски период између две паузе (у минутима)"
# Settings dialog
msgid "Time to prepare for a break (in seconds)"
msgstr ""
msgstr "Време припреме за паузу (у секундама)"
# Settings dialog
msgid "Keyboard shortcuts disabled period (in seconds)"
msgstr ""
msgstr "Временски период искључења пречица тастатуре (у секундама)"
# Settings dialog
msgid "Postponement duration (in minutes)"
msgstr ""
msgstr "Дужина трајања Одлагања (у минутима)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "Прикажите паузе насумичним редоследом"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
msgstr ""
msgstr "Обавезна пауза (без могућности одлагања пауза)"
# Settings dialog
msgid "Allow postponing breaks"
msgstr ""
msgstr "Дозволи одлагање пауза"
# Settings dialog
msgid "Persist the internal state"
msgstr ""
msgstr "Задржи интерни статус"
# Settings dialog
msgid "Use RPC server to receive runtime commands"
msgstr ""
msgstr "Користите RPC сервер како бисте примили runtime команде"
# Settings dialog
msgid "Without the RPC server, command-line commands may not work"
msgstr ""
msgstr "Без RPC сервера, унос путем командних-линија можда неће бити успешан"
# Settings dialog
msgid "Long break interval must be a multiple of short break interval"
msgstr ""
"Интервали између дугих пауза морају бити неколико пута дужи од интервала "
"између кратких пауза"
# Settings dialog
msgid "Reset"
msgstr ""
msgstr "Поново покрените"
# Settings dialog
msgid "Are you sure you want to reset all settings to default?"
msgstr ""
"Да ли сигурно желите да вратите сва подешавања на подразумевана подешавања?"
# Settings dialog
msgid "Options"
msgstr ""
msgstr "Опције"
# Settings dialog
msgid "Short Breaks"
msgstr ""
msgstr "Кратке Паузе"
# Settings dialog
msgid "Long Breaks"
msgstr ""
msgstr "Дуге Паузе"
# Settings dialog
msgid "Delete"
msgstr ""
msgstr "Обришите"
# Settings dialog
msgid "Are you sure you want to delete this break?"
msgstr ""
msgstr "Да ли сигурно желите да обришете ову паузу?"
# Settings dialog
msgid "You can't undo this action."
msgstr ""
msgstr "Не можете опозвати радњу."
# Settings dialog
msgid "Break"
msgstr ""
msgstr "Пауза"
# Settings dialog
msgid "Breaks"
msgstr ""
msgstr "Паузе"
# Settings dialog
msgid "Plugins"
msgstr ""
msgstr "Додаци"
# Settings dialog
msgid "Type"
msgstr ""
msgstr "Укуцајте"
# Settings dialog
msgid "Short"
msgstr ""
msgstr "Кратка"
# Settings dialog
msgid "Long"
msgstr ""
msgstr "Дуга"
# Settings dialog
msgid "Image"
msgstr ""
msgstr "Слика"
# Settings dialog
msgid "Select"
msgstr ""
msgstr "Изаберите"
# Settings dialog
msgid "Please select an image"
msgstr ""
msgstr "Молимо Вас изаберите слику"
# Settings dialog
msgid "Duration"
msgstr ""
msgstr "Дужина трајања"
# Settings dialog
msgid "Time to wait"
msgstr ""
msgstr "Време чекања"
# Settings dialog
msgid "Override"
msgstr ""
msgstr "Преписати"
# Settings dialog
msgid "Time (in seconds)"
msgstr ""
msgstr "Време (у секундама)"
# Settings dialog
msgid "Time (in minutes)"
msgstr ""
msgstr "Време (у минутима)"
# Settings dialog
msgid "Break Settings"
msgstr ""
msgstr "Подешавање паузе"
# Settings dialog
msgid "Plugin Settings"
msgstr ""
msgstr "Подешавање додатака"
# Settings dialog
msgid "Plugin does not support %s desktop environment"
msgstr ""
msgstr "Додатак не подржава % радну површину"
# Settings dialog
msgid "Please install the Python module '%s'"
msgstr ""
msgstr "Молимо Вас, преузмите модул '%s' за Пајтон"
# Settings dialog
msgid "Please install the command-line tool '%s'"
msgstr ""
msgstr "Молимо Вас, преузмите алатку командне-линије '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "Неправилан формат за извршавање cron посла '%s'"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
msgstr ""
"Молимо Вас, додајте ресурс %(resource)s у %(config_resource)s директоријум"
# Settings dialog
msgid "New Break"
msgstr ""
msgstr "Нова Пауза"
# Settings dialog
msgid "Remove"
msgstr ""
msgstr "Уклоните"
# Settings dialog
msgid "Discard"
msgstr ""
msgstr "Одбаците"
# Settings dialog
msgid "Save"
msgstr ""
msgstr "Сачувајте"
# plugin/audiblealert
msgid "Audible Alert"
msgstr ""
msgstr "Звучно Обавештење"
# plugin/audiblealert
msgid "Play audible alert before and after breaks"
msgstr ""
msgstr "Пустите звучно обавештење пре и после пауза"
# plugin/audiblealert
msgid "Play audible alert before breaks"
msgstr ""
msgstr "Пустите звучно обавештење пре пауза"
# plugin/audiblealert
msgid "Play audible alert after breaks"
msgstr ""
msgstr "Пустите звучно овавештење након пауза"
# plugin/donotdisturb
msgid "Do Not Disturb"
msgstr ""
msgstr "Не Узнемиравај"
# plugin/donotdisturb
msgid "Skip break if the active window is in fullscreen mode"
msgstr ""
msgstr "Прескочите паузу уколико је тренутни радни прозор у пуном екрану"
# plugin/donotdisturb
msgid "Do not interrupt these windows anytime"
msgstr ""
msgstr "Никада не ометајте ове радне прозоре"
# plugin/donotdisturb
msgid "Interrupt these windows regardless of their state"
msgstr ""
msgstr "Ометајте ове радне прозоре без обзира на њихово стање"
# plugin/donotdisturb
msgid "Switch the interruptible windows to normal mode"
msgstr ""
msgstr "Промените променљив радни прозор у нормалан режим"
# plugin/donotdisturb
msgid "Do not disturb while on battery"
msgstr ""
msgstr "Не Узнемиравај док компјутер ради са батерије"
# plugin/healthstats
msgid "Health Statistics"
msgstr ""
msgstr "Здравствена статистика"
# plugin/healthstats
msgid "Show statistics based on how you use Safe Eyes"
msgstr ""
msgstr "Покажи статистику на основу Ваше употребе Safe Eyes-a"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "Интервал ресетовања Података (cron послова)"
# plugin/notification
msgid "Notification"
msgstr ""
msgstr "Обавештење"
# plugin/notification
msgid "Show a system notification before breaks"
msgstr ""
msgstr "Покажите системско обавештење пре почетка пауза"
# plugin/notification
msgid "Ready for a short break in %s seconds"
msgstr ""
msgstr "Спремите се за кратку паузу у року од %s секунди"
# plugin/notification
msgid "Ready for a long break in %s seconds"
msgstr ""
msgstr "Спремите се за дугу паузу у року од %s секунди"
# plugin/screensaver
msgid "Screensaver"
msgstr ""
msgstr "Чувар екрана"
# plugin/screensaver
msgid "Lock the screen after long breaks by starting screensaver"
msgstr ""
"Закључајте екран за време дугих паузи тако што ћете укључити чувар екрана"
# plugin/screensaver
msgid "Custom screensaver command"
msgstr ""
msgstr "Команда за чувар екрана по жељи"
# plugin/screensaver
msgid "Minimum seconds to skip without screensaver"
msgstr ""
msgstr "Најмањи број секунди за прескакање без чувара екрана"
# plugin/screensaver
msgid "Lock screen"
msgstr ""
msgstr "Закључајте екран"
# plugin/smartpause
msgid "Smart Pause"
msgstr ""
msgstr "Паметна Пауза"
# plugin/smartpause
msgid "Pause Safe Eyes if the system is idle"
msgstr ""
msgstr "Зауставите Safe-Eyes уколико систем мирује"
# plugin/smartpause
msgid "Minimum idle time to pause Safe Eyes (in seconds)"
msgstr ""
"Најкраћи временски период потребан за заустављање Safe Eyes-a (у секундама)"
# plugin/smartpause
msgid "Interpret idle time equivalent to upcoming break duration as a break"
msgstr ""
"Протумачите време мировања еквивалентно трајању предстојеће паузе као паузу"
# plugin/smartpause
msgid "Postpone the next break until the system becomes idle"
msgstr ""
msgstr "Одложите наредну паузу док систем не постане неактиван"
#: plugins/trayicon
msgid "Tray Icon"
msgstr ""
msgstr "Иконица на панелу"
#: plugins/trayicon
msgid "Show a tray icon in the notification area"
msgstr ""
msgstr "Покажите иконицу на панелу у Обавештењима"
#: plugins/trayicon
msgid "Show next break time in tray icon"
msgstr ""
msgstr "Покажите време следеће паузе на иконици на панелу"
#: plugins/trayicon
msgid "Allow disabling Safe Eyes"
msgstr ""
msgstr "Дозволи онемогућавање Safe Eyes-a"
#: plugins/trayicon
msgid "About"
msgstr ""
msgstr "О програму"
#: plugins/trayicon
msgid "Disable Safe Eyes"
msgstr ""
msgstr "Онемогући Safe Eyes"
#: plugins/trayicon
msgid "Disabled until %s"
msgstr ""
msgstr "Онемогућено до %s"
#: plugins/trayicon
msgid "Disabled until restart"
msgstr ""
msgstr "Онемогућено до ресетовања"
#: plugins/trayicon
msgid "Enable Safe Eyes"
msgstr ""
msgstr "Омогући Safe Eyes"
#: plugins/trayicon
msgid "For %d Hour"
msgid_plural "For %d Hours"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[0] "сат"
msgstr[1] "сати"
msgstr[2] "сати"
#: plugins/trayicon
msgid "For %d Minute"
msgid_plural "For %d Minutes"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[0] "минут"
msgstr[1] "минута"
msgstr[2] "минута"
#: plugins/trayicon
msgid "For %d Second"
msgid_plural "For %d Seconds"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[0] "секунда"
msgstr[1] "секунде"
msgstr[2] "секунди"
#: plugins/trayicon
msgid "Next break at %s"
msgstr ""
msgstr "Наредна пауза је у %s"
#: plugins/trayicon
msgid "No Breaks Available"
msgstr ""
msgstr "Нема доступних Пауза"
#: plugins/trayicon
msgid "Settings"
msgstr ""
msgstr "Подешавања"
#: plugins/trayicon
msgid "Take a break now"
msgstr ""
msgstr "Сада направи паузу"
#: plugins/trayicon
msgid "Until restart"
msgstr ""
msgstr "До ресетовања"
#: plugins/trayicon
msgid "Quit"
msgstr ""
msgstr "Изађите"
# plugin/mediacontrol
msgid "Media Control"
msgstr ""
msgstr "Контрола медија"
# plugin/mediacontrol
msgid "Pause media players from the break screen"
msgstr ""
msgstr "Зауставите рад медијских плејера са екрана Паузе"
# plugin/mediacontrol
msgid "Pause media"
msgstr ""
msgstr "Паузирај медије"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2020-09-28 07:40+0000\n"
"Last-Translator: Mattias Münster <mattiasmun@gmail.com>\n"
"PO-Revision-Date: 2023-02-11 11:39+0000\n"
"Last-Translator: Luna Jernberg <droidbittin@gmail.com>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/safe-eyes/"
"translations/sv/>\n"
"Language: sv\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.3-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)"
@ -275,7 +275,7 @@ msgstr "Installera kommandoradsverktyget '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "Ogiltigt cron uttryck '%s'"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -347,7 +347,7 @@ msgstr "Visa statistik baserat på hur du använder Safe Eyes"
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "Återställningsintervall för statistik (cron-uttryck)"
# plugin/notification
msgid "Notification"

View File

@ -6,17 +6,17 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-01-27 09:32+0000\n"
"Last-Translator: Dmitriy Q <krotesk@mail.ru>\n"
"PO-Revision-Date: 2024-02-15 13:01+0000\n"
"Last-Translator: Сергій <sergiy.goncharuk.1@gmail.com>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/safe-eyes/"
"translations/uk/>\n"
"Language: uk\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"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.5-dev\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 5.4-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -48,7 +48,7 @@ msgstr "Випийте води"
# Long break
msgid "Walk for a while"
msgstr "Трохи походіть"
msgstr "Прогуляйтесь"
# Long break
msgid "Lean back at your seat and relax"
@ -139,7 +139,7 @@ msgstr "Тривалість відкладення (в хвилинах)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "Показувати перерви у випадковому порядку"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
@ -196,7 +196,7 @@ msgstr "Ви упевнені, що хочете видалити цю пере
# Settings dialog
msgid "You can't undo this action."
msgstr "Цю дію неможливо відмінити."
msgstr "Цю дію неможливо скасувати."
# Settings dialog
msgid "Break"
@ -275,9 +275,8 @@ msgid "Please install the command-line tool '%s'"
msgstr "Будь ласка, встановіть засіб вказівкового рядка «%s»"
# Settings dialog
#, fuzzy
msgid "Invalid cron expression '%s'"
msgstr "Неприпустимий вираз cron '% s'"
msgstr "Неприпустимий вираз cron '%s'"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -290,7 +289,7 @@ msgstr "Нова перерва"
# Settings dialog
msgid "Remove"
msgstr "Видалити"
msgstr "Вилучити"
# Settings dialog
msgid "Discard"
@ -351,7 +350,7 @@ msgstr "Показувати статистику на основі викори
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "Інтервал скидання статистики (вираз cron)"
# plugin/notification
msgid "Notification"

View File

@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2018-08-26 03:45+0000\n"
"Last-Translator: Hoàng Trần <hoangtk102@gmail.com>\n"
"PO-Revision-Date: 2022-11-26 23:54+0000\n"
"Last-Translator: Minh P <phandinhminh@protonmail.ch>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/safe-eyes/"
"translations/vi/>\n"
"Language: vi\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 3.2-dev\n"
"X-Generator: Weblate 4.15-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -79,7 +79,7 @@ msgstr "Chạy Safe Eyes trong chế độ gỡ rối"
# Commandline arg description
msgid "print the status of running safeeyes instance and exit"
msgstr ""
msgstr "in trạng thái chạy phiên bản Safe Eyes và thoát"
# Status message
msgid "Safe Eyes is not running"
@ -90,6 +90,8 @@ msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr ""
"Safe Eyes đang chạy mà không có máy chủ RPC. Bạn hãy bật nó lên để sử dụng "
"tham số dòng lệnh nhé."
# About dialog
msgid "Close"
@ -139,7 +141,7 @@ msgstr "Thời gian tạm hoãn (bằng phút)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "Hiển thị theo thứ tự ngẫu nhiên"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
@ -151,15 +153,15 @@ msgstr "Cho phép tạm hoãn nghỉ ngơi"
# Settings dialog
msgid "Persist the internal state"
msgstr "Persist the internal state"
msgstr "Duy trì nội trạng thái"
# Settings dialog
msgid "Use RPC server to receive runtime commands"
msgstr ""
msgstr "Sử dụng máy chủ RPC để nhận lệnh thời gian chạy"
# Settings dialog
msgid "Without the RPC server, command-line commands may not work"
msgstr ""
msgstr "Nếu không có máy chủ RPC, các lệnh dòng lệnh có thể không hoạt động"
# Settings dialog
msgid "Long break interval must be a multiple of short break interval"
@ -167,11 +169,11 @@ msgstr "Thời gian nghỉ dài phải là bội số của thời gian nghỉ n
# Settings dialog
msgid "Reset"
msgstr ""
msgstr "Đặt lại"
# Settings dialog
msgid "Are you sure you want to reset all settings to default?"
msgstr ""
msgstr "Bạn có chắc chắn muốn đặt lại tất cả cài đặt về mặc định không?"
# Settings dialog
msgid "Options"
@ -187,15 +189,15 @@ msgstr "Nghỉ ngơi dài"
# Settings dialog
msgid "Delete"
msgstr ""
msgstr "Xóa"
# Settings dialog
msgid "Are you sure you want to delete this break?"
msgstr ""
msgstr "Bạn có chắc chắn muốn xóa thời gian nghỉ này không?"
# Settings dialog
msgid "You can't undo this action."
msgstr ""
msgstr "Bạn không thể hoàn tác hành động này."
# Settings dialog
msgid "Break"
@ -239,7 +241,7 @@ msgstr "Thời gian"
# Settings dialog
msgid "Time to wait"
msgstr ""
msgstr "Thời gian chờ"
# Settings dialog
msgid "Override"
@ -275,7 +277,7 @@ msgstr "Vui lòng cài đặt công cụ dòng lệnh (command-line tool) '%s'"
# Settings dialog
msgid "Invalid cron expression '%s'"
msgstr ""
msgstr "Biểu thức cron '%s' không hợp lệ"
# Settings dialog
msgid "Please add the resource %(resource)s to %(config_resource)s directory"
@ -303,15 +305,15 @@ msgstr "Thông báo âm thanh"
# plugin/audiblealert
msgid "Play audible alert before and after breaks"
msgstr ""
msgstr "Phát âm thanh cảnh báo trước và sau khi nghỉ giải lao"
# plugin/audiblealert
msgid "Play audible alert before breaks"
msgstr ""
msgstr "Phát âm thanh cảnh báo trước khi nghỉ giải lao"
# plugin/audiblealert
msgid "Play audible alert after breaks"
msgstr ""
msgstr "Phát âm thanh cảnh báo sau khi nghỉ giải lao"
# plugin/donotdisturb
msgid "Do Not Disturb"
@ -336,7 +338,7 @@ msgstr "Chuyển các cửa sổ có thể ngắt được sang chế độ bìn
# plugin/donotdisturb
msgid "Do not disturb while on battery"
msgstr ""
msgstr "Không làm phiền khi đang sử dụng pin"
# plugin/healthstats
msgid "Health Statistics"
@ -348,7 +350,7 @@ msgstr "Hiện thống kê dựa trên việc bạn sử dụng Safe Eyes như t
# plugin/healthstats
msgid "Statistics reset interval (cron expression)"
msgstr ""
msgstr "Khoảng thời gian đặt lại thống kê (biểu thức cron)"
# plugin/notification
msgid "Notification"
@ -384,7 +386,7 @@ msgstr "Số giây thối thiểu để bỏ qua mà không có màn hình chờ
# plugin/screensaver
msgid "Lock screen"
msgstr ""
msgstr "Khóa màn hình"
# plugin/smartpause
msgid "Smart Pause"
@ -406,7 +408,7 @@ msgstr ""
# plugin/smartpause
msgid "Postpone the next break until the system becomes idle"
msgstr ""
msgstr "Hoãn lần nghỉ tiếp theo cho đến khi hệ thống không hoạt động"
#: plugins/trayicon
msgid "Tray Icon"
@ -422,7 +424,7 @@ msgstr "Hiện thời gian nghỉ tiếp theo ở biểu tượng khay"
#: plugins/trayicon
msgid "Allow disabling Safe Eyes"
msgstr ""
msgstr "Cho phép tắt Safe Eyes"
#: plugins/trayicon
msgid "About"
@ -485,12 +487,12 @@ msgstr "Thoát"
# plugin/mediacontrol
msgid "Media Control"
msgstr ""
msgstr "Kiểm soát phương tiện"
# plugin/mediacontrol
msgid "Pause media players from the break screen"
msgstr ""
msgstr "Tạm dừng trình phát đa phương tiện từ màn hình nghỉ"
# plugin/mediacontrol
msgid "Pause media"
msgstr ""
msgstr "Tạm dừng media"

View File

@ -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: Eric <spice2wolf@gmail.com>\n"
"PO-Revision-Date: 2024-02-21 10:01+0000\n"
"Last-Translator: aerowolf <aerowolf@tom.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"safe-eyes/translations/zh_Hans/>\n"
"Language: zh_CN\n"
@ -15,23 +15,23 @@ 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.1\n"
"X-Generator: Weblate 5.5-dev\n"
# Short break
msgid "Tightly close your eyes"
msgstr "闭上您的眼睛休息一会"
msgstr "闭上眼睛休息一下"
# Short break
msgid "Roll your eyes a few times to each side"
msgstr "左右滚动您的眼珠"
msgstr "左右转动眼球"
# Short break
msgid "Rotate your eyes in clockwise direction"
msgstr "顺时针方向转动您的眼珠"
msgstr "顺时针方向转动眼球"
# Short break
msgid "Rotate your eyes in counterclockwise direction"
msgstr "逆时针方向转动您的眼珠"
msgstr "逆时针方向转动眼球"
# Short break
msgid "Blink your eyes"
@ -39,11 +39,11 @@ msgstr "眨眨眼"
# Short break
msgid "Focus on a point in the far distance"
msgstr "望远:将视线聚焦到远处物体上"
msgstr "远眺:看看尽可能远的远处"
# Short break
msgid "Have some water"
msgstr "喝点水"
msgstr "喝点水"
# Long break
msgid "Walk for a while"
@ -51,7 +51,7 @@ msgstr "站起来走走"
# Long break
msgid "Lean back at your seat and relax"
msgstr "靠在椅背上休息一"
msgstr "靠在椅背上休息一"
# Commandline arg description
msgid "show the about dialog"
@ -59,15 +59,15 @@ msgstr "显示“关于”对话框"
# Commandline arg description
msgid "disable the currently running safeeyes instance"
msgstr "禁用当前正在运行的Safe Eyes"
msgstr "暂停当前正在运行的Safe Eyes"
# Commandline arg description
msgid "enable the currently running safeeyes instance"
msgstr "启用当前正在运行的Safe Eyes"
msgstr "恢复当前正在运行的Safe Eyes"
# Commandline arg description
msgid "quit the running safeeyes instance and exit"
msgstr "退出正在运行的Safe Eeyes"
msgstr "退出Safe Eeyes"
# Commandline arg description
msgid "show the settings dialog"
@ -79,17 +79,17 @@ msgstr "以调试模式运行Safe Eyes"
# Commandline arg description
msgid "print the status of running safeeyes instance and exit"
msgstr "打印Safe Eyes运行状态后退出"
msgstr "显示Safe Eyes运行状态后退出"
# Status message
msgid "Safe Eyes is not running"
msgstr "Safe Eyes尚未运行"
msgstr "Safe Eyes 没有运行"
# RPC not enabled message
msgid ""
"Safe Eyes is running without an RPC server. Turn it on to use command-line "
"arguments."
msgstr "Safe Eyes 正在没有RPC服务器的情况下运行。打开以使用命令行参数。"
msgstr "Safe Eyes 正在没有RPC服务器的情况下运行。打开RPC服务器可以使用命令行参数。"
# About dialog
msgid "Close"
@ -106,7 +106,7 @@ msgstr ""
# About dialog
msgid "License"
msgstr "许可"
msgstr "许可"
# Break screen
msgid "Skip"
@ -142,7 +142,7 @@ msgstr "以随机顺序显示休息"
# Settings dialog
msgid "Strict break (No way to skip breaks)"
msgstr "坚持休息(无法跳过)"
msgstr "坚持休息(不允许跳过)"
# Settings dialog
msgid "Allow postponing breaks"
@ -150,7 +150,7 @@ msgstr "允许推迟休息"
# Settings dialog
msgid "Persist the internal state"
msgstr "持内部状态"
msgstr "持内部状态"
# Settings dialog
msgid "Use RPC server to receive runtime commands"
@ -414,11 +414,11 @@ msgstr "在通知区域显示托盘图标"
#: plugins/trayicon
msgid "Show next break time in tray icon"
msgstr "在托盘图标显示下次休息时间"
msgstr "在托盘图标显示下次休息时间"
#: plugins/trayicon
msgid "Allow disabling Safe Eyes"
msgstr "允许禁用Safe Eyes"
msgstr "允许暂停Safe Eyes"
#: plugins/trayicon
msgid "About"
@ -426,19 +426,19 @@ msgstr "关于"
#: plugins/trayicon
msgid "Disable Safe Eyes"
msgstr "禁用 Safe Eyes"
msgstr "暂停 Safe Eyes"
#: plugins/trayicon
msgid "Disabled until %s"
msgstr "禁用软件直到 %s"
msgstr "暂停,直到 %s"
#: plugins/trayicon
msgid "Disabled until restart"
msgstr "禁用软件直到重启"
msgstr "暂停,直到重启"
#: plugins/trayicon
msgid "Enable Safe Eyes"
msgstr "启用 Safe Eyes"
msgstr "恢复 Safe Eyes"
#: plugins/trayicon
msgid "For %d Hour"
@ -457,7 +457,7 @@ msgstr[0] "%d 秒"
#: plugins/trayicon
msgid "Next break at %s"
msgstr "下次休息在 %s"
msgstr "下次休息在 %s"
#: plugins/trayicon
msgid "No Breaks Available"

View File

@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: 2021-01-06 13:14+0000\n"
"PO-Revision-Date: 2024-01-30 14:01+0000\n"
"Last-Translator: 麋悟BigELK176 <bigelk176@gmail.com>\n"
"Language-Team: Chinese (Traditional) <https://hosted.weblate.org/projects/"
"safe-eyes/translations/zh_Hant/>\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.4.1-dev\n"
"X-Generator: Weblate 5.4-dev\n"
# Short break
msgid "Tightly close your eyes"
@ -136,7 +136,7 @@ msgstr "推遲休息時長(分鐘)"
# Settings dialog
msgid "Show breaks in random order"
msgstr ""
msgstr "顯示休息隨機順序"
# Settings dialog
msgid "Strict break (No way to skip breaks)"

View File

@ -77,6 +77,7 @@
"version": "0.0.3",
"settings": {
"show_time_in_tray": false,
"show_long_time_in_tray": false,
"allow_disabling": true,
"disable_options": [{
"time": 30,
@ -103,7 +104,6 @@
"version": "0.0.3",
"settings": {
"idle_time": 5,
"interpret_idle_as_break": false,
"postpone_if_active": false
}
},
@ -121,7 +121,7 @@
"enabled": false,
"version": "0.0.2",
"settings": {
"statistics_reset_interval": 24
"statistics_reset_cron": "0 0 * * *"
}
},
{

View File

@ -96,7 +96,7 @@ class SafeEyesCore:
self.scheduled_next_break_timestamp = int(next_break_time)
utility.start_thread(self.__scheduler_job)
def stop(self):
def stop(self, is_resting=False):
"""
Stop Safe Eyes if it is running.
"""
@ -110,7 +110,7 @@ class SafeEyesCore:
self.waiting_condition.acquire()
self.running = False
if self.context['state'] != State.QUIT:
self.context['state'] = State.STOPPED
self.context['state'] = State.RESTING if (is_resting) else State.STOPPED
self.waiting_condition.notify_all()
self.waiting_condition.release()
@ -131,7 +131,17 @@ class SafeEyesCore:
logging.debug("Postpone the break for %d seconds", self.postpone_duration)
self.context['postponed'] = True
def take_break(self):
def get_break_time(self, break_type = None):
"""
Returns the next break time
"""
break_obj = self.break_queue.get_break(break_type)
if not break_obj:
return False
time = self.scheduled_next_break_time + datetime.timedelta(minutes=break_obj.time - self.break_queue.get_break().time)
return time
def take_break(self, break_type = None):
"""
Calling this method stops the scheduler and show the next break screen
"""
@ -139,15 +149,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
"""
@ -164,9 +174,11 @@ class SafeEyesCore:
self.running = False
self.waiting_condition.notify_all()
self.waiting_condition.release()
time.sleep(1) # Wait for 1 sec to ensure the sceduler is dead
time.sleep(1) # Wait for 1 sec to ensure the scheduler 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):
@ -176,32 +188,33 @@ class SafeEyesCore:
if not self.running:
return
self.context['state'] = State.WAITING
# Convert to seconds
time_to_wait = self.break_queue.get_break().time * 60
current_time = datetime.datetime.now()
current_timestamp = current_time.timestamp()
if self.context['state'] == State.RESTING and self.paused_time > -1:
# Safe Eyes was resting
paused_duration = int(current_timestamp - self.paused_time)
self.paused_time = -1
if paused_duration > self.break_queue.get_break(BreakType.LONG_BREAK).duration:
logging.info('Skip next long break due to the pause %ds longer than break duration', paused_duration)
# Skip the next long break
self.break_queue.reset()
if self.context['postponed']:
# Previous break was postponed
logging.info('Prepare for postponed break')
time_to_wait = self.postpone_duration
self.context['postponed'] = False
elif self.paused_time > -1 and self.break_queue.is_long_break():
# Safe Eyes was paused earlier and next break is long
paused_duration = int(current_timestamp - self.paused_time)
self.paused_time = -1
if paused_duration > self.break_queue.get_break().duration:
logging.info('Skip next long break due to the pause longer than break duration')
# Skip the next long break
self.break_queue.next()
if current_timestamp < self.scheduled_next_break_timestamp:
elif current_timestamp < self.scheduled_next_break_timestamp:
# Non-standard break was set.
time_to_wait = round(self.scheduled_next_break_timestamp - current_timestamp)
self.scheduled_next_break_timestamp = -1
else:
# Use next break, convert to seconds
time_to_wait = self.break_queue.get_break().time * 60
self.scheduled_next_break_time = current_time + datetime.timedelta(seconds=time_to_wait)
self.context['state'] = State.WAITING
utility.execute_main_thread(self.__fire_on_update_next_break, self.scheduled_next_break_time)
# Wait for the pre break warning period
@ -244,8 +257,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 +272,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):

View File

@ -33,7 +33,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</property>
along with this program. If not, see &lt;https://www.gnu.org/licenses/&gt;.</property>
</object>
<object class="GtkWindow" id="window_about">
<property name="can_focus">False</property>
@ -71,7 +71,7 @@ along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</pro
<property name="valign">center</property>
<property name="margin_top">10</property>
<property name="margin_bottom">10</property>
<property name="label" translatable="yes">Safe Eyes 2.1.3</property>
<property name="label" translatable="yes">Safe Eyes 2.1.5</property>
<property name="justify">center</property>
<attributes>
<attribute name="style" value="normal"/>
@ -135,14 +135,14 @@ along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.</pro
</child>
<child>
<object class="GtkLinkButton" id="btn_url">
<property name="label" translatable="yes">http://slgobinath.github.io/SafeEyes</property>
<property name="label" translatable="yes">https://slgobinath.github.io/SafeEyes</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="focus_on_click">False</property>
<property name="receives_default">True</property>
<property name="halign">center</property>
<property name="relief">none</property>
<property name="uri">http://slgobinath.github.io/SafeEyes</property>
<property name="uri">https://slgobinath.github.io/SafeEyes</property>
</object>
<packing>
<property name="expand">False</property>

View File

@ -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,43 @@ 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:
if self.__long_queue is None:
return None;
return self.__long_queue[self.__current_long]
if self.__short_queue is None:
return None;
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 +156,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 +169,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 +203,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):
@ -255,12 +258,13 @@ class State(Enum):
"""
Possible states of Safe Eyes.
"""
START = 0,
WAITING = 1,
PRE_BREAK = 2,
BREAK = 3,
STOPPED = 4,
QUIT = 5
START = 0, # Starting scheduler
WAITING = 1, # User is working (waiting for next break)
PRE_BREAK = 2, # Preparing for break
BREAK = 3, # Break
STOPPED = 4, # Disabled
QUIT = 5, # Quitting
RESTING = 6 # Resting (natural break)
class EventHook:
@ -304,6 +308,8 @@ class Config:
# self.__force_upgrade = ['long_breaks', 'short_breaks']
if init:
# if create_startup_entry finds a broken autostart symlink, it will repair it
utility.create_startup_entry(force=False)
if self.__user_config is None:
utility.initialize_safeeyes()
self.__user_config = self.__system_config

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -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;

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>io.github.slgobinath.SafeEyes</id>
<name>Safe Eyes</name>
<developer_name>Gobinath</developer_name>
<summary>A Free and Open Source tool for Linux users to reduce and prevent repetitive strain
injury (RSI).</summary>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0</project_license>
<categories>
<category>Utility</category>
<category>Accessibility</category>
</categories>
<description>
<p>
Protect your eyes from eye strain using this simple and beautiful, yet extensible break
reminder
</p>
<p>
Features:
</p>
<p>
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
</p>
</description>
<launchable type="desktop-id">io.github.slgobinath.SafeEyes.desktop</launchable>
<screenshots>
<screenshot type="default">
<image>https://slgobinath.github.io/SafeEyes/assets/screenshots/safeeyes_1.png</image>
</screenshot>
<screenshot>
<image>https://slgobinath.github.io/SafeEyes/assets/screenshots/safeeyes_3.png</image>
</screenshot>
<screenshot>
<image>https://slgobinath.github.io/SafeEyes/assets/screenshots/safeeyes_6.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://slgobinath.github.io/SafeEyes/</url>
<releases>
<release version="2.1.6" date="2023-06-04" />
</releases>
<content_rating type="oars-1.1" />
</component>

View File

@ -27,18 +27,28 @@ A plugin must have the following directory structure:
The plugin.py can have following methods but all are optional:
- description()
If a custom description has to be displayed, use this function
- on_init(context, safeeyes_config, plugin_config)
- init(context, safeeyes_config, plugin_config)
Initialize the plugin. Will be called after loading and after every changes in configuration
- on_start()
Executes when Safe Eyes is enabled
- on_stop()
Executes when Safe Eyes is disabled
- on_exit()
Executes before Safe Eyes exits
- on_pre_break(break_obj)
Executes at the start of the prepare time for a break
- on_start_break(break_obj)
Executes when a break starts
- on_stop_break()
Executes when a break stops
- on_countdown(countdown, seconds)
Executes every second throughout a break
- update_next_break(break_obj, break_time)
Executes when the next break changes
- enable()
Executes once the plugin.py is loaded as a module
- disable()
Executes if the plugin is disabled at the runtime by the user
- on_exit()
Executes before Safe Eyes exits
"""
import importlib
@ -84,8 +94,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:

View File

@ -80,16 +80,15 @@ def is_active_window_skipped_xorg(pre_break):
# Extract the process name
process_names = re.findall('"(.+?)"', stdout)
if process_names:
process = process_names[1].lower()
if process in skip_break_window_classes:
process_name = process_names[1].lower()
if _window_class_matches(process_name, skip_break_window_classes):
return True
elif process in take_break_window_classes:
elif _window_class_matches(process_name, take_break_window_classes):
if is_fullscreen and unfullscreen_allowed and not pre_break:
try:
active_window.unfullscreen()
except BaseException:
logging.error(
'Error in unfullscreen the window ' + process)
except BaseException as e:
logging.error('Error in unfullscreen the window ' + process_name, exc_info=e)
return False
return is_fullscreen
@ -97,6 +96,10 @@ def is_active_window_skipped_xorg(pre_break):
return False
def _window_class_matches(window_class: str, classes: list) -> bool:
return any(map(lambda w: w in classes, window_class.split()))
def is_on_battery():
"""
Check if the computer is running on battery.
@ -131,12 +134,16 @@ def init(ctx, safeeyes_config, plugin_config):
global dnd_while_on_battery
logging.debug('Initialize Skip Fullscreen plugin')
context = ctx
skip_break_window_classes = plugin_config['skip_break_windows'].split()
take_break_window_classes = plugin_config['take_break_windows'].split()
skip_break_window_classes = _normalize_window_classes(plugin_config['skip_break_windows'])
take_break_window_classes = _normalize_window_classes(plugin_config['take_break_windows'])
unfullscreen_allowed = plugin_config['unfullscreen']
dnd_while_on_battery = plugin_config['while_on_battery']
def _normalize_window_classes(classes_as_str: str):
return [w.lower() for w in classes_as_str.split()]
def on_pre_break(break_obj):
"""
Lifecycle method executes before the pre-break period.

View File

@ -19,22 +19,6 @@
import datetime
from safeeyes import utility
def _get_next_reset_time(current_time, statistics_reset_cron):
import croniter
try:
cron = croniter.croniter(statistics_reset_cron, current_time)
return cron.get_next(datetime.datetime)
except:
# Error in getting the next reset time
return None
def validate(plugin_config, plugin_settings):
if not utility.module_exist("croniter"):
return _("Please install the Python module '%s'") % "croniter"
# Validate the cron expression
statistics_reset_cron = plugin_settings.get('statistics_reset_cron', '0 0 * * *')
if _get_next_reset_time(datetime.datetime.now(), statistics_reset_cron) is None:
return _("Invalid cron expression '%s'") % statistics_reset_cron
else:
return None

View File

@ -25,199 +25,156 @@ import datetime
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
last_screen_time = -1
statistics_reset_cron = '0 0 * * *' # Every midnight
time_to_reset_break = datetime.datetime.now()
statistics_reset_cron = None
default_statistics_reset_cron = '0 0 * * *' # Every midnight
next_reset_time = None
enabled = True
start_time = None
def init(ctx, safeeyes_config, plugin_config):
"""
Initialize the plugin.
"""
global enabled
global context
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
global last_screen_time
global next_reset_time
logging.debug('Initialize Health Stats plugin')
context = ctx
statistics_reset_cron = plugin_config.get('statistics_reset_cron', '0 0 * * *')
# Compute the next reset time
next_reset_time = _get_next_reset_time(datetime.datetime.now(), statistics_reset_cron)
enabled = next_reset_time is not None
if not enabled:
# There is an error in the cron expression
logging.error("Error in parsing the cron expression `" + statistics_reset_cron + "`. Health Stats plugin is disabled.")
return
statistics_reset_cron = plugin_config.get('statistics_reset_cron', default_statistics_reset_cron)
if session is None:
# Read the session
session = context['session']['plugin'].get('healthstats', None)
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,
'next_reset_time': next_reset_time.strftime("%Y-%m-%d %H:%M:%S")}
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)
str_next_reset_time = session.get('next_reset_time', None)
if str_time:
safe_eyes_start_time = datetime.datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
if str_next_reset_time:
next_reset_time = datetime.datetime.strptime(str_time, "%Y-%m-%d %H:%M:%S")
_reset_stats()
defaults = {
'breaks': 0,
'skipped_breaks': 0,
'screen_time': 0,
'total_breaks': 0,
'total_skipped_breaks': 0,
'total_screen_time': 0,
'total_resets': 0,
}
session = context['session']['plugin'].get('healthstats', {}) | defaults
if 'no_of_breaks' in session:
# Ignore old format session.
session = defaults
context['session']['plugin']['healthstats'] = session
_get_next_reset_time()
def on_stop_break():
"""
After the break, check if it is skipped.
"""
# Check if the plugin is enabled
if not enabled:
return
global no_of_skipped_breaks
# Check if break was skipped.
global session
if context['skipped']:
no_of_skipped_breaks += 1
session['no_of_skipped_breaks'] = no_of_skipped_breaks
session['skipped_breaks'] += 1
# Screen time is starting again.
on_start()
def on_start_break(break_obj):
global session
session['breaks'] += 1
# Screen time has stoped.
on_stop()
def on_stop():
global start_time
_reset_stats()
if start_time:
screen_time = datetime.datetime.now() - start_time
session['screen_time'] += round(screen_time.total_seconds())
start_time = None
def get_widget_title(break_obj):
"""
Return the widget title.
"""
# Check if the plugin is enabled
if not enabled:
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
return _('Health Statistics')
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
global last_screen_time
global next_reset_time
global session
# Check if the reset time has passed
current_time = datetime.datetime.now()
total_duration_sec = (current_time - safe_eyes_start_time).total_seconds()
if current_time >= next_reset_time:
logging.debug("Resetting the health statistics")
# Reset statistics
if safe_eyes_start_time < next_reset_time:
# Safe Eyes is running even before the reset time
# Consider the reset time as the new start time
safe_eyes_start_time = next_reset_time
total_duration_sec = (current_time - safe_eyes_start_time).total_seconds()
if next_reset_time and datetime.datetime.now() >= next_reset_time:
logging.info("Resetting the health statistics")
# Update the next_reset_time
next_reset_time = _get_next_reset_time(current_time, statistics_reset_cron)
_get_next_reset_time()
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
session['last_screen_time'] = last_screen_time
session['next_reset_time'] = next_reset_time.strftime("%Y-%m-%d %H:%M:%S")
return total_duration_sec
# Reset statistics
session['total_breaks'] += session['breaks']
session['total_skipped_breaks'] += session['skipped_breaks']
session['total_screen_time'] += session['screen_time']
session['total_resets'] += 1
session['breaks'] = 0
session['skipped_breaks'] = 0
session['screen_time'] = 0
def get_widget_content(break_obj):
"""
Return the statistics.
"""
# Check if the plugin is enabled
if not enabled:
return ""
total_duration_sec = _reset_stats()
screen_time = round((total_duration_sec - total_idle_time) / 60)
hours, minutes = divmod(screen_time, 60)
time_format = '{:02d}:{:02d}'.format(hours, minutes)
if hours > 6 or round((no_of_skipped_breaks / no_of_breaks), 1) >= 0.2:
global next_reset_time
resets = session['total_resets']
if session['screen_time'] > 21600 or (session['breaks'] and session['skipped_breaks'] / session['breaks']) >= 0.2:
# Unhealthy behavior -> Red broken heart
heart = '💔️'
else:
# Healthy behavior -> Green heart
heart = '💚'
if last_screen_time < 0:
screen_time_diff = ''
else:
hrs_diff, mins_diff = divmod(abs(screen_time - last_screen_time), 60)
symbol = ''
if screen_time > last_screen_time:
symbol = '+'
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)
content = [
heart,
f"BREAKS: {session['breaks']}",
f"SKIPPED: {session['skipped_breaks']}",
f"SCREEN TIME: {_format_interval(session['screen_time'])}",
]
if resets:
content[1] += f" [{round(session['total_breaks'] / resets, 1)}]"
content[2] += f" [{round(session['total_skipped_breaks'] / resets, 1)}]"
content[3] += f" [{_format_interval(session['total_screen_time'] / resets)}]"
content = "\t".join(content)
if resets:
content += f"\n\t[] = average of {resets} reset(s)"
if next_reset_time is None:
content += f"\n\tSettings error in statistics reset interval: {statistics_reset_cron}"
return content
def on_start():
"""
Add the idle period to the total idle time.
Track the start time.
"""
# Check if the plugin is enabled
if not enabled:
return ""
global start_time
_reset_stats()
global total_idle_time
# idle_period is provided by Smart Pause plugin
total_idle_time += context.get('idle_period', 0)
session['total_idle_time'] = total_idle_time
start_time = datetime.datetime.now()
def _get_next_reset_time():
global next_reset_time
global session
def _get_next_reset_time(current_time, statistics_reset_cron):
try:
cron = croniter.croniter(statistics_reset_cron, current_time)
next_time = cron.get_next(datetime.datetime)
logging.debug("Health stats will be reset at " + next_time.strftime("%Y-%m-%d %H:%M:%S"))
return next_time
cron = croniter.croniter(statistics_reset_cron, datetime.datetime.now())
next_reset_time = cron.get_next(datetime.datetime)
session['next_reset_time'] = next_reset_time.strftime("%Y-%m-%d %H:%M:%S")
logging.debug("Health stats will be reset at " + session['next_reset_time'])
except:
# Error in getting the next reset time
return None
logging.error("Error in statistics reset expression: " + statistics_reset_cron)
next_reset_time = None
def _format_interval(seconds):
screen_time = round(seconds / 60)
hours, minutes = divmod(screen_time, 60)
return '{:02d}:{:02d}'.format(hours, minutes)

View File

@ -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:

View File

@ -20,12 +20,6 @@
"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",

View File

@ -23,6 +23,8 @@ def validate(plugin_config, plugin_settings):
command = None
if utility.DESKTOP_ENVIRONMENT == "gnome" and utility.IS_WAYLAND:
command = "dbus-send"
elif utility.DESKTOP_ENVIRONMENT == "sway":
command = "swayidle"
else:
command = "xprintidle"
if not utility.command_exist(command):

View File

@ -35,17 +35,58 @@ idle_condition = threading.Condition()
lock = threading.Lock()
active = False
idle_time = 0
enable_safe_eyes = None
disable_safe_eyes = None
enable_safeeyes = None
disable_safeeyes = None
smart_pause_activated = False
idle_start_time = None
next_break_time = None
next_break_duration = 0
short_break_interval = 0
waiting_time = 2
interpret_idle_as_break = False
is_wayland_and_gnome = False
use_swayidle = False
swayidle_process = None
swayidle_lock = threading.Lock()
swayidle_idle = 0
swayidle_active = 0
def __swayidle_running():
return (swayidle_process is not None and
swayidle_process.poll() is None)
def __start_swayidle_monitor():
global swayidle_process
global swayidle_start
global swayidle_idle
global swayidle_active
logging.debug('Starting swayidle subprocess')
swayidle_process = subprocess.Popen([
"swayidle", "timeout", "1", "date +S%s", "resume", "date +R%s"
], stdout=subprocess.PIPE, bufsize=1, universal_newlines=True, encoding='utf-8')
for line in swayidle_process.stdout:
with swayidle_lock:
typ = line[0]
timestamp = int(line[1:])
if typ == 'S':
swayidle_idle = timestamp
elif typ == 'R':
swayidle_active = timestamp
def __stop_swayidle_monitor():
if __swayidle_running():
logging.debug('Stopping swayidle subprocess')
swayidle_process.terminate()
def __swayidle_idle_time():
with swayidle_lock:
if not __swayidle_running():
utility.start_thread(__start_swayidle_monitor)
# Idle more recently than active, meaning idle time isn't stale.
if swayidle_idle > swayidle_active:
idle_time = int(datetime.datetime.now().timestamp()) - swayidle_idle
return idle_time
return 0
def __gnome_wayland_idle_time():
"""
@ -76,6 +117,8 @@ def __system_idle_time():
try:
if is_wayland_and_gnome:
return __gnome_wayland_idle_time()
elif use_swayidle:
return __swayidle_idle_time()
# Convert to seconds
return int(subprocess.check_output(['xprintidle']).decode('utf-8')) / 1000
except BaseException:
@ -106,29 +149,29 @@ def init(ctx, safeeyes_config, plugin_config):
Initialize the plugin.
"""
global context
global enable_safe_eyes
global disable_safe_eyes
global enable_safeeyes
global disable_safeeyes
global postpone
global idle_time
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
logging.debug('Initialize Smart Pause plugin')
context = ctx
enable_safe_eyes = context['api']['enable_safeeyes']
disable_safe_eyes = context['api']['disable_safeeyes']
enable_safeeyes = context['api']['enable_safeeyes']
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
long_break_duration = safeeyes_config.get('long_break_duration')
waiting_time = min(2, idle_time) # If idle time is 1 sec, wait only 1 sec
is_wayland_and_gnome = context['desktop'] == 'gnome' and context['is_wayland']
use_swayidle = context['desktop'] == 'sway'
def __start_idle_monitor():
@ -151,29 +194,25 @@ 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_safe_eyes(None)
elif system_idle_time < idle_time and context['state'] == State.STOPPED and idle_start_time is not None:
disable_safeeyes(None, True)
elif system_idle_time < idle_time and context['state'] == State.RESTING 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 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 break %d", idle_seconds, long_break_duration)
enable_safe_eyes(-1, idle_seconds >= long_break_duration)
elif idle_seconds < short_break_interval:
if idle_seconds < short_break_interval:
# Credit back the idle time
if next_break_time is not None:
# This method runs in a thread since the start.
# It may run before next_break is initialized in the update_next_break method
next_break = next_break_time + idle_period
enable_safe_eyes(next_break.timestamp())
enable_safeeyes(next_break.timestamp())
else:
enable_safe_eyes()
enable_safeeyes()
else:
# User is idle for more than the time between two breaks
enable_safe_eyes()
enable_safeeyes()
def on_start():
@ -199,6 +238,8 @@ def on_stop():
smart_pause_activated = False
return
logging.debug('Stop Smart Pause plugin')
if use_swayidle:
__stop_swayidle_monitor()
__set_active(False)
idle_condition.acquire()
idle_condition.notify_all()

View File

@ -18,6 +18,12 @@
"type": "BOOL",
"default": false
},
{
"id": "show_long_time_in_tray",
"label": "Show only long breaks for tray icon time",
"type": "BOOL",
"default": false
},
{
"id": "allow_disabling",
"label": "Allow disabling Safe Eyes",
@ -48,4 +54,4 @@
]
}
]
}
}

View File

@ -17,10 +17,16 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
from safeeyes.model import BreakType
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as appindicator
try:
gi.require_version('AppIndicator3', '0.1')
from gi.repository import AppIndicator3 as appindicator
except:
#fall back to Ayatana
gi.require_version('AyatanaAppIndicator3', '0.1')
from gi.repository import AyatanaAppIndicator3 as appindicator
from gi.repository import Gtk
import logging
from safeeyes import utility
@ -47,10 +53,11 @@ class TrayIcon:
self.on_show_settings = context['api']['show_settings']
self.on_show_about = context['api']['show_about']
self.quit = context['api']['quit']
self.on_enable = context['api']['enable_safeeyes']
self.on_disable = context['api']['disable_safeeyes']
self.enable_safeeyes = context['api']['enable_safeeyes']
self.disable_safeeyes = context['api']['disable_safeeyes']
self.take_break = context['api']['take_break']
self.has_breaks = context['api']['has_breaks']
self.get_break_time = context['api']['get_break_time']
self.plugin_config = plugin_config
self.date_time = None
self.active = True
@ -62,7 +69,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
@ -71,7 +78,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()
@ -80,10 +87,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']:
@ -111,7 +116,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
@ -122,9 +127,21 @@ class TrayIcon:
# Add the sub menu to the enable/disable menu
self.item_disable.set_submenu(self.sub_menu_disable)
# Settings menu item
# Manual break 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()
@ -177,7 +194,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])
@ -190,24 +207,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.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'))
@ -263,13 +283,25 @@ class TrayIcon:
"""
A private method to be called within this class to update the next break information using self.dateTime.
"""
formatted_time = utility.format_time(self.date_time)
message = _('Next break at %s') % (formatted_time)
formatted_time = utility.format_time(self.get_break_time())
long_time = self.get_break_time(BreakType.LONG_BREAK)
if long_time:
long_time = utility.format_time(long_time)
if long_time == formatted_time:
message = _('Next long break at %s') % (long_time)
else:
message = _('Next breaks at %s/%s') % (formatted_time, long_time)
else:
message = _('Next break at %s') % (formatted_time)
# Update the menu item label
utility.execute_main_thread(self.item_info.set_label, message)
# Update the tray icon label
if self.plugin_config.get('show_time_in_tray', False):
self.indicator.set_label(formatted_time, '')
show_long = long_time and self.plugin_config.get('show_long_time_in_tray', False)
self.indicator.set_label(long_time if show_long else formatted_time, '')
else:
self.indicator.set_label('', '')
@ -277,7 +309,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):
"""
@ -288,7 +324,7 @@ class TrayIcon:
if not self.active:
with self.lock:
self.enable_ui()
self.on_enable()
self.enable_safeeyes()
# Notify all schedulers
self.idle_condition.acquire()
self.idle_condition.notify_all()
@ -306,13 +342,13 @@ class TrayIcon:
time_to_wait = args[1]
if time_to_wait <= 0:
info = _('Disabled until restart')
self.on_disable(info)
self.disable_safeeyes(info)
self.wakeup_time = None
self.item_info.set_label(info)
else:
self.wakeup_time = datetime.datetime.now() + datetime.timedelta(minutes=time_to_wait)
info = _('Disabled until %s') % utility.format_time(self.wakeup_time)
self.on_disable(info)
self.disable_safeeyes(info)
self.item_info.set_label(info)
utility.start_thread(self.__schedule_resume, time_minutes=time_to_wait)
@ -337,7 +373,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)
@ -352,7 +388,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)
@ -373,9 +409,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:
@ -384,9 +420,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):
"""

View File

@ -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.3"
SAFE_EYES_VERSION = "2.1.6"
class SafeEyes:
@ -93,10 +93,10 @@ 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.context['api']['get_break_time'] = self.safe_eyes_core.get_break_time
self.plugins_manager.init(self.context, self.config)
atexit.register(self.persist_session)
@ -158,7 +158,7 @@ class SafeEyes:
if self.active:
logging.info("Stop Safe Eyes due to system suspend")
self.plugins_manager.stop()
self.safe_eyes_core.stop()
self.safe_eyes_core.stop(True)
else:
# Resume from sleep
if self.active and self.safe_eyes_core.has_breaks():
@ -239,14 +239,14 @@ class SafeEyes:
self.safe_eyes_core.start(scheduled_next_break_time, reset_breaks)
self.plugins_manager.start()
def disable_safeeyes(self, status=None):
def disable_safeeyes(self, status=None, is_resting = False):
"""
Listen to tray icon disable action and send the signal to core.
"""
if self.active:
self.active = False
self.plugins_manager.stop()
self.safe_eyes_core.stop()
self.safe_eyes_core.stop(is_resting)
if status is None:
status = _('Disabled until restart')
self._status = status
@ -295,11 +295,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):
"""

View File

@ -41,7 +41,7 @@ class BreakScreen:
This class reads the break_screen.glade and build the user interface.
"""
def __init__(self, context, on_skip, on_postpone, style_sheet_path):
def __init__(self, context, on_skipped, on_postponed, style_sheet_path):
self.context = context
self.count_labels = []
self.display = Display()
@ -50,8 +50,8 @@ class BreakScreen:
self.is_pretified = False
self.keycode_shortcut_postpone = 65
self.keycode_shortcut_skip = 9
self.on_postpone = on_postpone
self.on_skip = on_skip
self.on_postponed = on_postponed
self.on_skipped = on_skipped
self.shortcut_disable_time = 2
self.strict_break = False
self.windows = []
@ -77,8 +77,8 @@ class BreakScreen:
Skip the break from the break screen
"""
logging.info("User skipped the break")
# Must call on_skip before close to lock screen before closing the break screen
self.on_skip()
# Must call on_skipped before close to lock screen before closing the break screen
self.on_skipped()
self.close()
def postpone_break(self):
@ -86,7 +86,7 @@ class BreakScreen:
Postpone the break from the break screen
"""
logging.info("User postponed the break")
self.on_postpone()
self.on_postponed()
self.close()
def on_window_delete(self, *args):

View File

@ -21,7 +21,6 @@ This module contains utility functions for Safe Eyes and its plugins.
"""
import errno
import imp
import inspect
import importlib
import json
@ -51,10 +50,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 +62,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
@ -290,6 +290,9 @@ def desktop_environment():
env = 'gnome'
elif desktop_session.startswith('ubuntu'):
env = 'unity'
elif current_desktop is not None:
if current_desktop.startswith('sway'):
env = 'sway'
DESKTOP_ENVIRONMENT = env
return env
@ -299,6 +302,13 @@ def is_wayland():
https://unix.stackexchange.com/a/325972/222290
"""
global IS_WAYLAND
# Easy method. Does not depend on loginctl
# https://stackoverflow.com/questions/45536141/how-i-can-find-out-if-a-linux-system-uses-wayland-or-x11/45537237#45537237
if "WAYLAND_DISPLAY" in os.environ:
IS_WAYLAND = True
return IS_WAYLAND
try:
session_id = subprocess.check_output(['loginctl']).split(b'\n')[1].split()[0]
output = subprocess.check_output(
@ -344,7 +354,7 @@ def module_exist(module):
Check wther the given Python module exists or not.
"""
try:
imp.find_module(module)
importlib.util.find_spec(module)
return True
except ImportError:
return False
@ -361,17 +371,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)
@ -382,27 +390,51 @@ def initialize_safeeyes():
shutil.copy2(SYSTEM_STYLE_SHEET_PATH, STYLE_SHEET_PATH)
os.chmod(STYLE_SHEET_PATH, 0o777)
create_startup_entry()
# initialize_safeeyes gets called when the configuration file is not present, which happens just after installation or manual deletion of .config/safeeyes/safeeyes.json file. In these cases, we want to force the creation of a startup entry
create_startup_entry(force=True)
def create_startup_entry():
def create_startup_entry(force=False):
"""
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')
# until SafeEyes 2.1.5 the startup entry had another name
# https://github.com/slgobinath/SafeEyes/commit/684d16265a48794bb3fd670da67283fe4e2f591b#diff-0863348c2143a4928518a4d3661f150ba86d042bf5320b462ea2e960c36ed275L398
obsolete_entry = os.path.join(startup_dir_path, 'safeeyes.desktop')
# Create the folder if not exist
mkdir(startup_dir_path)
create_link = False
# Remove existing files
delete(startup_entry)
if force:
# if force is True, just create the link
create_link = True
else:
# if force is False, we want to avoid creating the startup symlink if it was manually deleted by the user, we want to create it only if a broken one is found
if os.path.islink(startup_entry):
# if the link exists, check if it is broken
try:
os.stat(startup_entry)
except FileNotFoundError:
# a FileNotFoundError will get thrown if the startup symlink is broken
create_link = True
# Create the new startup entry
try:
os.symlink(SYSTEM_DESKTOP_FILE, startup_entry)
except OSError:
logging.error("Failed to create startup entry at %s" % startup_entry)
if os.path.islink(obsolete_entry):
# if a link with the old naming exists, delete it and create a new one
create_link = True
delete(obsolete_entry)
if create_link:
# Create the folder if not exist
mkdir(startup_dir_path)
# Remove existing files
delete(startup_entry)
# Create the new startup entry
try:
os.symlink(SYSTEM_DESKTOP_FILE, startup_entry)
except OSError:
logging.error("Failed to create startup entry at %s" % startup_entry)
def initialize_platform():
@ -413,13 +445,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)
@ -482,7 +514,7 @@ def replace_style_sheet():
os.chmod(STYLE_SHEET_PATH, 0o777)
def intialize_logging(debug):
def initialize_logging(debug):
"""
Initialize the logging framework using the Safe Eyes specific configurations.
"""
@ -656,7 +688,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

View File

@ -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.3",
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.3.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(),

42
validate_po.py Normal file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env python3
# Safe Eyes is a utility to remind you to take break frequently
# to protect your eyes from eye strain.
# Copyright (C) 2021 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# 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.
# 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 os
import polib
import sys
def validate_po(locale: str, path: str) -> bool:
success = True
po = polib.pofile(path)
for entry in po:
if entry.msgstr and (entry.msgid.count("%") != entry.msgstr.count("%")):
print("Number of variables mismatched in " + locale)
print(entry.msgid + " -> " + entry.msgstr)
print()
success = False
return success
success = True
locales = os.listdir('safeeyes/config/locale')
for locale in sorted(locales):
path = os.path.join('safeeyes/config/locale', locale, "LC_MESSAGES/safeeyes.po")
if os.path.isfile(path):
print('Validating translation %s...' % path)
success = validate_po(locale, path) and success
sys.exit(0 if success else 1)