Fix a bunch of memory problems in beagle:
[beagle.git] / beagled / ThunderbirdQueryable / ThunderbirdQueryable.cs
blob29997723898e4035e7070b62b3208ba093a9a033
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.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));
51 indexer = null;
53 GMime.Global.Init ();
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 ()
63 base.Start ();
64 ExceptionHandlingThread.Start (new ThreadStart (StartWorker));
67 private void StartWorker ()
69 Logger.Log.Info ("Starting Thunderbird backend");
70 Stopwatch watch = new Stopwatch ();
71 watch.Start ();
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);
77 return;
80 State = QueryableState.Crawling;
81 indexer = new ThunderbirdIndexer (this, Thunderbird.GetProfilePaths (root_path));
82 indexer.Crawl ();
83 State = QueryableState.Idle;
85 watch.Stop ();
86 Logger.Log.Info ("Thunderbird backend done in {0}s", watch.ElapsedTime);
89 private bool IndexDataCheck ()
91 if (!Directory.Exists (Thunderbird.GetRootPath ()))
92 return true;
94 StartWorker ();
95 return false;
98 // We need this in order to perform custom queries to the lucene database
99 override protected LuceneQueryingDriver BuildLuceneQueryingDriver (string index_name,
100 int minor_version,
101 bool read_only_mode)
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 ();
143 do {
144 while (enumerator == null || !enumerator.MoveNext ())
145 return false;
146 } while (MatchesDate ((enumerator.Current as Uri)));
148 return true;
151 private bool MatchesDate (Uri uri)
153 LuceneAccess.StoredInfo info = lucene.GetStoredInfo (uri);
155 try {
156 if (!info.Equals (end_date) && info.LastIndex.CompareTo (end_date) < 0)
157 return false;
158 } catch {}
160 return true;
163 public string StatusName {
164 get {
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; }