smooth-io 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +2 -0
  2. data/.rvmrc +1 -0
  3. data/.travis +6 -0
  4. data/CNAME +1 -0
  5. data/Gemfile +13 -0
  6. data/Gemfile.lock +147 -0
  7. data/Guardfile +5 -0
  8. data/LICENSE.md +22 -0
  9. data/README.md +33 -0
  10. data/Rakefile +10 -0
  11. data/bin/smooth +8 -0
  12. data/doc/presenters.md +47 -0
  13. data/lib/smooth.rb +56 -0
  14. data/lib/smooth/adapters/rails_cache.rb +19 -0
  15. data/lib/smooth/adapters/redis_cache.rb +36 -0
  16. data/lib/smooth/backends/active_record.rb +56 -0
  17. data/lib/smooth/backends/base.rb +84 -0
  18. data/lib/smooth/backends/file.rb +80 -0
  19. data/lib/smooth/backends/redis.rb +71 -0
  20. data/lib/smooth/backends/redis_namespace.rb +10 -0
  21. data/lib/smooth/backends/rest_client.rb +29 -0
  22. data/lib/smooth/collection.rb +236 -0
  23. data/lib/smooth/collection/cacheable.rb +12 -0
  24. data/lib/smooth/collection/query.rb +14 -0
  25. data/lib/smooth/endpoint.rb +23 -0
  26. data/lib/smooth/meta_data.rb +33 -0
  27. data/lib/smooth/meta_data/application.rb +29 -0
  28. data/lib/smooth/meta_data/inspector.rb +67 -0
  29. data/lib/smooth/model.rb +93 -0
  30. data/lib/smooth/presentable.rb +76 -0
  31. data/lib/smooth/presentable/api_endpoint.rb +49 -0
  32. data/lib/smooth/presentable/chain.rb +46 -0
  33. data/lib/smooth/presentable/controller.rb +39 -0
  34. data/lib/smooth/queryable.rb +35 -0
  35. data/lib/smooth/queryable/converter.rb +8 -0
  36. data/lib/smooth/queryable/settings.rb +23 -0
  37. data/lib/smooth/resource.rb +10 -0
  38. data/lib/smooth/version.rb +3 -0
  39. data/smooth-io.gemspec +35 -0
  40. data/spec/blueprints/people.rb +4 -0
  41. data/spec/environment.rb +17 -0
  42. data/spec/lib/backends/active_record_spec.rb +17 -0
  43. data/spec/lib/backends/base_spec.rb +77 -0
  44. data/spec/lib/backends/file_spec.rb +46 -0
  45. data/spec/lib/backends/multi_spec.rb +47 -0
  46. data/spec/lib/backends/redis_namespace_spec.rb +41 -0
  47. data/spec/lib/backends/redis_spec.rb +40 -0
  48. data/spec/lib/backends/rest_client_spec.rb +0 -0
  49. data/spec/lib/collection/query_spec.rb +9 -0
  50. data/spec/lib/collection_spec.rb +87 -0
  51. data/spec/lib/examples/cacheable_collection_spec.rb +27 -0
  52. data/spec/lib/examples/smooth_model_spec.rb +13 -0
  53. data/spec/lib/meta_data/application_spec.rb +43 -0
  54. data/spec/lib/meta_data_spec.rb +32 -0
  55. data/spec/lib/model_spec.rb +54 -0
  56. data/spec/lib/presentable/api_endpoint_spec.rb +54 -0
  57. data/spec/lib/presentable_spec.rb +80 -0
  58. data/spec/lib/queryable/converter_spec.rb +104 -0
  59. data/spec/lib/queryable_spec.rb +27 -0
  60. data/spec/lib/resource_spec.rb +17 -0
  61. data/spec/lib/smooth_spec.rb +13 -0
  62. data/spec/spec_helper.rb +23 -0
  63. data/spec/support/models.rb +28 -0
  64. data/spec/support/schema.rb +16 -0
  65. metadata +359 -0
@@ -0,0 +1,2 @@
1
+ tmp
2
+ site
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3-p392@smooth --create
data/.travis ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ branches:
5
+ only:
6
+ - master
data/CNAME ADDED
@@ -0,0 +1 @@
1
+ smooth.io
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+ gemspec
3
+
4
+ group :development, :test do
5
+ gem 'rspec'
6
+ gem "rake"
7
+ gem 'fakeredis'
8
+ gem 'guard'
9
+ gem 'rb-fsevent'
10
+ gem 'growl'
11
+ gem 'guard-bundler'
12
+ gem 'guard-rspec'
13
+ end
@@ -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)
@@ -0,0 +1,5 @@
1
+ guard 'rspec' do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec/" }
5
+ end
@@ -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.
@@ -0,0 +1,33 @@
1
+ # Smooth.io
2
+ [![Build Status](https://travis-ci.org/datapimp/smooth.png?branch=master)](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
+
@@ -0,0 +1,10 @@
1
+ require 'bundler/setup'
2
+ require 'rspec/core/rake_task'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |rspec|
7
+ rspec.rspec_opts = ['--backtrace']
8
+ end
9
+
10
+ task :default => :spec
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'smooth'
5
+ rescue
6
+ require 'rubygems'
7
+ require 'smooth'
8
+ end
@@ -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
+
@@ -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