remove dead code around page views

Removes unused methods and associations from models, and removes the
PageViewRange model completely, which is no longer used.

test plan:
  * run the specs
  * verify that no active page-view-related functionality was inadvertently removed

Change-Id: I8522d151555db64a0ad2548334ae642f9fefd54e
Reviewed-on: https://gerrit.instructure.com/9324
Tested-by: Hudson <hudson@instructure.com>
Reviewed-by: Cody Cutrer <cody@instructure.com>
This commit is contained in:
Brian Palmer 2012-03-09 10:30:31 -07:00
parent 9eda70c99a
commit 0b570f89f9
9 changed files with 13 additions and 409 deletions

View File

@ -80,7 +80,6 @@ class Account < ActiveRecord::Base
has_many :created_learning_outcomes, :class_name => 'LearningOutcome', :as => :context
has_many :learning_outcome_tags, :class_name => 'ContentTag', :as => :context, :conditions => ['content_tags.tag_type = ? AND workflow_state != ?', 'learning_outcome_association', 'deleted']
has_many :associated_learning_outcomes, :through => :learning_outcome_tags, :source => :learning_outcome
has_many :page_views
has_many :error_reports
has_many :announcements, :class_name => 'AccountNotification'
has_many :alerts, :as => :context, :include => :criteria
@ -415,103 +414,11 @@ class Account < ActiveRecord::Base
account_chain(opts).map(&:id)
end
memoize :account_chain_ids
def all_page_views
PageView.of_account(self)
end
def membership_for_user(user)
self.account_users.find_by_user_id(user && user.id)
end
def page_views_by_day(*args)
dates = (!args.empty? && args) || [1.year.ago, Time.now ]
PageView.count(
:group => "date(created_at)",
:order => "date(created_at)",
:conditions => {
:account_id => self_and_all_sub_accounts,
:created_at => (dates.first)..(dates.last)
}
)
end
memoize :page_views_by_day
def page_views_by_hour(*args)
dates = (!args.empty? && args) || [1.year.ago, Time.now ]
group = case PageView.connection.adapter_name
when "SQLite"
"strftime('%H', created_at)"
else
"extract(hour from created_at)"
end
PageView.count(
:group => group,
:order => group,
:conditions => {
:account_id => self_and_all_sub_accounts,
:created_at => (dates.first)..(dates.last)
}
)
end
memoize :page_views_by_hour
def page_view_hourly_report(*args)
# if they dont supply a date range then use the first day returned by page_views_by_day (which should be the first day that there is pageview statistics gathered)
hours = []
max = page_views_by_hour(*args).map{|key, val| val}.compact.max
24.times do |hour|
utc_hour = ActiveSupport::TimeWithZone.new(Time.parse("#{hour}:00"), Time.zone).utc.hour
hours << [hour, ((page_views_by_hour(*args)[utc_hour.to_s].to_f / max.to_f * 100.0).to_i rescue 0) ]
end
hours
end
def page_view_data(*args)
# if they dont supply a date range then use the first day returned by page_views_by_day (which should be the first day that there is pageview statistics gathered)
dates = args.empty? ? [page_views_by_day.sort.first.first.to_datetime, Time.now] : args
days = []
dates.first.to_datetime.upto(dates.last) do |d|
# this * 1000 part is because the Highcharts expects something like what Date.UTC(2006, 2, 28) would give you,
# which is MILLISECONDS from the unix epoch, ruby's to_f gives you SECONDS since then.
days << [ (d.at_beginning_of_day.to_f * 1000).to_i , page_views_by_day[d.to_date.to_s].to_i ]
end
days
rescue
return []
end
memoize :page_view_data
def most_popular_courses(options={})
conditions = {
:account_id => self_and_all_sub_accounts
}
if options[:dates]
conditions.merge!({
:created_at => (options[:dates].first)..(options[:dates].last)
})
end
PageView.scoped(
:select => 'count(*) AS page_views_count, context_type, context_id',
:group => "context_type, context_id",
:conditions => conditions,
:order => "page_views_count DESC"
).map do |context|
context.attributes.merge({"page_views_count" => context.page_views_count.to_i}).with_indifferent_access
end
end
memoize :most_popular_courses
def popularity_of(context)
index = most_popular_courses.index( most_popular_courses.detect { |i|
i[:context_type] == context.class.to_s && i[:context_id] == context.id
})
index ?
{ :rank => index, :page_views_count => most_popular_courses[index][:page_views_count] } :
{ :rank => courses.count, :page_views_count => 0 }
end
memoize :popularity_of
def account_membership_types
res = ['AccountAdmin']
res += self.parent_account.account_membership_types if self.parent_account

View File

@ -107,13 +107,6 @@ class AssetUserAccess < ActiveRecord::Base
end
end
def self.summarize_asset_accesses
@accesses = AssetUserAccess.to_be_summarized
if !@accesses.empty?
@accesses.each{|a| a.generate_summaries }
end
end
def display_name
# repair existing AssetUserAccesses that have bad display_names
if read_attribute(:display_name) == asset_code
@ -172,70 +165,4 @@ class AssetUserAccess < ActiveRecord::Base
asset = Context.find_asset_by_asset_string(asset_code)
asset
end
def generate_summaries
contexts = []
obj = self
while (obj.respond_to?(:context) && obj.context) || (obj.respond_to?(:account) && obj.account)
if (obj.respond_to?(:context) && obj.context)
contexts << obj.context
obj = obj.context
else
contexts << obj.account
obj = obj.account
end
end
page_views = self.page_views
found_ranges = {}
page_views.each do |view|
view_week = view.created_at.to_date
# Week range is Monday to Sunday
view_week = (view_week - 1) - (view_week - 1).wday + 1
view_month = Date.new(y=view.created_at.year, m=view.created_at.month, d=1) #view.created_at.strftime("%m:%Y")
if !found_ranges[view_week]
contexts.each do |context|
week_range = self.asset_access_ranges.find_by_start_on_and_end_on_and_context_id_and_context_type(view_week, view_week + 6, context.id, context.class.to_s)
week_range ||= self.asset_access_ranges.build(:start_on => view_week, :end_on => view_week + 6, :context => context)
week_range.user_id = self.user_id
week_range.asset_code = self.asset_code
week_range.save
end
end
if !found_ranges[view_month]
contexts.each do |context|
month_range = self.asset_access_ranges.find_by_start_on_and_end_on_and_context_id_and_context_type(view_month, (view_month >> 1) - 1, context.id, context.class.to_s)
month_range ||= self.asset_access_ranges.build(:start_on => view_month, :end_on => (view_month >> 1) - 1, :context => context)
month_range.user_id = self.user_id
month_range.asset_code = self.asset_code
month_range.save
end
end
found_ranges[view_week] = true
found_ranges[view_month] = true
end
self.asset_access_ranges.incomplete.each do |range|
views = page_views.select{|v| v.created_at >= range.start_on && v.created_at <= range.end_on.tomorrow}
range.view_score = 0
range.participate_score = 0
range.interaction_seconds = 0
range.action_level = 'view'
views.each do |view|
range.view_score += 1
range.asset_category ||= self.asset_category
range.display_name = self.display_name
range.membership_type ||= self.membership_type
range.participate_score += 1 if view.participated
range.interaction_seconds += view.interaction_seconds if view.interaction_seconds
range.action_level = 'participate' if view.participated
end
range.workflow_state = 'complete' if Time.now > range.end_on.tomorrow
range.save
end
self.summarized_at = Time.now
self.save
end
named_scope :to_be_summarized, :order => 'updated_at', :conditions => ['summarized_at IS NULL'], :limit => 500
named_scope :to_be_resummarized, :order => 'summarized_at', :conditions => ['summarized_at < ?', 24.hours.ago], :limit => 5
end

View File

@ -392,15 +392,6 @@ class Course < ActiveRecord::Base
self.non_unique_associated_accounts.uniq
end
# objects returned from this query will give you an additional attribute "page_views_count" that you can use, so:
# Account.first.courses.most_active(10).first.page_views_count #=> "466"
named_scope :most_active, lambda { |limit|
{
:select => "courses.*, (SELECT COUNT(*) FROM page_views WHERE context_id = courses.id AND context_type = 'Course') AS page_views_count",
:order => "page_views_count DESC",
:limit => limit
}
}
named_scope :recently_started, lambda {
{:conditions => ['start_at < ? and start_at > ?', Time.now.utc, 1.month.ago], :order => 'start_at DESC', :limit => 10}
}

View File

@ -234,29 +234,6 @@ class Enrollment < ActiveRecord::Base
self.save
end
def page_views_by_day(options={})
conditions = {
:context_id => course.id,
:context_type => course.class.to_s,
:user_id => user.id
}
if options[:dates]
conditions.merge!({
:created_at => (options[:dates].first)..(options[:dates].last)
})
end
page_views_as_hash = {}
PageView.count(
:group => "date(created_at)",
:conditions => conditions
).each do |day|
page_views_as_hash[day.first] = day.last
end
page_views_as_hash
end
memoize :page_views_by_day
def defined_by_sis?
!!self.sis_source_id
end

View File

@ -68,15 +68,6 @@ class PageView < ActiveRecord::Base
self.context.name rescue ""
end
named_scope :recent_with_user, lambda {
{:order => 'page_views.id DESC', :limit => 100, :include => :user}
}
named_scope :to_be_summarized, lambda {
{:conditions => 'page_views.summarized IS NULL', :order => 'page_views.created_at', :limit => 1 }
}
named_scope :summarize_range, lambda {|context, start_at, end_at|
{:conditions => ['page_views.context_id = ? AND page_views.context_type = ? AND page_views.created_at > ? AND page_views.created_at < ?', context.id, context.class.to_s, start_at.utc, end_at.utc] }
}
named_scope :after, lambda{ |date|
{:conditions => ['page_views.created_at > ?', date] }
}
@ -87,21 +78,6 @@ class PageView < ActiveRecord::Base
{:limit => limit }
}
def generate_summaries
self.summarized = true
self.save
hour_start = ActiveSupport::TimeWithZone.new(Time.utc(self.created_at.year, self.created_at.month, self.created_at.day, self.created_at.hour), Time.zone).utc
hour_end = hour_start + (60*60)
range = PageViewRange.find_by_context_id_and_context_type_and_start_at_and_end_at(self.context_id, self.context_type, hour_start, hour_end)
range ||= PageViewRange.create(:context => self.context, :start_at => hour_start, :end_at => hour_end)
range.re_summarize
day_start = Time.utc(self.created_at.year, self.created_at.month, self.created_at.day)
day_end = day_start + 1.day
range = PageViewRange.find_by_context_id_and_context_type_and_start_at_and_end_at(self.context_id, self.context_type, day_start, day_end)
range ||= PageViewRange.create(:context => self.context, :start_at => day_start, :end_at => day_end)
range.re_summarize
end
def self.page_views_enabled?
!!page_view_method
end

View File

@ -1,114 +0,0 @@
#
# Copyright (C) 2011 Instructure, Inc.
#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
class PageViewRange < ActiveRecord::Base
include Workflow
belongs_to :context, :polymorphic => true
serialize :data
attr_accessible :context, :start_at, :end_at
workflow do
state :needs_re_summarization
state :summarized
end
def re_summarize
@hash_data = {}
@page_view_count = 0
@participated_count = 0
@interaction_tally = 0
@developer_key_count = 0
PageView.summarize_range(context, start_at.utc, end_at.utc).each do |view|
tally(view)
end
if context.is_a?(Account)
(context.courses + context.groups).each do |sub_context|
range = PageViewRange.find_by_context_id_and_context_type_and_start_at_and_end_at(sub_context.id, sub_context.class.to_s, start_at.utc, end_at.utc)
tally_range(range) if range
end
context.sub_accounts.each do |account|
range = PageViewRange.find_by_context_id_and_context_type_and_start_at_and_end_at(account.id, account.class.to_s, start_at.utc, end_at.utc)
tally_range(range) if range
end
end
self.page_view_count = @page_view_count
self.page_participated_count = @participated_count
self.total_interaction_seconds = @interaction_tally
self.mean_interaction_seconds = (@page_view_count == 0 ? 0 : @interaction_tally.to_f / @page_view_count.to_f)
self.developer_key_count = @developer_key_count
self.data = @hash_data
self.workflow_state = 'summarized'
self.save!
account = nil
account = context.parent_account if context.respond_to?(:parent_account)
account = context.account if context.respond_to?(:account)
if account
range = PageViewRange.find_by_context_id_and_context_type_and_start_at_and_end_at(account.id, account.class.to_s, start_at.utc, end_at.utc)
range ||= PageViewRange.create(:context => account, :start_at => start_at.utc, :end_at => end_at.utc)
range.mark_for_review
end
self
end
def mark_for_review
self.workflow_state = 'needs_re_summarization'
self.save!
account = nil
account = context.parent_account if context.respond_to?(:parent_account)
account = context.account if context.respond_to?(:account)
if account
range = PageViewRange.find_by_context_id_and_context_type_and_start_at_and_end_at(account.id, account.class.to_s, start_at.utc, end_at.utc)
range ||= PageViewRange.create(:context => account, :start_at => start_at.utc, :end_at => end_at.utc)
range.mark_for_review
end
end
def tally_range(range)
@page_view_count += range.page_view_count
@participated_count += range.page_participated_count
@interaction_tally += range.total_interaction_seconds
@developer_key_count += range.developer_key_count
if range.data && range.data[:user_agents]
range.data[:user_agents].each{|agent, count|
@hash_data[:user_agents] ||= {}
@hash_data[:user_agents][agent] ||= 0
@hash_data[:user_agents][agent] += count
}
end
end
def tally(view)
@page_view_count += 1
@participated_count += 1 if view.contributed
@developer_key_count += 1 if view.developer_key
@interaction_tally += view.interaction_seconds || 5
@hash_data[:user_agents] ||= {}
@hash_data[:user_agents][view.user_agent] ||= 0
@hash_data[:user_agents][view.user_agent] += 1
view.summarized = true
view.save
end
named_scope :for_review, lambda{
{:conditions => ['page_view_ranges.workflow_state = ?', 'needs_re_summarization'], :order => :updated_at, :limit => 5}
}
named_scope :re_summarize_recent, lambda{
{:conditions => ['page_view_ranges.start_at > ? AND page_view_ranges.updated_at < ?', 1.week.ago, 3.hours.ago], :order => :updated_at, :limit => 5 }
}
end

View File

@ -169,25 +169,6 @@ class User < ActiveRecord::Base
}
}
# scopes to the most active users across the system
named_scope :most_active, lambda { |*args|
{
:joins => [:page_views],
:order => "users.page_views_count DESC",
:limit => (args.first || 10)
}
}
# scopes to the most active users (by page view count) in a context:
# User.x_most_active_in_context(30, Course.find(112)) # will give you the 30 most active users in course 112
named_scope :x_most_active_in_context, lambda { |*args|
{
:select => "users.*, (SELECT COUNT(*) FROM page_views WHERE user_id = users.id AND context_id = #{args.last.id} AND context_type = '#{args.last.class.to_s}') AS page_views_count",
:order => "page_views_count DESC",
:limit => (args.first || 10),
}
}
has_a_broadcast_policy
validates_length_of :name, :maximum => maximum_string_length, :allow_nil => true
@ -198,25 +179,6 @@ class User < ActiveRecord::Base
after_save :generate_reminders_if_changed
after_save :update_account_associations_if_necessary
def page_views_by_day(options={})
conditions = {}
if options[:dates]
conditions.merge!({
:created_at => (options[:dates].first)..(options[:dates].last)
})
end
page_views_as_hash = {}
self.page_views.count(
:group => "date(created_at)",
:order => "date(created_at)",
:conditions => conditions
).each do |day|
page_views_as_hash[day.first] = day.last
end
page_views_as_hash
end
memoize :page_views_by_day
def self.skip_updating_account_associations(&block)
@skip_updating_account_associations = true
block.call
@ -371,27 +333,6 @@ class User < ActiveRecord::Base
end
end
def page_view_data(options={})
# if they dont supply a date range then use the first day returned by page_views_by_day
# (which should be the first day that there is pageview statistics gathered)
dates = options[:dates] && options[:dates].first ?
[options[:dates].first, (options[:dates].last || Time.now)] :
[page_views_by_day.sort.first.first.to_datetime, Time.now]
enrollments_with_page_views = enrollments.reject{ |e| e.page_views_by_day(:dates => dates).empty? }
days = []
dates.first.to_datetime.upto(dates.last) do |d|
# this * 1000 part is because the Highcharts expects something like what Date.UTC(2006, 2, 28) would give you,
# which is MILLISECONDS from the unix epoch, ruby's to_f gives you SECONDS since then.
days << [ (d.at_beginning_of_day.to_f * 1000).to_i, page_views_by_day(:dates => dates)[d.to_date.to_s].to_i, nil, nil].concat(
# these 2 nil's at the end here are because the google annotatedtimeline expects a title and a text,
# we can put something meaninful here once we start tracking noteworth events
enrollments_with_page_views.map{ |enrollment| [ enrollment.page_views_by_day(:dates => dates)[d.to_date.to_s].to_i, nil, nil] }
).flatten
end
{ :days => days, :labels => ["All Page Views"] + enrollments_with_page_views.map{ |e| e.course.name } }
end
memoize :page_view_data
# These two methods can be overridden by a plugin if you want to have an approval process for new teachers
def registration_approval_required?; false; end
def new_teacher_registration(form_params = {}); end

View File

@ -0,0 +1,11 @@
class DropPageViewRanges < ActiveRecord::Migration
tag :postdeploy
def self.up
drop_table :page_view_ranges
end
def self.down
raise ActiveRecord::IrreversibleMigration
end
end

View File

@ -307,18 +307,6 @@ describe Account do
a2.enrollment_terms.size.should == 0
end
context "page view reports" do
before(:each) do
@a = Account.create!(:name => 'nada')
end
it "should build hourly reports" do
lambda{@a.page_views_by_hour}.should_not raise_error
end
it "should build daily reports" do
lambda{@a.page_views_by_day}.should_not raise_error
end
end
def account_with_admin_and_restricted_user(account)
account.add_account_membership_type('Restricted Admin')
admin = User.create