irc3.plugins.feeds Feeds pluginΒΆ

Send a notification on channel on new feed entry.

Your config must looks like this:

[bot]
includes =
    irc3.plugins.feeds

[irc3.plugins.feeds]
channels = #irc3                             # global channel to notify
delay = 5                                    # delay to check feeds
directory = ~/.irc3/feeds                    # directory to store feeds
hook = irc3.plugins.feeds.default_hook       # dotted name to a callable
fmt = [{name}] {entry.title} - {entry.link}  # formatter

# some feeds: name = url
github/irc3 = https://github.com/gawel/irc3/commits/master.atom#irc3
# custom formatter for the feed
github/irc3.fmt = [{feed.name}] New commit: {entry.title} - {entry.link}
# custom channels
github/irc3.channels = #irc3dev #irc3
# custom delay
github/irc3.delay = 10

Hook is a dotted name refering to a callable (function or class) wich take a list of entries as argument. It should yield the entries you want really show:

>>> def hook(entries):
...     for entry in entries:
...         if 'something bad' not in entry.title:
...             yield entry

>>> class Hook:
...     def __init__(self, bot):
...         self.bot = bot
...     def __call__(self, entries):
...         for entry in entries:
...             if 'something bad' not in entry.title:
...                 yield entry

Here is a more complete hook used on freenode#irc3:

class FeedsHook(object):
    """Custom hook for irc3.plugins.feeds"""

    def __init__(self, bot):
        self.bot = bot
        self.packages = [
            'asyncio', 'irc3', 'panoramisk',
            'requests', 'trollius', 'webtest',
            'pyramid',
        ]

    def filter_travis(self, entry):
        """Only show the latest entry iif this entry is in a new state"""
        fstate = entry.filename + '.state'
        if os.path.isfile(fstate):
            with open(fstate) as fd:
                state = fd.read().strip()
        else:
            state = None
        if 'failed' in entry.summary:
            nstate = 'failed'
        else:
            nstate = 'success'
        with open(fstate, 'w') as fd:
            fd.write(nstate)
        if state != nstate:
            build = entry.title.split('#')[1]
            entry['title'] = 'Build #{0} {1}'.format(build, nstate)
            return True

    def filter_pypi(self, entry):
        """Show only usefull packages"""
        for package in self.packages:
            if entry.title.lower().startswith(package):
                return entry

    def __call__(self, entries):
        travis = {}
        for entry in entries:
            if entry.feed.name.startswith('travis/'):
                travis[entry.feed.name] = entry
            elif entry.feed.name.startswith('pypi/'):
                yield self.filter_pypi(entry)
            else:
                yield entry
        for entry in travis.values():
            if self.filter_travis(entry):
                yield entry