sraas 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []