use v5.36; #use Feature::Compat::Class 0.07; use Object::Pad 0.78; package Object::Groupware::DAV 0.01; class Object::Groupware::DAV : isa(Object::Groupware); use utf8; use Feature::Compat::Try; use Net::Netrc; use IO::Interactive::Tiny; use Log::Any qw( ); use URI; use IO::Prompter; use Cal::DAV; use DateTime; use Object::Groupware::Calendar; field $log = undef; field $uri : param; field $user : param = undef; field $pass : param = undef; field $session; ADJUST { # TODO: use Object::Pad 0.07 and move this to field initializer $log //= Log::Any->get_logger; $uri = URI->new($uri) or $log->fatal( 'failed to parse URI %s', $uri ) && exit 2; $log->debug('resolve credentials...'); my $mach; ( $user, $pass ) = split ':', $uri->userinfo if !$user and $uri->userinfo; $mach = Net::Netrc->lookup( $uri->host, $user ) unless $user and defined $pass; if ($mach) { $user ||= $mach->login; $pass ||= $mach->password; $log->infof( 'will use .netrc provided credentials for user %s', $user ); } elsif ( IO::Interactive::Tiny::is_interactive() ) { $log->warn( 'will ask for missing info - this will fail in headless mode'); $user ||= prompt 'Enter your username'; $pass ||= prompt 'Enter your password', -echo => '*'; } $log->debugf( 'resolved credentials for user %s', $user ); } method get ($new_uri) { $uri = URI->new($new_uri) or $log->fatal( 'failed to parse URI %s', $uri ) && exit 2 if $new_uri; # fetch and parse CalDAV calendar data $log->debug('fetch and parse CalDAV calendar data...'); $session //= Cal::DAV->new( user => $user, pass => $pass, url => $uri, ); # TODO: if calendar object is empty on reused session with no new uri, # warn on stderr with list of available collections using this sequence: # 1. PROPFIND on base-URL for {DAV:}current-user-principal # 2. PROPFIND for calendar-home-set property in caldav namespace # 3. PROPFIND with depth: 1 # as documented at return Object::Groupware::Calendar->new( data => $session->cal, dt_locale => $self->dt_locale, dt_time_zone => $self->dt_time_zone, ); } 1;