Adds support for extending a calendar config with

another calendar config.
This commit is contained in:
xelast418 2023-09-20 20:50:37 +12:00
parent e5acc4fd1d
commit 27064a9c61
No known key found for this signature in database
GPG key ID: 76EE00E7C90D5B64
2 changed files with 68 additions and 0 deletions

View file

@ -30,6 +30,11 @@ The JSON configuration file should look like the following.
```json
[
{
"conf": true,
"extends": "str",
"extendFail": "str",
},
{
"url":"str",
"name":"str",
@ -104,9 +109,20 @@ Only the `url` and the `name` field are mandatory.
- `redactAs`: Replaces the content of the field with the specified string
If multiple calendars are specified in the configuration list, their events will be merged in the resulting ics feed.
The first dataset with {"conf": true,} specifies options that are globally applied to all calenders in the conf. Omit this set to disable. Options
- `extends`: string specifying the name (excluding .json) of another config file to extend.
- `extendFail`: string speciying the action to take if an extend fails, either "fail" or "ignore". Default is "fail".
## Usage
Once the config file is created, the corresponding HTTP endpoint is accessible. For example, if the file `app/config/my-calendar.json` contains the configuration, the HTTP endpoint will be `http://localhost:8088/my-calendar`.
A config can extend another config file, to do this the extended config should contain begin with`{
"conf": true,
"extends": <name of calendar>,
"extendFail": "fail",
},`
For an extend to work calendars MUST share the same name between the configs
An extending config cannot remove data from a base calendar but can modify fields
## Limitations
Currently, the application only merges events of the ics feeds, the alarms and todos are not supported.

View file

@ -348,6 +348,26 @@ def process(path: str, from_cache: bool = True) -> Calendar:
data = []
for entry in config:
if entry.get("conf", False) == True:
if entry.get("extends", None) is not None:
try:
o = "app/config/" + sanitize_filename(entry["extends"]) + ".json"
print("Try to open " + o)
file = open(o, "r")
baseConfig = json.loads(file.read())
file.close()
extendingConfig = config
try:
config = merge_json(baseConfig, extendingConfig)
except:
config = extendingConfig
except:
if entry.get("extendFail", "fail") == "fail":
raise FileNotFoundError("The calendar is not cached")
else:
pass
continue
cal = load_cal(entry)
@ -448,3 +468,35 @@ def horodate(cal: Calendar, prefix='') -> Calendar:
if event.description is not None else prefix + ' ' + now
return cal
def merge_json(base, extention):
"""Merges two config files by updating the value of base with the values in extention.
:param base: the base config file
:type base: dict
:param extention: the config file to merge with the base
:type extention: dict
:return: the merged config file
:rtype: dict
"""
newJson = base.copy()
def update_json(target, source):
for key, value in source.items():
if isinstance(value, dict) and key in target and isinstance(target[key], dict):
update_json(target[key], value)
else:
target[key] = value
for dataset in newJson:
for dset in extention:
if newJson["name"] == dset["name"]:
update_json(newJson, dset)
return newJson