File Coverage

blib/lib/CalDAV/Simple.pm
Criterion Covered Total %
statement 18 34 52.9
branch 0 6 0.0
condition n/a
subroutine 6 9 66.6
pod 2 2 100.0
total 26 51 50.9


line stmt bran cond sub pod time code
1             package CalDAV::Simple;
2              
3 1     1   681 use 5.006;
  1         3  
  1         33  
4 1     1   4 use strict;
  1         2  
  1         34  
5 1     1   11 use warnings;
  1         1  
  1         32  
6 1     1   512 use Moo 1.006;
  1         11234  
  1         7  
7 1     1   1109 use Carp qw/ croak /;
  1         1  
  1         55  
8 1     1   355 use CalDAV::Simple::Task;
  1         4  
  1         830  
9              
10             our $VERSION = '0.01';
11              
12             has ua => (
13             is => 'ro',
14             default => sub {
15             require HTTP::Tiny;
16             require IO::Socket::SSL;
17             return HTTP::Tiny->new(agent => __PACKAGE__.'/'.$VERSION);
18             },
19             );
20              
21             has calendar => (is => 'ro');
22             has username => (is => 'ro');
23             has password => (is => 'ro');
24             has croak_on_failure => (is => 'ro', default => sub { 1 });
25             has _url => (is => 'lazy');
26              
27             sub _build__url
28             {
29 0     0     my $self = shift;
30            
31             # This is a hack for doing basic auth
32 0 0         if ($self->calendar =~ m!^(https?://)(.*)$!) {
33 0           return $1.$self->username.':'.$self->password.'@'.$2;
34             }
35             else {
36             # This is probably my fault :-)
37 0           croak sprintf("unexpected format calendar '%s'\n",
38             $self->calendar);
39             }
40             }
41              
42             my $request = sub {
43             my $self = shift;
44             my $param = shift;
45              
46             return $self->ua->request($param->{verb}, $param->{url},
47             {
48             headers => $param->{headers},
49             content => $param->{content},
50             });
51             };
52              
53             sub tasks
54             {
55 0     0 1   my $self = shift;
56 0           my $body = '';
57 0           my $response = $self->$request({
58             verb => 'REPORT',
59             url => $self->_url,
60             content => $body,
61             headers => {
62             'Depth' => 1,
63             'Prefer' => 'return-minimal',
64             'Content-Type' => 'application/xml; charset=utf-8',
65             },
66             });
67 0 0         if ($response->{success}) {
68 0           my @tasks;
69 0           while ($response->{content} =~ m!(.*?)!msg) {
70 0           push(@tasks, CalDAV::Simple::Task->new(vcal_string => $1));
71             }
72 0           return @tasks;
73             }
74             else {
75 0 0         return undef unless $self->croak_on_failure;
76              
77             # TODO: make some effort to determine what kind of failure :-)
78 0           croak "failed to get tasks\n";
79             }
80             }
81              
82             sub delete_task
83             {
84 0     0 1   my ($self, $task) = @_;
85 0           my $response = $self->$request({
86             verb => 'DELETE',
87             url => $self->_url.'/'.$task->uid.'.ics',
88             headers => {
89             'If-Match' => $task->etag,
90             'Content-Type' => 'application/xml; charset=utf-8',
91             },
92             });
93             }
94              
95              
96             1;
97              
98             =head1 NAME
99              
100             CalDAV::Simple - a simple interface to calendar services via a subset of CalDAV
101              
102             =head1 SYNOPSIS
103              
104             use CalDAV::Simple;
105              
106             my $cal = CalDAV::Simple->new(
107             username => $username,
108             password => $password,
109             calendar => $url,
110             );
111              
112             my @tasks = $cal->tasks;
113              
114             foreach my $task (@tasks) {
115             printf "task '%s' is due '%s'\n", $task->summary, $task->due;
116             }
117              
118             =head1 DESCRIPTION
119              
120             This is a ALPHA quality module for talking to a CalDAV server.
121             Currently it just provides an interface for getting tasks
122             and deleting individual tasks.
123              
124             This distribution is currently a lash-up: I hacked together something to
125             solve a problem. It does things the quick dirty way, and the interface
126             is likely to change from release to release. So far I've only tested it
127             against L's CalDAV server: I've no idea if
128             it will work with other servers yet. Please let me know either way.
129              
130             =head1 METHODS
131              
132             =head2 new
133              
134             This expects three attributes: username, password, and calendar.
135             The latter is the URL for your calendar.
136              
137             =head2 tasks
138              
139             Returns a list of all tasks in the calendar.
140             Each entry in the list is an instance of L.
141             Look at the document for that module to see what attributes are provided.
142              
143             =head2 delete_task
144              
145             Takes a task (instance of L) and deletes it
146             from the calendar.
147              
148             =head1 LIMITATIONS
149              
150             This is very much alpha quality and has only been tested against one CalDAV server.
151             The XML returned by the server is currently handled with regular expressions,
152             and I haven't read any specs to find out what range of results I can expect.
153              
154             In short: your mileage may vary :-)
155              
156             =head1 SEE ALSO
157              
158             L - instances of this are returned by the C method,
159             and expected as the argument to the C method.
160              
161             L -
162             documentation about CalDAV, which I've been using as a guide when hacking this up.
163              
164             L - about CalDAV.
165              
166             =head1 REPOSITORY
167              
168             L
169              
170             =head1 AUTHOR
171              
172             Neil Bowers Eneilb@cpan.orgE
173              
174             =head1 COPYRIGHT AND LICENSE
175              
176             This software is copyright (c) 2015 by Neil Bowers .
177              
178             This is free software; you can redistribute it and/or modify it under
179             the same terms as the Perl 5 programming language system itself.
180              
181             =cut
182