~taktaktaktaktaktaktaktaktaktak/do-plugins/docklets

« back to all changes in this revision

Viewing changes to GMailDocklet/src/GMailAtom.cs

  • Committer: Levi Bard
  • Date: 2010-03-16 14:36:05 UTC
  • Revision ID: taktaktaktaktaktaktaktaktaktak@gmail.com-20100316143605-iamsxlz9iizymss6
Check for mail in all configured labels.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
using System.Net;
21
21
using System.Web;
22
22
using System.Xml;
 
23
using System.Linq;
23
24
 
24
25
using Gdk;
25
26
using Gtk;
63
64
                public string FromEmail;
64
65
                public DateTime SendDate;
65
66
                public string Link;
 
67
                public string Label;
66
68
        }
67
69
        
68
70
        /// <summary>
90
92
                        // this is not implemented in mono yet
91
93
//                      ServicePointManager.ServerCertificateValidationCallback +=
92
94
//                              (sender, cert, chain, errors) => { return true; };
 
95
                         messages = new List<UnreadMessage> ();
93
96
                }
94
97
                
95
98
                static void HandleStateChanged (object o, NetworkStateChangedEventArgs state)
97
100
                        ResetTimer ();
98
101
                }
99
102
                
100
 
                static List<UnreadMessage> messages = new List<UnreadMessage> ();
 
103
                static List<UnreadMessage> messages;
101
104
                
102
105
                public static IEnumerable<UnreadMessage> Messages {
103
106
                        get {
135
138
                
136
139
                public static string CurrentLabel {
137
140
                        get {
138
 
                                if (Preferences.CurrentLabel >= 0 && Preferences.CurrentLabel < Preferences.Labels.Length)
139
 
                                        return Preferences.Labels [Preferences.CurrentLabel];
140
 
                                else
141
 
                                        return "Inbox";
 
141
                                return Preferences.User;
142
142
                        }
143
143
                }
144
144
                
145
145
                public static bool ValidateCredentials (string username, string password)
146
146
                {
147
147
                        try {
148
 
                                String[] login = username.Split (new char[] {'@'});
149
 
                                string domain = login.Length > 1 ? login [1] : "gmail.com";
150
 
                                string url = "https://mail.google.com/a/" + domain;
151
 
                                if (domain.Equals ("gmail.com") || domain.Equals ("googlemail.com"))
152
 
                                        url = "https://mail.google.com/mail";
153
 
                                url += "/feed/atom/";
154
 
                                
155
 
                                Log<GMailAtom>.Info ("Fetching Atom feed: " + url);
156
 
                                HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
157
 
                                request.UserAgent = @"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10";
158
 
                                request.Credentials = new NetworkCredential (username, password);
159
 
                                // remove when ServicePointManager.ServerCertificateValidationCallback implemented in mono
160
 
                                System.Net.ServicePointManager.CertificatePolicy = new CertHandler ();
161
 
                                
162
 
                                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse ())
163
 
                                        try { } finally {
164
 
                                                response.Close ();
165
 
                                        }
 
148
                                string url = GetBaseUrl (username);
 
149
                                PerformRequest (url, null);
166
150
                        } catch (WebException e) {
167
151
                                if (e.Message.IndexOf ("401") != -1) return false;
168
152
                        } catch (Exception) { }
170
154
                        return true;
171
155
                }
172
156
                
 
157
                /// <summary>
 
158
                /// Given an email address, get the base feed url
 
159
                /// </summary>
 
160
                static string GetBaseUrl (string username)
 
161
                {
 
162
                        String[] login = username.Split (new char[] {'@'});
 
163
                        string domain = login.Length > 1 ? login [1] : "gmail.com";
 
164
                        string url = "https://mail.google.com/a/" + domain;
 
165
                        if (domain.Equals ("gmail.com") || domain.Equals ("googlemail.com"))
 
166
                                url = "https://mail.google.com/mail";
 
167
                        return url + "/feed/atom/";
 
168
                }
 
169
                
 
170
                /// <summary>
 
171
                /// Perform an HTTP request
 
172
                /// </summary>
 
173
                /// <param name="url">
 
174
                /// A <see cref="System.String"/>: The request url
 
175
                /// </param>
 
176
                /// <param name="xml">
 
177
                /// A <see cref="XmlDocument"/>: An xml document to be filled, if non-null
 
178
                /// </param>
 
179
                static void PerformRequest (string url, XmlDocument xml)
 
180
                {
 
181
                        Log<GMailAtom>.Info ("Fetching Atom feed: " + url);
 
182
                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
 
183
                        request.UserAgent = @"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10";
 
184
                        request.Credentials = new NetworkCredential (Preferences.User, Preferences.Password);
 
185
                        // remove when ServicePointManager.ServerCertificateValidationCallback implemented in mono
 
186
                        System.Net.ServicePointManager.CertificatePolicy = new CertHandler ();
 
187
                        
 
188
                        HttpWebResponse response = (HttpWebResponse)request.GetResponse ();
 
189
                        try {
 
190
                                if (null != xml)
 
191
                                        xml.Load (response.GetResponseStream ());
 
192
                        } finally {
 
193
                                response.Close ();
 
194
                        }
 
195
                        
 
196
                }
 
197
                
173
198
                static void CheckGMail ()
174
199
                {
 
200
                        OnGMailChecking ();
175
201
                        Services.Application.RunOnThread (() => {
 
202
                                CheckGMailWorker ();
 
203
                        });
 
204
                }
 
205
                
 
206
                /// <summary>
 
207
                /// Async worker method - checks gmail, notifies when complete
 
208
                /// </summary>
 
209
                static void CheckGMailWorker ()
 
210
                {
 
211
                        try {
 
212
                                string url = GetBaseUrl (Preferences.User);
 
213
                                Dictionary<string,List<UnreadMessage>> unread = new Dictionary<string,List<UnreadMessage>> ();
 
214
                                List<UnreadMessage> unreadForLabel = null;
 
215
                                List<UnreadMessage> allUnread = new List<UnreadMessage> ();
 
216
                                UnreadMessage tmpMessage;
 
217
                                DateTime lastChecked = DateTime.Now;
 
218
                                
 
219
                                
 
220
                                UnreadCount = NewCount = 0;
 
221
                                
 
222
                                foreach (string label in Preferences.Labels) {
 
223
                                        unreadForLabel = new List<UnreadMessage> ();
 
224
                                        lastChecked = CheckGMailLabel (string.Format ("{0}{1}", url, HttpUtility.UrlEncode (label)), unreadForLabel);
 
225
                        
 
226
                                        if (0 < unreadForLabel.Count) {
 
227
                                                unread[label] = unreadForLabel;
 
228
                                                for (int i=0; i<unreadForLabel.Count; ++i) {
 
229
                                                        tmpMessage = unreadForLabel[i];
 
230
                                                        UnreadCount++;
 
231
                                                        tmpMessage.Label = label;
 
232
                                                        allUnread.Add (tmpMessage);
 
233
                                                        
 
234
                                                        if (tmpMessage.SendDate > Preferences.LastChecked) {
 
235
                                                                NewCount++;
 
236
                                                        }
 
237
                                                }
 
238
                                        }
 
239
                                }
 
240
                                
 
241
                                messages = allUnread;
 
242
                                
 
243
                                if (Preferences.Notify) {
 
244
                                        if (NewCount > 5)
 
245
                                                Services.Notifications.Notify (CurrentLabel, String.Format ("You have {0} new, unread messages", NewCount), "gmail-logo.png@" + State.GetType ().Assembly.FullName);
 
246
                                        else {
 
247
                                                foreach (UnreadMessage message in from message in messages
 
248
                                                                  where Preferences.LastChecked < message.SendDate
 
249
                                                                  select message)
 
250
                                                        Services.Notifications.Notify (message.Topic, string.Format ("{0}{1}({2})", AddinManager.CurrentLocalizer.GetString ("From: "), message.From, message.Label), "gmail-logo.png@" + State.GetType ().Assembly.FullName);
 
251
                                        }
 
252
                                }
 
253
                                
 
254
                                Preferences.LastChecked = lastChecked;
 
255
                                
 
256
                                Services.Application.RunOnMainThread (OnGMailChecked);
 
257
                        } catch (NullReferenceException) {
 
258
                                Services.Application.RunOnMainThread (() =>
 
259
                                        OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Feed Error")));
 
260
                        } catch (XmlException) {
 
261
                                Services.Application.RunOnMainThread (() =>
 
262
                                        OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Feed Error")));
 
263
                        } catch (WebException e) {
 
264
                                if (e.Message.IndexOf ("401") != -1)
 
265
                                        Services.Application.RunOnMainThread (() =>
 
266
                                                OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Invalid Username")));
 
267
                                else
 
268
                                        Services.Application.RunOnMainThread (() =>
 
269
                                                OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Network Error")));
 
270
                        } catch (Exception e) {
 
271
                                Log<GMailAtom>.Error (e.ToString ());
 
272
                                Services.Application.RunOnMainThread (() =>
 
273
                                        OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("General Error")));
 
274
                        }
 
275
                }
 
276
                
 
277
                /// <summary>
 
278
                /// Checks a single gmail label for new mail
 
279
                /// </summary>
 
280
                /// <param name="url">
 
281
                /// A <see cref="System.String"/>: The label's url
 
282
                /// </param>
 
283
                /// <param name="unreadMessages">
 
284
                /// A <see cref="ICollection<UnreadMessage>"/>: A collection of UnreadMessages to be filled
 
285
                /// </param>
 
286
                /// <returns>
 
287
                /// A <see cref="DateTime"/>: The last modified time
 
288
                /// </returns>
 
289
                static DateTime CheckGMailLabel (string url, ICollection<UnreadMessage> unreadMessages)
 
290
                {
 
291
                        XmlDocument xml = new XmlDocument ();
 
292
                        XmlNamespaceManager nsmgr = new XmlNamespaceManager (xml.NameTable);
 
293
                        nsmgr.AddNamespace ("atom", "http://purl.org/atom/ns#");
 
294
                        DateTime lastChecked = DateTime.Now;
 
295
                        
 
296
                        PerformRequest (url, xml);
 
297
                        
 
298
                        XmlNodeList nodelist = xml.SelectNodes ("//atom:entry", nsmgr);
 
299
                        
 
300
                        for (int i = 0; i < nodelist.Count; i++)
 
301
                        {
 
302
                                XmlNode item = nodelist.Item (i);
 
303
                                
 
304
                                UnreadMessage message = new UnreadMessage ();
 
305
                                message.Topic = HttpUtility.HtmlDecode (item.SelectSingleNode ("atom:title", nsmgr).InnerText);
 
306
                                message.FromName = HttpUtility.HtmlDecode (item.SelectSingleNode ("atom:author/atom:name", nsmgr).InnerText);
 
307
                                message.FromEmail = item.SelectSingleNode ("atom:author/atom:email", nsmgr).InnerText;
 
308
                                message.From = message.FromName + " <" + message.FromEmail + ">";
176
309
                                try {
177
 
                                        Services.Application.RunOnMainThread (OnGMailChecking);
178
 
 
179
 
                                        String[] login = Preferences.User.Split (new char[] {'@'});
180
 
                                        string domain = login.Length > 1 ? login [1] : "gmail.com";
181
 
                                        string url = "https://mail.google.com/a/" + domain;
182
 
                                        if (domain.Equals ("gmail.com") || domain.Equals ("googlemail.com"))
183
 
                                                url = "https://mail.google.com/mail";
184
 
                                        url += "/feed/atom/" + HttpUtility.UrlEncode (CurrentLabel);
185
 
                                        
186
 
                                        Log<GMailAtom>.Info ("Fetching Atom feed: " + url);
187
 
                                        HttpWebRequest request = (HttpWebRequest)WebRequest.Create (url);
188
 
                                        request.UserAgent = @"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.10) Gecko/2009042523 Ubuntu/9.04 (jaunty) Firefox/3.0.10";
189
 
                                        request.Credentials = new NetworkCredential (Preferences.User, Preferences.Password);
190
 
                                        // remove when ServicePointManager.ServerCertificateValidationCallback implemented in mono
191
 
                                        System.Net.ServicePointManager.CertificatePolicy = new CertHandler ();
192
 
                                        
193
 
                                        XmlDocument xml = new XmlDocument ();
194
 
                                        XmlNamespaceManager nsmgr = new XmlNamespaceManager (xml.NameTable);
195
 
                                        nsmgr.AddNamespace ("atom", "http://purl.org/atom/ns#");
196
 
                                        
197
 
                                        using (HttpWebResponse response = (HttpWebResponse)request.GetResponse ())
198
 
                                                try {
199
 
                                                        xml.Load (response.GetResponseStream ());
200
 
                                                } finally {
201
 
                                                        response.Close ();
202
 
                                                }
203
 
                                        
204
 
                                        List<UnreadMessage> tmp = new List<UnreadMessage> ();
205
 
                                        XmlNodeList nodelist = xml.SelectNodes ("//atom:entry", nsmgr);
206
 
                                        
207
 
                                        for (int i = 0; i < nodelist.Count; i++)
208
 
                                        {
209
 
                                                XmlNode item = nodelist.Item (i);
210
 
                                                
211
 
                                                UnreadMessage message = new UnreadMessage ();
212
 
                                                message.Topic = HttpUtility.HtmlDecode (item.SelectSingleNode ("atom:title", nsmgr).InnerText);
213
 
                                                message.FromName = HttpUtility.HtmlDecode (item.SelectSingleNode ("atom:author/atom:name", nsmgr).InnerText);
214
 
                                                message.FromEmail = item.SelectSingleNode ("atom:author/atom:email", nsmgr).InnerText;
215
 
                                                message.From = message.FromName + " <" + message.FromEmail + ">";
216
 
                                                try {
217
 
                                                        message.SendDate = DateTime.Parse (item.SelectSingleNode ("atom:modified", nsmgr).InnerText);
218
 
                                                } catch (Exception) {}
219
 
                                                message.Link = item.SelectSingleNode ("atom:link", nsmgr).Attributes ["href"].InnerText;
220
 
                                                
221
 
                                                tmp.Add (message);
222
 
                                        }
223
 
                                        
224
 
                                        UnreadCount = Convert.ToInt32 (xml.SelectSingleNode ("//atom:fullcount", nsmgr).InnerText);
225
 
                                        
226
 
                                        NewCount = 0;
227
 
                                        foreach (UnreadMessage message in tmp)
228
 
                                                if (message.SendDate > Preferences.LastChecked)
229
 
                                                        NewCount++;
230
 
                                        
231
 
                                        if (Preferences.Notify) {
232
 
                                                if (NewCount > 5)
233
 
                                                        Services.Notifications.Notify (CurrentLabel, String.Format ("You have {0} new, unread messages", NewCount), "gmail-logo.png@" + State.GetType ().Assembly.FullName);
234
 
                                                else
235
 
                                                        foreach (UnreadMessage message in tmp)
236
 
                                                                if (message.SendDate > Preferences.LastChecked)
237
 
                                                                        Services.Notifications.Notify (message.Topic, AddinManager.CurrentLocalizer.GetString ("From: ") + message.From, "gmail-logo.png@" + State.GetType ().Assembly.FullName);
238
 
                                        }
239
 
                                        
240
 
                                        try {
241
 
                                                Preferences.LastChecked = DateTime.Parse (xml.SelectSingleNode ("/atom:feed/atom:modified", nsmgr).InnerText);
242
 
                                        } catch (Exception) { Preferences.LastChecked = DateTime.Now; }
243
 
                                        
244
 
                                        messages = tmp;
245
 
                                        Services.Application.RunOnMainThread (OnGMailChecked);
246
 
                                } catch (NullReferenceException) {
247
 
                                        Services.Application.RunOnMainThread (() =>
248
 
                                                OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Feed Error")));
249
 
                                } catch (XmlException) {
250
 
                                        Services.Application.RunOnMainThread (() =>
251
 
                                                OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Feed Error")));
252
 
                                } catch (WebException e) {
253
 
                                        if (e.Message.IndexOf ("401") != -1)
254
 
                                                Services.Application.RunOnMainThread (() =>
255
 
                                                        OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Invalid Username")));
256
 
                                        else
257
 
                                                Services.Application.RunOnMainThread (() =>
258
 
                                                        OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("Network Error")));
259
 
                                } catch (Exception e) {
260
 
                                        Log<GMailAtom>.Error (e.ToString ());
261
 
                                        Services.Application.RunOnMainThread (() =>
262
 
                                                OnGMailFailed (AddinManager.CurrentLocalizer.GetString ("General Error")));
263
 
                                }
264
 
                        });
 
310
                                        message.SendDate = DateTime.Parse (item.SelectSingleNode ("atom:modified", nsmgr).InnerText);
 
311
                                } catch (Exception) {}
 
312
                                message.Link = item.SelectSingleNode ("atom:link", nsmgr).Attributes ["href"].InnerText;
 
313
                                
 
314
                                unreadMessages.Add (message);
 
315
                        }
 
316
                        
 
317
                        try {
 
318
                                lastChecked = DateTime.Parse (xml.SelectSingleNode ("/atom:feed/atom:modified", nsmgr).InnerText);
 
319
                        } catch (Exception) { }
 
320
                        
 
321
                        return lastChecked;
265
322
                }
266
323
                
267
324
                public static void OnGMailChecked ()