/GoogleReaderNotifier/GoogleReaderNotifier.ReaderAPI/GoogleReader.cs
http://reader-notifier-mod.googlecode.com/ · C# · 417 lines · 330 code · 72 blank · 15 comment · 49 complexity · 0efb98a3ff37e0a52a9a915ffa91b78e MD5 · raw file
- using System;
- using System.Net;
- using System.Text;
- using System.IO;
- using System.Xml;
- using System.Collections.Generic;
- using GoogleReaderNotifier.ReaderAPI.Data;
- using System.Reflection;
- using System.Windows.Forms;
- using System.Drawing;
-
- namespace GoogleReaderNotifier.ReaderAPI
- {
- /// <summary>
- /// Summary description for GoogleReader.
- /// </summary>
- public class GoogleReader
- {
- #region Private variables
-
- private CookieCollection _Cookies = new CookieCollection();
- private CookieContainer _cookiesContainer = new CookieContainer();
- private bool _loggedIn = false;
- private string[] _loginAuth;
- private XmlDocument xdocAll;
-
- #endregion
-
- #region Public variables
-
- public string LoginError = "";
- public string[] ProxyUser = new string[3];
-
- #endregion
-
- public bool LoggedIn
- {
- get { return _loggedIn; }
- }
-
- #region Application Code
-
- // https://www.google.com/reader/atom/user/-/state/com.google/reading-list // get full feed of items
-
- public string Login(string username, string password)
- {
- _loggedIn = false;
- LoginError = "";
-
- HttpWebRequest req = CreateRequest("https://www.google.com/accounts/ClientLogin?service=reader");
-
- string exc = PostLoginForm(req, String.Format("accountType=GOOGLE&Email={0}&Passwd={1}&service=reader&source=GRaiN-Notifier-" + Assembly.GetExecutingAssembly().GetName().Version, Uri.EscapeDataString(username), Uri.EscapeDataString(password)));
-
- if (exc.IndexOf("System.Net.WebException") != -1)
- {
- LoginError += exc + "\r\n";
- if (ProxyUser[0] == "request")
- return "ProxyAuthRequired";
- return "CONNECT_ERROR";
- }
-
- try
- {
- string _helper = GetResponseString(req);
- _loggedIn = (_helper.IndexOf("error", StringComparison.OrdinalIgnoreCase) == -1) && (_helper.IndexOf("auth", StringComparison.OrdinalIgnoreCase) != -1);
- if (_loggedIn == true)
- {
- _loginAuth = _helper.Split('\n');
- foreach (string st in _loginAuth)
- {
- if (st != string.Empty)
- {
- string[] coo = st.Split('=');
- if (coo[0] == "SID")
- _cookiesContainer.Add(new Cookie(coo[0], coo[1], "/", ".google.com"));
- }
- }
-
- }
- else
- {
- LoginError += _helper + "\r\n";
- }
- }
- catch (Exception ex)
- {
- _loggedIn = false;
- string _exc = ex.ToString();
- LoginError += "Exception in GetResponseString. \r\n" + _exc + "\r\n";
- }
-
- if (!_loggedIn)
- return "AUTH_ERROR";
- else
- LoginError = string.Empty;
- return string.Empty;
- }
-
- private delegate string LocateUnreadItemIdentifierDelegate(string identifierSource);
-
- private string LocateFeedIdentifier(string identifierSource)
- {
- return identifierSource.Substring(identifierSource.LastIndexOf("/http") + 1);
- }
-
- private string LocateTagIdentifier(string identifierSource)
- {
- return identifierSource.Substring(identifierSource.LastIndexOf("/label/") + "/label/".Length);
- }
-
- public bool CollectUnreadFeeds(UnreadItemCollection unreadFeeds)
- {
- System.Diagnostics.Debug.Assert(unreadFeeds != null, "unreadFeeds must be assigned.");
-
- return CollectUnreadItems(unreadFeeds, null, null);
- }
-
- public bool CollectUnreadTags(UnreadItemCollection unreadTags, List<string> tagFilterList)
- {
- System.Diagnostics.Debug.Assert(unreadTags != null, "unreadTags must be assigned.");
-
- return CollectUnreadItems(null, unreadTags, tagFilterList);
- }
-
- public void CollectTags(List<String> tags)
- {
- System.Diagnostics.Debug.Assert(tags != null, "tags must be assigned.");
-
- if (!LoggedIn)
- {
- throw new Exception("Must be logged in to collect tags");
- }
-
- XmlDocument xdoc;
- string identifier;
-
- xdoc = this.GetTagListXMLDocument();
-
- tags.Clear();
-
- foreach (XmlNode node in xdoc.SelectNodes("//object/string[contains(.,'/label/') and contains(.,'user/')]"))
- {
- identifier = LocateTagIdentifier(node.InnerText);
-
- tags.Add(identifier);
- }
- }
-
- public bool CollectUnreadItems(UnreadItemCollection unreadFeeds, UnreadItemCollection unreadTags, List<string> identifierFilterList)
- {
- bool result = true;
- //int unreadCount;
- XmlDocument xdoc;
-
- result = LoggedIn;
-
- if (result)
- {
- xdoc = this.GetAllUnreadCountsXMLDocument();
- xdocAll = this.GetSubscriptionListXMLDocument();
-
- // Collect feed information
- if (unreadFeeds != null)
- {
- unreadFeeds.Clear();
-
- CollectUnreadItemsBySelectedNodes(xdoc, "//object/string[contains(.,'user/') and contains(.,'/state/com.google/reading-list')]", unreadFeeds, LocateFeedIdentifier, null);
- }
-
-
- // Collect tag information
- if (unreadTags != null)
- {
- unreadTags.Clear();
-
- CollectUnreadItemsBySelectedNodes(xdoc, "//object/string[contains(.,'/label/') and contains(.,'user/')]", unreadTags, LocateTagIdentifier, identifierFilterList);
- }
- }
-
- return result;
- }
-
- private void CollectUnreadItemsBySelectedNodes(XmlDocument xdoc, string nodeSelection, UnreadItemCollection unreadItems, LocateUnreadItemIdentifierDelegate locateIdentifierDelegate, List<string> identifierFilterList)
- {
- int unreadCount;
- UnreadItem unreadItem;
- string identifier;
- string feedName;
- bool addToList;
-
- foreach (XmlNode node in xdoc.SelectNodes(nodeSelection))
- {
- unreadCount = Convert.ToInt32(node.ParentNode.SelectSingleNode("number").InnerText);
- identifier = locateIdentifierDelegate(node.InnerText);
- feedName = GetFeedNameById(identifier);
- addToList = (unreadCount > 0) && ((identifierFilterList == null) || identifierFilterList.Contains(identifier));
-
- if (addToList)
- {
- unreadItem = new UnreadItem();
-
- unreadItem.Identifier = identifier;
- unreadItem.FeedName = feedName;
- unreadItem.ArticleCount = unreadCount;
-
-
- unreadItems.Add(unreadItem);
- }
- }
- }
-
- private XmlDocument GetAllUnreadCountsXMLDocument()
- {
- string url = "https://www.google.com/reader/api/0/unread-count?all=true";
- string theXml = GetResponseString(CreateRequest(url));
-
- XmlDocument xdoc = new XmlDocument();
- xdoc.LoadXml(theXml);
-
- return xdoc;
- }
-
- private XmlDocument GetTagListXMLDocument()
- {
- string url = "https://www.google.com/reader/api/0/tag/list";
- string theXml = GetResponseString(CreateRequest(url));
-
- XmlDocument xdoc = new XmlDocument();
- xdoc.LoadXml(theXml);
-
- return xdoc;
- }
-
- private XmlDocument GetSubscriptionListXMLDocument()
- {
- string url = "https://www.google.com/reader/api/0/subscription/list";
- string theXml = GetResponseString(CreateRequest(url));
-
- XmlDocument xdoc = new XmlDocument();
- xdoc.LoadXml(theXml);
-
- return xdoc;
- }
-
- private string GetFeedNameById(string feedId)
- {
- try
- {
- XmlNode node = xdocAll.SelectSingleNode("//string[@name='id' and .='feed/" + feedId + "']/../string[@name='title']");
- if (node != null)
- return node.InnerText;
- else
- return " - ";
- }
- catch{
- return " - ";
- }
- }
-
- #endregion
-
- #region HTTP Functions
-
- public string GetResponseStrEx(String url)
- {
- string xstr = GetResponseString(CreateRequest(url));
-
- return xstr;
- }
-
- private string GetResponseString(HttpWebRequest req)
- {
- string responseString = null;
- try
- {
- HttpWebResponse res = (HttpWebResponse)req.GetResponse();
- res.Cookies = req.CookieContainer.GetCookies(req.RequestUri);
- _Cookies.Add(res.Cookies);
-
- using (StreamReader read = new StreamReader(res.GetResponseStream()))
- {
- responseString = read.ReadToEnd();
- }
- res.Close();
- //_currentHTML = responseString;
-
- }
- catch (WebException ex)
- {
- using (StreamReader read = new StreamReader(ex.Response.GetResponseStream()))
- {
- responseString = read.ReadToEnd();
- }
- //res.Close();
- string exc = ex.ToString();
- LoginError += responseString+"\r\n" +exc + "\r\n";
- }
- catch (Exception ex)
- {
- string exc = ex.ToString();
- LoginError += exc + "\r\n";
- }
- return responseString;
- }
-
- private string PostLoginForm(HttpWebRequest req, string p)
- {
- string exc = string.Empty;
- req.ContentType = "application/x-www-form-urlencoded";
- req.Method = "POST";
- //req.Referer = _currentURL;
- byte[] b = Encoding.UTF8.GetBytes(p);
- req.ContentLength = b.Length;
- try
- {
- using (Stream s = req.GetRequestStream())
- {
- s.Write(b, 0, b.Length);
- s.Close();
- }
- }
- catch (Exception ex)
- {
- exc = ex.ToString();
- if (ex.GetType().Name == "WebException" && exc.IndexOf("(407)") != -1 && ProxyUser[0] !="missing")
- {
- ProxyUser[0] = "request";
- }
- }
- return exc;
- }
-
- private HttpWebRequest CreateRequest(string url)
- {
- HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
- //WebProxy defaultProxy = WebProxy.GetDefaultProxy();
- IWebProxy defaultProxy = HttpWebRequest.GetSystemWebProxy();
- req.Proxy = defaultProxy; // if we wanted to disable proxying, can be done by setting to null I think
- if (ProxyUser[0] == "request")
- {
- DialogResult result = GetProxyUser(ref ProxyUser[1], ref ProxyUser[2]);
- if (result == DialogResult.OK && ProxyUser[1] != "" && ProxyUser[2] != "")
- {
- ProxyUser[0] = "exist";
- }
- else
- {
- ProxyUser[0] = "missing";
- }
- }
- if (ProxyUser[0] == "exist" && ProxyUser[1] != "" && ProxyUser[2] != "")
- {
- req.Proxy.Credentials = new NetworkCredential(ProxyUser[1], ProxyUser[2]);
- }
- //req.Proxy = null;
- //req.UserAgent = _user.UserAgent;
- req.UserAgent = "GRaiN/" + Assembly.GetExecutingAssembly().GetName().Version + "(Google Reader Notifier for Windows)";
- req.Referer = "http://yoni-zaf.appspot.com/notifier?version=" + Assembly.GetExecutingAssembly().GetName().Version;
- req.CookieContainer = _cookiesContainer;
- if (_loggedIn)
- req.Headers.Add("Authorization", "GoogleLogin auth=" + _loginAuth[2].Split('=')[1]);
- //req.Referer = _currentURL; // set the referring url properly to appear as a regular browser
- //_currentURL = url; // set the current url so the next request will have the right referring url ( might not work for sub pages )
- return req;
- }
-
- #endregion
-
- public static DialogResult GetProxyUser(ref string userName, ref string passWord)
- {
- Form form = new Form();
- Label label = new Label();
- TextBox textBoxUser = new TextBox();
- TextBox textBoxPass = new TextBox();
- Button buttonOk = new Button();
- Button buttonCancel = new Button();
-
- form.Text = "GRaiN";
- label.Text = "Proxy require username and password:";
- textBoxUser.Text = userName;
- textBoxPass.Text = passWord;
- textBoxPass.UseSystemPasswordChar = true;
-
- buttonOk.Text = "OK";
- buttonCancel.Text = "Cancel";
- buttonOk.DialogResult = DialogResult.OK;
- buttonCancel.DialogResult = DialogResult.Cancel;
-
- label.SetBounds(9, 20, 372, 13);
- textBoxUser.SetBounds(12, 40, 372, 20);
- textBoxPass.SetBounds(12, 65, 372, 20);
- buttonOk.SetBounds(228, 92, 75, 23);
- buttonCancel.SetBounds(309, 92, 75, 23);
-
- label.AutoSize = true;
- textBoxUser.Anchor = textBoxUser.Anchor | AnchorStyles.Right;
- textBoxPass.Anchor = textBoxPass.Anchor | AnchorStyles.Right;
- buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
- buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
-
- form.ClientSize = new Size(396, 125);
- form.Controls.AddRange(new Control[] { label, textBoxUser, textBoxPass, buttonOk, buttonCancel });
- form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
- form.FormBorderStyle = FormBorderStyle.FixedDialog;
- form.StartPosition = FormStartPosition.CenterScreen;
- form.MinimizeBox = false;
- form.MaximizeBox = false;
- form.AcceptButton = buttonOk;
- form.CancelButton = buttonCancel;
-
- DialogResult dialogResult = form.ShowDialog();
- userName = textBoxUser.Text;
- passWord = textBoxPass.Text;
- return dialogResult;
- }
- }
- }