Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

First pass at bringing code across

  • Loading branch information...
commit 627dc6168f67ba4f09c3bbdf08571b1d26b20f3f 0 parents
James Stewart authored March 04, 2013
7  Gemfile
... ...
@@ -0,0 +1,7 @@
  1
+source 'https://rubygems.org'
  2
+
  3
+gem 'actionmailer', '3.2.12'
  4
+gem 'oauth'
  5
+gem 'garb'
  6
+gem 'terminal-table'
  7
+gem 'aws-ses', '0.4.4', :require => 'aws/ses'
70  Gemfile.lock
... ...
@@ -0,0 +1,70 @@
  1
+GEM
  2
+  remote: https://rubygems.org/
  3
+  specs:
  4
+    actionmailer (3.2.12)
  5
+      actionpack (= 3.2.12)
  6
+      mail (~> 2.4.4)
  7
+    actionpack (3.2.12)
  8
+      activemodel (= 3.2.12)
  9
+      activesupport (= 3.2.12)
  10
+      builder (~> 3.0.0)
  11
+      erubis (~> 2.7.0)
  12
+      journey (~> 1.0.4)
  13
+      rack (~> 1.4.5)
  14
+      rack-cache (~> 1.2)
  15
+      rack-test (~> 0.6.1)
  16
+      sprockets (~> 2.2.1)
  17
+    activemodel (3.2.12)
  18
+      activesupport (= 3.2.12)
  19
+      builder (~> 3.0.0)
  20
+    activesupport (3.2.12)
  21
+      i18n (~> 0.6)
  22
+      multi_json (~> 1.0)
  23
+    aws-ses (0.4.4)
  24
+      builder
  25
+      mail (> 2.2.5)
  26
+      mime-types
  27
+      xml-simple
  28
+    builder (3.0.4)
  29
+    crack (0.3.2)
  30
+    erubis (2.7.0)
  31
+    garb (0.9.1)
  32
+      activesupport (>= 2.2.0)
  33
+      crack (>= 0.1.6)
  34
+    hike (1.2.1)
  35
+    i18n (0.6.4)
  36
+    journey (1.0.4)
  37
+    mail (2.4.4)
  38
+      i18n (>= 0.4.0)
  39
+      mime-types (~> 1.16)
  40
+      treetop (~> 1.4.8)
  41
+    mime-types (1.21)
  42
+    multi_json (1.6.1)
  43
+    oauth (0.4.7)
  44
+    polyglot (0.3.3)
  45
+    rack (1.4.5)
  46
+    rack-cache (1.2)
  47
+      rack (>= 0.4)
  48
+    rack-test (0.6.2)
  49
+      rack (>= 1.0)
  50
+    sprockets (2.2.2)
  51
+      hike (~> 1.2)
  52
+      multi_json (~> 1.0)
  53
+      rack (~> 1.0)
  54
+      tilt (~> 1.1, != 1.3.0)
  55
+    terminal-table (1.4.5)
  56
+    tilt (1.3.4)
  57
+    treetop (1.4.12)
  58
+      polyglot
  59
+      polyglot (>= 0.3.1)
  60
+    xml-simple (1.1.2)
  61
+
  62
+PLATFORMS
  63
+  ruby
  64
+
  65
+DEPENDENCIES
  66
+  actionmailer (= 3.2.12)
  67
+  aws-ses (= 0.4.4)
  68
+  garb
  69
+  oauth
  70
+  terminal-table
104  lib/analytics_interface.rb
... ...
@@ -0,0 +1,104 @@
  1
+require 'oauth'
  2
+require 'garb'
  3
+require 'active_support/core_ext'
  4
+
  5
+class MainVisits
  6
+  extend Garb::Model
  7
+
  8
+  metrics :pageviews, :unique_pageviews, :avg_time_on_page
  9
+  dimensions :page_path, :page_title
  10
+end
  11
+
  12
+class Overview
  13
+  extend Garb::Model
  14
+
  15
+  metrics :visitors, :new_visits
  16
+end
  17
+
  18
+module AnalyticsUtils
  19
+  def percentage_change(from, to)
  20
+    change = 100 * (to.to_f - from.to_f) / from.to_f
  21
+    change = change.round(2)
  22
+    if change > 0
  23
+      "+#{change}"
  24
+    else
  25
+      change.to_s
  26
+    end
  27
+  end
  28
+end
  29
+
  30
+class AnalyticsInterface
  31
+
  32
+  attr_accessor :profile, :property, :oauth_token, :oauth_secret
  33
+  
  34
+  def initialize(analytics_id, oauth_token, oauth_secret)
  35
+    establish_garb_session
  36
+    self.property = Garb::Management::WebProperty.all.detect { |p| p.id == analytics_id }
  37
+    self.profile = Garb::Management::Profile.all.detect { |p| p.web_property_id == analytics_id }
  38
+    self.oauth_token = oauth_token
  39
+    self.oauth_secret = oauth_secret
  40
+  end
  41
+  
  42
+  def weekly_stats
  43
+    yesterday = Date.yesterday
  44
+    start_of_the_week = yesterday - 7.days
  45
+    start_of_previous_week = start_of_the_week - 7.days
  46
+
  47
+    first_period = overview(start_of_the_week, yesterday)
  48
+    second_period = overview(start_of_previous_week, start_of_the_week)
  49
+    describe_period(first_period, second_period, "this week", "last week")
  50
+  end
  51
+
  52
+  def daily_stats
  53
+    yesterday = Date.yesterday
  54
+    day_before_yesterday = Date.yesterday - 1.day
  55
+
  56
+    first_period = overview(yesterday, yesterday)
  57
+    second_period = overview(day_before_yesterday, day_before_yesterday)
  58
+    describe_period(first_period, second_period, "yesterday", "the day before")
  59
+  end
  60
+
  61
+  def main_visits_data
  62
+    profile.main_visits(
  63
+      :start_date => Date.yesterday,
  64
+      :end_date => Date.yesterday,
  65
+      :limit => 10,
  66
+      :sort => :unique_pageviews.desc
  67
+    )
  68
+  end
  69
+
  70
+private
  71
+  include AnalyticsUtils
  72
+
  73
+  def overview(start_date, end_date)
  74
+    profile.overview(
  75
+      :filters => { :page_path.does_not_contain => 'admin' }, 
  76
+      :start_date => start_date,
  77
+      :end_date => end_date
  78
+    ).first
  79
+  end
  80
+
  81
+  def describe_period(current_period, previous_period, this_kind, last_kind)
  82
+    {
  83
+      visitors: current_period.visitors,
  84
+      visitors_change: percentage_change(previous_period.visitors, current_period.visitors),
  85
+      new_visits: current_period.new_visits,
  86
+      new_visits_change: percentage_change(previous_period.new_visits, current_period.new_visits)
  87
+    }
  88
+  end
  89
+
  90
+  def build_oauth_token
  91
+    consumer = OAuth::Consumer.new('anonymous', 'anonymous', {
  92
+      :site => 'https://www.google.com',
  93
+      :request_token_path => '/accounts/OAuthGetRequestToken',
  94
+      :access_token_path => '/accounts/OAuthGetAccessToken',
  95
+      :authorize_path => '/accounts/OAuthAuthorizeToken'
  96
+    })
  97
+
  98
+    OAuth::AccessToken.new(consumer, oauth_token, oauth_secret)
  99
+  end
  100
+  
  101
+  def establish_garb_session
  102
+    Garb::Session.access_token = build_oauth_token
  103
+  end
  104
+end
36  lib/report_mailer.rb
... ...
@@ -0,0 +1,36 @@
  1
+require 'terminal-table'
  2
+
  3
+class ReportMailer < ActionMailer::Base
  4
+  default from: "winston@alphagov.co.uk"
  5
+
  6
+  def daily_analytics(recipient_address, daily, weekly, top_ten_pages)
  7
+    @daily = daily
  8
+    @weekly = weekly
  9
+    @top_ten_pages = top_ten_pages
  10
+
  11
+    mail(to: recipient_address, subject: analytics_subject(daily, weekly)) do |format|
  12
+      format.text
  13
+    end
  14
+  end
  15
+
  16
+  protected
  17
+  def top_ten_table(top_ten_pages)
  18
+    Terminal::Table.new do |t|
  19
+      t.add_row ['Title', 'Page Views', 'Unique Page Views', 'Avg Time on Page']
  20
+      t.add_separator
  21
+      top_ten_pages.each do |detail|
  22
+        t.add_row [
  23
+          detail.page_title, detail.pageviews, detail.unique_pageviews,
  24
+          detail.avg_time_on_page.to_i
  25
+        ]
  26
+      end
  27
+    end
  28
+  end
  29
+  
  30
+  def analytics_subject(daily, weekly)
  31
+    [
  32
+      "NEEDOTRON DAILY: Yesterday: #{daily[:visitors]} (#{daily[:visitors_change]}%) #{daily[:new_visits]} (#{daily[:new_visits_change]}%)",
  33
+      "7 days: #{weekly[:visitors]} (#{weekly[:visitors_change]}%) #{weekly[:new_visits]} (#{weekly[:new_visits_change]}%)"
  34
+    ].join(' | ')
  35
+  end
  36
+end
21  send_email.rb
... ...
@@ -0,0 +1,21 @@
  1
+#!/usr/bin/env ruby
  2
+
  3
+require 'action_mailer'
  4
+require 'aws/ses'
  5
+
  6
+require_relative 'lib/analytics_interface'
  7
+require_relative 'lib/report_mailer'
  8
+
  9
+view_path = File.expand_path('views', File.dirname(__FILE__))
  10
+
  11
+ActionMailer::Base.add_delivery_method :ses, AWS::SES::Base,
  12
+  :access_key_id     => ENV['SES_ACCESS_KEY_ID'],
  13
+  :secret_access_key => ENV['SES_SECRET_KEY']
  14
+ActionMailer::Base.delivery_method = :ses
  15
+ActionMailer::Base.view_paths = view_path
  16
+
  17
+interface = AnalyticsInterface.new(ENV['ANALYTICS_ACCOUNT_ID'], ENV['GOOGLE_OAUTH_TOKEN'], ENV['GOOGLE_OAUTH_SECRET'])
  18
+daily = interface.daily_stats
  19
+weekly = interface.weekly_stats
  20
+details = interface.main_visits_data
  21
+ReportMailer.daily_analytics(ENV['RECIPIENT_ADDRESS'], daily, weekly, details).deliver
15  views/report_mailer/daily_analytics.text.erb
... ...
@@ -0,0 +1,15 @@
  1
+UNIQUE VISITS YESTERDAY: <%= @daily[:visitors] %> (<%= @daily[:visitors_change] %>%)
  2
+NEW VISITS YESTERDAY: <%= @daily[:new_visits] %> (<%= @daily[:new_visits_change] %>%)
  3
+
  4
+UNIQUE VISITS LAST 7 DAYS: <%= @weekly[:visitors] %> (<%= @weekly[:visitors_change] %>%)
  5
+NEW VISITS LAST 7 DAYS: <%= @weekly[:new_visits] %> (<%= @weekly[:new_visits_change] %>%)
  6
+
  7
+TOP PAGES YESTERDAY
  8
+
  9
+  Title (page views / unique page views / average time)
  10
+
  11
+<% @top_ten_pages.each do |page| %>
  12
+  <%= page.page_title %> (<%= page.pageviews %> / <%= page.unique_pageviews %> / <%= page.avg_time_on_page.to_i %>)
  13
+  <%= "https://www.gov.uk#{page.page_path}" %>
  14
+
  15
+<% end %>

0 notes on commit 627dc61

Please sign in to comment.
Something went wrong with that request. Please try again.