cachai 0.0.5 → 0.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a68c5c6afde964d4ecd799d7c2e705cde5d95807
4
- data.tar.gz: 10102a0163b14777843eeb6c31a8e5feaa81dff7
3
+ metadata.gz: f79e9baf1b4289c37e88e4208c5fa4ac903b5cf9
4
+ data.tar.gz: b91b0e7f759f7d6c2c95ec5b7ef70a77fecc0a00
5
5
  SHA512:
6
- metadata.gz: 5d177b7ac254f245304d90ef4ace65ea8c80f18107e7c6e6442f9fd88b45e1ca81eef82fb5a8bc2629e67c3d02afbbfaf2cf26abbac5082319ac593ab39f89c8
7
- data.tar.gz: 0dbba4a304b01779cbfd9d27d97c0e1f147dde0cb1f98b1dd5253a7491ff2cfe5e3c9a6f19891ef6d2007a6259372a4c30e604ab95814c16c42219bccea5ec94
6
+ metadata.gz: d8a52ba8af374c0c7f0b3811214963b1ae46e43f6885da2070a15059e184b117110c939ce236b7be92cd65a6b870f87f3bf185d080868f0db408c82299bc4e5f
7
+ data.tar.gz: 9b3576d707f7d9f1120886fecc20b963b918e8d4b64abc822157a039a43a3ffc349f17ea1434a14fc981f0f5d59e8601b1bf374e0ead3dd153fb24f37e7ab7dc
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  db/*.sqlite3
2
+ pkg
data/cachai.gemspec CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "cachai"
7
- spec.version = '0.0.5'
7
+ spec.version = '0.0.7'
8
8
  spec.authors = ["Tomás Pollak"]
9
9
  spec.email = ["tomas@forkhq.com"]
10
10
  spec.description = %q{Middleware for embedabble comments.}
@@ -19,10 +19,12 @@ Gem::Specification.new do |spec|
19
19
 
20
20
  spec.add_development_dependency "bundler", "~> 1.3"
21
21
  spec.add_development_dependency "rspec", "~> 2.6"
22
+ spec.add_development_dependency "rack-test"
22
23
 
23
24
  spec.add_dependency "redis"
24
25
  spec.add_dependency "sinatra"
25
26
  spec.add_dependency "sinatra-activerecord"
26
27
  spec.add_dependency "sqlite3"
27
28
  spec.add_dependency "rake"
29
+ spec.add_dependency "sendgrid-ruby"
28
30
  end
data/db/schema.rb CHANGED
@@ -26,7 +26,7 @@ ActiveRecord::Schema.define(version: 20130901232253) do
26
26
  t.string "author_url"
27
27
  t.string "author_ip", :length => 15
28
28
  t.text "content", :null => false
29
- t.integer "parent_id"
29
+ t.integer "parent_id", :default => 0
30
30
  t.integer "approved", :default => 1, :length => 1, :null => false
31
31
  t.datetime "created_at"
32
32
  t.datetime "updated_at"
data/lib/cachai.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'sinatra/base'
2
+ require 'sendgrid-ruby'
2
3
  require 'redis'
3
4
  require 'json'
4
- require 'rake'
5
5
 
6
6
  require_relative 'models'
7
7
  require_relative 'akismet'
@@ -19,21 +19,28 @@ module Cachai
19
19
  # use Rack::Static, :urls => %w(/css /img /js /favicon.ico), :root => 'public'
20
20
  use ActiveRecord::ConnectionAdapters::ConnectionManagement
21
21
 
22
+ CACHE_MINUTES = 10 * 60 # 10 minutes
23
+
22
24
  def initialize(app, opts = nil)
23
25
  opts = opts || {}
24
- @domain = opts.delete(:domain) or raise 'Domain required.'
26
+ domain = opts.delete(:domain) or raise 'Domain required.'
27
+ redis_host = opts.delete(:redis_host) || 'localhost'
25
28
 
29
+ Cachai.domain = domain
30
+ Cachai.cache = Redis.new(:host => redis_host)
26
31
  Cachai.load_db!
27
32
 
28
- redis_host = opts.delete(:redis_host) || 'localhost'
29
- @redis = Redis.new(:host => redis_host)
30
-
31
33
  if key = opts.delete(:akismet_key)
32
- @akismet = Akismet.new(:api_key => key, :blog => "http://#{@domain}")
34
+ @akismet = Akismet.new(:api_key => key, :blog => "http://#{domain}")
33
35
  else
34
36
  puts "No Akismet key found! Will not check comments for spam."
35
37
  end
36
38
 
39
+ if sendgrid_opts = opts.delete(:sendgrid)
40
+ @sendgrid = SendGrid::Client.new(sendgrid_opts)
41
+ @recipient = opts.delete(:recipient) or raise "No recipient set!"
42
+ end
43
+
37
44
  super(app)
38
45
  end
39
46
 
@@ -48,16 +55,14 @@ module Cachai
48
55
  get '/comments.?:format?' do
49
56
  check_domain!(params[:domain])
50
57
 
51
- @redis.del(redis_key(params[:path])) if params[:nocache]
52
-
53
58
  # puts "Comments for: #{params[:domain]}#{params[:path]}"
54
- json_list = get_comments(params[:path])
59
+ json_list = get_comments(params[:path], params[:nocache])
55
60
 
56
61
  if params[:callback]
57
62
  content_type 'application/javascript'
58
63
  "#{params[:callback]}(#{json_list});"
59
64
  else
60
- json(list)
65
+ json(json_list)
61
66
  end
62
67
  end
63
68
 
@@ -66,8 +71,9 @@ module Cachai
66
71
  data = JSON.parse(request.body.read)
67
72
  check_domain!(data['domain'])
68
73
 
69
- headers['Access-Control-Allow-Origin'] = data['protocol'] + '//' + data['domain']
74
+ halt(400, "Missing params") if data['protocol'].blank? or data['path'].blank?
70
75
 
76
+ headers['Access-Control-Allow-Origin'] = data['protocol'] + '//' + data['domain']
71
77
  permalink = 'http://' + data['domain'] + data['path']
72
78
  halt(400, "No spam allowed") if is_spam?(data, permalink, request)
73
79
 
@@ -76,25 +82,31 @@ module Cachai
76
82
  :author_name => data['author_name'],
77
83
  :author_email => data['author_email'],
78
84
  :author_url => data['author_url'],
79
- :parent_id => data['parent_id'],
85
+ :parent_id => data['parent_id'].to_i,
80
86
  :author_ip => request.ip
81
87
  }
82
88
 
83
89
  post = Post.find_or_create_by_path(data['path'])
84
90
  response = Response.create!(attrs.merge(:post_id => post.id))
91
+ Cachai.clear_cache(data['path'])
92
+ notify_new_response(response, data['path'])
85
93
 
86
- @redis.del(redis_key(data['path']))
87
94
  json({ :status => 'ok', :comment => response })
88
95
 
89
96
  rescue JSON::ParserError
90
97
  status 400 and json({ :error => 'Invalid JSON.' })
91
98
  rescue ActiveRecord::RecordInvalid => e
92
99
  status 422 and json({ :error => e.message })
100
+ rescue => e
101
+ puts e.message
102
+ puts e.backtrace.join("\n")
103
+ status 500 and "Something went wrong."
93
104
  end
94
105
  end
95
106
 
96
107
  private
97
108
 
109
+ =begin
98
110
  def set_cache(timestamp)
99
111
  return if timestamp.nil?
100
112
  last_modified timestamp
@@ -105,9 +117,10 @@ module Cachai
105
117
  cache_control :public, :no_cache, :no_store, :must_revalidate, :max_age => 0
106
118
  # expires 1.year.ago
107
119
  end
120
+ =end
108
121
 
109
122
  def check_domain!(domain)
110
- halt(400, 'Invalid domain.') unless domain == @domain
123
+ halt(400, 'Invalid domain.') unless domain == Cachai.domain
111
124
  end
112
125
 
113
126
  def not_found(message = nil)
@@ -119,9 +132,10 @@ module Cachai
119
132
  return obj.is_a?(String) ? obj : obj.to_json
120
133
  end
121
134
 
122
- def get_comments(path)
123
- key = redis_key(path)
124
- unless json_list = @redis.get(key)
135
+ def get_comments(path, nocache = false)
136
+ key = Cachai.key_for(path)
137
+
138
+ unless !nocache && json_list = Cachai.cache.get(key)
125
139
  puts "Not cached. Getting from DB: #{path}"
126
140
 
127
141
  if post = Post.find_by_path(path)
@@ -130,9 +144,10 @@ module Cachai
130
144
  json_list = '[]'
131
145
  end
132
146
 
133
- @redis.set(key, json_list)
134
- @redis.expire(key, 60 * 60) # one hour
147
+ Cachai.cache.set(key, json_list)
148
+ Cachai.cache.expire(key, CACHE_MINUTES)
135
149
  end
150
+
136
151
  json_list
137
152
  end
138
153
 
@@ -153,22 +168,18 @@ module Cachai
153
168
  result
154
169
  end
155
170
 
156
- def redis_key(path)
157
- "comments:#{@domain}:#{path}"
158
- end
159
-
160
171
  def is_spam?(data, link, request)
161
172
  return false unless @akismet
162
173
  # return true if blacklisted?(name, email, content)
163
174
 
164
175
  comment = {
165
- :user_ip => request.ip,
166
- :referrer => request.referrer,
167
- :user_agent => request.user_agent,
168
- :permalink => link,
169
- :comment_type => 'comment',
170
- :comment_content => data['content'],
171
- :comment_author => data['author_name'],
176
+ :user_ip => request.ip,
177
+ :referrer => request.referrer,
178
+ :user_agent => request.user_agent,
179
+ :permalink => link,
180
+ :comment_type => 'comment',
181
+ :comment_content => data['content'],
182
+ :comment_author => data['author_name'],
172
183
  :comment_author_url => data['author_url'],
173
184
  :comment_author_email => data['author_email']
174
185
  }
@@ -181,6 +192,20 @@ module Cachai
181
192
  false
182
193
  end
183
194
 
195
+ def notify_new_response(response, path)
196
+ mail = SendGrid::Mail.new do |m|
197
+ m.to = @recipient
198
+ m.from = 'comments@' + Cachai.domain
199
+ m.reply_to = response.author_email
200
+ m.subject = "New comment from #{response.author_name} at #{path}"
201
+ m.text = "#{response.content}\n\n--\nhttp://#{Cachai.domain}/#{path}"
202
+ end
203
+
204
+ puts @sendgrid.send(mail)
205
+ rescue SendGrid::Exception => e
206
+ puts e.inspect
207
+ end
208
+
184
209
  end
185
210
 
186
211
  end
data/lib/models.rb CHANGED
@@ -22,6 +22,34 @@ module Cachai
22
22
  # SQLite3::SQLException => e
23
23
  # return !e.message['no such table']
24
24
  false
25
+ rescue ActiveRecord::ConnectionNotEstablished
26
+ puts "Connection not established."
27
+ false
28
+ end
29
+
30
+ def self.domain=(value)
31
+ @domain = value
32
+ end
33
+
34
+ def self.domain
35
+ @domain
36
+ end
37
+
38
+ def self.cache=(obj)
39
+ @cache = obj
40
+ end
41
+
42
+ def self.cache
43
+ @cache
44
+ end
45
+
46
+ def self.clear_cache(path)
47
+ cache.del(key_for(path))
48
+ end
49
+
50
+ def self.key_for(path)
51
+ raise "Domain not set!" unless @domain
52
+ "comments:#{@domain}:#{path}"
25
53
  end
26
54
 
27
55
  class Post < ActiveRecord::Base
@@ -34,11 +62,14 @@ module Cachai
34
62
  find_by_path(path) || create({:path => path})
35
63
  end
36
64
 
65
+ def clear_cache
66
+ Cachai.clear_cache(path)
67
+ end
37
68
  end
38
69
 
39
70
  class Response < ActiveRecord::Base
40
71
  belongs_to :post
41
- validates_presence_of :author_name, :author_name, :author_email, :content
72
+ validates_presence_of :author_name, :author_email, :content
42
73
 
43
74
  scope :approved, lambda { where(:approved => 1) }
44
75
  scope :comment, lambda { where(:response_type => 'comment') }
@@ -0,0 +1,206 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'get comments' do
4
+ include Rack::Test::Methods
5
+
6
+ def app
7
+ TestApp
8
+ end
9
+
10
+ describe 'no domain' do
11
+
12
+ it 'returns 400' do
13
+ get '/comments.json', :path => '/foobar'
14
+ puts last_response.body
15
+ last_response.status.should == 400
16
+ end
17
+
18
+ end
19
+
20
+ describe 'no path' do
21
+
22
+ it 'returns 400' do
23
+ get '/comments.json', :domain => 'invalid.com'
24
+ last_response.status.should == 400
25
+ end
26
+
27
+ end
28
+
29
+ describe 'existing domain and path' do
30
+
31
+ describe 'invalid domain' do
32
+
33
+ it 'returns 400' do
34
+ get '/comments.json', :domain => 'invalid.com'
35
+ last_response.status.should == 400
36
+ end
37
+
38
+ end
39
+
40
+ describe 'valid domain' do
41
+
42
+ let(:cache_key) { Cachai.key_for('/blog/post.html') }
43
+
44
+ before do
45
+ Cachai.cache.del(cache_key)
46
+ end
47
+
48
+ describe 'unexisting post' do
49
+
50
+ it 'returns 200' do
51
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
52
+ last_response.status.should == 200
53
+ end
54
+
55
+ it 'returns an empty JSON array' do
56
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
57
+ last_response.body.should == '[]'
58
+ end
59
+
60
+ it 'does not create a new entry for that post' do
61
+ expect do
62
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
63
+ end.not_to change(Cachai::Post, :count)
64
+ end
65
+
66
+ end
67
+
68
+ describe 'existing post, no comments' do
69
+
70
+ before do
71
+ Cachai::Post.create(:path => '/blog/post.html')
72
+ Cachai::Post.count.should == 1
73
+ end
74
+
75
+ it 'returns 200' do
76
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
77
+ last_response.status.should == 200
78
+ end
79
+
80
+ it 'queries the database' do
81
+ # ActiveRecord::Base.should_receive(:query)
82
+ Cachai::Post.should_receive(:find_by_path)
83
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
84
+ end
85
+
86
+ it 'returns an empty JSON array' do
87
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
88
+ last_response.body.should == '[]'
89
+ end
90
+
91
+ end
92
+
93
+ describe 'existing post, with comments' do
94
+
95
+ before do
96
+ Cachai::Post.delete_all
97
+
98
+ post = Cachai::Post.create(:path => '/blog/post.html')
99
+ Cachai::Post.count.should == 1
100
+
101
+ post.responses.create({
102
+ :content => 'Foobar',
103
+ :author_name => 'Someone',
104
+ :author_email => 'test@email.com'
105
+ })
106
+
107
+ post.responses.count.should == 1
108
+ end
109
+
110
+ describe 'not in cache' do
111
+
112
+ before do
113
+ Cachai.cache.get(cache_key).should be_nil
114
+ end
115
+
116
+ it 'returns 200' do
117
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
118
+ last_response.status.should == 200
119
+ end
120
+
121
+ it 'queries the database' do
122
+ # ActiveRecord::Base.connection.should_receive(:execute)
123
+ Cachai::Post.should_receive(:find_by_path)
124
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
125
+ end
126
+
127
+ it 'returns an JSON array with comment' do
128
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
129
+ data = JSON.parse(last_response.body)
130
+ data.count.should == 1
131
+ end
132
+
133
+ it 'stores data in cache' do
134
+ Cachai.cache.should_receive(:set)
135
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
136
+ end
137
+
138
+ end
139
+
140
+ describe 'in cache' do
141
+
142
+ before do
143
+ Cachai.cache.set(cache_key, 'something')
144
+ Cachai.cache.get(cache_key).should == 'something'
145
+ end
146
+
147
+ describe 'without nocache param' do
148
+
149
+ it 'returns 200' do
150
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
151
+ last_response.status.should == 200
152
+ end
153
+
154
+ it 'does not query the database' do
155
+ # ActiveRecord::Base.should_not_receive(:query)
156
+ Cachai::Post.should_not_receive(:find_by_path)
157
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
158
+ end
159
+
160
+ it 'returns an JSON array with comment' do
161
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
162
+ last_response.body.should == 'something'
163
+ end
164
+
165
+ it 'does not store data in cache' do
166
+ Cachai.cache.should_not_receive(:set)
167
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
168
+ end
169
+
170
+ end
171
+
172
+ describe 'with nocache=1' do
173
+
174
+ it 'returns 200' do
175
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
176
+ last_response.status.should == 200
177
+ end
178
+
179
+ it 'queries the database' do
180
+ # ActiveRecord::Base.should_receive(:query)
181
+ Cachai::Post.should_receive(:find_by_path)
182
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
183
+ end
184
+
185
+ it 'returns an JSON array with comment' do
186
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
187
+ data = JSON.parse(last_response.body)
188
+ data.count.should == 1
189
+ end
190
+
191
+ it 'stores data in cache' do
192
+ Cachai.cache.should_receive(:set)
193
+ get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
194
+ end
195
+
196
+ end
197
+
198
+ end
199
+
200
+ end
201
+
202
+ end
203
+
204
+ end
205
+
206
+ end
@@ -0,0 +1,135 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe 'post comment' do
4
+ include Rack::Test::Methods
5
+
6
+ def app
7
+ TestApp
8
+ end
9
+
10
+ def post_comment(opts = {})
11
+ data = {
12
+ :domain => 'domain.com',
13
+ :protocol => 'http',
14
+ :path => '/another/blog/post.html',
15
+ :content => 'New comment',
16
+ :author_name => 'Some author',
17
+ :author_email => 'test@email.com',
18
+ :author_url => 'http://url.com'
19
+ }.merge(opts)
20
+ post '/comments.json', data.to_json, { 'CONTENT_TYPE' => 'application/json' }
21
+ end
22
+
23
+ describe 'no domain' do
24
+
25
+ it 'returns 400' do
26
+ post_comment :domain => nil
27
+ puts last_response.body
28
+ last_response.status.should == 400
29
+ end
30
+
31
+ end
32
+
33
+ describe 'no protocol' do
34
+
35
+ it 'returns 400' do
36
+ post_comment :protocol => nil
37
+ last_response.status.should == 400
38
+ end
39
+
40
+ end
41
+
42
+ describe 'no path' do
43
+
44
+ it 'returns 400' do
45
+ post_comment :path => nil
46
+ last_response.status.should == 400
47
+ end
48
+
49
+ end
50
+
51
+ describe 'existing domain and path' do
52
+
53
+ describe 'invalid domain' do
54
+
55
+ it 'returns 400' do
56
+ post_comment :domain => 'invalid.com'
57
+ last_response.status.should == 400
58
+ end
59
+
60
+ end
61
+
62
+ describe 'valid domain' do
63
+
64
+ describe 'no author name' do
65
+
66
+ it 'returns 422' do
67
+ post_comment :author_name => nil
68
+ last_response.status.should == 422
69
+ end
70
+
71
+ end
72
+
73
+ describe 'no email' do
74
+
75
+ it 'returns 422' do
76
+ post_comment :author_email => nil
77
+ last_response.status.should == 422
78
+ end
79
+
80
+ end
81
+
82
+ describe 'no content' do
83
+
84
+ it 'returns 422' do
85
+ post_comment :content => nil
86
+ last_response.status.should == 422
87
+ end
88
+
89
+ end
90
+
91
+ describe 'valid data' do
92
+
93
+ describe 'unexisting post' do
94
+
95
+ before do
96
+ Cachai::Post.delete_all
97
+ end
98
+
99
+ it 'creates a new entry for that post' do
100
+ expect do
101
+ post_comment
102
+ end.to change(Cachai::Post, :count).by(1)
103
+ end
104
+
105
+ it 'creates a new response for that post' do
106
+ expect do
107
+ post_comment
108
+ end.to change(Cachai::Response, :count).by(1)
109
+ end
110
+
111
+ end
112
+
113
+ describe 'existing post' do
114
+
115
+ it 'does not create a new post entry' do
116
+ expect do
117
+ post_comment
118
+ end.not_to change(Cachai::Post, :count).by(1)
119
+ end
120
+
121
+ it 'creates a new response for that post' do
122
+ expect do
123
+ post_comment
124
+ end.to change(Cachai::Response, :count).by(1)
125
+ end
126
+
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,30 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'bundler/setup'
4
+ require 'active_record'
5
+ require 'cachai'
6
+ require 'rack/test'
7
+
8
+ ActiveRecord::Base.establish_connection(
9
+ "adapter" => "sqlite3",
10
+ "database" => ':memory:'
11
+ )
12
+
13
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
14
+
15
+ # this is done automatically by cachai
16
+ # load File.join(File.dirname(__FILE__), '/../db/schema.rb')
17
+
18
+ class TestApp < Sinatra::Base
19
+ use Cachai::Middleware, {
20
+ :domain => 'domain.com',
21
+ :recipient => 'test@example.com',
22
+ :sendgrid => {
23
+ :api_key => 'test',
24
+ :api_user => 'test'
25
+ }
26
+ }
27
+ get '/' do
28
+ 'Hello world'
29
+ end
30
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cachai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomás Pollak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-25 00:00:00.000000000 Z
11
+ date: 2015-09-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack-test
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'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: redis
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,20 @@ dependencies:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sendgrid-ruby
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'
111
139
  description: Middleware for embedabble comments.
112
140
  email:
113
141
  - tomas@forkhq.com
@@ -117,7 +145,6 @@ extra_rdoc_files: []
117
145
  files:
118
146
  - ".gitignore"
119
147
  - Gemfile
120
- - Gemfile.lock
121
148
  - Procfile
122
149
  - README.md
123
150
  - Rakefile
@@ -127,6 +154,9 @@ files:
127
154
  - lib/cachai.rb
128
155
  - lib/models.rb
129
156
  - lib/time_ago.rb
157
+ - spec/get_comments_test.rb
158
+ - spec/post_comments_test.rb
159
+ - spec/spec_helper.rb
130
160
  - test/app_test.rb
131
161
  homepage: ''
132
162
  licenses:
@@ -148,9 +178,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
178
  version: '0'
149
179
  requirements: []
150
180
  rubyforge_project:
151
- rubygems_version: 2.4.5
181
+ rubygems_version: 2.2.0
152
182
  signing_key:
153
183
  specification_version: 4
154
184
  summary: Middleware for embedabble comments.
155
185
  test_files:
186
+ - spec/get_comments_test.rb
187
+ - spec/post_comments_test.rb
188
+ - spec/spec_helper.rb
156
189
  - test/app_test.rb
190
+ has_rdoc:
data/Gemfile.lock DELETED
@@ -1,63 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- cachai (0.0.1)
5
- rake
6
- sinatra
7
- sinatra-activerecord
8
- sqlite3
9
-
10
- GEM
11
- remote: http://rubygems.org/
12
- specs:
13
- activemodel (4.2.1)
14
- activesupport (= 4.2.1)
15
- builder (~> 3.1)
16
- activerecord (4.2.1)
17
- activemodel (= 4.2.1)
18
- activesupport (= 4.2.1)
19
- arel (~> 6.0)
20
- activesupport (4.2.1)
21
- i18n (~> 0.7)
22
- json (~> 1.7, >= 1.7.7)
23
- minitest (~> 5.1)
24
- thread_safe (~> 0.3, >= 0.3.4)
25
- tzinfo (~> 1.1)
26
- arel (6.0.0)
27
- builder (3.2.2)
28
- diff-lcs (1.2.5)
29
- i18n (0.7.0)
30
- json (1.8.3)
31
- minitest (5.7.0)
32
- rack (1.6.1)
33
- rack-protection (1.5.3)
34
- rack
35
- rake (10.4.2)
36
- rspec (2.99.0)
37
- rspec-core (~> 2.99.0)
38
- rspec-expectations (~> 2.99.0)
39
- rspec-mocks (~> 2.99.0)
40
- rspec-core (2.99.2)
41
- rspec-expectations (2.99.2)
42
- diff-lcs (>= 1.1.3, < 2.0)
43
- rspec-mocks (2.99.3)
44
- sinatra (1.4.6)
45
- rack (~> 1.4)
46
- rack-protection (~> 1.4)
47
- tilt (>= 1.3, < 3)
48
- sinatra-activerecord (2.0.6)
49
- activerecord (>= 3.2)
50
- sinatra (~> 1.0)
51
- sqlite3 (1.3.10)
52
- thread_safe (0.3.5)
53
- tilt (2.0.1)
54
- tzinfo (1.2.2)
55
- thread_safe (~> 0.1)
56
-
57
- PLATFORMS
58
- ruby
59
-
60
- DEPENDENCIES
61
- bundler (~> 1.3)
62
- cachai!
63
- rspec (~> 2.6)