dotfiles

Obligatory dotfiles repo
git clone git://git.danielmoch.com/dotfiles.git
Log | Files | Refs

commit 5f49d72724f518a44ef03564fe411112212d9937
parent 784a30a3b165174e7c083adb917a7d3beb55e4d7
Author: Daniel Moch <daniel@danielmoch.com>
Date:   Fri, 29 Jun 2018 13:34:30 -0400

Add urlwatch config

Diffstat:
A.config/urlwatch/hooks.py | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.config/urlwatch/urls.yaml | 27+++++++++++++++++++++++++++
A.config/urlwatch/urlwatch.yaml | 45+++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 238 insertions(+), 0 deletions(-)

diff --git a/.config/urlwatch/hooks.py b/.config/urlwatch/hooks.py @@ -0,0 +1,166 @@ +# +# Example hooks file for urlwatch +# +# Copyright (c) 2008-2018 Thomas Perl <m@thp.io> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +import re + +from urlwatch import filters +from urlwatch import jobs +from urlwatch import reporters + +from bs4 import BeautifulSoup + +#class CustomLoginJob(jobs.UrlJob): +# """Custom login for my webpage""" +# +# __kind__ = 'custom-login' +# __required__ = ('username', 'password') +# +# def retrieve(self, job_state): +# return 'Would log in to {} with {} and {}\n'.format(self.url, self.username, self.password) + + +#class CaseFilter(filters.FilterBase): +# """Custom filter for changing case, needs to be selected manually""" +# +# __kind__ = 'case' +# +# def filter(self, data, subfilter=None): +# # The subfilter is specified using a colon, for example the "case" +# # filter here can be specified as "case:upper" and "case:lower" +# +# if subfilter is None: +# subfilter = 'upper' +# +# if subfilter == 'upper': +# return data.upper() +# elif subfilter == 'lower': +# return data.lower() +# else: +# raise ValueError('Unknown case subfilter: %r' % (subfilter,)) + + +#class IndentFilter(filters.FilterBase): +# """Custom filter for indenting, needs to be selected manually""" +# +# __kind__ = 'indent' +# +# def filter(self, data, subfilter=None): +# # The subfilter here is a number of characters to indent +# +# if subfilter is None: +# indent = 8 +# else: +# indent = int(subfilter) +# +# ret + +class GitHubFilter(filters.FilterBase): + """Search for new Github releases or tags""" + __kind__ = 'github' + + def filter(self, data, subfilter=None): + soup = BeautifulSoup(data, "html5lib") + + releases = soup.select('h1.release-title a') + tags = soup.select('span.tag-name') + + if releases: + results = [rel.text for rel in releases] + return '\n'.join(results) + + elif tags: + results = [tag.text for tag in tags] + return '\n'.join(results) + + else: + fallback = soup.select('div.site') + return '\n'.join([str(tag) for tag in fallback]) + +class PyPIFilter(filters.FilterBase): + """Search for new releases at pypi.python.org""" + __kind__ = 'pypi' + + def filter(self, data, subfilter=None): + soup = BeautifulSoup(data, "html5lib") + + downloads = soup.select('table.list tr > td > span > a:nth-of-type(1)') + if downloads: + downloads = [dl.text for dl in downloads] + return '\n'.join(downloads) + else: + return data + +class PyPIOrgFilter(filters.FilterBase): + """Search for new releases on PyPI (pypi.org)""" + __kind__ = 'pypiorg' + + def filter(self, data, subfilter=None): + soup = BeautifulSoup(data, "html5lib") + + releases = soup.find_all('p', class_='release__version') + if releases: + releases = [rel.a.text for rel in releases] + return '\n'.join(releases) + else: + return data + +class CustomMatchUrlFilter(filters.AutoMatchFilter): + # The AutoMatchFilter will apply automatically to all filters + # that have the given properties set + MATCH = {'url': 'http://example.org/'} + + def filter(self, data): + return data.replace('foo', 'bar') + +class CustomRegexMatchUrlFilter(filters.RegexMatchFilter): + # Similar to AutoMatchFilter + MATCH = {'url': re.compile('http://example.org/.*')} + + def filter(self, data): + return data.replace('foo', 'bar') + + +class CustomTextFileReporter(reporters.TextReporter): + """Custom reporter that writes the text-only report to a file""" + + __kind__ = 'custom_file' + + def submit(self): + with open(self.config['filename'], 'w') as fp: + fp.write('\n'.join(super().submit())) + + +class CustomHtmlFileReporter(reporters.HtmlReporter): + """Custom reporter that writes the HTML report to a file""" + + __kind__ = 'custom_html' + + def submit(self): + with open(self.config['filename'], 'w') as fp: + fp.write('\n'.join(super().submit())) diff --git a/.config/urlwatch/urls.yaml b/.config/urlwatch/urls.yaml @@ -0,0 +1,27 @@ +filter: github +kind: url +url: https://github.com/mozilla/django-csp/releases +--- +filter: pypiorg +kind: url +url: https://pypi.org/project/django-otp/#history +--- +filter: pypiorg +kind: url +url: https://pypi.org/project/django_csp/#history +--- +filter: pypiorg +kind: url +url: https://pypi.org/project/django_csp/#history +--- +filter: pypiorg +kind: url +url: https://pypi.org/project/python-forecastio/#history +--- +filter: github +kind: url +url: https://github.com/orakaro/rainbowstream/releases +--- +filter: pypiorg +kind: url +url: https://pypi.org/project/rainbowstream/#history diff --git a/.config/urlwatch/urlwatch.yaml b/.config/urlwatch/urlwatch.yaml @@ -0,0 +1,45 @@ +display: + error: true + new: true + unchanged: false +report: + email: + enabled: false + from: '' + html: false + method: smtp + sendmail: + path: sendmail + smtp: + host: localhost + keyring: true + port: 25 + starttls: true + subject: '{count} changes: {jobs}' + to: '' + html: + diff: unified + mailgun: + api_key: '' + domain: '' + enabled: false + from_mail: '' + from_name: '' + subject: '{count} changes: {jobs}' + to: '' + pushbullet: + api_key: '' + enabled: false + pushover: + app: '' + device: '' + enabled: false + sound: spacealarm + user: '' + stdout: + color: true + enabled: true + text: + details: true + footer: true + line_length: 75