smooth-io 0.0.5
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.
- data/.gitignore +2 -0
- data/.rvmrc +1 -0
- data/.travis +6 -0
- data/CNAME +1 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +147 -0
- data/Guardfile +5 -0
- data/LICENSE.md +22 -0
- data/README.md +33 -0
- data/Rakefile +10 -0
- data/bin/smooth +8 -0
- data/doc/presenters.md +47 -0
- data/lib/smooth.rb +56 -0
- data/lib/smooth/adapters/rails_cache.rb +19 -0
- data/lib/smooth/adapters/redis_cache.rb +36 -0
- data/lib/smooth/backends/active_record.rb +56 -0
- data/lib/smooth/backends/base.rb +84 -0
- data/lib/smooth/backends/file.rb +80 -0
- data/lib/smooth/backends/redis.rb +71 -0
- data/lib/smooth/backends/redis_namespace.rb +10 -0
- data/lib/smooth/backends/rest_client.rb +29 -0
- data/lib/smooth/collection.rb +236 -0
- data/lib/smooth/collection/cacheable.rb +12 -0
- data/lib/smooth/collection/query.rb +14 -0
- data/lib/smooth/endpoint.rb +23 -0
- data/lib/smooth/meta_data.rb +33 -0
- data/lib/smooth/meta_data/application.rb +29 -0
- data/lib/smooth/meta_data/inspector.rb +67 -0
- data/lib/smooth/model.rb +93 -0
- data/lib/smooth/presentable.rb +76 -0
- data/lib/smooth/presentable/api_endpoint.rb +49 -0
- data/lib/smooth/presentable/chain.rb +46 -0
- data/lib/smooth/presentable/controller.rb +39 -0
- data/lib/smooth/queryable.rb +35 -0
- data/lib/smooth/queryable/converter.rb +8 -0
- data/lib/smooth/queryable/settings.rb +23 -0
- data/lib/smooth/resource.rb +10 -0
- data/lib/smooth/version.rb +3 -0
- data/smooth-io.gemspec +35 -0
- data/spec/blueprints/people.rb +4 -0
- data/spec/environment.rb +17 -0
- data/spec/lib/backends/active_record_spec.rb +17 -0
- data/spec/lib/backends/base_spec.rb +77 -0
- data/spec/lib/backends/file_spec.rb +46 -0
- data/spec/lib/backends/multi_spec.rb +47 -0
- data/spec/lib/backends/redis_namespace_spec.rb +41 -0
- data/spec/lib/backends/redis_spec.rb +40 -0
- data/spec/lib/backends/rest_client_spec.rb +0 -0
- data/spec/lib/collection/query_spec.rb +9 -0
- data/spec/lib/collection_spec.rb +87 -0
- data/spec/lib/examples/cacheable_collection_spec.rb +27 -0
- data/spec/lib/examples/smooth_model_spec.rb +13 -0
- data/spec/lib/meta_data/application_spec.rb +43 -0
- data/spec/lib/meta_data_spec.rb +32 -0
- data/spec/lib/model_spec.rb +54 -0
- data/spec/lib/presentable/api_endpoint_spec.rb +54 -0
- data/spec/lib/presentable_spec.rb +80 -0
- data/spec/lib/queryable/converter_spec.rb +104 -0
- data/spec/lib/queryable_spec.rb +27 -0
- data/spec/lib/resource_spec.rb +17 -0
- data/spec/lib/smooth_spec.rb +13 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/support/models.rb +28 -0
- data/spec/support/schema.rb +16 -0
- metadata +359 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.3-p392@smooth --create
|
data/.travis
ADDED
data/CNAME
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
smooth.io
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
smooth (0.0.5)
|
5
|
+
activerecord (>= 3.2.12)
|
6
|
+
activesupport (>= 3.2.12)
|
7
|
+
faye
|
8
|
+
redis
|
9
|
+
redis-namespace
|
10
|
+
sinatra
|
11
|
+
squeel
|
12
|
+
typhoeus
|
13
|
+
virtus (= 0.5.5)
|
14
|
+
|
15
|
+
GEM
|
16
|
+
remote: https://rubygems.org/
|
17
|
+
specs:
|
18
|
+
activemodel (3.2.13)
|
19
|
+
activesupport (= 3.2.13)
|
20
|
+
builder (~> 3.0.0)
|
21
|
+
activerecord (3.2.13)
|
22
|
+
activemodel (= 3.2.13)
|
23
|
+
activesupport (= 3.2.13)
|
24
|
+
arel (~> 3.0.2)
|
25
|
+
tzinfo (~> 0.3.29)
|
26
|
+
activesupport (3.2.13)
|
27
|
+
i18n (= 0.6.1)
|
28
|
+
multi_json (~> 1.0)
|
29
|
+
addressable (2.3.5)
|
30
|
+
arel (3.0.2)
|
31
|
+
backports (3.3.4)
|
32
|
+
builder (3.0.4)
|
33
|
+
coderay (1.0.9)
|
34
|
+
cookiejar (0.3.0)
|
35
|
+
descendants_tracker (0.0.1)
|
36
|
+
diff-lcs (1.2.1)
|
37
|
+
em-http-request (1.1.0)
|
38
|
+
addressable (>= 2.3.4)
|
39
|
+
cookiejar
|
40
|
+
em-socksify (>= 0.3)
|
41
|
+
eventmachine (>= 1.0.3)
|
42
|
+
http_parser.rb (>= 0.6.0.beta.2)
|
43
|
+
em-socksify (0.3.0)
|
44
|
+
eventmachine (>= 1.0.0.beta.4)
|
45
|
+
ethon (0.6.1)
|
46
|
+
ffi (>= 1.3.0)
|
47
|
+
mime-types (~> 1.18)
|
48
|
+
eventmachine (1.0.3)
|
49
|
+
faker (0.9.5)
|
50
|
+
i18n (~> 0.4)
|
51
|
+
fakeredis (0.4.1)
|
52
|
+
redis (~> 3.0.0)
|
53
|
+
faye (0.8.9)
|
54
|
+
cookiejar (>= 0.3.0)
|
55
|
+
em-http-request (>= 0.3.0)
|
56
|
+
eventmachine (>= 0.12.0)
|
57
|
+
faye-websocket (>= 0.4.0)
|
58
|
+
rack (>= 1.0.0)
|
59
|
+
yajl-ruby (>= 1.0.0)
|
60
|
+
faye-websocket (0.7.0)
|
61
|
+
eventmachine (>= 0.12.0)
|
62
|
+
websocket-driver (>= 0.3.0)
|
63
|
+
ffi (1.9.0)
|
64
|
+
growl (1.0.3)
|
65
|
+
guard (1.6.2)
|
66
|
+
listen (>= 0.6.0)
|
67
|
+
lumberjack (>= 1.0.2)
|
68
|
+
pry (>= 0.9.10)
|
69
|
+
terminal-table (>= 1.4.3)
|
70
|
+
thor (>= 0.14.6)
|
71
|
+
guard-bundler (1.0.0)
|
72
|
+
bundler (~> 1.0)
|
73
|
+
guard (~> 1.1)
|
74
|
+
guard-rspec (2.4.1)
|
75
|
+
guard (>= 1.1)
|
76
|
+
rspec (~> 2.11)
|
77
|
+
http_parser.rb (0.6.0.beta.2)
|
78
|
+
i18n (0.6.1)
|
79
|
+
listen (0.7.3)
|
80
|
+
lumberjack (1.0.2)
|
81
|
+
machinist (1.0.6)
|
82
|
+
method_source (0.8.1)
|
83
|
+
mime-types (1.25)
|
84
|
+
multi_json (1.8.0)
|
85
|
+
polyamorous (0.6.4)
|
86
|
+
activerecord (>= 3.0)
|
87
|
+
pry (0.9.12)
|
88
|
+
coderay (~> 1.0.5)
|
89
|
+
method_source (~> 0.8)
|
90
|
+
slop (~> 3.4)
|
91
|
+
rack (1.5.2)
|
92
|
+
rack-protection (1.5.0)
|
93
|
+
rack
|
94
|
+
rack-test (0.6.2)
|
95
|
+
rack (>= 1.0)
|
96
|
+
rake (10.0.3)
|
97
|
+
rb-fsevent (0.9.3)
|
98
|
+
redis (3.0.2)
|
99
|
+
redis-namespace (1.3.1)
|
100
|
+
redis (~> 3.0.0)
|
101
|
+
rspec (2.13.0)
|
102
|
+
rspec-core (~> 2.13.0)
|
103
|
+
rspec-expectations (~> 2.13.0)
|
104
|
+
rspec-mocks (~> 2.13.0)
|
105
|
+
rspec-core (2.13.0)
|
106
|
+
rspec-expectations (2.13.0)
|
107
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
108
|
+
rspec-mocks (2.13.0)
|
109
|
+
sinatra (1.4.3)
|
110
|
+
rack (~> 1.4)
|
111
|
+
rack-protection (~> 1.4)
|
112
|
+
tilt (~> 1.3, >= 1.3.4)
|
113
|
+
slop (3.4.3)
|
114
|
+
sqlite3 (1.3.7)
|
115
|
+
squeel (1.1.1)
|
116
|
+
activerecord (>= 3.0)
|
117
|
+
activesupport (>= 3.0)
|
118
|
+
polyamorous (~> 0.6.0)
|
119
|
+
terminal-table (1.4.5)
|
120
|
+
thor (0.17.0)
|
121
|
+
tilt (1.4.1)
|
122
|
+
typhoeus (0.6.5)
|
123
|
+
ethon (~> 0.6.1)
|
124
|
+
tzinfo (0.3.37)
|
125
|
+
virtus (0.5.5)
|
126
|
+
backports (~> 3.3)
|
127
|
+
descendants_tracker (~> 0.0.1)
|
128
|
+
websocket-driver (0.3.0)
|
129
|
+
yajl-ruby (1.1.0)
|
130
|
+
|
131
|
+
PLATFORMS
|
132
|
+
ruby
|
133
|
+
|
134
|
+
DEPENDENCIES
|
135
|
+
faker (~> 0.9.5)
|
136
|
+
fakeredis
|
137
|
+
growl
|
138
|
+
guard
|
139
|
+
guard-bundler
|
140
|
+
guard-rspec
|
141
|
+
machinist (~> 1.0.6)
|
142
|
+
rack-test
|
143
|
+
rake
|
144
|
+
rb-fsevent
|
145
|
+
rspec
|
146
|
+
smooth!
|
147
|
+
sqlite3 (~> 1.3.3)
|
data/Guardfile
ADDED
data/LICENSE.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
MIT Copyright (c) 2010-2013 Jonathan Soeder
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Smooth.io
|
2
|
+
[](https://travis-ci.org/datapimp/smooth)
|
3
|
+
|
4
|
+
### Syncable Cross Platform Persistence
|
5
|
+
|
6
|
+
Smooth.io is provides a free JSON API out of the box, with a declarative syntax
|
7
|
+
to control who can query the API, and what they are able to see.
|
8
|
+
|
9
|
+
Smooth resources expose configuration data in their API endpoints that
|
10
|
+
allow for API clients to discover reource, configure themselves to the data schema.
|
11
|
+
|
12
|
+
Smooth resources have automatic caching with smart expiration, and built in HTTP cache control.
|
13
|
+
|
14
|
+
- Swappable Storage Backends
|
15
|
+
- [ ] Redis Backend
|
16
|
+
- [ ] File Backend
|
17
|
+
- [ ] ActiveRecord Backend
|
18
|
+
|
19
|
+
- Query Interfaces
|
20
|
+
- [ ] Squeel
|
21
|
+
- [ ] Backbone-Query
|
22
|
+
|
23
|
+
- REST Interfaces
|
24
|
+
- [ ] Rails Controller
|
25
|
+
- [ ] Restful Sinatra App
|
26
|
+
- [ ] Faye Pub/Sub fo Auto-Syncing
|
27
|
+
|
28
|
+
- Clients / Syncing
|
29
|
+
- [ ] Ruby
|
30
|
+
- [ ] Coffeescript
|
31
|
+
- [ ] iOS
|
32
|
+
- [ ] Android
|
33
|
+
|
data/Rakefile
ADDED
data/bin/smooth
ADDED
data/doc/presenters.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
## Presenters
|
2
|
+
|
3
|
+
Smooth::Resource classes expose an API for querying data, presenting it
|
4
|
+
it as a desired view, and customizing that presentation for the role of
|
5
|
+
the user querying the API.
|
6
|
+
|
7
|
+
Given the following model configuration:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
class Person < ActiveRecord::Base
|
11
|
+
include Smooth::Resource
|
12
|
+
end
|
13
|
+
|
14
|
+
class PersonPresenter
|
15
|
+
def self.default
|
16
|
+
[:name, :public_profile_attributes]
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.admin_default
|
20
|
+
default + [:coolness_rating, :black_listed?]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
We will eventually query this resource through the Smooth::Presentable::Controller
|
26
|
+
and will end up making our call to the Query API via the following
|
27
|
+
chain:
|
28
|
+
|
29
|
+
If we are an admin:
|
30
|
+
|
31
|
+
```
|
32
|
+
# uses the admin_default presenter
|
33
|
+
Person.present(query).as(:default).to(:admin)
|
34
|
+
```
|
35
|
+
|
36
|
+
If we are something else, that is not defined, it defaults:
|
37
|
+
|
38
|
+
```
|
39
|
+
# uses the default presenter
|
40
|
+
Person.present(query).as(:default).to(:something_else)
|
41
|
+
```
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
data/lib/smooth.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'active_support/core_ext'
|
2
|
+
require 'active_record'
|
3
|
+
require 'typhoeus'
|
4
|
+
require 'redis'
|
5
|
+
require 'redis-namespace'
|
6
|
+
require 'squeel'
|
7
|
+
require 'virtus'
|
8
|
+
|
9
|
+
module Smooth
|
10
|
+
mattr_accessor :data_directory, :namespace
|
11
|
+
|
12
|
+
def self.namespace
|
13
|
+
@@namespace || "smooth"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.project
|
17
|
+
if defined?(::Rails)
|
18
|
+
Rails.application.class.to_s
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.environment
|
23
|
+
ENV['RAILS_ENV'] || ENV['SMOOTH_ENV'] || "development"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.data_directory
|
27
|
+
@@data_directory || File.join(ENV['HOME'],'.smooth',environment)
|
28
|
+
end
|
29
|
+
|
30
|
+
require 'smooth/version'
|
31
|
+
require 'smooth/meta_data'
|
32
|
+
require 'smooth/meta_data/application'
|
33
|
+
|
34
|
+
require 'smooth/queryable'
|
35
|
+
|
36
|
+
require 'smooth/presentable/chain'
|
37
|
+
require 'smooth/presentable/controller'
|
38
|
+
require 'smooth/presentable/api_endpoint'
|
39
|
+
require 'smooth/presentable'
|
40
|
+
|
41
|
+
require 'smooth/backends/base'
|
42
|
+
require 'smooth/backends/active_record'
|
43
|
+
require 'smooth/backends/file'
|
44
|
+
require 'smooth/backends/redis'
|
45
|
+
require 'smooth/backends/redis_namespace'
|
46
|
+
require 'smooth/backends/rest_client'
|
47
|
+
|
48
|
+
require 'smooth/adapters/redis_cache.rb'
|
49
|
+
|
50
|
+
require 'smooth/model'
|
51
|
+
require 'smooth/collection/cacheable'
|
52
|
+
require 'smooth/collection/query'
|
53
|
+
|
54
|
+
require 'smooth/collection'
|
55
|
+
require "smooth/resource"
|
56
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Smooth
|
2
|
+
module Adapters
|
3
|
+
class RailsCache
|
4
|
+
|
5
|
+
def get key
|
6
|
+
Rails.cache.get(key)
|
7
|
+
end
|
8
|
+
|
9
|
+
def write key, value
|
10
|
+
Rails.cache.write(key, value)
|
11
|
+
value
|
12
|
+
end
|
13
|
+
|
14
|
+
def fetch key, &block
|
15
|
+
Rails.cache.fetch key, &block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Smooth
|
2
|
+
module Adapters
|
3
|
+
class RedisCache
|
4
|
+
attr_accessor :redis
|
5
|
+
|
6
|
+
def initialize redis, options={}
|
7
|
+
if redis.is_a?(Hash)
|
8
|
+
options = redis
|
9
|
+
redis = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
@redis = redis || Redis.new(options)
|
13
|
+
end
|
14
|
+
|
15
|
+
def get key
|
16
|
+
redis.get(key)
|
17
|
+
end
|
18
|
+
|
19
|
+
def write key, value
|
20
|
+
redis.set(key, value)
|
21
|
+
value
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch key
|
25
|
+
result = get(key)
|
26
|
+
|
27
|
+
if result.nil? and block_given?
|
28
|
+
fallback = yield
|
29
|
+
result = write(key, fallback)
|
30
|
+
end
|
31
|
+
|
32
|
+
result
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Smooth
|
2
|
+
module Backends
|
3
|
+
class ActiveRecord < Base
|
4
|
+
|
5
|
+
attr_accessor :model
|
6
|
+
|
7
|
+
def initialize options={}
|
8
|
+
super
|
9
|
+
if @model = options[:model]
|
10
|
+
model.send(:include, Smooth::Backends::ActiveRecord::QueryAdapter)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def query params={}
|
15
|
+
model.respond_to?(:query) ? model.query(params) : model.smooth_query(params)
|
16
|
+
end
|
17
|
+
|
18
|
+
def index
|
19
|
+
model.scoped
|
20
|
+
end
|
21
|
+
|
22
|
+
def show id
|
23
|
+
model.find(id)
|
24
|
+
end
|
25
|
+
|
26
|
+
def update attributes
|
27
|
+
record = model.find(attributes[:id])
|
28
|
+
record.update_attributes(attributes)
|
29
|
+
record
|
30
|
+
end
|
31
|
+
|
32
|
+
def destroy id
|
33
|
+
!!(model = model.find(id) && model.destroy)
|
34
|
+
end
|
35
|
+
|
36
|
+
def create attributes
|
37
|
+
record = model.create(attributes)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module ActiveRecord::QueryAdapter
|
42
|
+
|
43
|
+
module ClassMethods
|
44
|
+
def smooth_query params={}
|
45
|
+
scoped
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.included(receiver)
|
50
|
+
receiver.extend ClassMethods
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|