From 26b9284f770edd7ac1e5775593192dfbccac1d89 Mon Sep 17 00:00:00 2001 From: Uncled1023 Date: Thu, 25 Feb 2016 16:41:31 -0800 Subject: [PATCH] Added Piwik tracking to the server side. --- .../Areas/API/Controllers/APIv1Controller.cs | 47 ++++++++++------- .../Areas/Privacy/Views/Privacy/Index.cshtml | 5 ++ .../Upload/Controllers/UploadController.cs | 6 ++- Teknik/Configuration/Config.cs | 5 ++ Teknik/Configuration/PiwikConfig.cs | 24 +++++++++ Teknik/Controllers/DefaultController.cs | 4 ++ Teknik/Filters/TrackingFilterAttribute.cs | 52 +++++++++++++++++++ Teknik/Global.asax.cs | 31 +++++++++++ Teknik/Helpers/HttpRequestExtensions.cs | 24 +++++++++ Teknik/Helpers/Tracking.cs | 47 +++++++++++++++++ Teknik/Teknik.csproj | 8 +++ Teknik/packages.config | 1 + 12 files changed, 235 insertions(+), 19 deletions(-) create mode 100644 Teknik/Configuration/PiwikConfig.cs create mode 100644 Teknik/Filters/TrackingFilterAttribute.cs create mode 100644 Teknik/Helpers/HttpRequestExtensions.cs create mode 100644 Teknik/Helpers/Tracking.cs diff --git a/Teknik/Areas/API/Controllers/APIv1Controller.cs b/Teknik/Areas/API/Controllers/APIv1Controller.cs index 94a8270..38c8e56 100644 --- a/Teknik/Areas/API/Controllers/APIv1Controller.cs +++ b/Teknik/Areas/API/Controllers/APIv1Controller.cs @@ -29,7 +29,9 @@ namespace Teknik.Areas.API.Controllers [AllowAnonymous] public ActionResult Upload(HttpPostedFileWrapper file, string contentType = null, bool encrypt = false, bool saveKey = false, string key = null, int keySize = 0, string iv = null, int blockSize = 0, bool genDeletionKey = false) { - try { + try + { + Tracking.TrackPageView(Request, "Upload", Subdomain); if (file != null) { if (file.ContentLength <= Config.UploadConfig.MaxUploadSize) @@ -129,6 +131,7 @@ namespace Teknik.Areas.API.Controllers { try { + Tracking.TrackPageView(Request, "Paste", Subdomain); Paste.Models.Paste paste = PasteHelper.CreatePaste(code, title, syntax, expireUnit, expireLength, password, hide); db.Pastes.Add(paste); @@ -155,29 +158,37 @@ namespace Teknik.Areas.API.Controllers public ActionResult Shorten(string url) { - if (url.IsValidUrl()) + try { - ShortenedUrl newUrl = Shortener.Shortener.ShortenUrl(url, Config.ShortenerConfig.UrlLength); - - db.ShortenedUrls.Add(newUrl); - db.SaveChanges(); - - string shortUrl = string.Format("{0}://{1}/{2}", HttpContext.Request.Url.Scheme, Config.ShortenerConfig.ShortenerHost, newUrl.ShortUrl); - if (Config.DevEnvironment) + Tracking.TrackPageView(Request, "Shorten", Subdomain); + if (url.IsValidUrl()) { - shortUrl = Url.SubRouteUrl("shortened", "Shortener.View", new { url = newUrl.ShortUrl }); - } + ShortenedUrl newUrl = Shortener.Shortener.ShortenUrl(url, Config.ShortenerConfig.UrlLength); - return Json(new - { - result = new + db.ShortenedUrls.Add(newUrl); + db.SaveChanges(); + + string shortUrl = string.Format("{0}://{1}/{2}", HttpContext.Request.Url.Scheme, Config.ShortenerConfig.ShortenerHost, newUrl.ShortUrl); + if (Config.DevEnvironment) { - shortUrl = shortUrl, - originalUrl = url + shortUrl = Url.SubRouteUrl("shortened", "Shortener.View", new { url = newUrl.ShortUrl }); } - }); + + return Json(new + { + result = new + { + shortUrl = shortUrl, + originalUrl = url + } + }); + } + return Json(new { error = new { message = "Must be a valid Url" } }); + } + catch (Exception ex) + { + return Json(new { error = new { message = "Exception: " + ex.Message } }); } - return Json(new { error = new { message = "Must be a valid Url" } }); } } } \ No newline at end of file diff --git a/Teknik/Areas/Privacy/Views/Privacy/Index.cshtml b/Teknik/Areas/Privacy/Views/Privacy/Index.cshtml index 08925c1..c1018b8 100644 --- a/Teknik/Areas/Privacy/Views/Privacy/Index.cshtml +++ b/Teknik/Areas/Privacy/Views/Privacy/Index.cshtml @@ -45,6 +45,11 @@ +

Analytics

+

+ We use Piwik to track user interaction with the site. This will store the first 2 bytes of your IP Address (e.g. 192.168.xxx.xxx) as an identifier. +

+ diff --git a/Teknik/Areas/Upload/Controllers/UploadController.cs b/Teknik/Areas/Upload/Controllers/UploadController.cs index 95b6772..0ace8c7 100644 --- a/Teknik/Areas/Upload/Controllers/UploadController.cs +++ b/Teknik/Areas/Upload/Controllers/UploadController.cs @@ -1,4 +1,5 @@ -using System; +using Piwik.Tracker; +using System; using System.Collections.Generic; using System.Data.Entity; using System.IO; @@ -145,6 +146,9 @@ namespace Teknik.Areas.Upload.Controllers Response.AppendHeader("Content-Disposition", cd.ToString()); + // Handle Piwik Tracking if enabled + Tracking.TrackPageView(Request, ViewBag.Title, Subdomain); + return File(data, upload.ContentType); } } diff --git a/Teknik/Configuration/Config.cs b/Teknik/Configuration/Config.cs index 0e95b60..09c8cef 100644 --- a/Teknik/Configuration/Config.cs +++ b/Teknik/Configuration/Config.cs @@ -34,6 +34,7 @@ namespace Teknik.Configuration private StreamConfig _StreamConfig; private ShortenerConfig _ShortenerConfig; private DatabaseConfig _DatabaseConfig; + private PiwikConfig _PiwikConfig; public bool DevEnvironment { get { return _DevEnvironment; } set { _DevEnvironment = value; } } public bool Migrate { get { return _Migrate; } set { _Migrate = value; } } @@ -84,6 +85,9 @@ namespace Teknik.Configuration // Database Configuration public DatabaseConfig DatabaseConfig { get { return _DatabaseConfig; } set { _DatabaseConfig = value; } } + // Piwik Configuration + public PiwikConfig PiwikConfig { get { return _PiwikConfig; } set { _PiwikConfig = value; } } + public Config() { _ConfigRWLock = new ReaderWriterLockSlim(); @@ -118,6 +122,7 @@ namespace Teknik.Configuration StreamConfig = new StreamConfig(); ShortenerConfig = new ShortenerConfig(); DatabaseConfig = new DatabaseConfig(); + PiwikConfig = new PiwikConfig(); } public static Config Deserialize(string text) diff --git a/Teknik/Configuration/PiwikConfig.cs b/Teknik/Configuration/PiwikConfig.cs new file mode 100644 index 0000000..5233924 --- /dev/null +++ b/Teknik/Configuration/PiwikConfig.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Teknik.Configuration +{ + public class PiwikConfig + { + public bool Enabled { get; set; } + + public string Url { get; set; } + + public int SiteId { get; set; } + + public PiwikConfig() + { + Enabled = false; + Url = string.Empty; + SiteId = 1; + } + } +} diff --git a/Teknik/Controllers/DefaultController.cs b/Teknik/Controllers/DefaultController.cs index e704f09..0c95b68 100644 --- a/Teknik/Controllers/DefaultController.cs +++ b/Teknik/Controllers/DefaultController.cs @@ -8,8 +8,12 @@ using Teknik.Areas.Error.Controllers; using Teknik.Areas.Error.ViewModels; using Teknik.Configuration; +using Piwik.Tracker; +using Teknik.Filters; + namespace Teknik.Controllers { + [TrackingFilter] public class DefaultController : Controller { private Config _config; diff --git a/Teknik/Filters/TrackingFilterAttribute.cs b/Teknik/Filters/TrackingFilterAttribute.cs new file mode 100644 index 0000000..582d06d --- /dev/null +++ b/Teknik/Filters/TrackingFilterAttribute.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using System.Web.Mvc; +using System.Web.UI; +using Teknik.Configuration; +using Teknik.Helpers; + +namespace Teknik.Filters +{ + public class TrackingFilterAttribute : ActionFilterAttribute + { + public override void OnActionExecuting(ActionExecutingContext filterContext) + { + base.OnActionExecuting(filterContext); + } + + public override void OnActionExecuted(ActionExecutedContext filterContext) + { + Config config = Config.Load(); + if (config.PiwikConfig.Enabled) + { + try + { + string sub = filterContext.HttpContext.Request.RequestContext.RouteData.Values["sub"].ToString(); + if (string.IsNullOrEmpty(sub)) + { + sub = filterContext.HttpContext.Request.Url.AbsoluteUri.GetSubdomain(); + } + string title = config.Title; + Page page = filterContext.HttpContext.Handler as Page; + + if (page != null) + { + title = page.Title; + } + Tracking.TrackPageView(filterContext.HttpContext.Request, title, sub); + } + catch (Exception ex) + { + + } + } + + base.OnActionExecuted(filterContext); + } + + } +} diff --git a/Teknik/Global.asax.cs b/Teknik/Global.asax.cs index bdf9c41..40a39ae 100644 --- a/Teknik/Global.asax.cs +++ b/Teknik/Global.asax.cs @@ -16,6 +16,10 @@ using Teknik.Areas.Error.Controllers; using System.Web.Helpers; using System.Diagnostics; using System.Collections.Specialized; +using Teknik.Configuration; +using Piwik.Tracker; +using System.Web.UI; +using Teknik.Helpers; namespace Teknik { @@ -62,6 +66,33 @@ namespace Teknik { context.Response.AppendHeader("Access-Control-Allow-Origin", origin); } + + //// Handle Piwik Tracking if enabled + //Config config = Config.Load(); + //if (config.PiwikConfig.Enabled) + //{ + // try + // { + // string sub = context.Request.RequestContext.RouteData.Values["sub"].ToString(); + // if (string.IsNullOrEmpty(sub)) + // { + // sub = context.Request.Url.AbsoluteUri.GetSubdomain(); + // } + // string title = config.Title; + // Page page = HttpContext.Current.Handler as Page; + + // if (page != null) + // { + // title = page.Title; + // } + // var newContext = ((HttpApplication)sender).Context; + // Tracking.TrackPageView(new HttpRequestWrapper(newContext.Request), title, sub); + // } + // catch (Exception ex) + // { + + // } + //} } protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) diff --git a/Teknik/Helpers/HttpRequestExtensions.cs b/Teknik/Helpers/HttpRequestExtensions.cs new file mode 100644 index 0000000..1ca1ae0 --- /dev/null +++ b/Teknik/Helpers/HttpRequestExtensions.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Web; + +namespace Teknik.Helpers +{ + public static class HttpRequestExtensions + { + public static string GetClientIpAddress(this HttpRequestMessage request) + { + if (request.Properties.ContainsKey("MS_HttpContext")) + { + return IPAddress.Parse(((HttpContextBase)request.Properties["MS_HttpContext"]).Request.UserHostAddress).ToString(); + } + return null; + } + + } +} diff --git a/Teknik/Helpers/Tracking.cs b/Teknik/Helpers/Tracking.cs new file mode 100644 index 0000000..2662663 --- /dev/null +++ b/Teknik/Helpers/Tracking.cs @@ -0,0 +1,47 @@ +using Piwik.Tracker; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web; +using Teknik.Configuration; + +namespace Teknik.Helpers +{ + public static class Tracking + { + public static void TrackPageView(HttpRequestBase request, string title, string sub) + { + Config config = Config.Load(); + // Handle Piwik Tracking if enabled + if (config.PiwikConfig.Enabled) + { + try + { + PiwikTracker.URL = config.PiwikConfig.Url; + PiwikTracker tracker = new PiwikTracker(config.PiwikConfig.SiteId); + + tracker.setForceVisitDateTime(DateTime.Now); + tracker.setUserAgent(request.UserAgent); + + tracker.setResolution(request.Browser.ScreenPixelsWidth, request.Browser.ScreenPixelsHeight); + tracker.setBrowserHasCookies(request.Browser.Cookies); + + string ipAddress = request.UserHostAddress; + + tracker.setIp(ipAddress); + + tracker.setUrl(request.Url.ToString()); + tracker.setUrlReferrer(request.UrlReferrer.ToString()); + + tracker.doTrackPageView(string.Format("{0} / {1}", sub, title)); + } + catch (Exception ex) + { + + } + } + } + } +} diff --git a/Teknik/Teknik.csproj b/Teknik/Teknik.csproj index 0826b47..0303e72 100644 --- a/Teknik/Teknik.csproj +++ b/Teknik/Teknik.csproj @@ -80,6 +80,10 @@ ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll True + + ..\packages\Piwik.Tracker.2.8.0.0\lib\net40\Piwik.Tracker.dll + True + ..\packages\routedebugger.2.1.4.0\lib\net40\RouteDebugger.dll @@ -231,6 +235,7 @@ + @@ -247,6 +252,7 @@ + Global.asax @@ -257,9 +263,11 @@ + + diff --git a/Teknik/packages.config b/Teknik/packages.config index 8476dc3..0fe51e8 100644 --- a/Teknik/packages.config +++ b/Teknik/packages.config @@ -25,6 +25,7 @@ +