Add feedreader component (#1836)
This commit is contained in:
parent
e61ffff646
commit
c0a7b0f474
3 changed files with 84 additions and 0 deletions
|
@ -92,6 +92,7 @@ omit =
|
|||
homeassistant/components/device_tracker/ubus.py
|
||||
homeassistant/components/discovery.py
|
||||
homeassistant/components/downloader.py
|
||||
homeassistant/components/feedreader.py
|
||||
homeassistant/components/garage_door/wink.py
|
||||
homeassistant/components/ifttt.py
|
||||
homeassistant/components/keyboard.py
|
||||
|
|
80
homeassistant/components/feedreader.py
Normal file
80
homeassistant/components/feedreader.py
Normal file
|
@ -0,0 +1,80 @@
|
|||
"""RSS/Atom feed reader for Home Assistant."""
|
||||
from datetime import datetime
|
||||
from logging import getLogger
|
||||
import voluptuous as vol
|
||||
from homeassistant.helpers.event import track_utc_time_change
|
||||
|
||||
REQUIREMENTS = ['feedparser==5.2.1']
|
||||
_LOGGER = getLogger(__name__)
|
||||
DOMAIN = "feedreader"
|
||||
EVENT_FEEDREADER = "feedreader"
|
||||
# pylint: disable=no-value-for-parameter
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: {
|
||||
'urls': [vol.Url()],
|
||||
}
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
class FeedManager(object):
|
||||
"""Abstraction over feedparser module."""
|
||||
|
||||
def __init__(self, url, hass):
|
||||
"""Initialize the FeedManager object, poll every hour."""
|
||||
self._url = url
|
||||
self._feed = None
|
||||
self._hass = hass
|
||||
# Initialize last entry timestamp as epoch time
|
||||
self._last_entry_timestamp = datetime.utcfromtimestamp(0).timetuple()
|
||||
_LOGGER.debug('Loading feed %s', self._url)
|
||||
self._update()
|
||||
track_utc_time_change(hass, lambda now: self._update(),
|
||||
minute=0, second=0)
|
||||
|
||||
def _log_no_entries(self):
|
||||
"""Send no entries log at debug level."""
|
||||
_LOGGER.debug('No new entries in feed %s', self._url)
|
||||
|
||||
def _update(self):
|
||||
"""Update the feed and publish new entries in the event bus."""
|
||||
import feedparser
|
||||
_LOGGER.info('Fetching new data from feed %s', self._url)
|
||||
self._feed = feedparser.parse(self._url,
|
||||
etag=None if not self._feed
|
||||
else self._feed.get('etag'),
|
||||
modified=None if not self._feed
|
||||
else self._feed.get('modified'))
|
||||
if not self._feed:
|
||||
_LOGGER.error('Error fetching feed data from %s', self._url)
|
||||
else:
|
||||
if self._feed.bozo != 0:
|
||||
_LOGGER.error('Error parsing feed %s', self._url)
|
||||
# Using etag and modified, if there's no new data available,
|
||||
# the entries list will be empty
|
||||
elif len(self._feed.entries) > 0:
|
||||
_LOGGER.debug('Entries available in feed %s', self._url)
|
||||
self._publish_new_entries()
|
||||
self._last_entry_timestamp = \
|
||||
self._feed.entries[0].published_parsed
|
||||
else:
|
||||
self._log_no_entries()
|
||||
|
||||
def _publish_new_entries(self):
|
||||
"""Publish new entries to the event bus."""
|
||||
new_entries = False
|
||||
for entry in self._feed.entries:
|
||||
# Consider only entries newer then the latest parsed one
|
||||
if entry.published_parsed > self._last_entry_timestamp:
|
||||
new_entries = True
|
||||
entry.update({'feed_url': self._url})
|
||||
self._hass.bus.fire(EVENT_FEEDREADER, entry)
|
||||
if not new_entries:
|
||||
self._log_no_entries()
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Setup the feedreader component."""
|
||||
urls = config.get(DOMAIN)['urls']
|
||||
feeds = [FeedManager(url, hass) for url in urls]
|
||||
return len(feeds) > 0
|
|
@ -49,6 +49,9 @@ eliqonline==1.0.11
|
|||
# homeassistant.components.thermostat.honeywell
|
||||
evohomeclient==0.2.4
|
||||
|
||||
# homeassistant.components.feedreader
|
||||
feedparser==5.2.1
|
||||
|
||||
# homeassistant.components.notify.free_mobile
|
||||
freesms==0.1.0
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue