Created
November 13, 2012 20:15
-
-
Save maximilian-krauss/4068111 to your computer and use it in GitHub Desktop.
WeightbotClient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Globalization; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Net; | |
using System.Web; | |
namespace coffeeInjection { | |
public class WeightbotDataEntry { | |
public DateTime DateTime { get; set; } | |
public double WeightInKg { get; set; } | |
public double WeightInLbs { get; set; } | |
} | |
public sealed class WeightbotClient { | |
private CookieContainer _cookieJar; | |
private bool _dataLoaded; | |
private readonly List<WeightbotDataEntry> _dataEntries; | |
private const string BaseUrl = "https://www.weightbot.com"; | |
private const string LoginIndexUrl = "https://www.weightbot.com/account/login"; | |
private const string LoginUrl = "https://www.weightbot.com/account/login"; | |
private const string ExportUrl = "https://www.weightbot.com/export"; | |
private const string LogoutUrl = "https://www.weightbot.com/account/logout"; | |
private const string ExceptionNoData = "No data available. Call DownloadWeightbotData first!"; | |
public WeightbotClient() { | |
_cookieJar = new CookieContainer(); | |
_dataEntries = new List<WeightbotDataEntry>(); | |
_dataLoaded = false; | |
} | |
public bool DownloadWeightbotData(string email, string password) { | |
_dataLoaded = false; | |
var loginIndexData = PerformRequest(CreateRequest(LoginIndexUrl, WebRequestMethods.Http.Get)); | |
var authenticityToken = FindAuthenticityToken(loginIndexData).Trim(); | |
var loginResponseData = PerformRequest(CreatePostRequest(LoginUrl, LoginIndexUrl, | |
Encoding.Default.GetBytes(string.Format("authenticity_token={0}&email={1}&password={2}", | |
HttpUtility.UrlEncode(authenticityToken), | |
HttpUtility.UrlEncode(email), | |
HttpUtility.UrlEncode(password))))); | |
if (loginResponseData.IndexOf("logout", StringComparison.Ordinal) == -1) | |
return false; | |
var exportResponse = PerformRequest(CreatePostRequest(ExportUrl, BaseUrl, Encoding.Default.GetBytes(string.Format("authenticity_token={0}",HttpUtility.UrlEncode(authenticityToken))))); | |
ProcessExportData(exportResponse); | |
PerformRequest(CreateRequest(LogoutUrl, WebRequestMethods.Http.Get)); | |
_dataLoaded = true; | |
return _dataLoaded; | |
} | |
public double AvgWeightKg { | |
get { | |
if(!_dataLoaded) | |
throw new Exception(ExceptionNoData); | |
return Math.Round(_dataEntries.Sum(e => e.WeightInKg)/_dataEntries.Count, 2); | |
} | |
} | |
public double MaxWeightKg { | |
get { | |
if (!_dataLoaded) | |
throw new Exception(ExceptionNoData); | |
return _dataEntries.Max(e => e.WeightInKg); | |
} | |
} | |
public double MinWeightKg { | |
get { | |
if (!_dataLoaded) | |
throw new Exception(ExceptionNoData); | |
return _dataEntries.Min(e => e.WeightInKg); | |
} | |
} | |
private HttpWebRequest CreateRequest(string url, string method) { | |
var request = (HttpWebRequest) WebRequest.Create(url); | |
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11"; | |
request.CookieContainer = _cookieJar; | |
request.Method = method; | |
return request; | |
} | |
private HttpWebRequest CreatePostRequest(string url, string referer, byte[] data) { | |
var request = CreateRequest(url, WebRequestMethods.Http.Post); | |
request.ContentType = "application/x-www-form-urlencoded"; | |
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; | |
request.ContentLength = data.Length; | |
request.Referer = referer; | |
using(var requestStream = request.GetRequestStream()) | |
requestStream.Write(data, 0, data.Length); | |
return request; | |
} | |
private string PerformRequest(HttpWebRequest request) { | |
var response = (HttpWebResponse)request.GetResponse(); | |
string responseData; | |
using (var reader = new StreamReader(response.GetResponseStream())) | |
responseData = reader.ReadToEnd(); | |
response.Close(); | |
_cookieJar = new CookieContainer(); | |
foreach(Cookie cookie in response.Cookies) | |
_cookieJar.Add(cookie); | |
return responseData; | |
} | |
private string FindAuthenticityToken(string body) { | |
var fieldIndex = body.IndexOf("authenticity_token", StringComparison.Ordinal); | |
var valueBegin = body.IndexOf("value=", fieldIndex, StringComparison.Ordinal) + 7; | |
var valueEnd = body.IndexOf("/>", valueBegin, StringComparison.Ordinal); | |
return body.Substring(valueBegin, (valueEnd - valueBegin)-2); | |
} | |
private void ProcessExportData(string data) { | |
_dataEntries.Clear(); | |
//We skip the first entry because it contains the column descriptions | |
foreach (var entryParts in data.Split(new[] {"\r","\n","\r\n"}, StringSplitOptions.RemoveEmptyEntries) | |
.Skip(1) | |
.Select(entry => entry.Split(new[] {","}, StringSplitOptions.RemoveEmptyEntries))) { | |
_dataEntries.Add(new WeightbotDataEntry { | |
DateTime = DateTime.Parse(entryParts[0], new CultureInfo("en-US")), | |
WeightInKg = double.Parse(entryParts[1], new CultureInfo("en-US")), | |
WeightInLbs = double.Parse(entryParts[2], new CultureInfo("en-US")) | |
}); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment