Skip to content

Instantly share code, notes, and snippets.

@maximilian-krauss
Created November 13, 2012 20:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximilian-krauss/4068111 to your computer and use it in GitHub Desktop.
Save maximilian-krauss/4068111 to your computer and use it in GitHub Desktop.
WeightbotClient
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