~do-plugins/do-plugins/trunk

« back to all changes in this revision

Viewing changes to Thunderbird/src/ThunderbirdContactItemSource.cs

  • Committer: Christopher James Halse Rogers
  • Date: 2013-05-04 18:44:31 UTC
  • mfrom: (674.3.13 do-plugins)
  • Revision ID: raof@ubuntu.com-20130504184431-16ns8sf2eurckunw
Merge Thunderbird fixes

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