-
-
Notifications
You must be signed in to change notification settings - Fork 336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apprise Integration #2796
Apprise Integration #2796
Conversation
@Safihre : Would you have a sample |
you can get it from: |
looks like this also requires additional dependencies,
PyYAML ? |
@thezoggy : I got to step out for about 3 hrs or so, but hopefully these test cases will pass. I'll have a look if not when i get back. Thanks for your help! I'd say don't merge this yet anyway, i cna update the |
looks like PyYAML does not do universal binaries for macos
which apparently they decided not to do: |
Does it really need yaml? Where is it used? |
Yes, if you use the I ended up having to do other things last night. I'll take another stab at it today. I'll just move the yaml Python code over as per link Zoggy shared. The other thing i wanted to do was adapt the Assets to use your icons. I presume that might be what you want since it was the case for the nzb-notify script. It won't be much effort Edit: I'm now seeing the problem; This may be usefully for testing with requirements.txt:
|
requirements.txt
Outdated
PyYAML; sys_platform != 'darwin' | ||
|
||
# Apprise Requirements | ||
requests |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please specify the exact versions. It's important for the packaging reproducibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
requirements.txt
Outdated
@@ -54,7 +55,17 @@ notify2==0.3.1; sys_platform != 'win32' and sys_platform != 'darwin' | |||
# Uncomment line below or manually install after installing requirements. | |||
# pygobject>=3.10.2; sys_platform != 'win32' and sys_platform != 'darwin' | |||
|
|||
# PyYAML does not have binary packages for Mac Users | |||
PyYAML --no-binary=PyYAML; sys_platform == 'darwin' | |||
PyYAML; sys_platform != 'darwin' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not have non-binary for all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's more efficient to use the binary when it's available. It's unfortunate that macos environment is impacted into a situation where they can't use it.
sabnzbd/cfg.py
Outdated
apprise_prio_warning = OptionBool("apprise", "apprise_prio_warning", False) | ||
apprise_prio_error = OptionBool("apprise", "apprise_prio_error", False) | ||
apprise_prio_queue_done = OptionBool("apprise", "apprise_prio_queue_done", False) | ||
apprise_prio_other = OptionBool("apprise", "apprise_prio_other", True) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we also have priorities? Since we have direct integration of Apprise now, then we could specify it, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took this to a slightly different level so i could accommodate the power of apprise. If i only focused on PushOver Priorities, you'd only be addressing 1 of the 100+ services Apprise can adapt to. See general description in PR for updated screenshot.
sabnzbd/notifier.py
Outdated
app_desc="SABnzbd Notification", | ||
app_url="http://sabnzbd.org/", | ||
image_path_mask=os.path.join(os.path.dirname(__file__), "apprise", "apprise-{TYPE}.png"), | ||
image_url_mask="https://raw.githubusercontent.com/sabnzbd/sabnzbd/develop/sabnzbd/apprise/apprise-{TYPE}.png", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we maybe host these at sabnzbd.org?
https://github.com/sabnzbd/sabnzbd.github.io/tree/master/images/icons
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure we can, let me know the URL i should use. Even using the one you just shared now:
https://github.com/sabnzbd/sabnzbd.github.io/tree/master/images/icons
becomeshttps://raw.githubusercontent.com/sabnzbd/sabnzbd.github.io/master/images/icons/
for direct reference.
Perhaps you man the url:
https://github.com/sabnzbd/sabnzbd.github.io/tree/master/images/icons
(as it is now) should change to:https://sabnzbd.org/images/icons/
?
So ... ?
# Prepare our Asset Object
asset = apprise.AppriseAsset(
app_id="SABnzbd",
app_desc="SABnzbd Notification",
app_url="http://sabnzbd.org/",
image_path_mask=os.path.join(os.path.dirname(__file__), "apprise", "apprise-{TYPE}.png"),
image_url_mask="https://sabnzbd.org/images/icons/apprise/apprise-{TYPE}.png",
image_url_logo="https://sabnzbd.org/images/icons/"
"apple-touch-icon-120x120-precomposed.png/apple-touch-icon-180x180-precomposed.png",
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that last one is what I mean. If you open a PR to add them to https://github.com/sabnzbd/sabnzbd.github.io/tree/master/images/icons then it will automatically be available at sabnzbd.org.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So just to follow up with this, we still need the images in this repository (somewhere), because notifications differ from where they get their data from. For Discord, Slack, etc, no problem,; they'll get their image from the web. But other services actually need their image uploaded as part of the payload for it's assembly. So the Apprise plugins are smart enough to determine if they need to go to the cloud for the error
/success
/info
/warning
message or to look on the local disk. Otherwise, it looks like we're good to go I see you merged abnzbd.github.io/309
I seemed to have broke things with the latest change, i'll have to work it out tomorrow if i have time (otherwise on the weekend). I created a new function called |
sabnzbd/notifier.py
Outdated
asset = apprise.AppriseAsset( | ||
app_id="SABnzbd", | ||
app_desc="SABnzbd Notification", | ||
app_url="http://sabnzbd.org/", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch! Done!
</label> | ||
<input type="checkbox" name="${section_label}_target_${type}_enable" id="${section_label}_target_${type}_enable" value="1" <!--#if int($getVar($section_label + '_target_' + $type + '_enable')) > 0 then 'checked="checked"' else ""#--> /> | ||
|
||
<input type="text" name="${section_label}_target_${type}" id="${section_label}_target_${type}" value="$getVar($section_label + '_target_' + $type)" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a placeholder="$T('default')"
to the overrides input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done 🙂
The build broke because you used |
@thezoggy sidenote: |
we already uses requests in our tests you know. :) using requests imho is mainly just to use code that just handles all the urllib quirks and made it cleaner to use. which back in the day when we were doing python2 or early python3 it would had prob made things a lot cleaner (which is mainly when I was bringing it up). now with more modern python its a little less important as its more of a glorified wrapper for urllib3, but then there are extensions that solve various scenarios that while prob aren't great use to us but of course are great for things like notification wrappers that need to do various authentication schemes/async threading and such. I would think there prob is benefits to using it to cleanup the getipaddress/urlgrabber/rss stuff... |
I'll address your concerns tomorrow, unfortunately I couldn't action it tonight. |
No rush, version 4.3.0 is still a while 🤗 |
I think i'm good for another round of reviews. Consider that Apprise supports file attachments too. So if you can think of edge cases (such as a failure) or whatnot where you way wish to also include all of the log files (or a core dump, or whatever you can think of) to be sent with the notification as well, that is very easy to adapt. (just food for thought) |
can squash most of the commits for this to cleanup history a bit also from earlier review, i noted that that notifier part should be wrapped in try to catch if something goes wrong just like we do with the rest of the notifiers |
@thezoggy : I'm not sure if try/catch is necessary. Under the hood of As for squash, sure, I don't mind doing it, but you can use the Squash & Merge button build right into GitHub too if you want. Either way, i have no problems actioning both of your requests! 🙂 Edit: Squashed commits into 1 |
Indeed I always use squash and merge! |
No problem; |
sabnzbd/notifier.py
Outdated
|
||
if not test: | ||
# Get a list of tags that are set to use the common list | ||
target = get_target(notification_type, "apprise") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you use OptionStr
, it's guaranteed to be a string.
I would suggest to replace these 3 lines by 1 line using the walrus operator:
if target := get_target(notification_type, "apprise"):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Never used this before; code shifted to conform to your suggestion.
sabnzbd/notifier.py
Outdated
|
||
try: | ||
# The below notifies anything added to our list | ||
return ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to use 1 liner here, let's just split it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
sabnzbd/notifier.py
Outdated
def get_target(notification_type: str, section: str) -> Union[str, bool, None]: | ||
"""Check target of `notification_type` in `section` if enabled is set""" | ||
try: | ||
return ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to use one-liner here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
sabnzbd/api.py
Outdated
@@ -657,7 +657,7 @@ def _api_warnings(name, kwargs): | |||
LOG_JSON_RE = re.compile(rb"'(apikey|api|username|password)': '(.*?)'", re.I) | |||
LOG_INI_HIDE_RE = re.compile( | |||
rb"(apikey|api|user|username|password|email_pwd|email_account|email_to|email_from|pushover_token|pushover_userkey" | |||
rb"|pushbullet_apikey|prowl_apikey|growl_password|growl_server|IPv[4|6] address|Public address IPv[4|6]-only|Local IPv6 address)\s?=.*", | |||
rb"|apprise_urls|pushbullet_apikey|prowl_apikey|growl_password|growl_server|IPv[4|6] address|Public address IPv[4|6]-only|Local IPv6 address)\s?=.*", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably we need to add the other specific-URL's?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is done correctly now (i cheated a bit)
sabnzbd/notifier.py
Outdated
app_id="SABnzbd", | ||
app_desc="SABnzbd Notification", | ||
app_url="https://sabnzbd.org/", | ||
image_path_mask=os.path.join(os.path.dirname(__file__), "apprise", "apprise-{TYPE}.png"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should have any images in the /sabnzbd
directory, it's only for code.
We should put it in /icons/apprise
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want me to hardcode /icons/apprise
or find it relative to the directory. This is the edge case with Apprise, there are like 70 services that just use the icons found on the web, but then there are like 30 that use the local icons stored on the server (True self-hosted vs pulling from the cloud).
This was why i originally stored the images here and then cross-referenced them here via both web and locally (it's now i do it with apprise, so it's just 1 directory to manage - link.
At the end of the day, to truly get the best use of Apprise, you need some images stored locally. If you want, i can just not set a mask over-ride at all, and you'll use the ones that ship with Apprise instead of some custom SABnzbd ones i rigged up quickly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can fix this one up when all the code is fine, we have some constants to handle this :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost!
sabnzbd/notifier.py
Outdated
if target := get_target(notification_type, "apprise"): | ||
if isinstance(target, str): | ||
if target: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be just 1 line:
if target := get_target(notification_type, "apprise"): | |
if isinstance(target, str): | |
if target: | |
if target := get_target(notification_type, "apprise"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only catch is that target
can return None, or False. Also if it's an empty string, we want to process it. That means an over-ride was specified, but no URLs were provided (so to use the default). If i do if target :=
, how is it going to handle an empty string case (perhaps it's already skipped over at this point, so default logic won't be applied? - in short, i want to get inside that if-block if we get an empty string returned.
I'll see if i can refactor get_target a bet better so it can conform to your minimized example.
Edit: Done
requirements.txt
Outdated
@@ -54,7 +55,17 @@ notify2==0.3.1; sys_platform != 'win32' and sys_platform != 'darwin' | |||
# Uncomment line below or manually install after installing requirements. | |||
# pygobject>=3.10.2; sys_platform != 'win32' and sys_platform != 'darwin' | |||
|
|||
# PyYAML does not have binary packages for Mac Users | |||
PyYAML==6.0.1 --no-binary=PyYAML; sys_platform == 'darwin' | |||
PyYAML==6.0.1; sys_platform != 'darwin' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this special darwin
stuff here as this is only for run-from-source users, for who pip
will get the correct version. The --no-binary
in build_release
will fix it for the release.
|
||
if not test: | ||
# Get a list of tags that are set to use the common list | ||
if target := get_target(notification_type, "apprise"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry I missed that about the empty string!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no worries; it makes a bit more sense now.. True - use Default, otherwise string means there are URLs to load.
sabnzbd/skintext.py
Outdated
"explain-apprise_urls": TT("Use a comma and/or space to identify more then one URL"), #: Apprise settings | ||
"explain-apprise_extra_urls": TT( | ||
"Optionally override the default URL(s) for specific cases. To disable a notification for a specific category:" | ||
" simply enable it below, but do not provide it a URL to trigger off of. Alternatively, use comma and/or " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this. What can users do here? And how is it different from unchecking a notification-type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the same thing. You can drop this if you like. Was just trying to make it clear that anything specified in the individual entries overrides the default (does not stack with it)
Push a few changes, what do you think? :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pyYAML is needed by Apprise. Zoggys advice to define these 2 entries was a really good one. I don't think we should remove it from the requirements.txt.
Also, the way it was gave every system that had the ability to leverage the binary package to do so yet still be compatible for the systems that couldn't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not removed, it's added a few lines down:
https://github.com/sabnzbd/sabnzbd/pull/2796/files#diff-4d7c51b1efe9043e44439a949dfd92e5827321b34082903477fd04876edb7552R55
But without the special darwin
stuff, as this is handled already here:
https://github.com/sabnzbd/sabnzbd/pull/2796/files#diff-ec12760430cbac327a0a49aff7d95b2803a24a5d066c654f37a78f9177fdf36aR108
Just the one comment on pyYAML. Not sure about the pyobject changes as it's not really related to this PR. I'll just trust you there. I can't see the GUI/HTML tweaks as I'm on my mobile phone right now, but i have no doubt you nailed them. 🙂 I can try to peek later when I'm at my PC.🚀
I'll try to have a look. |
@caronc Could you maybe double check if everything still works with my changes? I don't have any of the API-based services myself, only |
Absolutely! I'm at my day job, but I'll do my best to test it when i can and get back you!🚀 |
@caronc Did you manage to check if it is still working as it should? :) |
It works fine for me |
@caronc Thanks! |
I think it started off as being simple, but with notification overrides on each category and references to your own images/icons, you got the full deal. So I'd say it's "Apprise Integration" at this point now 🙂 |
@caronc Is there a way we can 'unittest' this? |
I don't see why we can't. There is almost 100% test coverage with Apprise already Are you just looking to test the function |
Yes, test if there's no crash when actually calling it. Due to missing imports or something like that. |
Yes, there is a global try/catch inside of the |
Just a light stab at Apprise integrations right into SABnzbd
Multiple URLs supported by simply separating each with a space and/or comma.
Updated Screenshot
![image](https://private-user-images.githubusercontent.com/850374/303176168-86763fa9-3f07-4a4a-b129-bdb8f63c3ce4.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTkwMjI3MDYsIm5iZiI6MTcxOTAyMjQwNiwicGF0aCI6Ii84NTAzNzQvMzAzMTc2MTY4LTg2NzYzZmE5LTNmMDctNGE0YS1iMTI5LWJkYjhmNjNjM2NlNC5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwNjIyJTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDYyMlQwMjEzMjZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT00Yzc3N2RlMWQxOTJmY2RlMzNjMGY1OTYxNzg0ODVlNzc0MDgwMGU3NmVjNjk1MzE0M2IzNGY1MDI3ZDMxN2ZhJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.bixCg2Q8ao5N_h-tBp1V3pMVINQnXrkKH_GvvqZWU-8)
Rules:
Consider the screenshot above:
Job Finished
,Job Failed
and/orOther Message
categories.Disk Full
error, ONLY a Discord notice is sent instead.