#!/usr/bin/env python3
# Software Name: ngsildclient
# SPDX-FileCopyrightText: Copyright (c) 2021 Orange
# SPDX-License-Identifier: Apache 2.0
#
# This software is distributed under the Apache 2.0;
# see the NOTICE file for more details.
#
# Author: Fabien BATTELLO <fabien.battello@orange.com> et al.
from __future__ import annotations
from typing import Union
from dataclasses import dataclass
from datetime import time
from enum import Enum
TimeOrStr = Union[time, str] # type alias
[docs]class WeekDay(Enum):
MONDAY = "Monday"
TUESDAY = "Tuesday"
WEDNESDAY = "Wednesday"
THURSDAY = "Thursday"
FRIDAY = "Friday"
SATURDAY = "Saturday"
SUNDAY = "Sunday"
WEEK = [day for day in WeekDay]
WEEK_END = [WeekDay.SATURDAY, WeekDay.SUNDAY]
WORKING_DAYS = [day for day in WEEK if day not in WEEK_END]
[docs]class OpeningHoursBuilder:
"""A helper class that allows to easily build an openingHours property.
Simplified. Support a single open timeslot per day.
Example
-------
>>> from ngsildclient import *
>>> builder = OpeningHoursBuilder()
>>> openinghours = builder.businessdays("10:00", "17:30").saturday("10:00", "14:00").build()
>>> # Add an openingHours property to the entity you're creating
>>> library = Entity("Library", "MyLibrary")
>>> library.prop("openingHours", openinghours)
>>> library.pprint()
{
"@context": [
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context.jsonld"
],
"id": "urn:ngsi-ld:Library:MyLibrary",
"type": "Library",
"openingHours": {
"type": "Property",
"value": [
{
"opens": "10:00",
"closes": "17:30",
"dayOfWeek": "Monday"
},
{
"opens": "10:00",
"closes": "17:30",
"dayOfWeek": "Tuesday"
},
{
"opens": "10:00",
"closes": "17:30",
"dayOfWeek": "Wednesday"
},
{
"opens": "10:00",
"closes": "17:30",
"dayOfWeek": "Thursday"
},
{
"opens": "10:00",
"closes": "17:30",
"dayOfWeek": "Friday"
},
{
"opens": "10:00",
"closes": "14:00",
"dayOfWeek": "Saturday"
}
]
}
}
"""
def __init__(self):
self._oh: dict = {}
@staticmethod
def _converttimes(opens, closes) -> tuple[str, str]:
opens = opens if isinstance(opens, str) else opens.strftime("%H:%M")
closes = closes if isinstance(closes, str) else closes.strftime("%H:%M")
return opens, closes
def monday(self, opens: TimeOrStr, closes: TimeOrStr):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
self._oh[WeekDay.MONDAY] = OpeningHoursSpecification(
opens, closes, WeekDay.MONDAY.value
)
return self
def tuesday(self, opens: TimeOrStr, closes: TimeOrStr):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
self._oh[WeekDay.TUESDAY] = OpeningHoursSpecification(
opens, closes, WeekDay.TUESDAY.value
)
return self
def wednesday(self, opens: TimeOrStr, closes: TimeOrStr):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
self._oh[WeekDay.WEDNESDAY] = OpeningHoursSpecification(
opens, closes, WeekDay.WEDNESDAY.value
)
return self
def thursday(self, opens: TimeOrStr, closes: TimeOrStr):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
self._oh[WeekDay.THURSDAY] = OpeningHoursSpecification(
opens, closes, WeekDay.THURSDAY.value
)
return self
def friday(self, opens: TimeOrStr, closes: TimeOrStr):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
self._oh[WeekDay.FRIDAY] = OpeningHoursSpecification(
opens, closes, WeekDay.FRIDAY.value
)
return self
def saturday(self, opens: TimeOrStr, closes: TimeOrStr):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
self._oh[WeekDay.SATURDAY] = OpeningHoursSpecification(
opens, closes, WeekDay.SATURDAY.value
)
return self
def sunday(self, opens: TimeOrStr, closes: TimeOrStr):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
self._oh[WeekDay.SUNDAY] = OpeningHoursSpecification(
opens, closes, WeekDay.SUNDAY.value
)
return self
def days(self, opens: TimeOrStr, closes: TimeOrStr, *days):
opens, closes = OpeningHoursBuilder._converttimes(opens, closes)
for day in days:
self._oh[day] = OpeningHoursSpecification(opens, closes, day.value)
return self
def weekend(self, opens: TimeOrStr, closes: TimeOrStr):
return self.days(opens, closes, *WEEK_END)
def businessdays(self, opens: TimeOrStr, closes: TimeOrStr, *exceptdays):
openingdays = [day for day in WORKING_DAYS if day not in exceptdays]
return self.days(opens, closes, *openingdays)
def wholeweek(self, opens: TimeOrStr, closes: TimeOrStr, *exceptdays):
return self.days(opens, closes, *WEEK)
def build(self) -> dict:
openingdays = []
for day in WeekDay:
if oh := self._oh.get(day, None):
openingdays.append(oh.to_dict())
return openingdays