dschep / ntfy

šŸ–„ļøšŸ“±šŸ”” A utility for sending notifications, on demand and when commands finish.
http://ntfy.rtfd.io
GNU General Public License v3.0
4.82k stars 214 forks source link

Pick backend based on screen lock #168

Open ianwremmel opened 6 years ago

ianwremmel commented 6 years ago

Similar to #94, it'd be really nice if I could use e.g. macos notifications when the screen is unlocked but switch to pushover if things took long enough that I locked my computer and went for coffee.

dschep commented 6 years ago

This is something I've wanted to do for a while, but I'm not sure how to best implement it. For now, I have #125 (which is what I personally use actually) that supports this feature via a meta-backend called multi. A config that does nothing when the terminal is focused, uses desktop notifications when unlocked&unfocused, and pushover when locked looks like this:

backends: [multi]
multi:
    locked:
        pushover:
            user_key: user-api-key
    unfocused:
        default: {}
    focused: {}

I'd prefer it be more integrated rather than a meta-backend but can't decide on the best implementation approach (both code & config).

You can try it out with pip install git+https://github.com/dschep/ntfy.git@locked#egg=ntfy

dschep commented 6 years ago

Oops, just re-read your post. That branch/pr only supports Linux for now. I have no clue how to do this on macOS or Windows, so any help on that front would be very welcome :smiley:

ianwremmel commented 6 years ago

Oh, cool, didnā€™t realize there was something already underway.

I donā€™t know python very well, but I got this idea from someone who did something similar with just (I think) zsh. Let me see if can find out how he did it.

As far as the config part, what youā€™ve got seems pretty reasonable. Other options that come to mind:

Fair warning, these ideas are very much pre-coffee and may not hold up. šŸ˜

pcl commented 6 years ago

Here's a commit that adds MacOS support. I haven't tested it in situ, as I'm using my own zsh solution for this problem currently, but this should give @ianwremmel what he needs.

Note that this builds on top of #125, which is like a year behind master.

The commit detects whether or not the screensaver is running, not whether or not the screen is locked. Depending on how the user has configured the screensaver and lock behavior, it's possible for the screen to lock without the screensaver engaged, and it's also possible for the screensaver to be on without a lock. I do not know how to detect locked-ness in High Sierra.

ianwremmel commented 6 years ago

Thanks @pcl! @dschep, if you donā€™t get to it first, Iā€™ll see if I can get an up to date pr for you in the next few days.

dschep commented 6 years ago

Go for it @ianwremmel, I don't have much time to work on this (not that it's abandoned, I still use ntfy every single time I touch a computer)

ianwremmel commented 6 years ago

Sounds good. Any pointers on how to use a local checkout instead of the version from pip?

On Mar 13, 2018, 6:04 AM -0700, Daniel Schep notifications@github.com, wrote:

Go for it @ianwremmel, I don't have much time to work on this (not that it's abandoned, I still use ntfy every single time I touch a computer) ā€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

dschep commented 6 years ago

use:

python setup.py develop
ianwremmel commented 6 years ago

So, I feel like there's an obvious python thing that I just don't know. I've run python setup.py develop and it seems to do the right things, but I can't figure out how to actually execute the checked out version. Any pointers?

ian@Ians-MacBook 09:03:49 ~/projects/ntfy on multi-screenlock 0 v9.4.0$ python ntfy/cli.py 
Traceback (most recent call last):
  File "ntfy/cli.py", line 9, in <module>
    from . import __version__, default_title, notify
ImportError: cannot import name '__version__'
ian@Ians-MacBook 09:03:56 ~/projects/ntfy on multi-screenlock 0 v9.4.0$ python ntfy/cli.py send test
Traceback (most recent call last):
  File "ntfy/cli.py", line 9, in <module>
    from . import __version__, default_title, notify
ImportError: cannot import name '__version__'
ian@Ians-MacBook 09:04:01 ~/projects/ntfy on multi-screenlock 0 v9.4.0$ 
dschep commented 6 years ago

You should just be able to run ntfy after runing that command. Another option is python -m ntfy.cli

ianwremmel commented 6 years ago

ah, ok. thanks!

I tried that, but it didn't seem to like the multi backend config when I just ran ntfy. python -m is working though.

I'm getting the error below when the screen is locked now. I'll dig into that in the next few days.

28:31: execution error: Terminal got an error: Canā€™t get window 1 whose frontmost = true. Invalid index. (-1719)
28:31: execution error: Terminal got an error: Canā€™t get window 1 whose frontmost = true. Invalid index. (-1719)
ianwremmel commented 6 years ago

ok, I've worked out a few things:

  1. @pcl's script doesn't seem to identify the screen being locked when you hit cmd+shift+esc which I think is a result of the subtle differences between screen locked, screen asleep, and screensaver active.
  2. When the screen is asleep (also possibly locked or with active screen saver) and the terminal is focused, the error in my previous post shows up.
  3. Not sure if this is intended or not, but when the screen is locked, the following config produces both a local and a push notification:
backends: [multi]
multi:
    locked:
        pushover:
            user_key: REDACTED
    unfocused:
        default: {}
    focused: {}

I got the detection working with the following.

import Quartz
d = Quartz.CGSessionCopyCurrentDictionary()
screenIsLocked = d.get("CGSSessionScreenIsLocked", 0) == 1

I think Quartz automatically comes in because of the dependency on pyobjc, but pyobjc-framework-Quartz might be required.

I think I can tackle point 2. Is point 3 intended?

pcl commented 6 years ago

My code only detects screensaver-ness, not locked-ness, as per my comment in the code. If you configure your screensaver appropriately, this is a moot issue.

Regarding the dual behavior: as I mentioned elsewhere, I am suspicious of the default ā€˜return Trueā€™ statement in the locked decision tree. That might be the cause of your woes.

dschep commented 6 years ago

Screensaver-ness is fine IMO. I just used locked-ness because they're synonymous because of the way i setup my machines.

ianwremmel commented 6 years ago

@pcl I'll check that, but I think it's actually the loop in multy.py. If I'm reading it right, it evaluates focused, locked, and screensaver independently and acts accordingly; the conditions don't appear to be mutually exclusive. @dschep Was your intent to notify only one backend or all that are configured for multi?

As far as screensaver vs locked, the more I think about it, the more I think using both solutions is correct, but my point last night was poorly worded. What I really meant was "I can't find a way to force the screensaver detection to return True, but the lock check I found works".

ianwremmel commented 6 years ago

ok, I've updated https://github.com/dschep/ntfy/pull/170 to use both detection methods. I think everything works, with the caveat of being notified in multiple ways when the screen is locked/screensavered.

(I checked if it is_locked() returning True is the cause; it's not.)

dschep commented 6 years ago

Yeah, you currently get 2 notifications when the screen is locked. This worked fine with how I use the plugin. I use shell-integration mostly these days and get desktop notifications so long as the terminal is unfocused and ALSO get a push notification when the screen is locked.

ianwremmel commented 6 years ago

Gotcha. Then, Iā€™d say #170 is ready to go.

ianwremmel commented 5 years ago

Any status on getting the multi backend merged? I'd love to install it without need to git clone and install from source.

dschep commented 5 years ago

I'd rather not ship without windows support, but I don't see myself adding that anytime soon.. so I guess I ought to merge this stuff.

just a quick note, the install from source is pretty straightforward since you can still do it through pip: pip install git+https://github.com/ianwremmel/ntfy@multi-screenlock

ianwremmel commented 5 years ago

posting this here because i'm using this branch, not the mainline release.

just a quick note, the install from source is pretty straightforward since you can still do it through pip: pip install git+https://github.com/ianwremmel/ntfy@multi-screenlock

@dschep thanks! that helped a lot; somehow, though, shell integration seems broken. If I explicitly call ntfy, things send, but i don't get the autosend after command completion.

I've got

# ntfy shell integration
if command -v ntfy > /dev/null 2>&1; then
  export AUTO_NTFY_DONE_OPTS='-b multi'
  export AUTO_NTFY_DONE_LONGER_THAN=-L2
  export AUTO_NTFY_DONE_UNFOCUSED_ONLY=-b
  export AUTO_NTFY_DONE_IGNORE="vim screen meld"
  eval "$(ntfy shell-integration)"
fi

any pointers on what might be broken or how to debug? are there changes in master that I should pull in, perhaps for the latest macos release?

Will it cause any issues for you if I rebase ianwremmel/ntfy@multi-screenlock on master?