Skip to content

Instantly share code, notes, and snippets.

@camwest
Created March 23, 2009 18:52
Show Gist options
  • Save camwest/83716 to your computer and use it in GitHub Desktop.
Save camwest/83716 to your computer and use it in GitHub Desktop.
require_dependency "user_training_report_status.rb"
require_dependency "content.rb"
require_dependency "course_status_report.rb"
class UserTrainingReport
REPORT_WORKER_KEY = "report_worker"
#class methods
def self.get_reports(user_ids, options = {})
user_ids.collect do |user_id|
self.new(user_id, options)
end
end
def self.prepare_workers(user_id)
MiddleMan.new_worker(:worker => :user_training_report_worker, :worker_key => "#{REPORT_WORKER_KEY}-#{user_id}")
end
#starts the background process to run through the reports
def self.queue_reports(reports, user_id)
MiddleMan.worker(:user_training_report_worker, "#{REPORT_WORKER_KEY}-#{user_id}").async_generate_reports(:arg => reports)
end
#checks to see if we are currently queued for reports
def self.generating_reports?(user_id)
MiddleMan.worker(:user_training_report_worker, "#{REPORT_WORKER_KEY}-#{user_id}").ask_result(:generating)
end
def self.get_generating_reports(user_id)
MiddleMan.worker(:user_training_report_worker, "#{REPORT_WORKER_KEY}-#{user_id}").ask_result(:current_reports)
end
#returns an instance of ReportCardStatus with information on the currently processing report
def self.get_current_report_status(user_id)
MiddleMan.worker(:user_training_report_worker, "#{REPORT_WORKER_KEY}-#{user_id}").ask_result(:current_report_status)
end
#gets a copy of UserTrainingReport that has been generated and cached
def self.get_generated_report(report_id, user_id)
MiddleMan.worker(:user_training_report_worker, "#{REPORT_WORKER_KEY}-#{user_id}").ask_result("GeneratedUserTrainingReport#{report_id}")
end
def self.cancel_generating_reports(user_id)
#delete the old worker
MiddleMan.worker(:user_training_report_worker, "#{REPORT_WORKER_KEY}-#{user_id}").delete
sleep(1)
#create a new one
MiddleMan.new_worker(:worker => :user_training_report_worker, :worker_key => "#{REPORT_WORKER_KEY}-#{user_id}")
#clean it up
MiddleMan.worker(:user_training_report_worker, "#{REPORT_WORKER_KEY}-#{user_id}").async_cleanup
end
def self.get_raw_course_data
courses = UserTrainingReport.new.course_content
# get all the breadcrumbs for each course
breadcrumbs = Rails.cache.fetch("CourseBreadcrumbs") do
breadcrumbs = {}
courses.each do |course|
category = Content.find(course.parent_id, { :select => "id, lft"})
breadcrumbs[category.id] = { :label => Content.breadcrumb_copy_for_content(category.id),
:lft => category.lft,
}
end
breadcrumbs
end
{
:courses => courses,
:breadcrumbs => breadcrumbs
}
end
def self.get_statuses
[ "All", "Not Started", "In Progress", "Completed"]
end
#instance stuff
attr_reader :user_id, :name, :courses, :unique_id, :date_range
#instance methods
def initialize(user_id = nil, options = {})
@date_range = get_date_range(options[:dateFrom], options[:dateTo])
@unique_id = self.object_id
@user_id = user_id
#only generate a name if the user_id was passed in
@name = name unless self.user_id == nil
end
#returns the proper name of the user
def name
@name ||= User.find_by_sql("SELECT CONCAT(first_name, ' ', last_name) AS name from users where id = #{self.user_id}").first.name
end
#generates a set of report data for the user
def generate
@courses ||= course_content.collect do |course|
complete_total = 0
child_ids = course.child_ids.split(",")
children_total = child_ids.length
complete_total = number_of_completed_children(child_ids)
complete_status = (complete_total == children_total) ? "Complete" : (complete_total > 0) ? "In Progress" : "Not Started"
if block_given?
status = UserTrainingReportStatus.new({
:unique_id => @unique_id,
:message => "Processed #{course.name}",
:percent => get_percentage(course_content.index(course), course_content.length)
})
yield( status )
end
#generate the object to store
CourseStatusReport.new({
:course_id => course.id,
:parent_id => course.parent_id,
:progress => "#{complete_total} / #{children_total}",
:status => complete_status
})
end
self
end
#returns a set of courses and their child node ids
def course_content
Rails.cache.fetch("ContentCourses") do
sql = "SELECT root_node.name, root_node.id, GROUP_CONCAT(children.id) as child_ids, root_node.parent_id "
sql += "FROM contents as root_node "
sql += "LEFT JOIN contents as children ON root_node.id = children.parent_id AND children.content_type_id = #{ContentTypes::CHAPTEROVERVIEW_CONTENT_TYPE_ID} "
sql += "WHERE root_node.content_type_id = #{ContentTypes::OVERVIEW_CONTENT_TYPE_ID} AND children.id IS NOT NULL "
sql += "GROUP BY root_node.id "
sql += "ORDER BY root_node.lft DESC"
Content.find_by_sql(sql)
end
end
private
def get_date_range(date_from, date_to)
{
:start => (date_from) ? Date.parse(date_from) : Date.parse('01/01/1995'),
:end => (date_to) ? Date.parse(date_to) : Date.parse( (Time.now + 1.days).to_s )
}
end
def number_of_completed_children(chapter_ids)
chapter_ids.inject(0) do |num_completed, chapter_id|
chapter_lookup = LookupProgress.find_by_sql("SELECT complete, updated_at from lookup_progresses WHERE content_id=#{chapter_id} and user_id = #{@user_id}").first
if(chapter_lookup)
if (completed_within_date_range?(chapter_lookup) )
num_completed += 1
end
end
num_completed
end
end
#checks to see if the chapter lookup was completed within the date range
def completed_within_date_range?(chapter_lookup)
(chapter_lookup.complete && chapter_lookup.updated_at > @date_range[:start] && chapter_lookup.updated_at < @date_range[:end]) ? true : false
end
def get_percentage(current_index, total_files)
(((current_index + 1).to_f / total_files.to_f) * 100).to_i
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment