~igors/do-plugins/Thunderbird-fix-redux

« back to all changes in this revision

Viewing changes to Thunderbird/src/ThunderbirdContactItemSource.cs

  • Committer: Igor Slepchin
  • Date: 2011-02-08 01:13:19 UTC
  • mfrom: (674.3.12 do-plugins)
  • Revision ID: igor.gnomedo@gmail.com-20110208011319-rax61pwj0xuona30
merge lp:~igors/do-plugins/Thunderbird-fix 

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
//  You should have received a copy of the GNU General Public License
18
18
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
 
// 
21
 
 
22
20
using System;
23
21
using System.IO;
24
22
using System.Collections;
25
23
using System.Collections.Generic;
26
24
 
27
25
using Do.Universe;
 
26
using Do.Platform;
28
27
 
29
28
using Beagle.Util;
30
29
 
33
32
 
34
33
        public class ThunderbirdContactItemSource : ItemSource
35
34
        {
36
 
                
37
 
                const string BeginProfileName = "Path=";
 
35
 
 
36
                class EmailContactDetail: Item, IContactDetailItem
 
37
                {
 
38
                        readonly string          detail, description;
 
39
                        readonly ContactItem owner;
 
40
 
 
41
                        public  EmailContactDetail (ContactItem owner, string detail)
 
42
                        {
 
43
                                this.owner      = owner;
 
44
                                this.detail = detail;
 
45
                                description = string.IsNullOrEmpty (owner["name"]) 
 
46
                                                          ? owner[detail]
 
47
                                                          : owner["name"];
 
48
                        }
 
49
 
 
50
                        public override string Name 
 
51
                        {
 
52
                                get     { return owner[detail]; }
 
53
                        }
 
54
 
 
55
                        public override string Description
 
56
                        {
 
57
                                get { return description; }
 
58
                        }
 
59
 
 
60
                        public override string Icon
 
61
                        {
 
62
                                get { return "thunderbird"; }
 
63
                        }
 
64
 
 
65
                        public string Key 
 
66
                        {
 
67
                                get { return detail; }
 
68
                        }
 
69
 
 
70
                        public string Value
 
71
                        {
 
72
                                get { return owner[detail]; }
 
73
                        }
 
74
                }
 
75
 
 
76
                class EmailList
 
77
                {
 
78
                        private Dictionary<string, uint> set;
 
79
 
 
80
                        public EmailList () { set = new Dictionary<string, uint> (); }
 
81
 
 
82
                        public void Add (string email, uint popularity)
 
83
                        {
 
84
                                if (!set.ContainsKey (email))
 
85
                                {
 
86
                                        set.Add (email, popularity);
 
87
                                }
 
88
                                else
 
89
                                {
 
90
                                        set[email] += popularity;
 
91
                                }
 
92
                        }
 
93
 
 
94
                        public bool Contains (string email)
 
95
                        {
 
96
                                return set.ContainsKey (email);
 
97
                        }
 
98
 
 
99
                        public uint this [string email]
 
100
                        {
 
101
                                get { return set[email]; }
 
102
                        }
 
103
 
 
104
                        public int Count {
 
105
                                get { return set.Count; }
 
106
                        }
 
107
 
 
108
                        public ICollection<string> Keys {
 
109
                                get { return set.Keys; }
 
110
                        }
 
111
                }
 
112
 
 
113
                class ThunderbirdEmail
 
114
                {
 
115
                        public readonly string email;
 
116
                        public readonly uint   popularity;
 
117
 
 
118
                        public ThunderbirdEmail (string email, uint popularity)
 
119
                        {
 
120
                                this.email              = email;
 
121
                                this.popularity = popularity;
 
122
                        }
 
123
                }
 
124
 
 
125
 
 
126
                const string BeginProfileName    = "Path=";
38
127
                const string BeginDefaultProfile = "Name=default";
39
 
                
40
 
                List<Item> contacts;
 
128
                const string THUNDERBIRD_EMAIL   = "email.thunderbird";
 
129
 
 
130
                Dictionary<string, Item> contacts; // name => ContactItem
41
131
                
42
132
                public ThunderbirdContactItemSource ()
43
133
                {
44
 
                        contacts = new List<Item> ();
45
 
                        UpdateItems ();
 
134
                        contacts = new Dictionary<string, Item> ();
46
135
                }
47
136
                
48
137
                public override IEnumerable<Type> SupportedItemTypes {
50
139
                                return new Type[] {
51
140
                                        typeof (ContactItem),
52
141
                                };
53
 
                        }
 
142
            }
54
143
                }
55
144
                
56
145
                public override string Name { get { return "Thunderbird Contacts"; } }
62
151
                        try {
63
152
                                _UpdateItems ();
64
153
                        } catch (Exception e) {
65
 
                                Console.Error.WriteLine ("Cannot index Thunderbird contacts because a {0} was thrown: {1}", e.GetType (), e.Message);
 
154
                                Log<ThunderbirdContactItemSource>.Error ("Cannot index Thunderbird contacts because a {0} was thrown: {1}", e.GetType (), e.Message);
66
155
                                return;
67
156
                        }
68
157
                }
69
158
                
70
159
                public override IEnumerable<Item> Items {
71
 
                        get { return contacts; }
 
160
                        get { return contacts.Values; }
72
161
                }
73
162
                
74
163
                public override IEnumerable<Item> ChildrenOfItem (Item item)
75
164
                {
 
165
                        ContactItem contact = item as ContactItem;
 
166
 
 
167
                        foreach (string detail in contact.Details)
 
168
                        {
 
169
                                if (detail.StartsWith (THUNDERBIRD_EMAIL))
 
170
                                {
 
171
                                        yield return new EmailContactDetail (contact, detail);
 
172
                                }
 
173
                        }
76
174
                        yield break;
77
175
                }
78
176
                
79
177
                void _UpdateItems ()
80
178
                {
81
 
                        MorkDatabase database;
82
 
                
 
179
                        MorkDatabase abook, history;
 
180
                        Dictionary<string, EmailList> emails = new Dictionary<string, EmailList> ();
 
181
 
 
182
                        abook = new MorkDatabase (GetThunderbirdAddressBookFilePath ());
 
183
                        abook.Read ();
 
184
                        abook.EnumNamespace = "ns:addrbk:db:row:scope:card:all";
 
185
 
 
186
                        history = new MorkDatabase (GetThunderbirdHistoryFilePath ());
 
187
                        history.Read ();
 
188
                        history.EnumNamespace = "ns:addrbk:db:row:scope:card:all";
 
189
 
 
190
                        addEmails (emails, history);
 
191
                        addEmails (emails, abook);
 
192
 
83
193
                        contacts.Clear ();
84
 
                        database = new MorkDatabase (GetThunderbirdAddressBookFilePath ());
85
 
                        database.Read ();
86
 
                        database.EnumNamespace = "ns:addrbk:db:row:scope:card:all";
 
194
                        foreach (string name in emails.Keys)
 
195
                        {
 
196
                                CreateThunderbirdContactItem (name, emails[name]);
 
197
                        }
 
198
                }
87
199
 
88
 
                        foreach (string id in database) {
89
 
                                Hashtable contact_row;
90
 
                                ContactItem contact;
91
 
                                
92
 
                                contact_row = database.Compile (id, database.EnumNamespace);
93
 
                                contact = CreateThunderbirdContactItem (contact_row);
94
 
                                if (contact != null)
95
 
                                        contacts.Add (contact);
 
200
                void addEmails (Dictionary<string, EmailList> emails, MorkDatabase database)
 
201
                {
 
202
                        foreach (string id in database)
 
203
                        {
 
204
                                Hashtable contact_row = database.Compile (id, database.EnumNamespace);
 
205
                                AddThunderbirdEmail (emails, contact_row);
96
206
                        }
97
207
                }
98
208
        
99
 
                ContactItem CreateThunderbirdContactItem (Hashtable row) {
100
 
                        ContactItem contact;
 
209
                void AddThunderbirdEmail (Dictionary<string, EmailList> emails, Hashtable row)
 
210
                {
101
211
                        string name, email;
102
 
                        
103
 
//                      foreach (object o in row.Keys)
104
 
//                              Console.WriteLine ("\t{0} --> {1}", o, row[o]);
 
212
                        uint popularity;
105
213
                        
106
214
                        // I think this will detect deleted contacts... Hmm...
107
215
                        if (row["table"] == null || row["table"] as string == "C6")
108
 
                                return null;
 
216
                                return;
109
217
                        
110
218
                        // Name
111
219
                        name = row["DisplayName"] as string;
112
220
                        if (name == null || name == string.Empty)
113
221
                                name = string.Format ("{0} {1}", row["FirstName"], row["LastName"]);
114
 
                        contact = ContactItem.Create (name);
115
222
                        
116
223
                        // Email
117
 
                        email = row["PrimaryEmail"] as string;
118
 
                        if (email != null && email != string.Empty)
119
 
                                contact["email"] = email;
 
224
                        email    = row["PrimaryEmail"] as string;
 
225
                        string p = row["PopularityIndex"] as string;
 
226
                        try {
 
227
                                popularity =  UInt32.Parse (p, System.Globalization.NumberStyles.HexNumber);
 
228
                        }
 
229
                        catch (Exception) {
 
230
                                popularity = 0;
 
231
                        }
120
232
                        
121
 
                        return contact;
122
 
                }
123
 
                
124
 
                string GetThunderbirdAddressBookFilePath ()
 
233
                        if (name == null || name.Trim () == string.Empty)
 
234
                                name = email;
 
235
 
 
236
                        if (string.IsNullOrEmpty (email))
 
237
                                return;
 
238
 
 
239
                        if (!emails.ContainsKey (name))
 
240
                        {
 
241
                                emails[name] = new EmailList ();
 
242
                        }
 
243
                        emails[name].Add (email, popularity);
 
244
                }
 
245
 
 
246
                void CreateThunderbirdContactItem (string name, EmailList emails)
 
247
                {
 
248
                        int emailCount = emails.Count;
 
249
                        ThunderbirdEmail[] sortedEmails = new ThunderbirdEmail[emailCount];
 
250
 
 
251
                        int i = 0;
 
252
                        foreach (string key in emails.Keys)
 
253
                        {
 
254
                                sortedEmails[i] = new ThunderbirdEmail (key, emails[key]);
 
255
                                i++;
 
256
                        }
 
257
                        Array.Sort (sortedEmails, (x, y) => (int) (y.popularity - x.popularity));
 
258
 
 
259
                        ContactItem contact = ContactItem.Create (name);
 
260
                        for (i = 0; i < emailCount; i++)
 
261
                        {
 
262
                                string detail   = THUNDERBIRD_EMAIL + "." + i;
 
263
                                contact[detail] = sortedEmails[i].email;
 
264
                        }
 
265
 
 
266
                        if (!contacts.ContainsKey (name.ToLower ()))
 
267
                        {
 
268
                                contacts.Add (name.ToLower (), contact);
 
269
                        }
 
270
                }
 
271
 
 
272
                string GetThunderbirdDefaultProfilePath ()
125
273
                {
126
274
                        string home, path, profile;
127
275
                        StreamReader reader;
128
276
 
129
277
                        profile = null;
130
278
                        home = System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal);
131
 
                        path = System.IO.Path.Combine (home, ".mozilla-thunderbird/profiles.ini");
 
279
                        path = System.IO.Path.Combine (home, ".thunderbird/profiles.ini");
132
280
                        try {
133
281
                                reader = System.IO.File.OpenText (path);
134
282
                        } catch {
148
296
                                }
149
297
                        }
150
298
                        reader.Close ();
151
 
                        
 
299
                        return profile;
 
300
                }
 
301
 
 
302
                string GetThunderbirdFilePath (string filename)
 
303
                {
 
304
                        string path, home, profile;
 
305
                        home = System.Environment.GetFolderPath (System.Environment.SpecialFolder.Personal);
 
306
                        profile = GetThunderbirdDefaultProfilePath ();
152
307
                        if (profile == null) {
153
308
                                return null;
154
309
                        }
155
 
                        path = System.IO.Path.Combine (home, ".mozilla-thunderbird");
 
310
                        path = System.IO.Path.Combine (home, ".thunderbird");
156
311
                        path = System.IO.Path.Combine (path, profile);
157
 
                        path = System.IO.Path.Combine (path, "abook.mab");
 
312
                        path = System.IO.Path.Combine (path, filename);
158
313
                        return path;
159
 
                        
160
314
                }
161
315
                
 
316
                string GetThunderbirdHistoryFilePath ()
 
317
                {
 
318
                        return GetThunderbirdFilePath ("history.mab");
 
319
                }
 
320
 
 
321
                string GetThunderbirdAddressBookFilePath ()
 
322
                {
 
323
                        return GetThunderbirdFilePath ("abook.mab");
 
324
                }
162
325
        }
163
326
}