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