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
.Collections
;
31 using System
.Threading
;
36 namespace Beagle
.Daemon
.KopeteQueryable
{
38 [QueryableFlavor (Name
="Kopete", Domain
=QueryDomain
.Local
, RequireInotify
=false)]
39 public class KopeteQueryable
: LuceneFileQueryable
{
41 private string config_dir
, log_dir
;
43 private int polling_interval_in_seconds
= 60;
45 private KopeteCrawler crawler
;
47 private KopeteBuddyListReader list
= new KopeteBuddyListReader ();
49 public KopeteQueryable () : base ("KopeteIndex")
51 config_dir
= Path
.Combine (PathFinder
.HomeDir
, ".kde/share/apps/kopete");
52 log_dir
= Path
.Combine (config_dir
, "logs");
55 /////////////////////////////////////////////////
57 private void StartWorker()
59 if (! Directory
.Exists (log_dir
)) {
60 GLib
.Timeout
.Add (60000, new GLib
.TimeoutHandler (CheckForExistence
));
64 Logger
.Log
.Info ("Starting Kopete log backend");
66 Stopwatch stopwatch
= new Stopwatch ();
72 crawler
= new KopeteCrawler (log_dir
);
75 if (!Inotify
.Enabled
) {
76 Scheduler
.Task task
= Scheduler
.TaskFromHook (new Scheduler
.TaskHook (CrawlHook
));
77 task
.Tag
= "Crawling ~/.kopete/logs to find new logfiles";
79 ThisScheduler
.Add (task
);
84 Logger
.Log
.Info ("Kopete log backend worker thread done in {0}", stopwatch
);
87 public override void Start ()
91 ExceptionHandlingThread
.Start (new ThreadStart (StartWorker
));
94 /////////////////////////////////////////////////
99 foreach (FileInfo file
in crawler
.Logs
)
100 IndexLog (file
.FullName
, Scheduler
.Priority
.Delayed
);
103 private void CrawlHook (Scheduler
.Task task
)
106 task
.Reschedule
= true;
107 task
.TriggerTime
= DateTime
.Now
.AddSeconds (polling_interval_in_seconds
);
110 /////////////////////////////////////////////////
112 // Sets up an Inotify watch on all subdirectories withing ~/.kopete/logs
113 private void Watch (string path
)
115 DirectoryInfo root
= new DirectoryInfo (path
);
120 Queue queue
= new Queue ();
121 queue
.Enqueue (root
);
123 while (queue
.Count
> 0) {
124 DirectoryInfo dir
= queue
.Dequeue () as DirectoryInfo
;
126 // Setup watches on the present directory.
127 Inotify
.Subscribe (dir
.FullName
, OnInotifyEvent
,
128 Inotify
.EventType
.Create
| Inotify
.EventType
.CloseWrite
);
130 // Add all subdirectories to the queue so their files can be indexed.
131 foreach (DirectoryInfo subdir
in dir
.GetDirectories ())
132 queue
.Enqueue (subdir
);
136 /////////////////////////////////////////////////
138 private bool CheckForExistence ()
140 if (!Directory
.Exists (log_dir
))
148 /////////////////////////////////////////////////
150 private void OnInotifyEvent (Inotify
.Watch watch
,
154 Inotify
.EventType type
)
159 string full_path
= Path
.Combine (path
, subitem
);
161 if ((type
& Inotify
.EventType
.Create
) != 0 && (type
& Inotify
.EventType
.IsDirectory
) != 0) {
166 if ((type
& Inotify
.EventType
.Modify
) != 0) {
167 IndexLog (full_path
, Scheduler
.Priority
.Immediate
);
172 /////////////////////////////////////////////////
174 private static Indexable
ImLogToIndexable (string filename
)
176 Uri uri
= UriFu
.PathToFileUri (filename
);
177 Indexable indexable
= new Indexable (uri
);
178 indexable
.ContentUri
= uri
;
179 indexable
.Timestamp
= File
.GetLastWriteTimeUtc (filename
);
180 indexable
.MimeType
= KopeteLog
.MimeType
;
181 indexable
.HitType
= "IMLog";
182 indexable
.CacheContent
= false;
187 private void IndexLog (string filename
, Scheduler
.Priority priority
)
189 if (! File
.Exists (filename
))
192 if (IsUpToDate (filename
))
195 Indexable indexable
= ImLogToIndexable (filename
);
196 Scheduler
.Task task
= NewAddTask (indexable
);
197 task
.Priority
= priority
;
198 task
.SubPriority
= 0;
199 ThisScheduler
.Add (task
);
202 override protected double RelevancyMultiplier (Hit hit
)
204 return HalfLifeMultiplierFromProperty (hit
, 0.25,
205 "fixme:endtime", "fixme:starttime");
208 override protected bool HitFilter (Hit hit
)
210 ImBuddy buddy
= list
.Search (hit
["fixme:speakingto"]);
213 if (buddy
.Alias
!= "")
214 hit
["fixme:speakingto_alias"] = buddy
.Alias
;