Updated ics_calendar.
This commit is contained in:
35
custom_components/ics_calendar/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
35
custom_components/ics_calendar/.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Home Assistant Setup**
|
||||
Please indicate your version of HA and how it is installed.
|
||||
|
||||
Version:
|
||||
|
||||
Installation Type (put an X between the square brackets for your HA):
|
||||
[] Home Assistant OS
|
||||
[] Home Assistant Supervised
|
||||
[] Home Assistant Container
|
||||
[] Home Assistant Core
|
||||
|
||||
Hardware platform:
|
||||
[] ARM
|
||||
[] x86-64
|
||||
|
||||
Are you running in a container environment like Docker or Kubernetes?
|
||||
[] Yes
|
||||
[] No
|
||||
|
||||
If running in a container, how is your image built?
|
||||
[] Official HA container image
|
||||
[] Official HA container image with customizations
|
||||
[] Custom built container image
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of the bug
|
||||
14
custom_components/ics_calendar/.github/dependabot.yml
vendored
Normal file
14
custom_components/ics_calendar/.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "pip" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
reviewers:
|
||||
- "franc6"
|
||||
10
custom_components/ics_calendar/.github/pull_request_template.md
vendored
Normal file
10
custom_components/ics_calendar/.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
Fixes #
|
||||
|
||||
Description of change:
|
||||
|
||||
## Formatting, testing, and code coverage
|
||||
Please note your pull request won't be accepted if you haven't properly formatted your source code, and ensured the unit tests are appropriate. Please note if you are not running on Windows, you can either run the scripts via a bash installation (like git-bash).
|
||||
|
||||
- [] formatstyle.sh reports no errors
|
||||
- [] All unit tests pass (test.sh)
|
||||
- [] Code coverage has not decreased (test.sh)
|
||||
21
custom_components/ics_calendar/.github/workflows/hacs.yaml
vendored
Normal file
21
custom_components/ics_calendar/.github/workflows/hacs.yaml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Validate with hassfest and run HACS action
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: "actions/checkout@v4"
|
||||
- name: Validate with hassfest
|
||||
uses: "home-assistant/actions/hassfest@master"
|
||||
- name: HACS Action
|
||||
uses: "hacs/action@main"
|
||||
with:
|
||||
category: integration
|
||||
46
custom_components/ics_calendar/.github/workflows/lint.yaml
vendored
Normal file
46
custom_components/ics_calendar/.github/workflows/lint.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [releases]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
version: "0.4.20"
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: "pyproject.toml"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv sync --prerelease=allow --dev --extra tests
|
||||
|
||||
- name: Run isort --check
|
||||
run: |
|
||||
uv run --prerelease=allow isort --check custom_components/ics_calendar tests
|
||||
|
||||
- name: Run black --check
|
||||
run: |
|
||||
uv run --prerelease=allow black --check custom_components/ics_calendar tests
|
||||
|
||||
- name: Run flake8
|
||||
run: |
|
||||
uv run --prerelease=allow flake8
|
||||
|
||||
- name: Run pydocstyle
|
||||
run: |
|
||||
uv run --prerelease=allow pydocstyle -v custom_components/ics_calendar tests
|
||||
|
||||
- name: Run pylint
|
||||
run: |
|
||||
uv run --prerelease=allow pylint custom_components/ics_calendar
|
||||
44
custom_components/ics_calendar/.github/workflows/runtests.yaml
vendored
Normal file
44
custom_components/ics_calendar/.github/workflows/runtests.yaml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
name: Run Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [releases]
|
||||
pull_request:
|
||||
branches: [releases]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set timezone
|
||||
run: |
|
||||
sudo timedatectl set-timezone America/New_York
|
||||
timedatectl
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v3
|
||||
with:
|
||||
version: "0.4.20"
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version-file: "pyproject.toml"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
uv sync --prerelease=allow --extra tests
|
||||
|
||||
- name: Run pytest
|
||||
run: |
|
||||
PYTHONDONTWRITEBYTECODE=1 uv run --prerelease=allow pytest tests/
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
@@ -88,6 +88,10 @@ TIMEOUT_OPTS_SCHEMA = vol.Schema(
|
||||
{vol.Optional(CONF_CONNECTION_TIMEOUT, default=None): cv.positive_float}
|
||||
)
|
||||
|
||||
FILTER_DOC_URL = (
|
||||
"https://github.com/franc6/ics_calendar/blob/releases/README.md#filters"
|
||||
)
|
||||
|
||||
|
||||
def is_array_string(arr_str: str) -> bool:
|
||||
"""Return true if arr_str starts with [ and ends with ]."""
|
||||
@@ -231,6 +235,7 @@ class ICSCalendarConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
data_schema=CALENDAR_OPTS_SCHEMA,
|
||||
errors=errors,
|
||||
last_step=False,
|
||||
description_placeholders={"filterdoc": FILTER_DOC_URL},
|
||||
)
|
||||
|
||||
async def async_step_connect_opts(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Constants for ics_calendar platform."""
|
||||
|
||||
VERSION = "5.1.5"
|
||||
VERSION = "5.1.7"
|
||||
DOMAIN = "ics_calendar"
|
||||
|
||||
CONF_DEVICE_ID = "device_id"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
"""Provide GetParser class."""
|
||||
|
||||
from .icalendarparser import ICalendarParser
|
||||
from .parsers.parser_ics import ParserICS
|
||||
from .parsers.parser_rie import ParserRIE
|
||||
|
||||
|
||||
class GetParser: # pylint: disable=R0903
|
||||
@@ -20,8 +18,16 @@ class GetParser: # pylint: disable=R0903
|
||||
# if parser_cls is not None:
|
||||
# return parser_cls(*args)
|
||||
if parser == "rie":
|
||||
from .parsers.parser_rie import ( # pylint: disable=C0415
|
||||
ParserRIE,
|
||||
)
|
||||
|
||||
return ParserRIE(*args)
|
||||
if parser == "ics":
|
||||
from .parsers.parser_ics import ( # pylint: disable=C0415
|
||||
ParserICS,
|
||||
)
|
||||
|
||||
return ParserICS(*args)
|
||||
|
||||
return None
|
||||
|
||||
@@ -8,6 +8,6 @@
|
||||
"integration_type": "service",
|
||||
"iot_class": "cloud_polling",
|
||||
"issue_tracker": "https://github.com/franc6/ics_calendar/issues",
|
||||
"requirements": ["icalendar~=6.1","python-dateutil>=2.9.0.post0","pytz>=2024.1","recurring_ical_events~=3.5,>=3.5.2","ics==0.7.2","arrow","httpx_auth>=0.22.0,<=0.23.1"],
|
||||
"version": "5.1.5"
|
||||
"requirements": ["icalendar~=6.1","python-dateutil>=2.9.0.post0","pytz>=2024.1","recurring_ical_events~=3.5,>=3.5.2","ics==0.7.2","arrow","httpx_auth>=0.22.0,<=0.23.1","tatsu>=4.2.6,<5.8.0"],
|
||||
"version": "5.1.7"
|
||||
}
|
||||
|
||||
@@ -76,7 +76,12 @@ class ParserICS(ICalendarParser):
|
||||
# summary = event.summary
|
||||
# elif hasattr(event, "name"):
|
||||
summary = event.name
|
||||
rrule = None
|
||||
for extra in event.extra:
|
||||
if extra.name == "RRULE":
|
||||
rrule = extra.value
|
||||
calendar_event: ParserEvent = ParserEvent(
|
||||
uid=event.uid,
|
||||
summary=summary,
|
||||
start=ParserICS.get_date(
|
||||
event.begin, event.all_day, offset_hours
|
||||
@@ -86,6 +91,14 @@ class ParserICS(ICalendarParser):
|
||||
),
|
||||
location=event.location,
|
||||
description=event.description,
|
||||
rrule=rrule,
|
||||
recurrence_id=(
|
||||
ParserICS.get_date(
|
||||
event.begin, event.all_day, offset_hours
|
||||
)
|
||||
if rrule
|
||||
else None
|
||||
),
|
||||
)
|
||||
if self._filter.filter_event(calendar_event):
|
||||
event_list.append(calendar_event)
|
||||
@@ -145,7 +158,12 @@ class ParserICS(ICalendarParser):
|
||||
# summary = temp_event.summary
|
||||
# elif hasattr(event, "name"):
|
||||
summary = temp_event.name
|
||||
rrule = None
|
||||
for extra in temp_event.extra:
|
||||
if extra.name == "RRULE":
|
||||
rrule = extra.value
|
||||
return ParserEvent(
|
||||
uid=temp_event.uid,
|
||||
summary=summary,
|
||||
start=ParserICS.get_date(
|
||||
temp_event.begin, temp_event.all_day, offset_hours
|
||||
@@ -155,6 +173,14 @@ class ParserICS(ICalendarParser):
|
||||
),
|
||||
location=temp_event.location,
|
||||
description=temp_event.description,
|
||||
rrule=rrule,
|
||||
recurrence_id=(
|
||||
ParserICS.get_date(
|
||||
temp_event.begin, temp_event.all_day, offset_hours
|
||||
)
|
||||
if rrule
|
||||
else None
|
||||
),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -75,11 +75,16 @@ class ParserRIE(ICalendarParser):
|
||||
continue
|
||||
|
||||
calendar_event: ParserEvent = ParserEvent(
|
||||
uid=event.get("UID"),
|
||||
summary=event.get("SUMMARY"),
|
||||
start=start,
|
||||
end=end,
|
||||
location=event.get("LOCATION"),
|
||||
description=event.get("DESCRIPTION"),
|
||||
# rrule=event.get("RRULE"),
|
||||
recurrence_id=ParserRIE.get_date(
|
||||
event.get("RECURRENCE-ID").dt
|
||||
),
|
||||
)
|
||||
if self._filter.filter_event(calendar_event):
|
||||
event_list.append(calendar_event)
|
||||
@@ -141,11 +146,16 @@ class ParserRIE(ICalendarParser):
|
||||
return None
|
||||
|
||||
return ParserEvent(
|
||||
uid=temp_event.get("UID"),
|
||||
summary=temp_event.get("SUMMARY"),
|
||||
start=temp_start,
|
||||
end=temp_end,
|
||||
location=temp_event.get("LOCATION"),
|
||||
description=temp_event.get("DESCRIPTION"),
|
||||
# rrule=temp_event.get("RRULE"),
|
||||
recurrence_id=ParserRIE.get_date(
|
||||
temp_event.get("RECURRENCE-ID").dt
|
||||
),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
"empty_url": "The url must not be empty.",
|
||||
"download_interval_too_small": "The download interval must be at least 15.",
|
||||
"exclude_include_cannot_be_the_same": "The exclude and include strings must not be the same",
|
||||
"exclude_must_be_array": "The exclude option must be an array of strings or regular expressions. See https://github.com/franc6/ics_calendar/blob/releases/README.md#filters for more information.",
|
||||
"include_must_be_array": "The include option must be an array of strings or regular expressions. See https://github.com/franc6/ics_calendar/blob/releases/README.md#filters for more information."
|
||||
"exclude_must_be_array": "The exclude option must be an array of strings or regular expressions. See {filterdoc} for more information.",
|
||||
"include_must_be_array": "The include option must be an array of strings or regular expressions. See {filterdoc} for more information."
|
||||
},
|
||||
"abort": {
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@
|
||||
"empty_url": "Die URL darf nicht leer sein.",
|
||||
"download_interval_too_small": "Das Download-Intervall muss mindestens 15 betragen.",
|
||||
"exclude_include_cannot_be_the_same": "Die Ausschluss- und Einschluss-Strings dürfen nicht identisch sein.",
|
||||
"exclude_must_be_array": "Die \"auszuschließenden Ereignisse\" müssen ein Array von Zeichenfolgen oder regulären Ausdrücken sein. Weitere Informationen finden Sie unter https://github.com/franc6/ics_calendar/blob/releases/README.md#filters.",
|
||||
"include_must_be_array": "Die \"einzuschließenden Ereignisse\" müssen ein Array von Zeichenfolgen oder regulären Ausdrücken sein. Weitere Informationen finden Sie unter https://github.com/franc6/ics_calendar/blob/releases/README.md#filters."
|
||||
"exclude_must_be_array": "Die \"auszuschließenden Ereignisse\" müssen ein Array von Zeichenfolgen oder regulären Ausdrücken sein. Weitere Informationen finden Sie unter {filterdoc}.",
|
||||
"include_must_be_array": "Die \"einzuschließenden Ereignisse\" müssen ein Array von Zeichenfolgen oder regulären Ausdrücken sein. Weitere Informationen finden Sie unter {filterdoc}."
|
||||
},
|
||||
"abort": {
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
"empty_url": "The url must not be empty.",
|
||||
"download_interval_too_small": "The download interval must be at least 15.",
|
||||
"exclude_include_cannot_be_the_same": "The exclude and include strings must not be the same",
|
||||
"exclude_must_be_array": "The exclude option must be an array of strings or regular expressions. See https://github.com/franc6/ics_calendar/blob/releases/README.md#filters for more information.",
|
||||
"include_must_be_array": "The include option must be an array of strings or regular expressions. See https://github.com/franc6/ics_calendar/blob/releases/README.md#filters for more information."
|
||||
"exclude_must_be_array": "The exclude option must be an array of strings or regular expressions. See {filterdoc} for more information.",
|
||||
"include_must_be_array": "The include option must be an array of strings or regular expressions. See {filterdoc} for more information."
|
||||
},
|
||||
"abort": {
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
"empty_url": "La url no debe estar vacía.",
|
||||
"download_interval_too_small": "El intervalo de descarga debe ser de al menos 15.",
|
||||
"exclude_include_cannot_be_the_same": "Las cadenas de exclusión e inclusión no deben ser las mismas",
|
||||
"exclude_must_be_array": "La opción de exclusión debe ser una matriz de cadenas o expresiones regulares. Consulte https://github.com/franc6/ics_calendar/blob/releases/README.md#filters para obtener más información.",
|
||||
"include_must_be_array": "La opción de inclusión debe ser un array de cadenas o expresiones regulares. Consulte https://github.com/franc6/ics_calendar/blob/releases/README.md#filters para obtener más información."
|
||||
"exclude_must_be_array": "La opción de exclusión debe ser una matriz de cadenas o expresiones regulares. Consulte {filterdoc} para obtener más información.",
|
||||
"include_must_be_array": "La opción de inclusión debe ser un array de cadenas o expresiones regulares. Consulte {filterdoc} para obtener más información."
|
||||
},
|
||||
"abort": {
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@
|
||||
"empty_url": "L'URL du calendrier doit être renseignée.",
|
||||
"download_interval_too_small": "L'intervalle de téléchargement ne peut pas être inférieur à 15 minutes.",
|
||||
"exclude_include_cannot_be_the_same": "Les valeurs d'exclusion et d'inclusion ne peuvent pas être identiques.",
|
||||
"exclude_must_be_array": "The exclude option must be an array of strings or regular expressions. See https://github.com/franc6/ics_calendar/blob/releases/README.md#filters for more information.",
|
||||
"include_must_be_array": "The include option must be an array of strings or regular expressions. See https://github.com/franc6/ics_calendar/blob/releases/README.md#filters for more information."
|
||||
"exclude_must_be_array": "L'option d'exclusion doit être un tableau de chaînes ou d'expressions régulières. Voir {filterdoc} pour plus d'informations.",
|
||||
"include_must_be_array": "L'option d'inclusion doit être un tableau de chaînes ou d'expressions régulières. Voir {filterdoc} pour plus d'informations."
|
||||
},
|
||||
"abort": {
|
||||
}
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
"empty_url": "A URL não pode estar vazia.",
|
||||
"download_interval_too_small": "O intervalo de download deve ser de pelo menos 15.",
|
||||
"exclude_include_cannot_be_the_same": "As strings de exclusão e inclusão não podem ser as mesmas.",
|
||||
"exclude_must_be_array": "A opção de exclusão deve ser um array de strings ou expressões regulares. Veja https://github.com/franc6/ics_calendar/blob/releases/README.md#filters para mais informações.",
|
||||
"include_must_be_array": "A opção de inclusão deve ser um array de strings ou expressões regulares. Veja https://github.com/franc6/ics_calendar/blob/releases/README.md#filters para mais informações."
|
||||
"exclude_must_be_array": "A opção de exclusão deve ser um array de strings ou expressões regulares. Veja {filterdoc} para mais informações.",
|
||||
"include_must_be_array": "A opção de inclusão deve ser um array de strings ou expressões regulares. Veja {filterdoc} para mais informações."
|
||||
},
|
||||
"abort": {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user