Compare commits

..

No commits in common. "213d1324bb0ab2335d25dcc4eb3f9e0a64e4a7cb" and "490d90cfd7b8ecb7f257d0e2636fc4fce0332cdf" have entirely different histories.

8 changed files with 43 additions and 152 deletions

17
conf/example.json Normal file
View file

@ -0,0 +1,17 @@
{
"auth": {
"kind": "none",
"data": null
},
"source": {
"kind": "ics_feed",
"data": {
"url": "https://www.phpclasses.org/browse/download/1/file/63438/name/example.ics",
"combine": true
}
},
"settings": {
"timezone": "UTC"
}
}

17
conf/zeitbild.json Normal file
View file

@ -0,0 +1,17 @@
{
"auth": {
"kind": "basic",
"data": null
},
"source": {
"kind": "ics_feed",
"data": {
"url": "http://{{username}}:{{password}}@localhost:7845/export/ics",
"combine": true
}
},
"settings": {
"timezone": "UTC"
}
}

View file

@ -1,23 +0,0 @@
{
"realms": [
{
"name": "holidays",
"auth": {
"kind": "static",
"data": {
"password": "secret"
}
},
"source": {
"kind": "ics_feed",
"data": {
"url": "https://www.kayaposoft.com/enrico/ics/v2.0?country=nor&fromDate=01-01-2025&toDate=31-12-2026&region=&holidayType=public_holiday&lang=no"
}
}
}
],
"settings": {
"timezone": "UTC"
}
}

103
readme.md
View file

@ -2,7 +2,7 @@
## Beschreibung ## Beschreibung
- bereitet rohe Kalender-Daten aus verschiedenen Quellen mittels CalDAV auf und stellt diese als Server bereit - stellt Kalender-Daten in Form eines CalDAV-Servers bereit
- basiert auf [sabre/dav](https://sabre.io/dav/) - basiert auf [sabre/dav](https://sabre.io/dav/)
@ -30,11 +30,7 @@
Zum lokalen Testen: Zum lokalen Testen:
- im build-Verzeichnis `php -S localhost:8000` ausführen - im build-Verzeichnis `php -S localhost:8000` ausführen
- CalDAV-Client einrichten mit Ziel-URL - im Browser `http://localhost:8000/` aufrufen
- URL: `http://localhost:8000/calendars/-/rides`
- Nutzername: `<realm-name>`
- Passwort: ``
Für den Produktiv-Betrieb: Für den Produktiv-Betrieb:
@ -42,98 +38,3 @@ Für den Produktiv-Betrieb:
- Web-Server neustarten - Web-Server neustarten
## Dokumentation
Der grobe Aufbau einer Konfigurations-Datei lässt sich in der [Beispiel-Konfiguration](misc/conf-example.dvn.json) sehen.
### Bezüge
_Bezüge_/_Realms_ dienen die Daten-Quellen. Sie sind in der Konfiguration im Knoten `realms` zu erfassen. Jeder Bezug hat:
- einen Namen (`name`),
- eine Zugangs-Definition (`auth`)
- eine Quell-Definition (`source`)
Beispiel:
```json
"realms": [
{
"name": "foo",
"auth": …
"source": …
},
{
"name": "bar",
"auth": …
"source": …
}
]
```
### Authentifizierungen
_Authentifizierungen_ steuern wie auf einen Bezug zugegriffen wird.
#### Fest
- es wird ein festes Passwort erwartet
- Beispiel:
```json
"auth": {
"kind": "static",
"data": {
"password": "secret"
}
}
```
#### Durchleiten
- es wird kein bestimmtes Passwort erwartet
- das eingegebene Passwort wird an den Aufruf der Quelle weitergeleitet
- Beispiel:
```json
"auth": {
"kind": "pass_through"
}
```
### Quellen
_Quellen_ sind die Stellen, die aufgerufen werden um die rohen Kalender-Daten zu erhalten.
#### ICS-Feed
Kalender-Daten, welche im [iCalendar](https://de.wikipedia.org/wiki/ICalendar)-Format `ics` vorliegen, können wie folgt eingebunden werden:
```json
"source" :{
"kind": "ics_feed",
"data": {
"url": "https://events.example.org/concerts.ics",
"conflate": true
}
}
```
`url` ist hierbei schlicht die URL zur `ics`-Datei. Diese kann man den Platzhaltern `{{username}}` und `{{password}}` versehen sein. Im Fall einer Authentifizierung mittels Durchleiten, werden diese Platzhalter durch die konkret vorliegenden Werte ersetzt.
Der Schalter `conflate` steuert, ob die erhaltenen Termine in einen Kalender zusammengefasst werden sollen, statt sie gemäß ihrer `VEVENT`-Feld-Werte `CATEGORIES` aufzutrennen. Das hat Auswirkungen auf die URL, die man im CalDAV-Client einstellen muss. Kommen in einer `ics`-Datei bspw. die `CATEGORIES`-Werte `day` und `night` vor und der Bezug hat den Name `music`, dann würden bei `"conflate": false` die Ziel-URL-Pfade `/calendars/-/music-day` und `/calendars/-/music-night` anliegen; bei `"conflate": true` nur `/calendars/-/music`.
### Angaben für Clients
- Kalender-URL: `<url-base>/calendars/-/<realm-name>[-<calendar-name>]`
- Nutzername: `<realm-name>[-<auth-username>]`
- Passwort: `<auth-password>`

View file

@ -68,6 +68,7 @@ function load(
return [ return [
'kind' => 'static', 'kind' => 'static',
'data' => [ 'data' => [
'username' => ($auth_raw['data']['username'] ?? $realm_raw['name']),
'password' => ($auth_raw['data']['password'] ?? $realm_raw['name']), 'password' => ($auth_raw['data']['password'] ?? $realm_raw['name']),
] ]
]; ];

View file

@ -18,7 +18,7 @@ require_once(DIR_LOGIC . '/conf.php');
function main( function main(
) : void ) : void
{ {
\davina\conf\load('conf.dvn.json'); \davina\conf\load('conf.json');
\davina\set_parameters([]); \davina\set_parameters([]);

View file

@ -159,32 +159,10 @@ class class_source_ics_feed
case 200: case 200:
{ {
$ics = $response->getBody(); $ics = $response->getBody();
try
{
$vcalendar = \davina\helpers\ics\vcalendar_decode($ics); $vcalendar = \davina\helpers\ics\vcalendar_decode($ics);
}
catch (\Throwable $throwable)
{
\error_log(
\davina\helpers\string_\coin(
'could not parse ics: {{reason}}',
[
'reason' => \strval($throwable),
]
)
);
$valendar = null;
}
if ($vcalendar === null)
{
throw (new \Exception('could not parse ics'));
}
else
{
$calendar = $this->vcalendar_to_calendar($vcalendar, $realm_name); $calendar = $this->vcalendar_to_calendar($vcalendar, $realm_name);
$calendar_raw = \davina\model\calendar_to_raw($calendar); $calendar_raw = \davina\model\calendar_to_raw($calendar);
return $calendar_raw; return $calendar_raw;
}
break; break;
} }
default: default:

View file

@ -81,7 +81,7 @@ def main():
else: else:
_shutil.copy( _shutil.copy(
args.conf_path, args.conf_path,
_os.path.join(args.output_directory, "conf.dvn.json") _os.path.join(args.output_directory, "conf.json")
) )
print(args.output_directory) print(args.output_directory)