add RTx::Calendar 0.07
[freeside.git] / rt / share / html / NoAuth / Calendar / dhandler
1 <%init>
2
3 use Data::ICal;
4 use Data::ICal::Entry::Todo;
5 use Data::ICal::Entry::Event;
6 use Date::ICal;
7
8 $RT::ICalTicketType   ||= "Data::ICal::Entry::Todo";
9 $RT::ICalReminderType ||= "Data::ICal::Entry::Event";
10
11 my ($UserId, $SearchId, $MagicNumber);
12 my $arg = $m->dhandler_arg;
13
14 if ($arg =~ m{^(\d+)@(\d+)/(.*)$}) {
15     $UserId = $1;
16     $SearchId = $2;
17     $MagicNumber = $3;
18 } elsif ($arg =~ m{^(\d+)/(.*)}) {
19     $UserId = $1;
20     $MagicNumber = $2;
21 } else {
22     Abort("Corrupted URL.");
23 }
24
25 my $CurrentUser = new RT::CurrentUser();
26 $CurrentUser->LoadById($UserId);
27 my $user = $CurrentUser->Name;
28
29 # if no user, abort
30 unless ($CurrentUser->Id) {
31     $RT::Logger->error("No such user id $UserId from $ENV{'REMOTE_ADDR'}");
32     $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
33     $m->abort;
34 }
35
36 # verify user has LoadSavedSearch right
37 if ($SearchId and not $CurrentUser->HasRight( Right => 'LoadSavedSearch',
38                                               Object=> $RT::System )) {
39     $RT::Logger->error("not enough rights for user $user from $ENV{'REMOTE_ADDR'}");
40     $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
41     $m->abort;
42 }
43
44
45 # if MagicNumber doesn't match the one stored in database, abort
46 my $Search;
47 my $ICalAttribute;
48 if ($SearchId) {
49     $Search = $CurrentUser->Attributes->WithId($SearchId);
50     $ICalAttribute = $Search->FirstAttribute('ICalURL');
51 } else {
52     $ICalAttribute = $CurrentUser->UserObj->FirstAttribute('ICalURL');
53 }
54
55 unless ($ICalAttribute) {
56     $RT::Logger->error("No such ICal feed for $user from $ENV{'REMOTE_ADDR'}");
57     $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
58     $m->abort;
59 }
60
61
62 if ($MagicNumber ne $ICalAttribute->Content) {
63     $RT::Logger->error("FAILED LOGIN for $user from $ENV{'REMOTE_ADDR'}");
64     $m->out("RT/".$RT::VERSION ." ".404 ."\n\nno such file\n");
65     $m->abort;
66 }
67
68 my $Tickets   = RT::Tickets->new($CurrentUser);
69
70 my $Query = "( Status = 'new' OR Status = 'open' OR Status = 'stalled')
71  AND ( Owner = '" . $CurrentUser->Id ."' OR Owner = 'Nobody'  )
72  AND ( Type = 'reminder' OR 'Type' = 'ticket' )";
73
74 $Query = $Search->SubValue('Query')
75     if $Search;
76
77 $Query .= " AND ( Due > '1970-01-01' OR Starts > '1970-01-01' )";
78
79 $Tickets->FromSQL($Query);
80
81 $Tickets->OrderBy(FIELD => 'Due', ORDER => 'ASC');
82
83 my $calendar = Data::ICal->new();
84
85 my ($uid) = $RT::WebURL =~ m{https?://([^:]+)};
86
87 while (my $Ticket = $Tickets->Next ) {
88
89     my $event;
90     if ($Ticket->Type eq 'ticket') {
91         $event = add_todo($Ticket, $uid);
92     } else {
93         $event = add_event($Ticket, $uid);
94     }
95     next unless $event;
96     $calendar->add_entry($event);
97 }
98
99 my $cal = $calendar->as_string;
100
101 $r->content_type('text/calendar;charset=utf-8');
102 $m->clear_buffer();
103 $m->out($cal);
104 $m->abort; 
105
106 sub add_event {
107     my ($Reminder, $uid) = @_;
108
109     return unless defined $Reminder->RefersTo->First;
110     my $Ticket  = $Reminder->RefersTo->First->TargetObj;
111     
112     my %event = (
113         summary => $Reminder->Subject ? $Reminder->Subject : '',
114         url        => "${RT::WebURL}/Ticket/Display.html?id=" . $Ticket->id,
115         uid        => Date::ICal->new( epoch => time() )->ical() . "-" . $Reminder->Id . "@" . $uid,
116         categories => $Ticket->QueueObj->Name,
117         dtstart     => Date::ICal->new( epoch => $Reminder->DueObj->Unix )->ical,
118     );
119
120     my $event = $RT::ICalReminderType->new();
121     $event->add_properties(%event);
122
123     return $event;
124 }
125
126 sub add_todo {
127     my ($Ticket, $uid) = @_;
128
129     my %vtodo = (
130         summary    => $Ticket->Subject ? $Ticket->Subject : '',
131         dtstart    => Date::ICal->new( epoch => $Ticket->CreatedObj->Unix )->ical,
132         url        => "${RT::WebURL}/Ticket/Display.html?id=" . $Ticket->id,
133         uid        => Date::ICal->new( epoch => time() )->ical() . "-" . $Ticket->Id . "@" . $uid,
134         categories => $Ticket->QueueObj->Name,
135     );
136
137     $vtodo{due} = Date::ICal->new( epoch => $Ticket->DueObj->Unix )->ical,
138         if $Ticket->DueObj;
139
140     if ($Ticket->OwnerObj->Id != $RT::Nobody->Id and $Ticket->OwnerObj->EmailAddress) {
141         $vtodo{organizer} = "MAILTO:" . $Ticket->OwnerObj->EmailAddress;
142         $vtodo{attendee} = "MAILTO:" . $Ticket->OwnerObj->EmailAddress;
143     } elsif ($Ticket->QueueObj->CommentAddress) {
144         $vtodo{organizer} = "MAILTO:" . $Ticket->QueueObj->CommentAddress;
145         $vtodo{attendee} = "MAILTO:" . $Ticket->QueueObj->CommentAddress; 
146     }
147
148     $vtodo{priority} = $Ticket->Priority
149         if $Ticket->Priority;
150
151     my $vtodo = $RT::ICalTicketType->new();
152     $vtodo->add_properties(%vtodo);
153
154     return $vtodo;
155 }
156
157
158
159 </%init>