aboutsummaryrefslogtreecommitdiff
path: root/lib/Object/Groupware/DAV.pm
blob: 5c191e316e8a87c436881eef9199ffe40ea0c62b (plain)
  1. use v5.36;
  2. use Feature::Compat::Class 0.07;
  3. package Object::Groupware::DAV 0.01;
  4. class Object::Groupware::DAV;
  5. use utf8;
  6. use Feature::Compat::Try;
  7. use POSIX qw(locale_h); # resolve LC_TIME
  8. use locale;
  9. use Net::Netrc;
  10. use IO::Interactive::Tiny;
  11. use Log::Any qw( );
  12. use URI;
  13. use IO::Prompter;
  14. use Cal::DAV;
  15. use DateTime;
  16. use Object::Groupware::Calendar;
  17. # use system locale to format DateTime objects parsed from iCal data
  18. DateTime->DefaultLocale( setlocale(LC_TIME) );
  19. field $log = Log::Any->get_logger;
  20. field $uri : param;
  21. field $user : param = undef;
  22. field $pass : param = undef;
  23. field $session;
  24. ADJUST {
  25. $uri = URI->new($uri)
  26. or $log->fatal( 'failed to parse URI %s', $uri ) && exit 2;
  27. $log->debug('resolve credentials...');
  28. my $mach;
  29. ( $user, $pass ) = split ':', $uri->userinfo
  30. if !$user and $uri->userinfo;
  31. $mach = Net::Netrc->lookup( $uri->host, $user )
  32. unless $user and defined $pass;
  33. if ($mach) {
  34. $user ||= $mach->login;
  35. $pass ||= $mach->password;
  36. $log->infof(
  37. 'will use .netrc provided credentials for user %s',
  38. $user
  39. );
  40. }
  41. elsif ( IO::Interactive::Tiny::is_interactive() ) {
  42. $log->warn(
  43. 'will ask for missing info - this will fail in headless mode');
  44. $user ||= prompt 'Enter your username';
  45. $pass ||= prompt 'Enter your password', -echo => '*';
  46. }
  47. $log->debugf( 'resolved credentials for user %s', $user );
  48. }
  49. method get ($new_uri)
  50. {
  51. $uri = URI->new($new_uri)
  52. or $log->fatal( 'failed to parse URI %s', $uri ) && exit 2
  53. if $new_uri;
  54. # fetch and parse CalDAV calendar data
  55. $log->debug('fetch and parse CalDAV calendar data...');
  56. $session //= Cal::DAV->new(
  57. user => $user,
  58. pass => $pass,
  59. url => $uri,
  60. );
  61. # TODO: if calendar object is empty on reused session with no new uri,
  62. # warn on stderr with list of available collections using this sequence:
  63. # 1. PROPFIND on base-URL for {DAV:}current-user-principal
  64. # 2. PROPFIND for calendar-home-set property in caldav namespace
  65. # 3. PROPFIND with depth: 1
  66. # as documented at <https://stackoverflow.com/a/11673483>
  67. return Object::Groupware::Calendar->new( data => $session->cal );
  68. }
  69. 1;