url_template = $url_template; $this->lifetime = $lifetime; $this->conflate = $conflate; $this->cache_file = \davina\helpers\call\convey( new \davina\helpers\cache\class_cache_file('data'), [ fn($x) => new \davina\helpers\cache\class_cache_encoded( $x, fn($value) => \json_encode($value), fn($value_encoded) => \json_decode($value_encoded, true) ), ] ); $this->cache_memory = \davina\helpers\call\convey( (new \davina\helpers\cache\class_cache_memory()), [ ] ); } /** */ private function url( $parameters ) : string { return \davina\helpers\string_\coin( $this->url_template, [ 'username' => ($parameters['auth_username'] ?? null), 'password' => ($parameters['auth_password'] ?? null), ] ); } /** */ private function vcalendar_to_calendar( \davina\helpers\ics\struct_vcalendar $vcalendar, ?string $realm_name ) : \davina\model\struct_calendar { return ( new \davina\model\struct_calendar( \array_map( fn($vevent) => (new \davina\model\struct_event( // id $vevent->uid, // title ( (! $this->conflate) ? $vevent->summary : \sprintf( '%s%s', $vevent->summary, \implode( '', \array_map( fn($category) => \sprintf(' (%s)', $category), $vevent->categories ) ) ) ), // begin \davina\helpers\ics\datetime_to_unix_timestamp($vevent->dtstart->value), // end ( ($vevent->dtend === null) ? null : \davina\helpers\ics\datetime_to_unix_timestamp($vevent->dtend->value) ), // location $vevent->location, // description $vevent->description, // 'tags ( (! $this->conflate) ? $vevent->categories : [] ) )), $vcalendar->events ) ) ); } /** */ private function retrieve( string $url, ?string $realm_name ) { $client = new \Sabre\HTTP\Client(); $request = new \Sabre\HTTP\Request( 'GET', $url, [], null ); $response = $client->send($request); $status_code = $response->getStatus(); switch ($status_code) { case 200: { $ics = $response->getBody(); try { $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_raw = \davina\model\calendar_to_raw($calendar); return $calendar_raw; } break; } default: { throw ( new \Exception( \sprintf( 'unhandled response status code: %u', $status_code ) ) ); break; } } } /** * [implementation] */ public function read( ) : \davina\model\struct_calendar { $parameters = \davina\get_parameters(); $url = $this->url($parameters); $key = \sprintf( '%s:%u', $url, $this->conflate ); $f1 = fn() => $this->retrieve( $url, $parameters['realm_name'] ); $f2 = fn() => \davina\helpers\cache\get( $this->cache_file, $key, $f1, [ 'ttl' => $this->lifetime, ] ); $f3 = fn() => \davina\helpers\cache\get( $this->cache_memory, $key, $f2, [ 'ttl' => null, ] ); return \davina\model\calendar_from_raw( ($f3)() ); } } ?>