File Coverage

blib/lib/App/gcal.pm
Criterion Covered Total %
statement 26 75 34.6
branch 2 22 9.0
condition 0 6 0.0
subroutine 8 11 72.7
pod 0 1 0.0
total 36 115 31.3


line stmt bran cond sub pod time code
1 1     1   51884 use strict;
  1         2  
  1         36  
2 1     1   4 use warnings;
  1         2  
  1         65  
3              
4             package App::gcal;
5             {
6             $App::gcal::VERSION = '1.121460';
7             }
8              
9 1     1   829 use Class::ReturnValue;
  1         17580  
  1         140  
10 1     1   892 use Data::ICal;
  1         34790  
  1         11  
11 1     1   1787 use DateTime::TimeZone;
  1         81482  
  1         726  
12              
13             # ABSTRACT: Command Line Interface interface to Google Calendar.
14              
15             # cache the timezone lookup
16             my $localTZ = DateTime::TimeZone->new( name => 'local' );
17              
18             my $gcal;
19              
20              
21             # entry point
22             sub run {
23 0     0 0 0 my ( $args, $username, $password ) = @_;
24              
25             # loop over args
26 0         0 for my $arg (@$args) {
27              
28 0         0 my $cal;
29 0 0 0     0 if ( ( -e $arg ) && ( -r $arg ) ) {
30              
31             # looks like a file
32 0         0 $cal = _process_file($arg);
33              
34             }
35             else {
36              
37             # give to ICal::QuickAdd
38 0         0 $cal = _process_text($arg);
39             }
40              
41 0 0       0 if ($cal) {
42 0         0 _save_to_gcal( $cal, $username, $password );
43             }
44             else {
45 0         0 print STDERR $cal->error_message . "\n";
46             }
47             }
48             }
49              
50             # process an ics file
51             sub _process_file {
52 2     2   2032 my ($file) = @_;
53              
54 2         20 my $calendar = Data::ICal->new( filename => $file );
55 2 100       9276 unless ($calendar) {
56 1         18 return _error("error parsing $file");
57             }
58              
59 1         6 return $calendar;
60             }
61              
62             # process a text event
63             sub _process_text {
64 0     0   0 my ($text) = @_;
65              
66 0         0 my $error_msg = 'error parsing text';
67              
68 0 0       0 unless ($text) {
69 0         0 return _error($error_msg);
70             }
71              
72 0         0 require ICal::Format::Natural;
73 0         0 my $calendar = ICal::Format::Natural::ical_format_natural($text);
74              
75 0 0       0 unless ( $calendar->isa('Data::ICal') ) {
76 0         0 return _error($error_msg);
77             }
78              
79 0         0 return $calendar;
80             }
81              
82             # save event to Google Calendar
83             sub _save_to_gcal {
84 0     0   0 my ( $cal, $username, $password ) = @_;
85              
86 0 0       0 unless ($gcal) {
87              
88 0 0 0     0 unless ( $username && $password ) {
89              
90             # get login and password from .netrc
91 0         0 require Net::Netrc;
92 0         0 my $netrc = Net::Netrc->lookup('google.com');
93              
94 0 0       0 unless ($netrc) {
95 0         0 die(
96             'Error. Could not find your credentials in your .netrc file'
97             );
98             }
99              
100 0         0 $username = $netrc->login;
101 0         0 $password = $netrc->password;
102             }
103              
104             # login
105 0         0 require Net::Google::Calendar;
106 0         0 $gcal = Net::Google::Calendar->new;
107 0         0 $gcal->login( $username, $password );
108             }
109              
110 0         0 for my $entry ( @{ $cal->entries } ) {
  0         0  
111              
112             # create gcal event
113 0         0 my $event = _create_new_gcal_event($entry);
114              
115             # save
116 0         0 my $tmp = $gcal->add_entry($event);
117 0 0       0 die "Couldn't add event: $@\n" unless defined $tmp;
118             }
119             }
120              
121             # converts Data::ICal to Net::Google::Calendar::Entry
122             sub _create_new_gcal_event {
123 1     1   855 my ($entry) = @_;
124              
125 1         807 require Net::Google::Calendar::Entry;
126 0         0 require DateTime::Format::ICal;
127              
128 0         0 my $event = Net::Google::Calendar::Entry->new();
129              
130 0         0 $event->title( $entry->property('summary')->[0]->value );
131              
132             # ensure the times are in the local timezone
133 0         0 my $dtstart = DateTime::Format::ICal->parse_datetime(
134             $entry->property('dtstart')->[0]->value );
135 0         0 $dtstart->set_time_zone($localTZ);
136 0         0 my $dtend = DateTime::Format::ICal->parse_datetime(
137             $entry->property('dtend')->[0]->value );
138 0         0 $dtend->set_time_zone($localTZ);
139 0         0 $event->when( $dtstart, $dtend );
140              
141 0         0 $event->status('confirmed');
142              
143             # optional
144 0 0       0 if ( $entry->property('description') ) {
145 0         0 $event->content( $entry->property('description')->[0]->value );
146             }
147 0 0       0 if ( $entry->property('location') ) {
148 0         0 $event->location( $entry->property('location')->[0]->value );
149             }
150              
151 0         0 return $event;
152             }
153              
154             # return an error
155             sub _error {
156 1     1   1 my $msg = shift;
157              
158 1         5 my $ret = Class::ReturnValue->new;
159 1         7 $ret->as_error( errno => 1, message => $msg );
160 1         382 return $ret;
161             }
162              
163              
164             1;
165              
166             __END__