sraas 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bb03f58651fdf3061f82991e8a9b63fe153df002
4
+ data.tar.gz: 960f4fad513c0d59eeb558de8b2eae1ac8ac587b
5
+ SHA512:
6
+ metadata.gz: 19ae79ca9b779f86c14ab7242d5e004b40fba2005217f65f0e68257e037f75ccbf1b971bdcd63c39663ab118e6400365b654e9ad53b2d31b9336527d461ae17d
7
+ data.tar.gz: fcb3521e82b61314923ebcb27b5b01ef3595fe16c77004fe0749e354b0560a94e5d17f622c7667a4243fb8c23be2f7c7d91dd407f3644c66ede1a958b287c06f
data/LICENSE ADDED
File without changes
@@ -0,0 +1,59 @@
1
+ # Straasio
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'sraas'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ In rails root run instalation script
20
+ ```bash
21
+ $ rake sraas:install
22
+ ```
23
+
24
+ Add your api key in `config/initializers/sraas.rb`
25
+ ```ruby
26
+ # API key
27
+ config.api_key = <API KEY>
28
+ ```
29
+
30
+ Run migrations
31
+ ```bash
32
+ $ rake db:migrate
33
+ ```
34
+
35
+ ## Using
36
+ Add to `models/user.rb` next line
37
+ ```ruby
38
+ class User < ApplicationRecord
39
+ has_sraas
40
+ end
41
+ ```
42
+ This will create polymorphic association `sraas_consumer` which provides interface for using SRAAS API
43
+
44
+ ## Tests
45
+ To run tests use
46
+ ```bash
47
+ $ rake spec
48
+ ```
49
+
50
+ ## Contributing
51
+ Contribution directions go here.
52
+
53
+ ## License
54
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
55
+
56
+ cd test/dummy; bin/rails generate model Hickwall sraas_consumer_id:string
57
+
58
+ # Deploy updated gem:
59
+ gem install pkg/sraas-0.2.2.gem
@@ -0,0 +1,35 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Straasio'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+
19
+ require 'rake/testtask'
20
+ import './lib/tasks/sraas_tasks.rake'
21
+
22
+ Rake::TestTask.new(:test) do |t|
23
+ t.libs << 'lib'
24
+ t.libs << 'test'
25
+ t.pattern = 'test/**/*_test.rb'
26
+ t.verbose = false
27
+ end
28
+
29
+ task default: :test
30
+
31
+ begin
32
+ require 'rspec/core/rake_task'
33
+ RSpec::Core::RakeTask.new(:spec)
34
+ rescue LoadError
35
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sraas'
4
+ puts Sraas.hi
5
+
@@ -0,0 +1,85 @@
1
+ require 'rest_client'
2
+ require 'sraas/consumer' if defined?(ActiveRecord::Base)
3
+ require 'sraas/railtie' if defined?(Rails)
4
+ require 'sraas/has_sraas' if defined?(Rails)
5
+ require 'sraas/configuration'
6
+
7
+ module Sraas
8
+ NoAPIKey = Class.new(StandardError)
9
+
10
+ class << self
11
+ def configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
15
+ def configure
16
+ yield(configuration)
17
+ end
18
+
19
+ def sraas_consumer_info(consumer_url)
20
+ JSON.parse(api_resource(:get, consumer_url))
21
+ end
22
+
23
+ def sraas_consumer_create(email, tags = [])
24
+ payload = { consumer: { email: email, tags: tags.join(',') } }
25
+ JSON.parse(api_resource(:post, consumers_endpoint, payload))
26
+ end
27
+
28
+ # This function exists so an admin-like UI
29
+ # can query many consumer IDs at once
30
+ # and then access them without creating dozens of requests.
31
+ def sraas_consumers_cache(consumer_ids)
32
+ payload = { consumer_uuids: consumer_ids }
33
+ data = api_resource(:post, bulk_consumers_endpoint, payload)
34
+ consumers = JSON.parse(data)
35
+ @cached_at = Time.now
36
+ @cache = consumers.inject({}) { |a, v| k = v['id']; a[k] = v; a }
37
+ end
38
+
39
+ def consumers_endpoint
40
+ "#{configuration.url}/consumers"
41
+ end
42
+
43
+ def bulk_consumers_endpoint
44
+ "#{configuration.url}/consumers/bulk"
45
+ end
46
+
47
+ def cards_endpoint
48
+ "#{configuration.url}/cards"
49
+ end
50
+
51
+ def template_decks_endpoint
52
+ "#{configuration.url}/template_decks"
53
+ end
54
+
55
+ def api_resource(http_method, url, payload = {})
56
+ RestClient::Request
57
+ .execute(
58
+ method: http_method,
59
+ url: url,
60
+ payload: payload,
61
+ headers: api_header
62
+ )
63
+ end
64
+
65
+ private
66
+
67
+ def ensure_api_key
68
+ # TODO: Provide meaningful message what is the reason of error
69
+ # and explanation how to fix this
70
+ raise NoAPIKey unless configuration.api_key
71
+ end
72
+
73
+ def api_header
74
+ ensure_api_key
75
+ {
76
+ accept: :json,
77
+ authorization: "Token token=#{configuration.api_key}",
78
+ }
79
+ end
80
+ end
81
+ end
82
+
83
+ if defined?(ActiveRecord::Base)
84
+ ActiveRecord::Base.include Sraas::HasSraas::LocalInstanceMethods
85
+ end
@@ -0,0 +1,10 @@
1
+ module Sraas
2
+ class Configuration
3
+ attr_accessor :url, :api_key
4
+
5
+ def initialize
6
+ @url = 'https://www.sraas.io'
7
+ @api_key = nil
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,116 @@
1
+ module Sraas
2
+ class Consumer < ActiveRecord::Base
3
+ self.table_name_prefix = 'sraas_'
4
+
5
+ belongs_to :sraas_consumerable, polymorphic: true
6
+
7
+ validates :consumer_uuid, presence: true
8
+
9
+ def review_count
10
+ info['available_to_review']
11
+ end
12
+
13
+ def learn_count
14
+ info['available_to_learn']
15
+ end
16
+
17
+ def cards_remaining
18
+ info['lesson_remaining_cards']
19
+ end
20
+
21
+ def lesson_progress
22
+ info['lesson_progress']
23
+ end
24
+
25
+ def current_lesson
26
+ info['current_lesson']
27
+ end
28
+
29
+ def cards_by_stars
30
+ info['cards_by_stars']
31
+ end
32
+
33
+ def learned_everything?
34
+ info['learned_everything']
35
+ end
36
+
37
+ def learned_anything?
38
+ info['learned_anything']
39
+ end
40
+
41
+ def next_review_at
42
+ Time.parse(info['next_review_at'])
43
+ rescue StandardError
44
+ 'N/A'
45
+ end
46
+
47
+ def info
48
+ # Only caching for lifetime of a single request since this object may get
49
+ # called many times in a view...
50
+ return @_info if defined?(@_info)
51
+ @_info = consumer
52
+ end
53
+
54
+ def lessons
55
+ parse_json { get("#{consumer_url}/lessons") }
56
+ end
57
+
58
+ def lesson(lesson_id)
59
+ lesson = parse_json { get("#{consumer_url}/lessons/#{lesson_id}") }
60
+ OpenStruct.new(progress: lesson['progress'], cards: lesson['cards'])
61
+ end
62
+
63
+ def card(card_uuid)
64
+ parse_json { get("#{Sraas.cards_endpoint}/#{card_uuid}") }
65
+ end
66
+
67
+ def report(correct_ids, incorrect_ids)
68
+ ids = "#{correct_ids}/#{incorrect_ids}"
69
+ parse_json { get("#{consumer_url}/report/#{ids}") }
70
+ end
71
+
72
+ def template_decks
73
+ parse_json { get(Sraas.template_decks_endpoint) }
74
+ end
75
+
76
+ def unlock_lesson(lesson = 1)
77
+ data = get("#{consumer_url}/unlock_lesson?lesson=#{lesson}")
78
+ data.code == 200
79
+ end
80
+
81
+ def add_template_deck_by_name(deck_name)
82
+ deck_uuid = detect_deck_by_name(deck_name).dig('id')
83
+ return false unless deck_uuid
84
+ url = "#{Sraas.template_decks_endpoint}/#{deck_uuid}/add_to_consumer"
85
+ payload = { consumer_id: [consumer_uuid] }
86
+ # TODO: Handle a request for a deck that doesn't exist elegantly.
87
+ # Right now this dies on the patch call:
88
+ data = Sraas.api_resource(:patch, url, payload)
89
+ data.code == 200
90
+ end
91
+
92
+ # This is a public method to provide to views parsing JSON in JavaScript
93
+ def consumer_url
94
+ "#{Sraas.consumers_endpoint}/#{consumer_uuid}"
95
+ end
96
+
97
+ private
98
+
99
+ def consumer
100
+ # To get caching from cache prefetch
101
+ Sraas.sraas_consumer_info(consumer_url)
102
+ end
103
+
104
+ def detect_deck_by_name(deck_name)
105
+ template_decks.detect { |deck| deck['name'] == deck_name } || {}
106
+ end
107
+
108
+ def get(url)
109
+ Sraas.api_resource(:get, url)
110
+ end
111
+
112
+ def parse_json(&block)
113
+ JSON.parse(block.call) if block_given?
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,43 @@
1
+ module Sraas
2
+ module HasSraas
3
+ module ClassMethods
4
+ def has_sraas(deck: nil)
5
+ has_one :sraas, as: :sraas_consumerable, class_name: Sraas::Consumer
6
+
7
+ after_create :configure_sraas_consumer!
8
+
9
+ self.sraas_default_deck = deck
10
+ end
11
+ end
12
+
13
+ module LocalInstanceMethods
14
+ def self.included(base)
15
+ base.extend ClassMethods
16
+ base.cattr_accessor(:sraas_default_deck)
17
+ end
18
+
19
+ def configure_sraas_consumer!
20
+ create_sraas(consumer_uuid: new_consumer['id'], sraas_consumerable: self)
21
+ sraas&.add_template_deck_by_name(self.class.sraas_default_deck) if self.class.sraas_default_deck
22
+ end
23
+
24
+ def consumer_id
25
+ sraas&.consumer_uuid || new_consumer['id']
26
+ end
27
+
28
+ private
29
+
30
+ def new_consumer
31
+ Sraas.sraas_consumer_create(email, tags)
32
+ end
33
+
34
+ def tags
35
+ [user_tag]
36
+ end
37
+
38
+ def user_tag
39
+ "user_id=#{id}"
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,7 @@
1
+ module Sraas
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ load File.expand_path('../tasks/sraas_tasks.rake', File.dirname(__FILE__))
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module Sraas
2
+ VERSION = '0.2.3'
3
+ end
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+
3
+ desc 'Copies model and migration to rails app'
4
+ namespace :sraas do
5
+ task :install do
6
+ FileUtils.cp_r(migration_path, rails_migration_path) unless migration_copied?
7
+ FileUtils.cp_r(initializers_path, rails_initializers_path)
8
+ end
9
+ end
10
+
11
+ def migration_copied?
12
+ Dir.glob("#{Dir.pwd}/db/migrate/*create_sraas_consumers.rb").any?
13
+ end
14
+
15
+ def rails_migration_path
16
+ "#{Dir.pwd}/db/migrate/#{next_migration_number}_create_sraas_consumers.rb"
17
+ end
18
+
19
+ def rails_initializers_path
20
+ "#{Dir.pwd}/config/initializers/sraas.rb"
21
+ end
22
+
23
+ def migration_path
24
+ "#{templates_path}/migrate/create_sraas_consumers.rb"
25
+ end
26
+
27
+ def initializers_path
28
+ "#{templates_path}/initializers/sraas.rb"
29
+ end
30
+
31
+ def templates_path
32
+ File.expand_path('templates', File.dirname(__FILE__))
33
+ end
34
+
35
+ def next_migration_number
36
+ Time.now.utc.strftime('%Y%m%d%H%M%S')
37
+ end
@@ -0,0 +1,7 @@
1
+ Sraas.configure do |config|
2
+ # Sraas provider URL
3
+ config.url = 'https://www.sraas.io'
4
+
5
+ # API key
6
+ config.api_key = nil # 'your-api-key'
7
+ end
@@ -0,0 +1,12 @@
1
+ class CreateSraasConsumers < ActiveRecord::Migration[5.0]
2
+ def change
3
+ create_table :sraas_consumers do |t|
4
+ t.string :consumer_uuid
5
+ t.integer :sraas_consumerable_id
6
+ t.string :sraas_consumerable_type
7
+ t.index [:sraas_consumerable_type, :sraas_consumerable_id], name: 'consumerable_idx'
8
+
9
+ t.timestamps
10
+ end
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sraas
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.3
5
+ platform: ruby
6
+ authors:
7
+ - Jonathan Siegel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 5.0.6
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 5.0.6
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
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: minitest
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: rspec
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: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
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: factory_bot
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
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: pry
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: More API gem than is reasonable.
126
+ email: no@nocontact.no
127
+ executables:
128
+ - sraas
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - LICENSE
133
+ - README.md
134
+ - Rakefile
135
+ - bin/sraas
136
+ - lib/sraas.rb
137
+ - lib/sraas/configuration.rb
138
+ - lib/sraas/consumer.rb
139
+ - lib/sraas/has_sraas.rb
140
+ - lib/sraas/railtie.rb
141
+ - lib/sraas/version.rb
142
+ - lib/tasks/sraas_tasks.rake
143
+ - lib/tasks/templates/initializers/sraas.rb
144
+ - lib/tasks/templates/migrate/create_sraas_consumers.rb
145
+ homepage: http://no.no/no
146
+ licenses: []
147
+ metadata: {}
148
+ post_install_message:
149
+ rdoc_options: []
150
+ require_paths:
151
+ - lib
152
+ required_ruby_version: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ version: '0'
157
+ required_rubygems_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ requirements: []
163
+ rubyforge_project:
164
+ rubygems_version: 2.6.12
165
+ signing_key:
166
+ specification_version: 4
167
+ summary: SRAAS.io API Gem
168
+ test_files: []