Closed caronc closed 5 years ago
I might map this to a different function (instead of add()) as I could see developers not wanting their users to use these new URLs directly. So maybe a simple load() function would be better and a --config (-c) for the CLI.
Useful. It would mean an app (eg LazyLibrarian) could allow the user to input/store their username, password, token, whatever, and the app would construct the url from the component parts. Would be good if the yaml could contain all the variant urls allowed for each plugin eg
growl://hostname
growl://hostname:portno
growl://password@hostname
growl://password@hostname:port
in a format that the app can complete depending what parts the user provided, so if we were only given hostname we use the first format, if we also have password we use 3rd, etc. Or maybe the url layouts should be in the details() function so the user doesn't get to edit it?
Exactly @philborman,
As an example, one could provide just the URL growl:// (and nothing more) in the YAML and then just identify all of the arguments below if you wanted ie:
urls:
# must remember colon (:) at end of url if you plan to do things this way though
- growl://:
args:
hostname: localhost
password: clear_text_password
# or a gmail example (thanks to email templating)
- mailto://:
user: myname
password: mypassword
hostname: gmail.com
I also thought, maybe a 'text-only file' would be handy to support too? It would be incredibly basic and ONLY support URLs:
# a simple text file version - URLs only
# use YAML for extra functionality
# pound symbols (#) would act as comments
growl://password@hostname:port
pbul://o.gn5kj6nfhv736I7jC3cj3QLRiyhgl98b
Or maybe the url layouts should be in the details() function so the user doesn't get to edit it?
Hmm... that's a tough one; if the URLs were part of the output provided by the details() function, it would only be for reference usage (I would think?). I mean, it might be helpful, but it only offers part of the puzzle. Some of the notification services (like Discord and Telegram) have entries like url://{tokena}/{tokenb}/ which would mean nothing to a brand new user unless they had first looked at the the help/wiki page to determine where these {tokens} come from. That said, I do realize that services like email:// and json:// are obvious when you see the URL examples, so for this there is value to your suggestion. This is a bit off topic of this particular issue though. I don't want to constrict templating or fixed urls because PushBullet for example has no limit to how many users/channels/devices you want to push your notification to. You just simply add another slash (/) to the end of your url and add the next thing that needs notifying.
Thoughts?
At the moment our apprise telegram notifier looks like this...
and the old notifier looked like this...
I think it's a lot easier for the user to handle the old style with clearly defined fields and let the app construct the url. Probably have a dropdown select box to choose the new notifier type from the service_names in apobj.details()['schemas'] and then add input boxes for the appropriate arguments for that schema.
You got a great thought process going on right now, i just want to steer it away from this thread since it's a bit off topic, but definitely worth talking about!
I brainstormed a few ideas and put them in the other ticket based on what you discussed here. But taking it in a slightly different route. I'm definitely interested in your input!
Edit: you should consider deleting that image if the telegram URL you identified IF it is actually valid. Great looking UI though!
I didn't realize how much of an undertaking configuration support & maintaining 100% code coverage would be. This latest push adds --config (-c) to the CLI in addition to --tag (-g) so you can label and control the reference to your entries.
The TEXT Based configuration file just looks like so:
# use pound/hashtag symbols to comment lines
# syntax is <tags>=<url> or jsut <url> on each line
desktop=gnome://
tv,kitchen=kodi://myuser:mypass@kitchen.hostame
tv,basement=kodi://myuser:mypass@basement.hostame
The file above is all your configuration file has to look like. If you save it in one of these locations then it will automatically be sourced for you when calling apprise from the command line:
# with respect to the above, we might do something like this:
notify -b "Notify only Kodi's in house" --tag=tv
That will cause only the tags (there are 2 of them in the example) to have the notifications sent
You can also get your configuration from another file, or even the internet:
# website
notify --config=https://myserver/my/apprise/config -b "notify everything"
# a local file and a website:
notify --config=https://myserver/my/apprise/config \
--config=/a/path/on/the/local/pc -b "notify everything"
# everything that can be loaded will automatically be notified unless
# you specify tags which will then cause only those that match
# to be triggered:
notify --config=https://myserver/my/apprise/config \
--config=/a/path/on/the/local/pc -b "notify everything" \
--tag=my-admin-team
Tagging is a whole level of it's own because you might want to OR tags together or even AND them. Apprise supports this:
# assuming you got your configuration in place:
notify -b "has TagA" --tag=TagA
notify -b "has TagA OR TagB" --tag=TagA --tag=TagB
# For each item you group with the same --tag value is AND'ed
notify -b "has TagA AND TagB" --tag="TagA, TagB"
notify -b "has (TagA AND TagB) OR TagC" --tag="TagA, TagB" --tag=TagC
For developers, there is a new object called AppriseConfig() which works very similar to the AppriseAsset() object. It is merely an optional object you can add to your Apprise experience.
Up until now, you would add URLs to Apprise like so:
from apprise import Apprise
a = Apprise()
a.add('mailto://user:pass@hotmail.com', tag='email')
a.add('gnome://', tag='desktop')
# Now the only change is you can also add() the AppriseConfig object
ac = AppriseConfig()
ac.add('/local/path/on/your/server/config')
# the proper file url format is preferred and works too
ac.add('file://~.apprise')
# urls too, http an https
ac.add('http://localhost/my/apprise/config/url/path')
# This object can be simply added into our apprise object as though
# it were a notification service:
a.add(ac)
# Send off our all of our notifications
a.notify()
# filter our notifications by what we tagged:
a.notify(tag="tv")
YAML Support added now which is slightly different then how it was identified at the start of this thread (so ignore that and role with this instead). Here is the configuration in it's absolute simplest form:
#
# Minimal Configuration Example
#
# Define your URLs
urls:
# Either on-line each entry like this:
- json://localhost
- xml://localhost
# Or add a colon to the end of the URL where you can optionally provide
# over-ride entries. One of the most likely entry to be used here
# is the tag entry. This gets extended to the global tag (if defined)
# above
- windows://:
# 'tag' is a special keyword that allows you to associate tags with your
# services:
- tag: desktop
To expand on tags, you can also identify a global entry that will be applied to ALL of the subsequent URL entries defined in the YAML file. Example
#
# Global Tag Configuration Example
#
# Define our version
version: 1
# Our global tags to associate with all of the URLs we define
tag: admin, devops
# Define your URLs (Mandatory!)
urls:
- xml://localhost
- json://localhost
- kodi://user:pass@myserver
You can over-ride the AppriseAsset Object too if you know the objects you want to update using the special keyword asset.
#
# Asset Override Configuration Example
#
# Define our version
version: 1
# Define an Asset object if you wish (Optional)
asset:
app_id: NuxRef
app_desc: NuxRef Notification
app_url: http://nuxref.com
# Define your URLs (Mandatory!)
urls:
- mailto://bill:pass@protomail.com
YAML configuration gets more powerful when you want to utilize a URL more then once. Here is a more complicated example:
# if no version is specified then version 1 is presumed. Thus this is a
# completely optional field. It's a good idea to just add this line because it
# will help with future ambiguity (if it ever occurs).
version: 1
# Define an Asset object if you wish (Optional)
asset:
app_id: AppriseTest
app_desc: Apprise Test Notifications
app_url: http://nuxref.com
# Optionally define some global tags to associate with ALL of your
# urls below.
tag: admin, devops
# Define your URLs (Mandatory!)
urls:
# One-liner (no colon at the end); just the url as you'd expect it:
- json://localhost
# A colon grants you customization; the below associates a tag
- xml://localhost:
- tag: customer
# Replication Example #
# The more elements you specify under a URL the more times the URL will
# get replicated and used. Hence this entry actually could be considered
# 2 URLs being called with just the destination email address changed:
- mailto://george:password@gmail.com:
- to: jason@hotmail.com
- to: fred@live.com
# Again... to re-iterate, the above mailto:// would actually fire two (2)
# separate emails each with a different destination address specified.
# Be careful when defining your arguments and differentiating between
# when to use the dash (-) and when not to. Each time you do, you will
# cause another instance to be created.
# Defining more then 1 element to a muti-set is easy, it looks like this:
- mailto://jackson:abc123@hotmail.com:
- to: jeff@gmail.com
tag: jeff, customer
- to: chris@yahoo.com
tag: chris, customer
Nothing changes from a development perspective; the example in the earlier comment is the same for this too.
.yml and .yaml files are assumed to be YAML where as anything else is assumed to follow the TEXT structure.
for HTTP requests, the Content-Type (Mime Type) is very important.
Support YAML formats:
Support TEXT formats:
You can always force the format and over-ride anything detected by adding ?format=text or ?format=yaml to your configuration URL.
# force a file that would have otherwise been interpreted as a text file
# to be considered a YAML one:
notify --config=https://myserver/my/apprise/config?format=yaml -b "notify everything"
This applies to developers to whenever they load the AppriseConfig object:
from apprise import Apprise
# create our object
a = Apprise()
# Our Config object while explicitly setting the format to yaml
# you can pass this in as an argument to the class to save
# ourselves from calling config.add().
config = AppriseConfig('https://myserver/yaml/?format=yaml')
# add our config object into apprise
a.add(config)
# Send our notification to all of the sites loaded from the specified
# configuration website
a.notify("hello world!")
Pull request created #79
Merged into master branch; closing issue.
One would simply utilize the file://, http:// and/or https:// URLs as part of their apprise syntax; however their meaning would be interpreted as read to fetch the notifications to load.
The idea is you lock all of your tokens, passwords and usernames in a yaml file that has permissions that only you can access. It's better than passing this information on the command line.
Here would be an example:
http:// and https:// would work the same as file:// except they'd go to the URL you specify and hope to find a YAML file to read. Ideally you should be passing back the correct mime type for this such as one of the following:
The most minimal apprise syntax would be as follows:
To take this feature a step further, the URL should be allowed to be constructed through options. This allows for an easier read (and doesn't require you to escape special characters such as slashes (/) or ampersands (&) since they otherwise conflict with the URL.
If we allow all of this, then we might as well additionally support the override of the apprise asset object too. So if we take this configuration one step further: