diff options
author | Jonas Smedegaard <dr@jones.dk> | 2024-08-28 22:06:00 +0200 |
---|---|---|
committer | Jonas Smedegaard <dr@jones.dk> | 2024-08-28 22:06:00 +0200 |
commit | 30e1a34d6f69f514c6c1c908c0f77a651074a175 (patch) | |
tree | 02a6601a802a2e7d5b901936f1ce898b68dce59a | |
parent | 944985c6a66e288f9a7f52cd25764bbfef2514ce (diff) |
define class Object::Groupware::DAV
-rwxr-xr-x | bin/events2md.pl | 59 | ||||
-rw-r--r-- | lib/Object/Groupware/DAV.pm | 86 |
2 files changed, 92 insertions, 53 deletions
diff --git a/bin/events2md.pl b/bin/events2md.pl index d0dc9b5..e9ef842 100755 --- a/bin/events2md.pl +++ b/bin/events2md.pl @@ -3,28 +3,20 @@ use v5.36; use utf8; use open qw(:std :encoding(UTF-8)); -use autodie; use Feature::Compat::Try; use FindBin qw($Bin); use lib "$Bin/../lib"; -use POSIX qw(locale_h); -use locale; -use Net::Netrc; -use List::Util qw(first); - use IO::Interactive::Tiny; use Log::Any qw($log); use Log::Any::Adapter; - use URI; -use IO::Prompter; -use Cal::DAV; use DateTime; use Path::Tiny; use Text::Xslate; +use Object::Groupware::DAV; use Object::Groupware::Calendar; if ( IO::Interactive::Tiny::is_interactive() ) { @@ -43,9 +35,6 @@ $CALENDAR_URI ||= shift @ARGV $OUTPUT_FILE = shift @ARGV if @ARGV; -# use system locale to format DateTime objects parsed from iCal data -DateTime->DefaultLocale( setlocale(LC_TIME) ); - # resolve calendar URIs my ( $base_uri, $calendar_uri, $calendar ); $base_uri = URI->new($BASE_URI) @@ -63,41 +52,12 @@ if ( $base_uri->scheme eq 'http' or $base_uri->scheme eq 'https' ) { $base_uri->eq($calendar_uri) and $calendar_uri = undef or $log->infof( 'will use calendar URI %s', $calendar_uri ); - # resolve credentials - $log->debug('resolve credentials...'); - my ( $mach, $user, $pass ); - ( $user, $pass ) = split ':', $base_uri->userinfo - if $base_uri->userinfo; - $user ||= $ENV{CAL_DAV_USER}; - $pass ||= $ENV{CAL_DAV_PASS}; - $mach = Net::Netrc->lookup( $base_uri->host, $user ) - if !$user or !$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 ); - - # fetch and parse CalDAV calendar data - $log->debug('fetch and parse CalDAV calendar data...'); - my $session = Cal::DAV->new( - user => $user, - pass => $pass, - url => $base_uri, + my $session = Object::Groupware::DAV->new( + user => $ENV{CAL_DAV_USER}, + pass => $ENV{CAL_DAV_PASS}, + uri => $base_uri, ); - $session->get($calendar_uri) - if $calendar_uri; - $calendar = Object::Groupware::Calendar->new( data => $session->cal ); + $calendar = $session->get($calendar_uri); } elsif ( $base_uri->scheme eq 'file' ) { defined $base_uri->file @@ -121,13 +81,6 @@ if ( $log->is_trace ) { p $calendar; } -# TODO: if list is empty and no calendar uri was explicitly supplied, -# warn on stdout with list of abailable 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 <https://stackoverflow.com/a/11673483> - # select subset of calendar events $log->debug('serialize calendar events...'); my $start; diff --git a/lib/Object/Groupware/DAV.pm b/lib/Object/Groupware/DAV.pm new file mode 100644 index 0000000..5c191e3 --- /dev/null +++ b/lib/Object/Groupware/DAV.pm @@ -0,0 +1,86 @@ +use v5.36; +use Feature::Compat::Class 0.07; + +package Object::Groupware::DAV 0.01; + +class Object::Groupware::DAV; + +use utf8; + +use Feature::Compat::Try; +use POSIX qw(locale_h); # resolve LC_TIME +use locale; +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; + +# use system locale to format DateTime objects parsed from iCal data +DateTime->DefaultLocale( setlocale(LC_TIME) ); + +field $log = Log::Any->get_logger; + +field $uri : param; +field $user : param = undef; +field $pass : param = undef; + +field $session; + +ADJUST { + $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 <https://stackoverflow.com/a/11673483> + + return Object::Groupware::Calendar->new( data => $session->cal ); +} + +1; |