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 State
= QueryableState
.Crawling
;
73 crawler
= new KopeteCrawler (log_dir
);
75 State
= QueryableState
.Idle
;
77 if (!Inotify
.Enabled
) {
78 Scheduler
.Task task
= Scheduler
.TaskFromHook (new Scheduler
.TaskHook (CrawlHook
));
79 task
.Tag
= "Crawling ~/.kopete/logs to find new logfiles";
81 ThisScheduler
.Add (task
);
86 Logger
.Log
.Info ("Kopete log backend worker thread done in {0}", stopwatch
);
89 public override void Start ()
93 ExceptionHandlingThread
.Start (new ThreadStart (StartWorker
));
96 /////////////////////////////////////////////////
101 foreach (FileInfo file
in crawler
.Logs
)
102 IndexLog (file
.FullName
, Scheduler
.Priority
.Delayed
);
105 private void CrawlHook (Scheduler
.Task task
)
108 task
.Reschedule
= true;
109 task
.TriggerTime
= DateTime
.Now
.AddSeconds (polling_interval_in_seconds
);
112 /////////////////////////////////////////////////
114 // Sets up an Inotify watch on all subdirectories withing ~/.kopete/logs
115 private void Watch (string path
)
117 DirectoryInfo root
= new DirectoryInfo (path
);
122 Queue queue
= new Queue ();
123 queue
.Enqueue (root
);
125 while (queue
.Count
> 0) {
126 DirectoryInfo dir
= queue
.Dequeue () as DirectoryInfo
;
128 // Setup watches on the present directory.
129 Inotify
.Subscribe (dir
.FullName
, OnInotifyEvent
,
130 Inotify
.EventType
.Create
| Inotify
.EventType
.CloseWrite
);
132 // Add all subdirectories to the queue so their files can be indexed.
133 foreach (DirectoryInfo subdir
in dir
.GetDirectories ())
134 queue
.Enqueue (subdir
);
138 /////////////////////////////////////////////////
140 private bool CheckForExistence ()
142 if (!Directory
.Exists (log_dir
))
150 /////////////////////////////////////////////////
152 private void OnInotifyEvent (Inotify
.Watch watch
,
156 Inotify
.EventType type
)
161 string full_path
= Path
.Combine (path
, subitem
);
163 if ((type
& Inotify
.EventType
.Create
) != 0 && (type
& Inotify
.EventType
.IsDirectory
) != 0) {
168 if ((type
& Inotify
.EventType
.Modify
) != 0) {
169 IndexLog (full_path
, Scheduler
.Priority
.Immediate
);
174 /////////////////////////////////////////////////
176 private static Indexable
ImLogToIndexable (string filename
)
178 Uri uri
= UriFu
.PathToFileUri (filename
);
179 Indexable indexable
= new Indexable (uri
);
180 indexable
.ContentUri
= uri
;
181 indexable
.Timestamp
= File
.GetLastWriteTimeUtc (filename
);
182 indexable
.MimeType
= KopeteLog
.MimeType
;
183 indexable
.HitType
= "IMLog";
184 indexable
.CacheContent
= false;
189 private void IndexLog (string filename
, Scheduler
.Priority priority
)
191 if (! File
.Exists (filename
))
194 if (IsUpToDate (filename
))
197 Indexable indexable
= ImLogToIndexable (filename
);
198 Scheduler
.Task task
= NewAddTask (indexable
);
199 task
.Priority
= priority
;
200 task
.SubPriority
= 0;
201 ThisScheduler
.Add (task
);
204 override protected double RelevancyMultiplier (Hit hit
)
206 return HalfLifeMultiplierFromProperty (hit
, 0.25,
207 "fixme:endtime", "fixme:starttime");
210 override protected bool HitFilter (Hit hit
)
212 ImBuddy buddy
= list
.Search (hit
["fixme:speakingto"]);
215 if (buddy
.Alias
!= "")
216 hit
["fixme:speakingto_alias"] = buddy
.Alias
;