Skip to content

Commit

Permalink
Merge pull request #633 from nitz/feature-add-reporter-prowl
Browse files Browse the repository at this point in the history
Add reporter: Prowl App
  • Loading branch information
thp committed Apr 9, 2021
2 parents 9186328 + 4bbab7e commit 1659be2
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@ The format mostly follows [Keep a Changelog](http://keepachangelog.com/en/1.0.0/

- New filter: `pretty-xml` to indent/pretty-print XML documents
- New filter: `jq` to parse, transform, and extract JSON data
- New reporter: `prowl` (by nitz)

### Fixed

Expand Down
35 changes: 35 additions & 0 deletions docs/source/reporters.rst
Expand Up @@ -55,6 +55,7 @@ At the moment, the following reporters are built-in:
- **telegram**: Send a message using Telegram
- **ifttt**: Send summary via IFTTT
- **xmpp**: Send a message using the XMPP Protocol
- **prowl**: Send a message via prowlapp.com

.. To convert the "urlwatch --features" output, use:
sed -e 's/^ \* \(.*\) - \(.*\)$/- **\1**: \2/'
Expand Down Expand Up @@ -365,3 +366,37 @@ If for whatever reason you cannot use a keyring to store your password
you can also set the ``insecure_password`` option in the XMPP config.
For more information about the security implications, see
:ref:`smtp-login-without-keyring`.

Prowl
-----

You can have notifications sent to you through the `Prowl` push
notification service, to recieve the notification on iOS.

To achieve this, you should register a new Prowl account, and have
the Prowl application installed on your iOS device.

To create an API key for urlwatch:

1. Log into the Prowl website at https://prowlapp.com/
2. Navigate to the “API Keys” tab.
3. Scroll to the “Generate a new API key” section.
4. Give the key a note that will remind you you've used it for urlwatch.
5. Press “Generate Key”
6. Copy the resulting key.

Here is a sample configuration:

.. code:: yaml
prowl:
enabled: true
api_key: '<your api key here>'
priority: 2
application: 'urlwatch example'
subject: '{count} changes: {jobs}'
The “subject" field is similar to the subject field in the email, and
will be used as the name of the Prowl event. The application is prepended
to the event and shown as the source of the event in the Prowl App.

60 changes: 60 additions & 0 deletions lib/urlwatch/reporters.py
Expand Up @@ -975,3 +975,63 @@ def submit(self):

for chunk in chunkstring(text, self.MAX_LENGTH, numbering=True):
asyncio.run(xmpp.send(chunk))


class ProwlReporter(TextReporter):
"""Send a detailed notification via prowlapp.com"""

__kind__ = 'prowl'

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def submit(self):
api_add = 'https://api.prowlapp.com/publicapi/add'

text = '\n'.join(super().submit())

if not text:
logger.debug('Not calling Prowl API (no changes)')
return

filtered_job_states = list(self.report.get_filtered_job_states(self.job_states))
subject_args = {
'count': len(filtered_job_states),
'jobs': ', '.join(job_state.job.pretty_name() for job_state in filtered_job_states),
}

# 'subject' used in the config file, but the API
# uses what might be called the subject as the 'event'
event = self.config['subject'].format(**subject_args)

# 'application' is prepended to the message in prowl,
# to show the source of the notification. this too,
# is user configurable, and may reference subject args
application = self.config.get('application')
if application is not None:
application = application.format(**subject_args)
else:
application = '{0} v{1}'.format(urlwatch.pkgname, urlwatch.__version__)

# build the data to post
post_data = {
'event': event[:1024].encode('utf8'),
'description': text[:10000].encode('utf8'),
'application': application[:256].encode('utf8'),
'apikey': self.config['api_key'],
'priority': self.config['priority']
}

# all set up, add the notification!
result = requests.post(api_add, data=post_data)

try:
if result.status_code in (requests.codes.ok, requests.codes.no_content):
logger.info("Prowl response: ok")
else:
logger.error("Prowl error: {0}".format(result.text))
except ValueError:
logger.error("Failed to parse Prowl response. HTTP status code: {0}, content: {1}".format(
result.status_code, result.content))

return result
7 changes: 7 additions & 0 deletions lib/urlwatch/storage.py
Expand Up @@ -170,6 +170,13 @@
'sender': '',
'recipient': '',
},
'prowl': {
'enabled': False,
'api_key': '',
'priority': 0,
'application': '',
'subject': '{count} changes: {jobs}'
},
},

'job_defaults': {
Expand Down

0 comments on commit 1659be2

Please sign in to comment.