Permalink
Browse files

Fully implemented totals on result,

added more type checks and conversions
  • Loading branch information...
1 parent afd09b3 commit 2b45f5331751cbade7279131ba0d6eeff9fd0a16 @Valve Valve committed Mar 4, 2014
@@ -30,7 +30,8 @@ public partial class MainWindow : Window {
var query = Query
.For(74167085, DateTime.Now.AddDays(-31), DateTime.Now)
- .WithMetrics(Metric.PageTracking.Pageviews);
+ .WithMetrics(Metric.PageTracking.Pageviews + Metric.PageTracking.AvgTimeOnPage + Metric.Session.TimeOnSite)
+ .WithDimensions(Dimension.Time.DayOfWeek);
var result = await api.Execute(query);
}
catch (ConnectionException ex) {
@@ -4,19 +4,28 @@
namespace Igooana.Extensions {
internal static class StringExtensions {
+ private static readonly Regex DateRegex = new Regex(@"20\d{2}(?:01|02|03|04|05|06|07|08|09|10|11|12)(?:0|1|2|3)[0-9]", RegexOptions.CultureInvariant);
internal static string UrlEncoded(this string input) {
return WebUtility.UrlEncode(input);
}
- internal static string FormatWith(this string format, params object[] args){
+ internal static string FormatWith(this string format, params object[] args) {
return String.Format(format, args);
}
internal static bool IsGaDate(this string input) {
if (String.IsNullOrWhiteSpace(input)) {
return false;
}
- return Regex.IsMatch(input, @"(?:1|2)\d{3}(?:01|02|03|04|05|06|07|08|09|10|11|12)(?:0|1|2|3)[0-9]");
+ return DateRegex.IsMatch(input);
+ }
+
+ internal static bool IsGaInteger(this string input) {
+ if (String.IsNullOrWhiteSpace(input)) {
+ return false;
+ }
+ // should be much faster than regex
+ return Array.TrueForAll<Char>(input.ToCharArray(), x => Char.IsDigit(x));
}
}
}
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
+using System.Collections.Generic;
namespace Igooana.Json {
internal class JsonResponse {
[JsonProperty(PropertyName="columnHeaders")]
@@ -9,6 +10,6 @@ internal class JsonResponse {
public string[][] Values { get; set; }
[JsonProperty(PropertyName="totalsForAllResults")]
- public dynamic Totals { get; set; }
+ public IDictionary<string, string> Totals { get; set; }
}
}
View
@@ -7,6 +7,8 @@ public class Metric {
#region Fields
+ public const string ColumnType = "METRIC";
+
private readonly string metricString;
private string category;
private string description;
View
@@ -5,6 +5,7 @@
using System.Dynamic;
using System.Globalization;
using System.Linq;
+using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Igooana {
@@ -23,38 +24,61 @@ public class Response {
internal static async Task<Response> Parse(string json) {
var jsonResponse = await json.ToObjectAsync<JsonResponse>();
- return new Response {
+ return new Response {
Values = ParseValues(jsonResponse.Values, jsonResponse.ColumnHeaders),
- Totals = jsonResponse.Totals
+ Totals = ParseTotals(jsonResponse.Totals, jsonResponse.ColumnHeaders)
};
}
- private static IEnumerable<dynamic> ParseValues(string[][] values, IList<ResponseColumn> columns) {
+ private static IEnumerable<dynamic> ParseValues(string[][] values, IEnumerable<ResponseColumn> columns) {
var columnTypes = columns.Select(c => GetTypeFromAnalyticsType(c.DataType)).ToList();
var propertyNames = columns.Select(c => PropertizeGaColumnName(c.Name)).ToList();
return values.Select(x => {
dynamic resultValue = new ExpandoObject();
IDictionary<string, object> resultAsDic = resultValue;
for (int i = 0; i < x.Length; i++) {
- // Special case handling, GA tells thaat "20131122" is a string while it's a date
- if (columnTypes[i] == typeof(string) && x[i].IsGaDate()) {
- resultAsDic[propertyNames[i]] = DateTime.ParseExact(x[i], "yyyyMMdd", CultureInfo.InvariantCulture);
- }
- else {
- resultAsDic[propertyNames[i]] = Convert.ChangeType(x[i], columnTypes[i]);
- }
+ resultAsDic[propertyNames[i]] = ConvertDataType(x[i], columnTypes[i]);
}
return resultValue;
});
}
+ private static dynamic ParseTotals(IDictionary<string, string> totals, IEnumerable<ResponseColumn> columns) {
+ //totals = {"ga:pageviews" : "234234"}
+ var newTotals = new ExpandoObject();
+ IDictionary<string, object> newTotalsAsDic = newTotals;
+ columns = columns.Where(x => x.ColumnType == Metric.ColumnType);
+ foreach (var total in totals) {
+ var column = columns.First(x => x.Name == total.Key);
+ Type type = GetTypeFromAnalyticsType(column.DataType);
+ newTotalsAsDic[PropertizeGaColumnName(total.Key)] = ConvertDataType(total.Value, type);
+ }
+ return newTotals;
+ }
+
+ private static object ConvertDataType(string value, Type desiredType) {
+ // Special case handling, GA tells thaat "20131122" is a string while it's a date
+ if (desiredType == typeof(string) && value.IsGaDate()) {
+ return DateTime.ParseExact(value, "yyyyMMdd", CultureInfo.InvariantCulture);
+ }
+ else if (desiredType == typeof(string) && value.IsGaInteger()) {
+ return Int32.Parse(value);
+ }
+ else {
+ return Convert.ChangeType(value, desiredType);
+ }
+ }
+
+
private static Type GetTypeFromAnalyticsType(string analyticsType) {
switch (analyticsType) {
case "INTEGER": return typeof(int);
case "FLOAT":
case "PERCENT":
+ case "TIME":
return typeof(float);
- case "STRING": return typeof(string);
+ case "STRING":
+ return typeof(string);
default: return typeof(string);
}
}

0 comments on commit 2b45f53

Please sign in to comment.