2 // ThunderbirdQueryable.cs: This is where all the magic begins!
4 // Copyright (C) 2006 Pierre Östlund
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // 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 FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 using System
.Threading
;
30 using System
.Collections
;
31 using System
.Text
.RegularExpressions
;
36 // Register the Thunderbird backend for this assembly.
37 [assembly
: Beagle
.Daemon
.IQueryableTypes (typeof (Beagle
.Daemon
.ThunderbirdQueryable
.ThunderbirdQueryable
))]
39 namespace Beagle
.Daemon
.ThunderbirdQueryable
{
41 [QueryableFlavor (Name
= "Thunderbird", Domain
= QueryDomain
.Local
, RequireInotify
= false)]
42 public class ThunderbirdQueryable
: LuceneQueryable
{
43 private static DateTime indexing_start
;
44 private ThunderbirdIndexer indexer
;
46 public ThunderbirdQueryable () :
47 base ("ThunderbirdIndex")
49 // Remove one second from the start time to make sure we don't run into any troubles
50 indexing_start
= DateTime
.UtcNow
.Subtract (new TimeSpan (0, 0, 1));
55 if (Environment
.GetEnvironmentVariable ("BEAGLE_THUNDERBIRD_DEBUG") != null) {
56 Thunderbird
.Debug
= true;
57 Logger
.Log
.Debug ("Running Thunderbird backend in debug mode");
61 public override void Start ()
64 ExceptionHandlingThread
.Start (new ThreadStart (StartWorker
));
67 private void StartWorker ()
69 Logger
.Log
.Info ("Starting Thunderbird backend");
70 Stopwatch watch
= new Stopwatch ();
73 string root_path
= Thunderbird
.GetRootPath ();
74 if (!Directory
.Exists (root_path
)) {
75 GLib
.Timeout
.Add (60000, new GLib
.TimeoutHandler (IndexDataCheck
));
76 Logger
.Log
.Info ("No data available for indexing in {0}", root_path
);
80 State
= QueryableState
.Crawling
;
81 indexer
= new ThunderbirdIndexer (this, Thunderbird
.GetProfilePaths (root_path
));
83 State
= QueryableState
.Idle
;
86 Logger
.Log
.Info ("Thunderbird backend done in {0}s", watch
.ElapsedTime
);
89 private bool IndexDataCheck ()
91 if (!Directory
.Exists (Thunderbird
.GetRootPath ()))
98 // We need this in order to perform custom queries to the lucene database
99 override protected LuceneQueryingDriver
BuildLuceneQueryingDriver (string index_name
,
103 return new LuceneAccess (index_name
, minor_version
, read_only_mode
);
106 /////////////////////////////////////////////////////////////////////////////////////
108 public Scheduler
.Task
NewRemoveTaskByDate (DateTime end_date
)
110 return NewAddTask (new DateIndexableGenerator (Driver
, Lucene
, end_date
));
113 // The purpose of this IndexableGenerator is to remove mails older than the
114 // specified date (when beagle began to index Thunderbird mails)
115 private class DateIndexableGenerator
: IIndexableGenerator
{
116 private LuceneQueryingDriver driver
;
117 private LuceneAccess lucene
;
118 private DateTime end_date
;
120 private Uri
[] stored_uris
;
121 private IEnumerator enumerator
;
123 public DateIndexableGenerator (LuceneQueryingDriver driver
, LuceneAccess lucene
, DateTime end_date
)
125 this.driver
= driver
;
126 this.lucene
= lucene
;
127 this.end_date
= end_date
;
128 this.stored_uris
= null;
131 public Indexable
GetNextIndexable ()
133 return new Indexable (IndexableType
.Remove
, (Uri
) enumerator
.Current
);
136 public bool HasNextIndexable ()
138 if (stored_uris
== null) {
139 stored_uris
= driver
.PropertyQuery (Property
.NewKeyword ("fixme:client", "thunderbird"));
140 enumerator
= stored_uris
.GetEnumerator ();
144 while (enumerator
== null || !enumerator
.MoveNext ())
146 } while (MatchesDate ((enumerator
.Current
as Uri
)));
151 private bool MatchesDate (Uri uri
)
153 LuceneAccess
.StoredInfo info
= lucene
.GetStoredInfo (uri
);
156 if (!info
.Equals (end_date
) && info
.LastIndex
.CompareTo (end_date
) < 0)
163 public string StatusName
{
165 return String
.Format ("Removing Thunderbird mails past {0}", end_date
.ToString ());
169 public void PostFlushHook () { }
172 /////////////////////////////////////////////////////////////////////////////////////
174 public LuceneAccess Lucene
{
175 get { return (LuceneAccess) Driver; }
178 public static DateTime IndexingStart
{
179 get { return indexing_start; }