RSS: Honor supybot.plugins.RSS.initialAnnounceHeadlines.

This commit is contained in:
Valentin Lorentz 2014-08-13 16:42:47 +02:00
parent 96ba33a296
commit c08a480f11
2 changed files with 40 additions and 14 deletions

View File

@ -63,15 +63,17 @@ announced_headlines_filename = \
class Feed: class Feed:
__slots__ = ('url', 'name', 'data', 'last_update', 'entries', __slots__ = ('url', 'name', 'data', 'last_update', 'entries',
'etag', 'modified', 'etag', 'modified', 'initial'
'lock', 'announced_entries') 'lock', 'announced_entries')
def __init__(self, name, url, plugin_is_loading=False, announced=None): def __init__(self, name, url, initial,
plugin_is_loading=False, announced=None):
assert name, name assert name, name
if not url: if not url:
assert utils.web.httpUrlRe.match(name), name assert utils.web.httpUrlRe.match(name), name
url = name url = name
self.name = name self.name = name
self.url = url self.url = url
self.initial = initial
self.data = None self.data = None
# We don't want to fetch feeds right after the plugin is # We don't want to fetch feeds right after the plugin is
# loaded (the bot could be starting, and thus already busy) # loaded (the bot could be starting, and thus already busy)
@ -84,8 +86,8 @@ class Feed:
utils.structures.TruncatableSet() utils.structures.TruncatableSet()
def __repr__(self): def __repr__(self):
return 'Feed(%r, %r, <bool>, %r)' % \ return 'Feed(%r, %r, %b, <bool>, %r)' % \
(self.name, self.url, self.announced_entries) (self.name, self.url, self.initial, self.announced_entries)
def get_command(self, plugin): def get_command(self, plugin):
docstring = format(_("""[<number of headlines>] docstring = format(_("""[<number of headlines>]
@ -152,7 +154,7 @@ class RSS(callbacks.Plugin):
except registry.NonExistentRegistryEntry: except registry.NonExistentRegistryEntry:
self.log.warning('%s is not a registered feed, removing.',name) self.log.warning('%s is not a registered feed, removing.',name)
continue continue
self.register_feed(name, url, True, announced.get(name, [])) self.register_feed(name, url, True, True, announced.get(name, []))
world.flushers.append(self._flush) world.flushers.append(self._flush)
def die(self): def die(self):
@ -194,9 +196,11 @@ class RSS(callbacks.Plugin):
registry.String('', _("""Feed-specific announce format. registry.String('', _("""Feed-specific announce format.
Defaults to supybot.plugins.RSS.announceFormat if empty."""))) Defaults to supybot.plugins.RSS.announceFormat if empty.""")))
def register_feed(self, name, url, plugin_is_loading, announced=[]): def register_feed(self, name, url, initial,
plugin_is_loading, announced=[]):
self.feed_names[name] = url self.feed_names[name] = url
self.feeds[url] = Feed(name, url, plugin_is_loading, announced) self.feeds[url] = Feed(name, url, initial,
plugin_is_loading, announced)
def remove_feed(self, feed): def remove_feed(self, feed):
del self.feed_names[feed.name] del self.feed_names[feed.name]
@ -253,7 +257,8 @@ class RSS(callbacks.Plugin):
feed.data = d.feed feed.data = d.feed
feed.entries = d.entries feed.entries = d.entries
feed.last_update = time.time() feed.last_update = time.time()
self.announce_feed(feed) (initial, feed.initial) = (feed.initial, False)
self.announce_feed(feed, initial)
def update_feed_in_thread(self, feed): def update_feed_in_thread(self, feed):
feed.last_update = time.time() feed.last_update = time.time()
@ -293,7 +298,7 @@ class RSS(callbacks.Plugin):
feed.announced_entries.truncate(2*len(entries)) feed.announced_entries.truncate(2*len(entries))
return new_entries return new_entries
def announce_feed(self, feed): def announce_feed(self, feed, initial):
new_entries = self.get_new_entries(feed) new_entries = self.get_new_entries(feed)
order = self.registryValue('sortFeedItems') order = self.registryValue('sortFeedItems')
@ -302,7 +307,15 @@ class RSS(callbacks.Plugin):
for channel in irc.state.channels: for channel in irc.state.channels:
if feed.name not in self.registryValue('announce', channel): if feed.name not in self.registryValue('announce', channel):
continue continue
for entry in new_entries: if initial:
n = self.registryValue('initialAnnounceHeadlines', channel)
if n:
announced_entries = new_entries[-n:]
else:
announced_entries = []
else:
announced_entries = new_entries
for entry in announced_entries:
self.announce_entry(irc, channel, feed, entry) self.announce_entry(irc, channel, feed, entry)
@ -355,7 +368,7 @@ class RSS(callbacks.Plugin):
""" """
self.assert_feed_does_not_exist(name, url) self.assert_feed_does_not_exist(name, url)
self.register_feed_config(name, url) self.register_feed_config(name, url)
self.register_feed(name, url, False) self.register_feed(name, url, True, False)
irc.replySuccess() irc.replySuccess()
add = wrap(add, ['feedName', 'url']) add = wrap(add, ['feedName', 'url'])
@ -405,7 +418,7 @@ class RSS(callbacks.Plugin):
irc.replySuccess() irc.replySuccess()
for name in feeds: for name in feeds:
feed = plugin.get_feed(name) feed = plugin.get_feed(name)
plugin.announce_feed(feed) plugin.announce_feed(feed, True)
add = wrap(add, [('checkChannelCapability', 'op'), add = wrap(add, [('checkChannelCapability', 'op'),
many(first('url', 'feedName'))]) many(first('url', 'feedName'))])
@ -437,7 +450,7 @@ class RSS(callbacks.Plugin):
self.log.debug('Fetching %u', url) self.log.debug('Fetching %u', url)
feed = self.get_feed(url) feed = self.get_feed(url)
if not feed: if not feed:
feed = Feed(url, url) feed = Feed(url, url, True)
if irc.isChannel(msg.args[0]): if irc.isChannel(msg.args[0]):
channel = msg.args[0] channel = msg.args[0]
else: else:
@ -470,7 +483,7 @@ class RSS(callbacks.Plugin):
pass pass
feed = self.get_feed(url) feed = self.get_feed(url)
if not feed: if not feed:
feed = Feed(url, url) feed = Feed(url, url, True)
self.update_feed_if_needed(feed) self.update_feed_if_needed(feed)
info = feed.data info = feed.data
if not info: if not info:

View File

@ -72,6 +72,19 @@ class RSSTestCase(ChannelPluginTestCase):
finally: finally:
self.assertNotError('rss remove xkcd') self.assertNotError('rss remove xkcd')
def testInitialAnnounce(self):
old_open = feedparser._open_resource
feedparser._open_resource = constant(xkcd_old)
try:
with conf.supybot.plugins.RSS.initialAnnounceHeadlines.context(0):
self.assertNotError('rss add xkcd http://xkcd.com/rss.xml')
self.assertNotError('rss announce add xkcd')
self.assertNoResponse(' ')
finally:
self._feedMsg('rss announce remove xkcd')
self._feedMsg('rss remove xkcd')
feedparser._open_resource = old_open
def testAnnounce(self): def testAnnounce(self):
old_open = feedparser._open_resource old_open = feedparser._open_resource
feedparser._open_resource = constant(xkcd_old) feedparser._open_resource = constant(xkcd_old)