Merge branch 'dev' into 'master'
Release 0.3.3 See merge request s3lph/icalendar-timeseries-server!8
This commit is contained in:
commit
59ea26514c
9 changed files with 38 additions and 16 deletions
|
@ -57,7 +57,7 @@ build_debian:
|
||||||
Section: web
|
Section: web
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Architecture: all
|
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
|
Description: Scrape iCalendar endpoints and present their data in a
|
||||||
timeseries format. A small service that scrapes iCalendar files
|
timeseries format. A small service that scrapes iCalendar files
|
||||||
served over HTTP, parses their contents and returns a timeseries
|
served over HTTP, parses their contents and returns a timeseries
|
||||||
|
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,6 +1,19 @@
|
||||||
# iCalendar Timeseries Server Changelog
|
# 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 -->
|
<!-- BEGIN RELEASE v0.3.2 -->
|
||||||
## Version 0.3.2
|
## Version 0.3.2
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,6 @@ The server would transform this into the following API response:
|
||||||
- `icalendar`: Parse iCalendar
|
- `icalendar`: Parse iCalendar
|
||||||
- `isodate`: Parse ISO-8601 time periods
|
- `isodate`: Parse ISO-8601 time periods
|
||||||
- `jinja2`: Template value replacements
|
- `jinja2`: Template value replacements
|
||||||
- `pytz`: Work with timezones
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
|
|
||||||
__version__ = '0.3.2'
|
__version__ = '0.3.3'
|
||||||
|
|
|
@ -26,6 +26,8 @@ def _parse_recurring(event: cal.Event, start: datetime, end: datetime, duration:
|
||||||
occurences: List[datetime] = []
|
occurences: List[datetime] = []
|
||||||
|
|
||||||
evstart = event.get('dtstart').dt
|
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
|
# First occurence lies in the future; no need to process further
|
||||||
if evstart >= end:
|
if evstart >= end:
|
||||||
return occurences
|
return occurences
|
||||||
|
|
|
@ -8,9 +8,10 @@ import urllib.request
|
||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import pytz
|
|
||||||
import jinja2
|
import jinja2
|
||||||
from isodate import Duration, parse_duration
|
from isodate import Duration, parse_duration
|
||||||
|
from dateutil import tz
|
||||||
|
from datetime import tzinfo
|
||||||
|
|
||||||
from icalendar_timeseries_server import __version__
|
from icalendar_timeseries_server import __version__
|
||||||
|
|
||||||
|
@ -93,7 +94,7 @@ class Config:
|
||||||
config = dict()
|
config = dict()
|
||||||
self._addr: str = _keycheck('addr', config, str, '', default_value='127.0.0.1')
|
self._addr: str = _keycheck('addr', config, str, '', default_value='127.0.0.1')
|
||||||
self._port: int = _keycheck('port', config, int, '', default_value=8090)
|
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._start_delta: Duration = _parse_timedelta('start_delta', config, '', default_value='PT')
|
||||||
self._end_delta: Duration = _parse_timedelta('end_delta', config, '', default_value='P30D')
|
self._end_delta: Duration = _parse_timedelta('end_delta', config, '', default_value='P30D')
|
||||||
self._calendars: Dict[str, CalendarConfig] = self._parse_calendars_config('calendars', config, '')
|
self._calendars: Dict[str, CalendarConfig] = self._parse_calendars_config('calendars', config, '')
|
||||||
|
@ -120,7 +121,7 @@ class Config:
|
||||||
return self._port
|
return self._port
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tz(self) -> pytz.tzinfo:
|
def tz(self) -> tzinfo:
|
||||||
return self._tz
|
return self._tz
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -185,7 +186,10 @@ def _parse_timezone(key: str,
|
||||||
path: str,
|
path: str,
|
||||||
default_value: Any = None) -> Any:
|
default_value: Any = None) -> Any:
|
||||||
zonename: str = _keycheck(key, config, str, path, default_value=default_value)
|
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,
|
def _parse_key_replace(key: str,
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import pytz
|
from datetime import timedelta, tzinfo
|
||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
|
from dateutil import tz
|
||||||
from isodate.duration import Duration
|
from isodate.duration import Duration
|
||||||
|
|
||||||
from icalendar_timeseries_server.config import _keycheck, _parse_timedelta, _parse_timezone, Config
|
from icalendar_timeseries_server.config import _keycheck, _parse_timedelta, _parse_timezone, Config
|
||||||
|
@ -113,10 +113,10 @@ class ConfigTest(unittest.TestCase):
|
||||||
'tz': 'Europe/Zurich',
|
'tz': 'Europe/Zurich',
|
||||||
'notz': 'North/Winterfell'
|
'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'),
|
self.assertEqual(_parse_timezone('def', config, '', default_value='Europe/Berlin'),
|
||||||
pytz.timezone('Europe/Berlin'))
|
tz.gettz('Europe/Berlin'))
|
||||||
with self.assertRaises(pytz.exceptions.UnknownTimeZoneError):
|
with self.assertRaises(ValueError):
|
||||||
_parse_timezone('notz', config, '')
|
_parse_timezone('notz', config, '')
|
||||||
|
|
||||||
def test_parse_full_config_valid(self):
|
def test_parse_full_config_valid(self):
|
||||||
|
@ -125,7 +125,7 @@ class ConfigTest(unittest.TestCase):
|
||||||
self.assertEqual(config.port, 8090)
|
self.assertEqual(config.port, 8090)
|
||||||
self.assertEqual(config.start_delta, Duration(hours=-3))
|
self.assertEqual(config.start_delta, Duration(hours=-3))
|
||||||
self.assertEqual(config.end_delta, Duration(days=30))
|
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):
|
def test_parse_calendars(self):
|
||||||
config = Config(json.loads(_CONFIG_VALID))
|
config = Config(json.loads(_CONFIG_VALID))
|
||||||
|
|
|
@ -17,4 +17,9 @@ if [[ "$1" == "configure" ]]; then
|
||||||
|
|
||||||
systemctl daemon-reload || true
|
systemctl daemon-reload || true
|
||||||
|
|
||||||
|
if [[ "$2" != "" ]]; then
|
||||||
|
# Restart after upgrading the package
|
||||||
|
systemctl restart icalendar-timeseries-server.service
|
||||||
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
5
setup.py
5
setup.py
|
@ -18,11 +18,10 @@ setup(
|
||||||
python_requires='>=3.6',
|
python_requires='>=3.6',
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'bottle',
|
'bottle',
|
||||||
'python-dateutil',
|
'python-dateutil>=2.8',
|
||||||
'icalendar',
|
'icalendar',
|
||||||
'isodate',
|
'isodate',
|
||||||
'jinja2',
|
'jinja2'
|
||||||
'pytz'
|
|
||||||
],
|
],
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
|
|
Loading…
Reference in a new issue