lib/cellect/server/grouped_workflow.rb
module Cellect
module Server
class GroupedWorkflow < Workflow
# Sets up the new workflow
def initialize(name, pairwise: false, prioritized: false)
self.subjects = { }
super
end
def groups
subjects
end
# Returns a group by id
# if the group_id is supplied it will select or setup this group
# when no group_id is supplied, it attempts to select a random group
# finally if no loaded groupes it falls back to creating a new empty group
def group(group_id = nil)
group = if group_id
fetch_or_setup_group(group_id)
else
subjects.values.sample
end
group || fetch_or_setup_group(group_id)
end
# Get unseen subjects from a group for a user
def unseen_for(user_name, group_id: nil, limit: 5)
group(group_id).subtract user(user_name).seen, limit
end
# Get a sample of subjects from a group for a user
#
# Accepts a hash in the form:
# {
# user_id: 123,
# group_id: 2,
# limit: 5
# }
def sample(opts = { })
if opts[:user_id]
unseen_for opts[:user_id], group_id: opts[:group_id], limit: opts[:limit]
else
group(opts[:group_id]).sample opts[:limit]
end
end
# Adds or updates a subject in a group
#
# Accepts a hash in the form:
# {
# subject_id: 1,
# group_id: 2,
# priority: 0.5 # (if the workflow is prioritized)
# }
def add(opts = { })
add_group = fetch_or_setup_group(opts[:group_id])
if prioritized?
add_group.add opts[:subject_id], opts[:priority]
else
add_group.add opts[:subject_id]
end
end
# Removes a subject from a group
#
# Accepts a hash in the form:
# {
# group_id: 1,
# subject_id: 2
# }
def remove(opts = { })
if group = subjects[opts[:group_id]]
group.remove opts[:subject_id]
end
end
# General information about this workflow
def status
# Get the number of subjects in each group
group_counts = Hash[*subjects.collect{ |id, set| [id, set.size] }.flatten]
super.merge({
grouped: true,
subjects: group_counts.values.inject(:+),
groups: group_counts
})
end
def grouped?
true
end
private
def data_loader
GroupedLoader.new(self)
end
def fetch_or_setup_group(group_id)
subjects[group_id] ||= set_klass.new
end
end
end
end