Skip to content

Instantly share code, notes, and snippets.

@imajes
Created August 9, 2014 21:26
Show Gist options
  • Save imajes/cb7884448c92dc0c7c25 to your computer and use it in GitHub Desktop.
Save imajes/cb7884448c92dc0c7c25 to your computer and use it in GitHub Desktop.
class Quill::BaseModel
include ActiveModel::Model
attr_accessor :id, :access_token
def self.special_attrs *attrs
return @special_attrs unless attrs.any?
@special_attrs = attrs
end
def self.inherited subclass
subclass.special_attrs *@special_attrs
end
def self.attributes *attrs
return @attributes if defined?(@attributes)
@attributes = attrs
attrs.dup.unshift(*@special_attrs).each do |attr|
class_eval <<-CODE
def #{attr}
@data[:#{attr}]
end
def #{attr}= value
@data[:#{attr}] = value
end
CODE
end
end
def initialize *args
@data = {}
super
load_model_attributes
end
def save(options={})
perform_validations(options) ? persist : false
end
def persist
data = @data.except(*self.class.special_attrs.dup)
serialized_data = {}
data.each do |key, value|
serialized_data[key] = value.to_yaml
end
params = { data: serialized_data }
self.class.special_attrs.each do |attr|
params[attr] = send(attr)
end
params = filter_params(params) if respond_to?(:filter_params)
object = persist_params params
self.id = object.uid if id.blank?
true
end
def load_model_attributes
return unless key_present?
object = find
object.data = {} if object.data.nil?
attrs = {}
self.id = object.uid
# load attributes defined on the superclass. These attributes
# are designated by Quill.
self.class.special_attrs.each do |attr|
attrs[attr] = object.send(attr)
end
# load user defined attributes. This is arbitrary data that the app
# has stored for this record.
self.class.attributes.each do |attr|
begin
if object.data[attr].to_s[0..2] == '---'
attrs[attr] = YAML.load(object.data[attr])
else
attrs[attr] = object.data[attr]
end
rescue Psych::SyntaxError
attrs[attr] = object.data[attr]
end
end
@data.reverse_merge!(attrs)
end
def save!
save || raise
end
def inspect
%Q|#<#{self.class.name} #{@data.map{|k,v| "#{k}=#{v.inspect}"}.join(' ')}>|
end
protected
def key_present?
id.present?
end
def persist_params params
if id.present?
api.activity_sessions.update(id, params)
else
api.activity_sessions.create(params)
end
end
def api
@api ||= Quill::Client.new(access_token: access_token)
end
def perform_validations(options={})
options[:validate] == false || valid?(options[:context])
end
end
module Quill
module Endpoint
class Base
attr_accessor :name, :api
class InvalidKeys < Exception ; end
def initialize api, name, definition
@api = api
@name = name
@attributes = definition['attributes'].keys
@readonly_attributes = definition['readonly_attributes'].try(:keys) || []
end
def find id, params = {}
check_keys(params)
response = api.get([name,id].join('/'), params)
Hashie::Mash.new(response.body['object'])
end
def create params
check_keys(params)
response = api.post(name, params)
Hashie::Mash.new(response.body['object'])
end
def update id, params
check_keys(params)
response = api.put([name,id].join('/'), params)
Hashie::Mash.new(response.body['object'])
end
def list
end
def check_keys params
invalid_keys = params.stringify_keys.keys - @attributes - @readonly_attributes
raise InvalidKeys, "Endpoint ##{name} does not support key(s) #{invalid_keys.join(', ')}" unless invalid_keys.empty?
end
end
end
end
require 'quill/endpoints'
module Quill
module EndpointDefinitions
def activities
Quill::Endpoint::Activities.new(self, 'activities', {"description"=>"\nProgrammatically interact with Activities on Compass. Typically only will\nread individual records from this resource.\n", "attributes"=>{"data"=>{}, "name"=>nil, "description"=>nil}, "access"=>{"list"=>["all"], "read"=>["all"], "update"=>["admin"], "create"=>["admin"], "destroy"=>["owner", "admin"]}, "options"=>{}})
end
def activity_sessions
Quill::Endpoint::ActivitySessions.new(self, 'activity_sessions', {"description"=>"\nCompass activity sessions are used to store progress information about a\nuser's interaction with an activity. Session's can be created without an\n+access_token+ to allow anonymous access. If you have an ID of an\nanonymous session you should also be able to update it without an\n+access_token+.\n", "attributes"=>{"percentage"=>nil, "time_spent"=>nil, "state"=>nil, "completed_at"=>nil, "data"=>{}, "temporary"=>nil, "activity_uid"=>nil, "anonymous"=>nil}, "access"=>{"list"=>["all"], "read"=>["owner"], "update"=>["owner", "admin"], "create"=>["all"], "destroy"=>["owner", "admin"]}, "options"=>{}})
end
def me
Quill::Endpoint::Me.new(self, 'me', {"description"=>"\nRequest information about the current authenticated user based on\n+access_token+.\n", "attributes"=>{"role"=>nil, "name"=>nil, "email"=>nil, "username"=>nil}, "options"=>{"singular"=>true}, "access"=>{"read"=>["all"], "update"=>["owner", "admin"], "create"=>["user"], "destroy"=>["owner", "admin"]}})
end
def ping
Quill::Endpoint::Ping.new(self, 'ping', {"description"=>"Alive check.\n", "attributes"=>{"session_id"=>nil, "status"=>nil}, "options"=>{"singular"=>true}, "access"=>{"read"=>["all"], "update"=>["owner", "admin"], "create"=>["user"], "destroy"=>["owner", "admin"]}})
end
end
end
module Quill
module Endpoint
autoload :Base, 'quill/endpoint_base'
class Activities < Base
# Programmatically interact with Activities on Compass. Typically only will
# read individual records from this resource.
# @param id [String] the id of the Activity
def find *args
super
end
# Programmatically interact with Activities on Compass. Typically only will
# read individual records from this resource.
# @param [Hash] properties properties for create
# @option properties [String] :data
# @option properties [String] :name
# @option properties [String] :description
def create *args
super
end
end
class ActivitySessions < Base
# Compass activity sessions are used to store progress information about a
# user's interaction with an activity. Session's can be created without an
# +access_token+ to allow anonymous access. If you have an ID of an
# anonymous session you should also be able to update it without an
# +access_token+.
# @param id [String] the id of the Activity session
def find *args
super
end
# Compass activity sessions are used to store progress information about a
# user's interaction with an activity. Session's can be created without an
# +access_token+ to allow anonymous access. If you have an ID of an
# anonymous session you should also be able to update it without an
# +access_token+.
# @param [Hash] properties properties for create
# @option properties [String] :percentage
# @option properties [String] :time_spent
# @option properties [String] :state
# @option properties [String] :completed_at
# @option properties [String] :data
# @option properties [String] :temporary
# @option properties [String] :activity_uid
# @option properties [String] :anonymous
def create *args
super
end
end
class Me < Base
# Request information about the current authenticated user based on
# +access_token+.
def find *args
super
end
# Request information about the current authenticated user based on
# +access_token+.
# @param [Hash] properties properties for create
# @option properties [String] :role
# @option properties [String] :name
# @option properties [String] :email
# @option properties [String] :username
def create *args
super
end
end
class Ping < Base
# Alive check.
def find *args
super
end
# Alive check.
# @param [Hash] properties properties for create
# @option properties [String] :session_id
# @option properties [String] :status
def create *args
super
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment