Skip to content
Snippets Groups Projects
Commit 5b24497e authored by Robert Goldmann's avatar Robert Goldmann
Browse files

Fixed #46 - GarbageContainerScheduleTile: optional pushbullet notification x days event

parent a9a9154b
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@ from typing import Dict, List
from flask import Blueprint
from babel.dates import format_date
from logic import Helpers
from logic.service.ServiceManager import ServiceManager
from logic.service.services.IcsService import CalendarEvent
from logic.tile.Tile import Tile
......@@ -23,10 +24,17 @@ class GarbageContainerScheduleTile(Tile):
EXAMPLE_SETTINGS = {
"path": "path/to/my/calendar.ics",
"garbageType": "Papier" or "Gelbe Säcke" or "Bioabfall" or "Restabfall",
"notificationViaPushbullet": {
"enable": False,
"daysBeforeEvent": 1,
"hour": 10,
"pushbulletToken": None
}
}
def __init__(self, uniqueName: str, settings: Dict, intervalInSeconds: int):
super().__init__(uniqueName, settings, intervalInSeconds)
self._lastNotificationDate = None
def fetch(self, pageName: str) -> Dict:
icsService = ServiceManager.get_instance().get_service_by_type_name('IcsService')
......@@ -43,28 +51,64 @@ class GarbageContainerScheduleTile(Tile):
if nextEvent:
nextEventDate = nextEvent.start
if isinstance(nextEventDate, datetime):
remainingDays = nextEventDate - datetime.now()
remainingDays = nextEventDate - self._get_current_date_time()
else:
remainingDays = nextEventDate - datetime.now().date()
remainingDays = nextEventDate - self._get_current_date_time().date()
remainingDays = remainingDays.days
nextEventDate = format_date(nextEventDate, self.DATE_FORMAT, 'de')
iconName = self.ICON_BY_GARBAGE_TYPE[self._settings['garbageType']]
self._send_notification(remainingDays, nextEventDate)
return {
'nextEventDate': nextEventDate,
'iconFileName': f'{iconName}.png',
'remainingDays': remainingDays
}
def _get_current_date_time(self) -> datetime:
return datetime.now()
def __find_next_date(self, events: List[CalendarEvent]) -> CalendarEvent or None:
now = datetime.now().date()
now = self._get_current_date_time().date()
for event in events:
if event.start < now:
continue
return event
return None
def _send_notification(self, remainingDays: int, nextEventDate: str):
notificationSettings = self._settings['notificationViaPushbullet']
if not notificationSettings['enable']:
self._lastNotificationDate = None
return
if remainingDays != notificationSettings['daysBeforeEvent']:
self._lastNotificationDate = None
return
now = self._get_current_date_time()
if now.hour < notificationSettings['hour']:
self._lastNotificationDate = None
return
if self._is_already_notified(now):
self._lastNotificationDate = None
return
self._lastNotificationDate = now.date()
title = 'DashboardLeaf - Garbage Schedule Notification'
description = f'"{self._settings["garbageType"]}" will be collected in {remainingDays} days ({nextEventDate})'
Helpers.send_notification_via_pushbullet(notificationSettings['pushbulletToken'], title, description)
def _is_already_notified(self, now: datetime) -> bool:
if self._lastNotificationDate is None:
return False
return self._lastNotificationDate == now.date()
def render(self, data: Dict) -> str:
return Tile.render_template(os.path.dirname(__file__), __class__.__name__, data=data)
......
from datetime import datetime
from unittest import mock
from logic import Helpers
from logic.tile.tiles.GarbageContainerScheduleTile import GarbageContainerScheduleTile
def example_settings(enableNotifications):
return {
"path": None,
"garbageType": "Papier" or "Gelbe Säcke" or "Bioabfall" or "Restabfall",
"notificationViaPushbullet": {
"enable": enableNotifications,
"daysBeforeEvent": 1,
"hour": 10,
"pushbulletToken": "myToken"
}
}
class TestIsAlreadyNotified:
def test_not_notified_should_return_false(self):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(False), 10)
assert tile._is_already_notified(datetime.now()) is False
def test_already_notified_but_not_today_should_return_false(self):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(False), 10)
tile.__lastNotificationDate = datetime(year=2021, month=3, day=18).date()
currentDateTime = datetime(year=2021, month=3, day=21, hour=11, minute=35, second=0)
assert tile._is_already_notified(currentDateTime) is False
def test_already_notified_should_return_true(self):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(False), 10)
tile._lastNotificationDate = datetime(year=2021, month=3, day=21).date()
currentDateTime = datetime(year=2021, month=3, day=21, hour=11, minute=35, second=0)
assert tile._is_already_notified(currentDateTime) is True
class TestSendNotification:
@mock.patch('logic.tile.tiles.GarbageContainerScheduleTile.Helpers')
def test_notification_disabled_should_do_nothing(self, helpersMock):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(False), 10)
tile._send_notification(1, '')
helpersMock.send_notification_via_pushbullet.assert_not_called()
@mock.patch('logic.tile.tiles.GarbageContainerScheduleTile.Helpers')
def test_notification_enabled_reaming_days_greater_than_settings_should_do_nothing(self, helpersMock):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(True), 10)
tile._send_notification(3, '')
helpersMock.send_notification_via_pushbullet.assert_not_called()
@mock.patch('logic.Helpers.requests')
def test_send_notification_after_settings_hour_should_call_pushbullet_api(self, requestsMock):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(True), 10)
requestsMock.post.return_value.status_code = 200
with mock.patch.object(tile, '_get_current_date_time', wraps=tile._get_current_date_time) as currentDateTimeMock:
currentDateTimeMock.return_value = datetime(year=2021, month=3, day=21, hour=11, minute=35, second=0)
tile._send_notification(1, '')
requestsMock.post.assert_called_once_with(Helpers.PUSHBULLET_PUSH_URL, data=mock.ANY, headers=mock.ANY)
@mock.patch('logic.tile.tiles.GarbageContainerScheduleTile.Helpers')
def test_send_notification_before_settings_hour_should_do_nothing(self, helpersMock):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(True), 10)
with mock.patch.object(tile, '_get_current_date_time', wraps=tile._get_current_date_time) as currentDateTimeMock:
currentDateTimeMock.return_value = datetime(year=2021, month=3, day=21, hour=9, minute=35, second=0)
tile._send_notification(1, '')
helpersMock.send_notification_via_pushbullet.assert_not_called()
@mock.patch('logic.Helpers.requests')
def test_already_notified_should_skip_sending(self, requestsMock):
tile = GarbageContainerScheduleTile('myGarbageScheduleTile', example_settings(True), 10)
requestsMock.post.return_value.status_code = 200
tile._send_notification(1, '')
tile._send_notification(1, '')
requestsMock.post.assert_called_once()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment