Merge branch 'dev' into 'master'

Release 0.3.3

See merge request s3lph/icalendar-timeseries-server!8
This commit is contained in:
s3lph 2020-06-18 22:42:06 +00:00
commit 59ea26514c
9 changed files with 38 additions and 16 deletions

View file

@ -57,7 +57,7 @@ build_debian:
Section: web
Priority: optional
Architecture: all
Depends: python3 (>= 3.7), python3-jinja2, python3-bottle, python3-dateutil, python3-icalendar, python3-isodate, python3-tz
Depends: python3 (>= 3.7), python3-jinja2, python3-bottle, python3-dateutil, python3-icalendar, python3-isodate
Description: Scrape iCalendar endpoints and present their data in a
timeseries format. A small service that scrapes iCalendar files
served over HTTP, parses their contents and returns a timeseries

View file

@ -1,6 +1,19 @@
# iCalendar Timeseries Server Changelog
<!-- BEGIN RELEASE v0.3.3 -->
## Version 0.3.3
### Changes
<!-- BEGIN CHANGES 0.3.3 -->
- Fix type confusion bug in recurring events
- Remove pytz dependency in favor of dateutil.tz
<!-- END CHANGES 0.3.3 -->
<!-- END RELEASE v0.3.3 -->
<!-- BEGIN RELEASE v0.3.2 -->
## Version 0.3.2

View file

@ -78,7 +78,6 @@ The server would transform this into the following API response:
- `icalendar`: Parse iCalendar
- `isodate`: Parse ISO-8601 time periods
- `jinja2`: Template value replacements
- `pytz`: Work with timezones
## Configuration

View file

@ -1,2 +1,2 @@
__version__ = '0.3.2'
__version__ = '0.3.3'

View file

@ -26,6 +26,8 @@ def _parse_recurring(event: cal.Event, start: datetime, end: datetime, duration:
occurences: List[datetime] = []
evstart = event.get('dtstart').dt
if isinstance(evstart, date) and not isinstance(evstart, datetime):
evstart = datetime(evstart.year, evstart.month, evstart.day, tzinfo=start.tzinfo)
# First occurence lies in the future; no need to process further
if evstart >= end:
return occurences

View file

@ -8,9 +8,10 @@ import urllib.request
import sys
import logging
import pytz
import jinja2
from isodate import Duration, parse_duration
from dateutil import tz
from datetime import tzinfo
from icalendar_timeseries_server import __version__
@ -93,7 +94,7 @@ class Config:
config = dict()
self._addr: str = _keycheck('addr', config, str, '', default_value='127.0.0.1')
self._port: int = _keycheck('port', config, int, '', default_value=8090)
self._tz: pytz.tzinfo = _parse_timezone('tz', config, '', default_value='UTC')
self._tz: tzinfo = _parse_timezone('tz', config, '', default_value='UTC')
self._start_delta: Duration = _parse_timedelta('start_delta', config, '', default_value='PT')
self._end_delta: Duration = _parse_timedelta('end_delta', config, '', default_value='P30D')
self._calendars: Dict[str, CalendarConfig] = self._parse_calendars_config('calendars', config, '')
@ -120,7 +121,7 @@ class Config:
return self._port
@property
def tz(self) -> pytz.tzinfo:
def tz(self) -> tzinfo:
return self._tz
@property
@ -185,7 +186,10 @@ def _parse_timezone(key: str,
path: str,
default_value: Any = None) -> Any:
zonename: str = _keycheck(key, config, str, path, default_value=default_value)
return pytz.timezone(zonename)
zone: zoneinfo = tz.gettz(zonename)
if zone is None:
raise ValueError(f'Unknown timezone: {zonename}')
return zone
def _parse_key_replace(key: str,

View file

@ -2,9 +2,9 @@
import unittest
import json
import pytz
from datetime import timedelta
from datetime import timedelta, tzinfo
from dateutil import tz
from isodate.duration import Duration
from icalendar_timeseries_server.config import _keycheck, _parse_timedelta, _parse_timezone, Config
@ -113,10 +113,10 @@ class ConfigTest(unittest.TestCase):
'tz': 'Europe/Zurich',
'notz': 'North/Winterfell'
}
self.assertEqual(_parse_timezone('tz', config, ''), pytz.timezone('Europe/Zurich'))
self.assertEqual(_parse_timezone('tz', config, ''), tz.gettz('Europe/Zurich'))
self.assertEqual(_parse_timezone('def', config, '', default_value='Europe/Berlin'),
pytz.timezone('Europe/Berlin'))
with self.assertRaises(pytz.exceptions.UnknownTimeZoneError):
tz.gettz('Europe/Berlin'))
with self.assertRaises(ValueError):
_parse_timezone('notz', config, '')
def test_parse_full_config_valid(self):
@ -125,7 +125,7 @@ class ConfigTest(unittest.TestCase):
self.assertEqual(config.port, 8090)
self.assertEqual(config.start_delta, Duration(hours=-3))
self.assertEqual(config.end_delta, Duration(days=30))
self.assertEqual(config.tz, pytz.timezone('Europe/Zurich'))
self.assertEqual(config.tz, tz.gettz('Europe/Zurich'))
def test_parse_calendars(self):
config = Config(json.loads(_CONFIG_VALID))

View file

@ -17,4 +17,9 @@ if [[ "$1" == "configure" ]]; then
systemctl daemon-reload || true
if [[ "$2" != "" ]]; then
# Restart after upgrading the package
systemctl restart icalendar-timeseries-server.service
fi
fi

View file

@ -18,11 +18,10 @@ setup(
python_requires='>=3.6',
install_requires=[
'bottle',
'python-dateutil',
'python-dateutil>=2.8',
'icalendar',
'isodate',
'jinja2',
'pytz'
'jinja2'
],
entry_points={
'console_scripts': [