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:
parent
9eda70c99a
commit
0b570f89f9
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue