class Clever::Client

Attributes

api_url[R]
app_id[RW]
app_token[RW]
logger[RW]
redirect_uri[RW]
staff_username_source[RW]
sync_id[RW]
tokens_endpoint[R]
username_source[RW]
vendor_key[RW]
vendor_secret[RW]

Public Class Methods

configure() { |client| ... } click to toggle source
# File lib/clever/client.rb, line 15
def self.configure
  client = new
  yield(client) if block_given?
  client
end
new() click to toggle source
# File lib/clever/client.rb, line 10
def initialize
  @api_url         = API_URL
  @tokens_endpoint = TOKENS_ENDPOINT
end

Public Instance Methods

admins(record_uids = []) click to toggle source
# File lib/clever/client.rb, line 88
def admins(record_uids = [])
  authenticate

  district_admins = Paginator.fetch(connection, Clever::DISTRICT_ADMINS_ENDPOINT,
                                    :get, Types::DistrictAdmin, client: self).force

  school_admins = Paginator.fetch(connection, Clever::SCHOOL_ADMINS_ENDPOINT,
                                  :get, Types::SchoolAdmin, client: self).force

  admins = (district_admins + school_admins).uniq(&:uid)

  return admins if record_uids.empty?

  admins.select { |record| record_uids.to_set.include?(record.uid) }
end
authenticate(app_id = @app_id) click to toggle source
# File lib/clever/client.rb, line 21
def authenticate(app_id = @app_id)
  return if @app_token

  response = tokens

  fail ConnectionError, response.raw_body unless response.success?

  set_token(response, app_id)
end
classrooms(*) click to toggle source

discard params to make the API behave the same as the one roster gem

# File lib/clever/client.rb, line 105
def classrooms(*)
  authenticate

  fetched_courses = courses

  terms_hash = terms.each_with_object({}) { |term, terms| terms[term.uid] = term  }

  sections.map do |section|
    course = fetched_courses.find { |clever_course| clever_course.uid == section.course }
    term = terms_hash[section.term_id]
    Types::Classroom.new(
      'id' => section.uid,
      'name' => section.name,
      'period' => section.period,
      'course_number' => course&.number,
      'grades' => section.grades,
      'subjects' => section.subjects,
      'term_name' => term&.name,
      'term_start_date' => term&.start_date,
      'term_end_date' => term&.end_date
    )
  end
end
connection() click to toggle source
# File lib/clever/client.rb, line 31
def connection
  @connection ||= Connection.new(self)
end
enrollments(classroom_uids = []) click to toggle source
# File lib/clever/client.rb, line 129
def enrollments(classroom_uids = [])
  authenticate

  fetched_sections = sections

  enrollments = parse_enrollments(classroom_uids, fetched_sections)

  p "Found #{enrollments.values.flatten.length} enrollments."

  enrollments
end
events(starting_after) click to toggle source
# File lib/clever/client.rb, line 66
def events(starting_after)
  authenticate

  endpoint = "#{Clever::EVENTS_ENDPOINT}?starting_after=#{starting_after}"
  Paginator.fetch(connection, endpoint, :get, Types::Event, client: self).force
end
most_recent_event() click to toggle source
# File lib/clever/client.rb, line 57
def most_recent_event
  authenticate

  endpoint = "#{Clever::EVENTS_ENDPOINT}?ending_before=last&limit=1"

  event = @connection.execute(endpoint).body[0]
  Types::Event.new(event['data']) if event
end
send_grade(request_body) click to toggle source
# File lib/clever/client.rb, line 141
def send_grade(request_body)
  authenticate

  @connection.execute(GRADES_ENDPOINT, :post, nil, request_body)
end
tokens() click to toggle source
# File lib/clever/client.rb, line 35
def tokens
  response = connection.execute(@tokens_endpoint)
  map_response!(response, Types::Token)
  response
end
user_uid_for_code(code) click to toggle source
# File lib/clever/client.rb, line 41
def user_uid_for_code(code)
  response = connection.execute(USER_TOKEN_ENDPOINT,
                                :post,
                                nil,
                                { code: code,
                                  grant_type: 'authorization_code',
                                  redirect_uri: redirect_uri })

  fail ConnectionError, response.raw_body unless response.success?

  connection.set_token(response.raw_body['access_token'])

  response = connection.execute(ME_ENDPOINT, :get)
  response&.body&.dig('id')
end

Private Instance Methods

map_response(type, data) click to toggle source
# File lib/clever/client.rb, line 191
def map_response(type, data)
  data.map { |item_data| type.new(item_data) }
end
map_response!(response, type) click to toggle source
# File lib/clever/client.rb, line 187
def map_response!(response, type)
  response.body = map_response(type, response.body) if response.success?
end
parse_enrollments(classroom_uids, sections) click to toggle source
# File lib/clever/client.rb, line 149
def parse_enrollments(classroom_uids, sections)
  sections.each_with_object(student: [], teacher: []) do |section, enrollments|
    next if classroom_uids.any? && !classroom_uids.include?(section.uid)

    parse_student_enrollments!(section, enrollments)
    parse_teacher_enrollments!(section, enrollments)
  end
end
parse_student_enrollments!(section, enrollments) click to toggle source
# File lib/clever/client.rb, line 158
def parse_student_enrollments!(section, enrollments)
  section.students.each do |student_uid|
    enrollments[:student] << Types::Enrollment.new(
      'classroom_uid' => section.uid,
      'user_uid' => student_uid
    )
  end
end
parse_teacher_enrollments!(section, enrollments) click to toggle source
# File lib/clever/client.rb, line 167
def parse_teacher_enrollments!(section, enrollments)
  section.teachers.each do |teacher_uid|
    enrollments[:teacher] << Types::Enrollment.new(
      'classroom_uid' => section.uid,
      'user_uid' => teacher_uid,
      'primary' => section.primary_teacher_uid == teacher_uid
    )
  end
end
set_token(tokens, app_id) click to toggle source
# File lib/clever/client.rb, line 177
def set_token(tokens, app_id)
  district_token = tokens.body.find { |district| district.owner['id'] == app_id }

  fail DistrictNotFound unless district_token

  connection.set_token(district_token.access_token)

  @app_token = district_token.access_token
end