4 // Copyright (C) 2005 Novell, Inc.
8 // Permission is hereby granted, free of charge, to any person obtaining a
9 // copy of this software and associated documentation files (the "Software"),
10 // to deal in the Software without restriction, including without limitation
11 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 // and/or sell copies of the Software, and to permit persons to whom the
13 // Software is furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 // DEALINGS IN THE SOFTWARE.
28 using System
.Globalization
;
35 namespace Beagle
.Daemon
.EvolutionDataServerQueryable
{
37 public class CalContainer
: Container
{
40 private CalView cal_view
;
41 private Scheduler
.Priority priority
= Scheduler
.Priority
.Delayed
;
43 public CalContainer (Evolution
.Source source
, EvolutionDataServerQueryable queryable
, string fingerprint
) : base (source
, queryable
, fingerprint
) { }
45 public override bool OpenClient ()
47 if (!this.source
.IsLocal ()) {
48 Logger
.Log
.Debug ("Skipping remote calendar {0}", this.source
.Uri
);
53 this.cal
= new Cal (this.source
, CalSourceType
.Event
);
55 } catch (Exception e
) {
56 Logger
.Log
.Warn ("Unable to open calendar {0}: {1}", this.source
.Uri
, e
.Message
);
63 public override void OpenView ()
65 this.cal_view
= this.cal
.GetCalView ("#t");
67 this.cal_view
.ObjectsAdded
+= OnObjectsAdded
;
68 this.cal_view
.ObjectsModified
+= OnObjectsModified
;
69 this.cal_view
.ObjectsRemoved
+= OnObjectsRemoved
;
70 this.cal_view
.ViewDone
+= OnViewDone
;
72 this.cal_view
.Start ();
75 public override void IndexAll ()
77 CalComponent
[] event_list
= this.cal
.GetItems ("#t");
79 Logger
.Log
.Debug ("Calendar has {0} items", event_list
.Length
);
81 foreach (CalComponent cc
in event_list
)
85 public override void IndexChanges ()
87 CalComponent
[] added
, changed
;
90 Logger
.Log
.Debug ("Getting calendar changes for {0}", this.source
.Uri
);
91 this.cal
.GetChanges ("beagle-" + this.fingerprint
, out added
, out changed
, out removed
);
92 Logger
.Log
.Debug ("Calendar {0}: {1} added, {2} changed, {3} removed",
93 this.cal
.Uri
, added
.Length
, changed
.Length
, removed
.Length
);
95 foreach (CalComponent cc
in added
)
98 foreach (CalComponent cc
in changed
)
102 // FIXME: Broken in e-d-s right now
103 foreach (string id
in removed
) {
104 RemoveCalComponent (id
);
109 public override void Remove ()
111 Logger
.Log
.Debug ("Removing calendar source {0}", this.source
.Uid
);
113 Property prop
= Property
.NewUnsearched ("fixme:source_uid", this.source
.Uid
);
114 this.queryable
.RemovePropertyIndexable (prop
);
116 this.cal_view
.Dispose ();
120 private void OnObjectsAdded (object o
, Evolution
.ObjectsAddedArgs args
)
122 foreach (CalComponent cc
in CalUtil
.CalCompFromICal (args
.Objects
.Handle
, this.cal_view
.Client
))
123 AddCalComponent (cc
);
126 private void OnObjectsModified (object o
, Evolution
.ObjectsModifiedArgs args
)
128 foreach (CalComponent cc
in CalUtil
.CalCompFromICal (args
.Objects
.Handle
, this.cal_view
.Client
))
129 AddCalComponent (cc
);
132 private void OnObjectsRemoved (object o
, Evolution
.ObjectsRemovedArgs args
)
134 // FIXME: This is a temporary workaround for the
135 // fact that the evolution bindings return a
136 // GLib.List with an object type, but there are
137 // really strings in there.
139 GLib
.List id_list
= new GLib
.List (args
.Uids
.Handle
,
142 foreach (string id
in id_list
)
143 RemoveCalComponent (id
);
146 private void OnViewDone (object o
, Evolution
.ViewDoneArgs args
)
148 // Now that we're done synching with the original
149 // state of the calendar, switch all new changes to
151 priority
= Scheduler
.Priority
.Immediate
;
154 /////////////////////////////////////
157 // calendar:///?source-uid=<value>&comp-uid=<value>[&comp-rid=value]
159 // The Uri class sucks SO MUCH ASS. It shits itself
160 // on foo:///?bar so we have to insert something in
161 // before "?bar". This is filed as Ximian bug #76146.
162 // Hopefully it is just a bug in Mono and not a
163 // fundamental problem of the Uri class. Fortunately
164 // Evolution can handle the horribly mangled URIs
165 // that come out of it.
167 private Uri
GetCalendarUri (CalComponent cc
) {
168 return GetCalendarUri (cc
.Uid
);
171 private Uri
GetCalendarUri (string id
) {
172 return new Uri (String
.Format ("calendar://uri-class-sucks/?source-uid={0}&comp-uid={1}",
173 this.source
.Uid
, id
));
176 /////////////////////////////////////
178 private void AddCalComponent (CalComponent cc
)
180 Indexable indexable
= CalComponentToIndexable (cc
);
182 this.queryable
.AddIndexable (indexable
, this.priority
);
185 private void RemoveCalComponent (string id
)
187 this.queryable
.RemoveIndexable (GetCalendarUri (id
));
190 /////////////////////////////////////
192 private Indexable
CalComponentToIndexable (CalComponent cc
)
194 Indexable indexable
= new Indexable (GetCalendarUri (cc
));
196 indexable
.Timestamp
= cc
.Dtstart
;
197 indexable
.HitType
= "Calendar";
199 indexable
.AddProperty (Property
.NewUnsearched ("fixme:source_uid", this.source
.Uid
));
200 indexable
.AddProperty (Property
.NewUnsearched ("fixme:uid", cc
.Uid
));
201 indexable
.AddProperty (Property
.NewDate ("fixme:starttime", cc
.Dtstart
.ToUniversalTime ()));
202 indexable
.AddProperty (Property
.NewDate ("fixme:endtime", cc
.Dtend
.ToUniversalTime ()));
204 foreach (string attendee
in cc
.Attendees
)
205 indexable
.AddProperty (Property
.New ("fixme:attendee", attendee
));
207 foreach (string comment
in cc
.Comments
)
208 indexable
.AddProperty (Property
.New ("fixme:comment", comment
));
210 foreach (string description
in cc
.Descriptions
)
211 indexable
.AddProperty (Property
.New ("fixme:description", description
));
213 foreach (string summary
in cc
.Summaries
)
214 indexable
.AddProperty (Property
.New ("fixme:summary", summary
));
216 foreach (string category
in cc
.Categories
)
217 indexable
.AddProperty (Property
.NewUnsearched ("fixme:category", category
));
219 foreach (string location
in cc
.Location
)
220 indexable
.AddProperty (Property
.New ("fixme:location", location
));