Merge the recent changes from HEAD onto the branch
[beagle.git] / beagled / ThunderbirdQueryable / ThunderbirdQueryable.cs
blob7afef9ef88aa10fe894e74741c38fe8e2eecb7f7
1 //
2 // ThunderbirdQueryable.cs: This is where all the magic begins!
3 //
4 // Copyright (C) 2006 Pierre Östlund
5 //
7 //
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
24 // SOFTWARE.
27 using System;
28 using System.IO;
29 using System.Threading;
30 using System.Collections;
31 using System.Text.RegularExpressions;
33 using Beagle;
34 using Beagle.Util;
36 // Register the Thunderbird backend for this assembly.
37 [assembly: Beagle.Daemon.IBackendTypes (typeof (Beagle.Daemon.ThunderbirdQueryable.ThunderbirdQueryable))]
39 namespace Beagle.Daemon.ThunderbirdQueryable {
41 [BackendFlavor (Name = "Thunderbird", Domain = QueryDomain.Local)]
42 public class ThunderbirdQueryable : LuceneQueryable {
43 private static DateTime indexing_start;
44 private ThunderbirdIndexer indexer;
46 public ThunderbirdQueryable () : base ("Thunderbird")
48 // Remove one second from the start time to make sure we don't run into any troubles
49 indexing_start = DateTime.UtcNow.Subtract (new TimeSpan (0, 0, 1));
50 indexer = null;
52 GMime.Global.Init ();
54 if (Environment.GetEnvironmentVariable ("BEAGLE_THUNDERBIRD_DEBUG") != null) {
55 Thunderbird.Debug = true;
56 Logger.Log.Debug ("Running Thunderbird backend in debug mode");
60 public override void Start ()
62 base.Start ();
63 ExceptionHandlingThread.Start (new ThreadStart (StartWorker));
66 private void StartWorker ()
68 Logger.Log.Info ("Starting Thunderbird backend");
69 Stopwatch watch = new Stopwatch ();
70 watch.Start ();
72 string root_path = Thunderbird.GetRootPath ();
73 if (!Directory.Exists (root_path)) {
74 GLib.Timeout.Add (60000, new GLib.TimeoutHandler (IndexDataCheck));
75 Logger.Log.Info ("No data available for indexing in {0}", root_path);
76 return;
79 State = QueryableState.Crawling;
80 indexer = new ThunderbirdIndexer (this, Thunderbird.GetProfilePaths (root_path));
81 indexer.Crawl ();
82 State = QueryableState.Idle;
84 watch.Stop ();
85 Logger.Log.Info ("Thunderbird backend done in {0}s", watch.ElapsedTime);
88 private bool IndexDataCheck ()
90 if (!Directory.Exists (Thunderbird.GetRootPath ()))
91 return true;
93 StartWorker ();
94 return false;
97 // We need this in order to perform custom queries to the lucene database
98 override protected LuceneQueryingDriver BuildLuceneQueryingDriver (string index_name,
99 int minor_version,
100 bool read_only_mode)
102 return new LuceneAccess (index_name, minor_version, read_only_mode);
105 /////////////////////////////////////////////////////////////////////////////////////
107 public Scheduler.Task NewRemoveTaskByDate (DateTime end_date)
109 return NewAddTask (new DateIndexableGenerator (Driver, Lucene, end_date));
112 // The purpose of this IndexableGenerator is to remove mails older than the
113 // specified date (when beagle began to index Thunderbird mails)
114 private class DateIndexableGenerator : IIndexableGenerator {
115 private LuceneQueryingDriver driver;
116 private LuceneAccess lucene;
117 private DateTime end_date;
119 private Uri[] stored_uris;
120 private IEnumerator enumerator;
122 public DateIndexableGenerator (LuceneQueryingDriver driver, LuceneAccess lucene, DateTime end_date)
124 this.driver = driver;
125 this.lucene = lucene;
126 this.end_date = end_date;
127 this.stored_uris = null;
130 public Indexable GetNextIndexable ()
132 return new Indexable (IndexableType.Remove, (Uri) enumerator.Current);
135 public bool HasNextIndexable ()
137 if (stored_uris == null) {
138 stored_uris = driver.PropertyQuery (Property.NewKeyword ("fixme:client", "thunderbird"));
139 enumerator = stored_uris.GetEnumerator ();
142 do {
143 while (enumerator == null || !enumerator.MoveNext ())
144 return false;
145 } while (MatchesDate ((enumerator.Current as Uri)));
147 return true;
150 private bool MatchesDate (Uri uri)
152 LuceneAccess.StoredInfo info = lucene.GetStoredInfo (uri);
154 try {
155 if (!info.Equals (end_date) && info.LastIndex.CompareTo (end_date) < 0)
156 return false;
157 } catch {}
159 return true;
162 public string StatusName {
163 get {
164 return String.Format ("Removing Thunderbird mails past {0}", end_date.ToString ());
168 public void PostFlushHook () { }
171 /////////////////////////////////////////////////////////////////////////////////////
173 public LuceneAccess Lucene {
174 get { return (LuceneAccess) Driver; }
177 public static DateTime IndexingStart {
178 get { return indexing_start; }