Skip to content

Commit

Permalink
Add pre-commit and code checks, add more typing
Browse files Browse the repository at this point in the history
  • Loading branch information
ogajduse committed Jul 28, 2023
1 parent 5cf6ac7 commit d13d12b
Show file tree
Hide file tree
Showing 14 changed files with 291 additions and 64 deletions.
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This is the configuration file for Dependabot. You can find configuration information below.
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# Note: Dependabot has a configurable max open PR limit of 5

version: 2
updates:
# Maintain dependencies for our GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
labels:
- "dependencies"
18 changes: 18 additions & 0 deletions .github/workflows/hacs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: HACS Action

on:
push:
pull_request:
schedule:
- cron: "0 0 * * *"

jobs:
hacs:
name: HACS Action
runs-on: "ubuntu-latest"
steps:
- name: HACS Action
uses: "hacs/action@main"
with:
category: "integration"
ignore: "brands"
File renamed without changes.
31 changes: 31 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI/CQ

on:
pull_request:
types: ["opened", "synchronize", "reopened"]

jobs:
codechecks:
name: Code Quality
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11"]
steps:
- name: Checkout Repository
uses: actions/checkout@v3

- name: Set Up Python-${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Pre Commit Checks
uses: pre-commit/[email protected]

- name: Install Dependencies
run: pip install .[dev]

- name: Analysis (git diff)
if: failure()
run: git diff
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Compiled python code.
*.pyc
build/
*.egg-info/
30 changes: 30 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# configuration for pre-commit git hooks

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: debug-statements
- repo: https://github.com/asottile/pyupgrade
rev: v3.3.0
hooks:
- id: pyupgrade
args: [--py311-plus]
- repo: https://github.com/psf/black
rev: "22.10.0"
hooks:
- id: black
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.4.1"
hooks:
- id: mypy
additional_dependencies: [homeassistant-stubs, voluptuous-stubs, types-python-dateutil]
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.0.278
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"python.formatting.provider": "black"
}
}
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
1 change: 1 addition & 0 deletions custom_components/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Init file for custom_components."""
3 changes: 1 addition & 2 deletions custom_components/feedparser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""
A component which allows you to parse an RSS feed into a sensor
"""A component which allows you to parse an RSS feed into a sensor.
For more details about this component, please refer to the documentation at
https://github.com/custom-components/sensor.feedparser
Expand Down
3 changes: 2 additions & 1 deletion custom_components/feedparser/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": [],
"documentation": "https://github.com/custom-components/feedparser/blob/master/README.md",
"iot_class": "cloud_polling",
"requirements": ["feedparser==6.0.10"],
"issue_tracker": "https://github.com/custom-components/feedparser/issues",
"requirements": ["feedparser==6.0.10", "python-dateutil"],
"version": "0.1.11"
}
119 changes: 61 additions & 58 deletions custom_components/feedparser/sensor.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
"""Feedparser sensor"""
"""Feedparser sensor."""
from __future__ import annotations

import asyncio
import re
from datetime import timedelta
import logging
from datetime import datetime, timedelta
from typing import TYPE_CHECKING

import feedparser # type: ignore[import]
import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from dateutil import parser
from feedparser import FeedParserDict
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
from homeassistant.const import CONF_NAME, CONF_SCAN_INTERVAL
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
import homeassistant.util.dt as dt
from homeassistant.util import dt

import feedparser
if TYPE_CHECKING:
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType

__version__ = "0.1.11"

COMPONENT_REPO = "https://github.com/custom-components/sensor.feedparser/"
COMPONENT_REPO = "https://github.com/custom-components/feedparser/"

REQUIREMENTS = ["feedparser"]

CONF_FEED_URL = "feed_url"
CONF_DATE_FORMAT = "date_format"
CONF_LOCAL_TIME = "local_time"
CONF_LOCAL_TIME = "local_time"
CONF_INCLUSIONS = "inclusions"
CONF_EXCLUSIONS = "exclusions"
CONF_SHOW_TOPN = "show_topn"
Expand All @@ -43,88 +45,93 @@
vol.Optional(CONF_INCLUSIONS, default=[]): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_EXCLUSIONS, default=[]): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL): cv.time_period,
}
},
)

_LOGGER = logging.getLogger(__name__)


"""@asyncio.coroutine"""
async def async_setup_platform(
hass: HomeAssistant,
config: ConfigType,
async_add_devices: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up the Feedparser sensor."""
async_add_devices(
[
FeedParserSensor(
feed=config[CONF_FEED_URL],
name=config[CONF_NAME],
date_format=config[CONF_DATE_FORMAT],
local_time=config[CONF_LOCAL_TIME],
show_topn=config[CONF_SHOW_TOPN],
inclusions=config[CONF_INCLUSIONS],
exclusions=config[CONF_EXCLUSIONS],
scan_interval=config[CONF_SCAN_INTERVAL],
)
local_time=config[CONF_LOCAL_TIME],
),
],
True,
update_before_add=True,
)


class FeedParserSensor(SensorEntity):
"""Representation of a Feedparser sensor."""

def __init__(
self,
self: FeedParserSensor,
feed: str,
name: str,
date_format: str,
show_topn: int,
exclusions: list[str | None],
inclusions: list[str | None],
scan_interval: timedelta,
local_time: bool,
show_topn: str,
exclusions: str,
inclusions: str,
scan_interval: int,
) -> None:
self._feed = feed
self._attr_name = name
self._attr_icon = "mdi:rss"
self._date_format = date_format
self._show_topn = show_topn
self._local_time = local_time
self._show_topn: int = show_topn
self._inclusions = inclusions
self._exclusions = exclusions
self._scan_interval = scan_interval
self._attr_state = None
self._entries = []
self._local_time = local_time
self._entries: list[dict[str, str]] = []
self._attr_extra_state_attributes = {"entries": self._entries}

def update(self):
parsed_feed = feedparser.parse(self._feed)
def update(self: FeedParserSensor) -> None:
"""Parse the feed and update the state of the sensor."""
parsed_feed: FeedParserDict = feedparser.parse(self._feed)

if not parsed_feed:
return False
else:
self._attr_state = (
self._show_topn
if len(parsed_feed.entries) > self._show_topn
else len(parsed_feed.entries)
)
self._entries = []

for entry in parsed_feed.entries[: self._attr_state]:
entry_value = {}

for key, value in entry.items():
if (
(self._inclusions and key not in self._inclusions)
or ("parsed" in key)
or (key in self._exclusions)
):
continue
if key in ["published", "updated", "created", "expired"]:
value = parser.parse(value)
if self._local_time:
value = dt.as_local(value)
value = value.strftime(self._date_format)
self._attr_native_value = None
return

self._attr_native_value = (
self._show_topn
if len(parsed_feed.entries) > self._show_topn
else len(parsed_feed.entries)
)
self._entries = []

for entry in parsed_feed.entries[: self._attr_state]:
entry_value = {}

for key, value in entry.items():
if (
(self._inclusions and key not in self._inclusions)
or ("parsed" in key)
or (key in self._exclusions)
):
continue
if key in ["published", "updated", "created", "expired"]:
time: datetime = parser.parse(value)
if self._local_time:
time = dt.as_local(time)
entry_value[key] = time.strftime(self._date_format)
else:
entry_value[key] = value

if "image" in self._inclusions and "image" not in entry_value.keys():
Expand All @@ -145,13 +152,9 @@ def update(self):
"image"
] = DEFAULT_THUMBNAIL # use default image if no image found

self._entries.append(entry_value)

@property
def state(self):
"""Return the state of the sensor."""
return self._attr_state
self._entries.append(entry_value)

@property
def extra_state_attributes(self):
def extra_state_attributes(self: FeedParserSensor) -> dict[str, list]:
"""Return entity specific state attributes."""
return {"entries": self._entries}
1 change: 0 additions & 1 deletion hacs.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"name": "Feedparser",
"homeassistant": "2021.4.0",
"domains": ["sensor"],
"render_readme": true
}
Loading

0 comments on commit d13d12b

Please sign in to comment.