Skip to content
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

File Attachment Support Added to Apprise #173

Merged
merged 7 commits into from
Nov 17, 2019
Merged

File Attachment Support Added to Apprise #173

merged 7 commits into from
Nov 17, 2019

Conversation

caronc
Copy link
Owner

@caronc caronc commented Nov 11, 2019

Description:

Related issue (if applicable): fixes #172

Completion Status

  • Attachment Support Added
  • CLI Attachment Support Added
  • README.md

Notifications Enhanced for Attachment Support

The following notifications have been updated to support attachments:

  • apprise/plugins/NotifyEmail.py
  • apprise/plugins/NotifySlack.py
  • apprise/plugins/NotifyDiscord.py

Checklist

  • The code change is tested and works locally.
  • There is no commented out code in this PR.
  • No lint errors (use flake8)
  • 100% test coverage

Details

The ability to attach one or more files to a notification (provided the service has been enhanced to support this new feature). Here is an example of an email I set to myself using the following command:

# Attach 3 images to my notification
apprise -t "We can send attachments now with Apprise!" \
  -b "Check out the attachments" \
  --attach test/var/apprise-test.gif \
  --attach test/var/apprise-test.jpeg \
  --attach test/var/apprise-test.png

The result looks like this (for Email):
Screenshot from 2019-11-11 11-54-01

Similar to how the Issue (#172) was written, this can all be done through the API just as easily:

import apprise

# create our apprise instance:
a = apprise.Apprise()

# add an attachment supported notification service:
a.add('mailto://user:pass@gmail.com')

# Send your notification but reference the attach parameter
a.notify('Woohoo Attachments!', attach='/path/to/attachment')

Sending more than one attachment requires you to use the AppriseAttachment object:
Similar to how the Issue (#172) was written, this can all be done through the API just as easily:

import apprise

# create our apprise instance:
a = apprise.Apprise()

# add an attachment supported notification service:
a.add('mailto://user:pass@gmail.com')

# Create our AppriseAttachment Object
attach = AppriseAttachment()

# Add all of your attachments...
attach.add('/path/to/attachment')

# This feature is also able to pull content down from the web just to re-attach it for you:
# Note: at this time, your URL shouldn't contain parameters as they will be ignore
attach.add('https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf')

# Send your notification but reference the attach parameter
a.notify('Woohoo Attachments!', attach=attach)

Some other things to note:

  1. The following schema's are supported: http://, https://, and file://. Absolute and relative paths to locations are internally treated as file:// automatically.
  2. Attachments are just silently ignored by the services that don't support them (yet).
  3. Attachments work like regular messages. So if they can't be loaded and/or sent you be notified when the notify() call returns.
  4. Wild cards aren't supported. You must identify a --attach (-a) for each attachment you want to identify.
  5. Directories aren't supported. Again... if you want to specify more then one attachment (at this time) then each entry must be identified individually.
  6. Currently attachments are limited to 5MB (per file). This can be over-ridden at a per-service level and or manually.
  7. Attachments (if located remotely) are not actually retrieved until they are needed (prior to being sent). If the notification services triggered don't support attachments, then they're never retrieved.
  8. Attachments are cached once remotely retrieved. Future calls referencing the same content access what has already been retrieved. For the CLI, cached content is lost once the command has finished execution. Each execution will retrieve content again. You can control how long cache is kept for within the life of Apprise through the URL (see below).

Caveats:

  1. At this time remote web requests can not contain URL parameters (e.g. ?dl=1&lang=en). The arguments within an attachment URL are currently used to pass configuration back to Apprise.
    • I'm considering the option of just dropping this rule for web requests since the URL can play a big role in the query for some things.
    • Alternatively I can try to extrapolate the Apprise configuration entries out of the URL and rebuild the request as is (with remaining arguments). The only catch with this approach is if your URL uses name=, mime=, cache=, and/or verify= then they will never make it upstream (as these are reserved for Apprise).

Attachment URL Arguments

Everything passed as an attachment is treated as a URL at the end of the day. If you pass in /path/to/your/attachment to Apprise, this actually just gets prefixed (behind the scenes) with file:// and referenced as file:///path/to/your/attachment.

If you want to pass in options, you do this though arguments on the URL.

name=

Allow you to over-ride the filename (from it's source) before passing it to the target notification service(s):

  • http://host/path/a-file-name-you-do-not-want.jpg/?name=apprise.jpg: the following Apprise Attachment URL would haul down the content located as http://host/path/a-file-name-you-do-not-want.jpg and rename it to apprise.jpg for the purpose of resending it through notifications.
  • file:///absolute/path/to/camera/images/DSC_000.jpg?name=FamilyPhoto.jpg: The same effect takes place for using files.

mime=

All files have a mime-type associated with them. A mime-type looks like image/png for example for PNG images. Apprise is smart enough to figure the mime-type out on it's own in most scenarios. Mime types really only play a big roll in the presentation side (at the notification service level). Hence telling Slack ahead of time it's getting an image vs a sound clip changes the rich experience you get presented. You can over-ride the mime type (if you don't like the way Apprise got it) by specifying mime= on your URL:

  • file:///path/to/content?name=Report.yaml: In this case Apprise will be smart enough to determine that the content is actually a YAML file which has a mimetype of text/x-yaml. Without knowing the name= value specified Apprise couldn't have otherwise determined that from just content.
  • file:///path/to/content?mime=text/x-yaml: In this example (very similar to the above), you let Apprise know ahead of time what the mime type is.

In most cases, you will seldom ever have to override and/or specify the mime type.

verify=

This is used for https requests only at this time. It is used to validate that the remote host name actually has a valid SSL Certificate. If you're running Apprise in a closed network where it can't verify the hostname of a secure website, you will need to set this to False. verify= is a common parameter that can also be used with Apprise Notification URLs and Apprise Configuration URLs as well. For consistency, it is also used here if needed.

cache=

By default this value is set to Yes if not otherwise specified. Possible values are:

  • A Boolean (Yes or No)
  • A positive integer representing how long the attachment is valid for before it should be considered stale and re-downloaded.

At the time of creating attachment support to Apprise, It only recognizes the following URLs (as identified above): file://, http://, and https:// . This cache= directive has no impact on local files (file://) as they never expire. However for files that have been retrieved remotely; sometimes we want to invalidate what we previously downloaded before posting the same attachment again. A use case for this could be a security camera. You can appoint Apprise to it and ensure that each time a notification is sent, an updated image is retrieved.

Setting the the cache= value to zero (0) or No have the same effect.

@codecov-io
Copy link

codecov-io commented Nov 11, 2019

Codecov Report

Merging #173 into master will not change coverage.
The diff coverage is 100%.

Impacted file tree graph

@@          Coverage Diff           @@
##           master   #173    +/-   ##
======================================
  Coverage     100%   100%            
======================================
  Files          63     68     +5     
  Lines        7262   7753   +491     
  Branches     1132   1244   +112     
======================================
+ Hits         7262   7753   +491
Impacted Files Coverage Δ
apprise/attachment/AttachHTTP.py 100% <100%> (ø)
apprise/attachment/__init__.py 100% <100%> (ø)
apprise/attachment/AttachBase.py 100% <100%> (ø)
apprise/AppriseAttachment.py 100% <100%> (ø)
apprise/plugins/NotifyBase.py 100% <100%> (ø) ⬆️
apprise/plugins/NotifyEmail.py 100% <100%> (ø) ⬆️
apprise/Apprise.py 100% <100%> (ø) ⬆️
apprise/plugins/NotifySlack.py 100% <100%> (ø) ⬆️
apprise/plugins/NotifyDiscord.py 100% <100%> (ø) ⬆️
apprise/attachment/AttachFile.py 100% <100%> (ø)
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5ee9065...0653835. Read the comment docs.

@caronc caronc merged commit e5c0334 into master Nov 17, 2019
@caronc caronc deleted the add-attachments branch November 17, 2019 13:43
@caronc caronc mentioned this pull request Nov 22, 2019
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

File Attachment Support
2 participants