cachai 0.0.5 → 0.0.7

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