activity_provider 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 49e3ea08edf92ebfb0c095c0554a39ceca2fb8b9
4
+ data.tar.gz: ee8be8564e1d4ffe580d82e080439ed22c1d7e6d
5
+ SHA512:
6
+ metadata.gz: 37b384b24235e17299f010f00331ae570b70174dde6c6c6dbd0f08a678412e3e71cf3f63d73c9288ee69edef96e056458489ac83fb89576caf6496f06afdf7e2
7
+ data.tar.gz: 2af9cc8e2da7d41d2e7a12d4d084f9f799d9b76265df1e4bae55a55bc2de7880b68b83617b991f41d998ee85d613f3c8e90d1a224415da813ade52f371c8c06f
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ before_install: gem install bundler -v 1.10.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activity_provider.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,70 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ # Note: The cmd option is now required due to the increasing number of ways
19
+ # rspec may be run, below are examples of the most common uses.
20
+ # * bundler: 'bundle exec rspec'
21
+ # * bundler binstubs: 'bin/rspec'
22
+ # * spring: 'bin/rspec' (This will use spring if running and you have
23
+ # installed the spring binstubs per the docs)
24
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
25
+ # * 'just' rspec: 'rspec'
26
+
27
+ guard :rspec, cmd: "bundle exec rspec" do
28
+ require "guard/rspec/dsl"
29
+ dsl = Guard::RSpec::Dsl.new(self)
30
+
31
+ # Feel free to open issues for suggestions and improvements
32
+
33
+ # RSpec files
34
+ rspec = dsl.rspec
35
+ watch(rspec.spec_helper) { rspec.spec_dir }
36
+ watch(rspec.spec_support) { rspec.spec_dir }
37
+ watch(rspec.spec_files)
38
+
39
+ # Ruby files
40
+ ruby = dsl.ruby
41
+ dsl.watch_spec_files_for(ruby.lib_files)
42
+
43
+ # Rails files
44
+ rails = dsl.rails(view_extensions: %w(erb haml slim))
45
+ dsl.watch_spec_files_for(rails.app_files)
46
+ dsl.watch_spec_files_for(rails.views)
47
+
48
+ watch(rails.controllers) do |m|
49
+ [
50
+ rspec.spec.("routing/#{m[1]}_routing"),
51
+ rspec.spec.("controllers/#{m[1]}_controller"),
52
+ rspec.spec.("acceptance/#{m[1]}")
53
+ ]
54
+ end
55
+
56
+ # Rails config changes
57
+ watch(rails.spec_helper) { rspec.spec_dir }
58
+ watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
+ watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
+
61
+ # Capybara features specs
62
+ watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
63
+ watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
64
+
65
+ # Turnip features and steps
66
+ watch(%r{^spec/acceptance/(.+)\.feature$})
67
+ watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
+ Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
+ end
70
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Ivan Kabluchkov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # ActivityProvider
2
+
3
+ Activity Provider for store data of education in LRS (Learning Record Store) based on xAPI specification https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md
4
+
5
+ ## Caution
6
+
7
+ This is very raw version and can contains many bugs or feature absence. Please, use it on your own risk. Bug reports are welcome.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'activity_provider'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install activity_provider
24
+
25
+ ## Usage
26
+
27
+ ### Setup
28
+
29
+ First of all, specify LRS url:
30
+
31
+ ```ruby
32
+ ActivityProvider.configure do |config|
33
+ config.xapi_url = 'http://somehost/'
34
+ end
35
+ ```
36
+
37
+ By default path of statement is `/statements`, but you can change it with your own:
38
+
39
+ ```ruby
40
+ ActivityProvider.configure do |config|
41
+ config.statement_path = '/other/statement/path'
42
+ end
43
+ ```
44
+
45
+ ### Save Statement
46
+
47
+ Actor, Verb and Object are mandatory. Other fields are optional.
48
+
49
+ ```ruby
50
+ account = ActivityProvider::LRS::Account.new({
51
+ home_page: 'http://somehost/users',
52
+ name: 123456
53
+ })
54
+ identifier = ActivityProvider::LRS::Identifier.new(account: account)
55
+ actor = ActivityProvider::LRS::Member.new(identifier: identifier)
56
+ verb = ActivityProvider::LRS::Verb.new(verb: 'answered')
57
+
58
+ score = ActivityProvider::LRS::Score.new(raw: 100, min: 1, max: 100)
59
+
60
+ object = ActivityProvider::LRS::LRSObject.new(
61
+ id: 'http://somehost/object/id'
62
+ )
63
+
64
+ result = ActivityProvider::LRS::Result.new(response: @user_answer_content.to_json.to_s,
65
+ success: true, score: score)
66
+ context_activities = { parent: [{ id: "http://somehost/parent/id" }] }
67
+ context = ActivityProvider::LRS::Context.new(context_activities: context_activities)
68
+ statement_argumenets = { actor: actor, verb: verb, object: object,
69
+ context: context, result: result }
70
+ statement = ActivityProvider::LRS::Statement.new({
71
+ actor: actor, verb: verb, object: object, context: context, result: result
72
+ })
73
+ statement.save # returns list of statements ids
74
+ ```
75
+
76
+ If statement's `id` is present, then ActivityProvider send PUT request, otherwise it send POST.
77
+
78
+ You can send batch of statements:
79
+
80
+ ```ruby
81
+ ActivityProvider.send_statements([statement1, statement2])
82
+ ```
83
+
84
+ ### Fetch Statement
85
+
86
+ ```ruby
87
+ statement = ActivityProvider::LRS::Statement.find('da3b6ac8-02f1-4ad5-9d7e-a34bde57404e')
88
+ statement.actor # => ActivityProvider::LRS::Member
89
+ ```
90
+
91
+ ## Contributing
92
+
93
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lfidnl/activity_provider.
94
+
95
+ ## License
96
+
97
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'activity_provider/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "activity_provider"
8
+ spec.version = ActivityProvider::VERSION
9
+ spec.authors = ["Ivan Kabluchkov"]
10
+ spec.email = ["ikabluchkov@gmail.com"]
11
+
12
+ spec.summary = %q{Activity Provider for LRS}
13
+ spec.description = %q{Activity Provider for store data of education in LRS (Learning Record Store) based on xAPI specification https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md}
14
+ spec.homepage = "https://github.com/lfidnl/activity_provider"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.10"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "guard-rspec"
24
+ spec.add_development_dependency "fakeweb"
25
+
26
+ spec.add_dependency('json')
27
+ spec.add_dependency('virtus')
28
+ spec.add_dependency('activesupport')
29
+ spec.add_dependency('activemodel')
30
+ spec.add_dependency('httparty')
31
+ end
@@ -0,0 +1,45 @@
1
+ require 'json'
2
+ require 'virtus'
3
+ require 'active_model'
4
+ require 'active_support/dependencies/autoload'
5
+ require 'active_support/concern'
6
+ require 'activity_provider/version'
7
+ require 'activity_provider/configuration'
8
+ require 'httparty'
9
+
10
+ module ActivityProvider
11
+ module LRS
12
+ extend ActiveSupport::Autoload
13
+ eager_autoload do
14
+ autoload :Base
15
+ autoload :Verb
16
+ autoload :Account
17
+ autoload :Identifier
18
+ autoload :Member
19
+ autoload :Group
20
+ autoload :LRSObject
21
+ autoload :Score
22
+ autoload :Result
23
+ autoload :ContextActivities
24
+ autoload :Statement
25
+ autoload :Context
26
+ autoload :ActivityDefinition
27
+ autoload :Client
28
+
29
+ module Validators
30
+ extend ActiveSupport::Autoload
31
+ autoload :IRLValidator
32
+ end
33
+ end
34
+ end
35
+
36
+ class << self
37
+ def configure
38
+ yield config
39
+ end
40
+
41
+ def config
42
+ @config ||= Configuration.new
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,9 @@
1
+ module ActivityProvider
2
+ class Configuration
3
+ attr_accessor :xapi_url, :statement_path
4
+
5
+ def initialize
6
+ @statement_path ||= '/statements'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Account < Base
4
+ include ActiveModel::Validations
5
+
6
+ attribute :home_page, String
7
+ attribute :name, String
8
+
9
+ validates_with Validators::IRLValidator, fields: [:home_page]
10
+
11
+ alias_method :homePage=, :home_page=
12
+
13
+ def as_json(*_args)
14
+ validate!
15
+ {
16
+ homePage: @home_page,
17
+ name: @name
18
+ }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class ActivityDefinition < Base
4
+ attribute :name, String
5
+ attribute :description, String
6
+ attribute :type, String
7
+ attribute :more_info, String
8
+ attribute :interaction_type, String
9
+ attribute :correct_responses_pattern, [String]
10
+ # TODO: Realize all types: choices | scale | source | target | steps
11
+
12
+ def as_json(*_args)
13
+ dumped_hash = {}
14
+ dumped_hash[:moreInfo] = @more_info if @more_info
15
+ dumped_hash[:interactionType] = @interaction_type if @interaction_type
16
+ dumped_hash[:correctResponsesPattern] = @correct_responses_pattern if @correct_responses_pattern
17
+ dumped_hash.merge!(dump_attributes(%i(name description type)))
18
+ dumped_hash
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,26 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Base
4
+ include Virtus.model
5
+
6
+ def to_json(*args)
7
+ as_json.to_json(*args)
8
+ end
9
+
10
+ def validate!
11
+ raise "Invalid entity #{self.class}: #{errors.full_messages}" unless valid?
12
+ end
13
+
14
+ private
15
+
16
+ def dump_attributes(attrs)
17
+ dumped_hash = {}
18
+ attrs.each do |attr|
19
+ instance_variable_value = instance_variable_get(:"@#{attr}")
20
+ dumped_hash[attr] = instance_variable_value if instance_variable_value
21
+ end
22
+ dumped_hash
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Client
4
+ include HTTParty
5
+ DEFAULT_HEADERS = { 'Content-Type' => 'application/json' }
6
+ base_uri ActivityProvider.config.xapi_url
7
+
8
+ def send_statements(statements)
9
+ response = self.class.post(ActivityProvider.config.statement_path,
10
+ body: statements.to_json,
11
+ headers: DEFAULT_HEADERS)
12
+ if response.response.is_a?(Net::HTTPSuccess)
13
+ JSON.parse(response.body)
14
+ else
15
+ fail response.body
16
+ end
17
+ end
18
+
19
+ def fetch_statement(statement_id)
20
+ response = self.class.get("#{ActivityProvider.config.statement_path}?statementId=#{statement_id}",
21
+ headers: DEFAULT_HEADERS)
22
+ if response.response.is_a?(Net::HTTPSuccess)
23
+ ActivityProvider::LRS::Statement.new(response.body)
24
+ else
25
+ fail response.body
26
+ end
27
+ end
28
+
29
+ def save_statement(statement)
30
+ response = self.class.put(ActivityProvider.config.statement_path,
31
+ body: statement.to_json,
32
+ headers: DEFAULT_HEADERS)
33
+ fail response.body unless response.response.is_a?(Net::HTTPSuccess)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Context < Base
4
+ attribute :registration, String
5
+ attribute :instructor, Member
6
+ attribute :team, Group
7
+ attribute :context_activities, ContextActivities
8
+ attribute :revision, String
9
+ attribute :platform, String
10
+ attribute :language, String
11
+ attribute :statement, Statement
12
+ attribute :extensions, JSON
13
+
14
+ alias_method :contextActivities=, :context_activities=
15
+
16
+ def as_json(*_args)
17
+ dumped_hash = {}
18
+ dumped_hash[:contextActivities] = @context_activities if @context_activities
19
+ dumped_hash.merge!(dump_attributes(%i(registration instructor team revision
20
+ platform language statement extensions)))
21
+ dumped_hash
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class ContextActivities < Base
4
+ attribute :parent, [LRSObject]
5
+ attribute :grouping, [LRSObject]
6
+ attribute :category, [LRSObject]
7
+ attribute :other, [LRSObject]
8
+
9
+ def as_json(*_args)
10
+ dump_attributes(%i(parent grouping category other))
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Group < Base
4
+ attribute :name, String
5
+ attribute :object_type, String
6
+ attribute :identifier, Identifier
7
+ attribute :members, Array[Member]
8
+
9
+ def initialize(args)
10
+ @object_type = 'Group'
11
+ super
12
+ end
13
+
14
+ def as_json(*_args)
15
+ dumped_hash = { objectType: @object_type }
16
+ dumped_hash[:name] = @name if @name
17
+ dumped_hash[:member] = @members if @members && !@members.empty?
18
+ dumped_hash.merge!(@identifier.as_json)
19
+ dumped_hash
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Identifier < Base
4
+ include ActiveModel::Validations
5
+
6
+ MAILTO = 'mailto:'
7
+
8
+ attribute :mbox, String
9
+ attribute :mbox_sha1sum, String
10
+ attribute :openid, String
11
+ attribute :account, Account
12
+
13
+ validates :mbox, format: { with: %r(\Amailto:.*@.*) }, allow_nil: true
14
+
15
+ def as_json(*_args)
16
+ normalize_mbox
17
+ validate!
18
+ dump_attributes(%i(mbox mbox_sha1sum openid account))
19
+ end
20
+
21
+ private
22
+
23
+ def normalize_mbox
24
+ return unless @mbox
25
+ @mbox.prepend(MAILTO) unless @mbox.start_with?(MAILTO)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class LRSObject < Base
4
+ include ActiveModel::Validations
5
+
6
+ attribute :id, String
7
+ attribute :object_type, String
8
+ attribute :definition, ActivityDefinition
9
+
10
+ validates :id, presence: true
11
+ validates :object_type, inclusion: { in: %w(Activity Statement StatementRef
12
+ SubSatement Agent Group) }
13
+
14
+ def initialize(args)
15
+ super
16
+ @object_type ||= 'Activity'
17
+ end
18
+
19
+ def as_json(*_args)
20
+ validate!
21
+ dumped_hash = {
22
+ id: @id,
23
+ objectType: @object_type
24
+ }
25
+ dumped_hash[:definition] = @definition if @definition && !@definition.empty?
26
+ dumped_hash
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Member < Base
4
+ attribute :name, String
5
+ attribute :object_type, String, default: 'Agent'
6
+ attribute :identifier, Identifier
7
+
8
+ alias_method :objectType, :object_type
9
+ alias_method :objectType=, :object_type=
10
+
11
+ def as_json(*_args)
12
+ dumped_hash = { objectType: @object_type }
13
+ dumped_hash[:name] = @name if @name
14
+ dumped_hash.merge!(@identifier.as_json)
15
+ dumped_hash
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,23 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Result < Base
4
+ include ActiveModel::Validations
5
+
6
+ attribute :success, Boolean
7
+ attribute :completion, Boolean
8
+ attribute :response, String
9
+ attribute :score, Score
10
+ attribute :duration, String
11
+ # TODO: add Extension
12
+
13
+ validates :duration, format: {
14
+ with: /P(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})/
15
+ }, allow_blank: true
16
+
17
+ def as_json(*_args)
18
+ validate!
19
+ dump_attributes(%i(response success completion score duration))
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Score < Base
4
+ include ActiveModel::Validations
5
+
6
+ attribute :scaled, Float
7
+ attribute :raw, Float
8
+ attribute :min, Float
9
+ attribute :max, Float
10
+
11
+ validates :scaled, inclusion: { in: -1..1 }, allow_nil: true
12
+
13
+ def as_json(*_args)
14
+ validate!
15
+ dump_attributes(%i(scaled raw min max))
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,62 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Statement < Base
4
+ include ActiveModel::Validations
5
+
6
+ attribute :actor, Member
7
+ attribute :verb, Verb
8
+ attribute :object, LRSObject
9
+ attribute :result, Result
10
+ attribute :context, Context
11
+ attribute :id, String
12
+ attribute :stored, DateTime
13
+
14
+ validates :actor, :verb, :object, presence: true
15
+
16
+ def initialize(*args)
17
+ if args.first.is_a?(String)
18
+ super(Statement.convert_json(args.first))
19
+ else
20
+ super(*args)
21
+ end
22
+ end
23
+
24
+ def save
25
+ if @id
26
+ ActivityProvider::LRS::Client.new.send_statement(self)
27
+ else
28
+ ActivityProvider::LRS::Client.new.send_statements([self])
29
+ end
30
+ end
31
+
32
+ def as_json(*_args)
33
+ validate!
34
+ dump_attributes(%i(actor verb object context result))
35
+ end
36
+
37
+ def self.find(id)
38
+ ActivityProvider.fetch_statement(id)
39
+ end
40
+
41
+ # Converting JSON to Hash for easy using Virtus
42
+ def self.convert_json(statement_json)
43
+ statement_hash = JSON.parse(statement_json)
44
+ actor = statement_hash['actor']
45
+ if actor
46
+ identifier = {}
47
+ identifier['account'] = actor.delete('account')
48
+ actor['identifier'] = identifier
49
+ end
50
+ verb = statement_hash['verb']
51
+ if verb
52
+ verb_name = verb['id'].match(%r{\/(\w*)$})
53
+ verb['verb'] = verb_name[1]
54
+ end
55
+
56
+ statement_hash['actor'] = actor
57
+ statement_hash['verb'] = verb
58
+ statement_hash
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,15 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ module Validators
4
+ class IRLValidator < ActiveModel::Validator
5
+ def validate(object)
6
+ options[:fields].each do |field|
7
+ unless object.send(field) =~ %r(^https?:\/\/.*)
8
+ object.errors.add(field, 'wrong format')
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ module ActivityProvider
2
+ module LRS
3
+ class Verb < Base
4
+ XAPI_VERBS_REFERENCE = 'http://www.adlnet.gov/expapi/verbs/'
5
+
6
+ attribute :verb, String
7
+
8
+ def as_json(*_args)
9
+ {
10
+ id: XAPI_VERBS_REFERENCE + @verb,
11
+ display: { :"en-US" => @verb }
12
+ }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module ActivityProvider
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activity_provider
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ivan Kabluchkov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: fakeweb
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: json
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: virtus
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: activemodel
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: httparty
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Activity Provider for store data of education in LRS (Learning Record
154
+ Store) based on xAPI specification https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md
155
+ email:
156
+ - ikabluchkov@gmail.com
157
+ executables: []
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".travis.yml"
164
+ - Gemfile
165
+ - Guardfile
166
+ - LICENSE.txt
167
+ - README.md
168
+ - Rakefile
169
+ - activity_provider.gemspec
170
+ - lib/activity_provider.rb
171
+ - lib/activity_provider/configuration.rb
172
+ - lib/activity_provider/lrs/account.rb
173
+ - lib/activity_provider/lrs/activity_definition.rb
174
+ - lib/activity_provider/lrs/base.rb
175
+ - lib/activity_provider/lrs/client.rb
176
+ - lib/activity_provider/lrs/context.rb
177
+ - lib/activity_provider/lrs/context_activities.rb
178
+ - lib/activity_provider/lrs/group.rb
179
+ - lib/activity_provider/lrs/identifier.rb
180
+ - lib/activity_provider/lrs/lrs_object.rb
181
+ - lib/activity_provider/lrs/member.rb
182
+ - lib/activity_provider/lrs/result.rb
183
+ - lib/activity_provider/lrs/score.rb
184
+ - lib/activity_provider/lrs/statement.rb
185
+ - lib/activity_provider/lrs/validators/irl_validator.rb
186
+ - lib/activity_provider/lrs/verb.rb
187
+ - lib/activity_provider/version.rb
188
+ homepage: https://github.com/lfidnl/activity_provider
189
+ licenses:
190
+ - MIT
191
+ metadata: {}
192
+ post_install_message:
193
+ rdoc_options: []
194
+ require_paths:
195
+ - lib
196
+ required_ruby_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ required_rubygems_version: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ version: '0'
206
+ requirements: []
207
+ rubyforge_project:
208
+ rubygems_version: 2.2.2
209
+ signing_key:
210
+ specification_version: 4
211
+ summary: Activity Provider for LRS
212
+ test_files: []