cachai 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/cachai.gemspec +1 -1
- data/db/schema.rb +18 -3
- data/lib/cachai.rb +40 -21
- data/lib/models.rb +67 -0
- metadata +3 -3
- data/lib/comment.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3b3122123c313c1e0eb4c2fd843ce971e484018
|
4
|
+
data.tar.gz: f35981e1eedad868a4efc3c19d59b9f0c9444521
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df702d38631c267a6d141f8a3680e1fc2b6f565597288c4ae455ae704bf701bc38ea25bcfdafb4e361ab60e54ecda1f885f7de7809e1d3ac7b41bc189e6cb134
|
7
|
+
data.tar.gz: a20dcf35e6547d2e45d9a843cd222cbb111df210b36e117d9d906b908f6ff928409cc24f7ce9a5f25373b1d2c726e23f012431b4044779487faf411007ead185
|
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.
|
7
|
+
spec.version = '0.0.3'
|
8
8
|
spec.authors = ["Tomás Pollak"]
|
9
9
|
spec.email = ["tomas@forkhq.com"]
|
10
10
|
spec.description = %q{Middleware for embedabble comments.}
|
data/db/schema.rb
CHANGED
@@ -12,15 +12,30 @@
|
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
14
|
ActiveRecord::Schema.define(version: 20130901232253) do
|
15
|
-
|
15
|
+
|
16
|
+
create_table "posts", force: true do |t|
|
17
|
+
t.integer "comments_allowed", :default => 1, :null => false
|
18
|
+
t.string "path", :null => false
|
19
|
+
end
|
20
|
+
|
21
|
+
create_table "responses", force: true do |t|
|
22
|
+
t.integer "post_id", :null => false
|
23
|
+
t.string "response_type", :default => 'comment', :null => false
|
16
24
|
t.string "author_name", :null => false
|
17
25
|
t.string "author_email", :null => false
|
18
26
|
t.string "author_url"
|
27
|
+
t.string "author_ip", :length => 15
|
19
28
|
t.text "content", :null => false
|
20
|
-
t.
|
29
|
+
t.integer "parent_id"
|
30
|
+
t.integer "approved", :default => 1, :length => 1, :null => false
|
21
31
|
t.datetime "created_at"
|
22
32
|
t.datetime "updated_at"
|
23
33
|
end
|
24
34
|
|
25
|
-
add_index :
|
35
|
+
add_index :posts, :path, :unique => true
|
36
|
+
add_index :responses, :approved
|
37
|
+
add_index :responses, :response_type
|
38
|
+
add_index :responses, :post_id
|
39
|
+
add_index :responses, :parent_id
|
40
|
+
|
26
41
|
end
|
data/lib/cachai.rb
CHANGED
@@ -3,7 +3,7 @@ require 'redis'
|
|
3
3
|
require 'json'
|
4
4
|
require 'rake'
|
5
5
|
|
6
|
-
require_relative '
|
6
|
+
require_relative 'models'
|
7
7
|
require_relative 'akismet'
|
8
8
|
|
9
9
|
module Cachai
|
@@ -23,7 +23,7 @@ module Cachai
|
|
23
23
|
opts = opts || {}
|
24
24
|
@domain = opts.delete(:domain) or raise 'Domain required.'
|
25
25
|
|
26
|
-
|
26
|
+
Cachai.load_db!
|
27
27
|
|
28
28
|
redis_host = opts.delete(:redis_host) || 'localhost'
|
29
29
|
@redis = Redis.new(:host => redis_host)
|
@@ -37,9 +37,19 @@ module Cachai
|
|
37
37
|
super(app)
|
38
38
|
end
|
39
39
|
|
40
|
+
get '/pingbacks.?:format?' do
|
41
|
+
# TODO
|
42
|
+
end
|
43
|
+
|
44
|
+
post '/pingbacks.?:format?' do
|
45
|
+
# TODO
|
46
|
+
end
|
47
|
+
|
40
48
|
get '/comments.?:format?' do
|
41
49
|
check_domain!(params[:domain])
|
42
50
|
|
51
|
+
@redis.del(redis_key(params[:path])) if params[:nocache]
|
52
|
+
|
43
53
|
# puts "Comments for: #{params[:domain]}#{params[:path]}"
|
44
54
|
json_list = get_comments(params[:path])
|
45
55
|
|
@@ -62,17 +72,19 @@ module Cachai
|
|
62
72
|
halt(400, "No spam allowed") if is_spam?(data, permalink, request)
|
63
73
|
|
64
74
|
attrs = {
|
65
|
-
:path => data['path'],
|
66
75
|
:content => data['content'],
|
67
76
|
:author_name => data['author_name'],
|
68
77
|
:author_email => data['author_email'],
|
69
|
-
:author_url => data['author_url']
|
78
|
+
:author_url => data['author_url'],
|
79
|
+
:parent_id => data['parent_id'],
|
80
|
+
:author_ip => request.ip
|
70
81
|
}
|
71
82
|
|
72
|
-
|
83
|
+
post = Post.find_by_path!(data['path'])
|
84
|
+
response = Response.create!(attrs.merge(:post_id => post.id))
|
73
85
|
|
74
86
|
@redis.del(redis_key(data['path']))
|
75
|
-
json({ :status => 'ok', :comment =>
|
87
|
+
json({ :status => 'ok', :comment => response })
|
76
88
|
|
77
89
|
rescue JSON::ParserError
|
78
90
|
status 400 and json({ :error => 'Invalid JSON.' })
|
@@ -94,20 +106,6 @@ module Cachai
|
|
94
106
|
# expires 1.year.ago
|
95
107
|
end
|
96
108
|
|
97
|
-
def load_schema
|
98
|
-
require 'sinatra/activerecord/rake'
|
99
|
-
require_relative '../db/schema.rb'
|
100
|
-
end
|
101
|
-
|
102
|
-
def schema_loaded?
|
103
|
-
Comment.first
|
104
|
-
true
|
105
|
-
rescue ActiveRecord::StatementInvalid => e
|
106
|
-
# SQLite3::SQLException => e
|
107
|
-
# return !e.message['no such table']
|
108
|
-
false
|
109
|
-
end
|
110
|
-
|
111
109
|
def check_domain!(domain)
|
112
110
|
halt(400, 'Invalid domain.') unless domain == @domain
|
113
111
|
end
|
@@ -125,13 +123,34 @@ module Cachai
|
|
125
123
|
key = redis_key(path)
|
126
124
|
unless json_list = @redis.get(key)
|
127
125
|
puts "Not cached. Getting from DB: #{path}"
|
128
|
-
|
126
|
+
post = Post.find_by_path!(path)
|
127
|
+
json_list = get_and_sort_comments_for(post).to_json
|
129
128
|
@redis.set(key, json_list)
|
130
129
|
@redis.expire(key, 60 * 60) # one hour
|
131
130
|
end
|
132
131
|
json_list
|
133
132
|
end
|
134
133
|
|
134
|
+
def get_and_sort_comments_for(post)
|
135
|
+
result = []
|
136
|
+
top_level = post.responses.comment.top_level
|
137
|
+
nested = post.responses.comment.nested
|
138
|
+
|
139
|
+
puts top_level.count
|
140
|
+
puts nested.count
|
141
|
+
|
142
|
+
top_level.each_with_index do |comment, i|
|
143
|
+
obj = comment.as_json
|
144
|
+
children = nested.select do |nested|
|
145
|
+
nested.parent_id == comment.id
|
146
|
+
end
|
147
|
+
obj.merge!(:children => children) if children.any?
|
148
|
+
result.push(obj)
|
149
|
+
end
|
150
|
+
|
151
|
+
result
|
152
|
+
end
|
153
|
+
|
135
154
|
def redis_key(path)
|
136
155
|
"comments:#{@domain}:#{path}"
|
137
156
|
end
|
data/lib/models.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'sinatra/activerecord'
|
2
|
+
require 'digest/md5'
|
3
|
+
require 'sqlite3'
|
4
|
+
require_relative 'time_ago'
|
5
|
+
|
6
|
+
ENV_NAME = ENV['RACK_ENV'] || 'development'
|
7
|
+
|
8
|
+
module Cachai
|
9
|
+
|
10
|
+
def self.load_db!
|
11
|
+
load_schema unless schema_loaded?
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.load_schema
|
15
|
+
require_relative '../db/schema.rb'
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.schema_loaded?
|
19
|
+
Post.first
|
20
|
+
true
|
21
|
+
rescue ActiveRecord::StatementInvalid => e
|
22
|
+
# SQLite3::SQLException => e
|
23
|
+
# return !e.message['no such table']
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
class Post < ActiveRecord::Base
|
28
|
+
has_many :responses
|
29
|
+
|
30
|
+
validates_presence_of :path
|
31
|
+
validates_uniqueness_of :path
|
32
|
+
end
|
33
|
+
|
34
|
+
class Response < ActiveRecord::Base
|
35
|
+
belongs_to :post
|
36
|
+
validates_presence_of :author_name, :author_name, :author_email, :content
|
37
|
+
|
38
|
+
scope :approved, lambda { where(:approved => 1) }
|
39
|
+
scope :comment, lambda { where(:response_type => 'comment') }
|
40
|
+
scope :pingback, lambda { where(:response_type => 'pingback') }
|
41
|
+
scope :top_level, lambda { where(:parent_id => 0) }
|
42
|
+
scope :nested, lambda { where("parent_id != 0") }
|
43
|
+
|
44
|
+
|
45
|
+
def as_json(options = {})
|
46
|
+
{
|
47
|
+
:id => id,
|
48
|
+
:author_name => author_name,
|
49
|
+
# :author_email => author_email,
|
50
|
+
:author_img => author_img,
|
51
|
+
:author_url => author_url,
|
52
|
+
:content => content,
|
53
|
+
:timestamp => created_at.to_i,
|
54
|
+
:parent_id => parent_id,
|
55
|
+
:type => response_type,
|
56
|
+
# :created_at => created_at,
|
57
|
+
:created_ago => Timeago.since(created_at)
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def author_img(size = 50)
|
62
|
+
id = Digest::MD5::hexdigest(author_email.strip.downcase)
|
63
|
+
"https://www.gravatar.com/avatar/#{id}.jpg?s=#{size}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
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.
|
4
|
+
version: 0.0.3
|
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-06-
|
11
|
+
date: 2015-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -125,7 +125,7 @@ files:
|
|
125
125
|
- db/schema.rb
|
126
126
|
- lib/akismet.rb
|
127
127
|
- lib/cachai.rb
|
128
|
-
- lib/
|
128
|
+
- lib/models.rb
|
129
129
|
- lib/time_ago.rb
|
130
130
|
- test/app_test.rb
|
131
131
|
homepage: ''
|
data/lib/comment.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'sinatra/activerecord'
|
2
|
-
require 'digest/md5'
|
3
|
-
require 'sqlite3'
|
4
|
-
require_relative 'time_ago'
|
5
|
-
|
6
|
-
ENV_NAME = ENV['RACK_ENV'] || 'development'
|
7
|
-
|
8
|
-
module Cachai
|
9
|
-
class Comment < ActiveRecord::Base
|
10
|
-
|
11
|
-
validates_presence_of :author_name, :author_name, :author_email, :content, :path
|
12
|
-
|
13
|
-
def as_json(options = {})
|
14
|
-
{
|
15
|
-
:id => id,
|
16
|
-
:author_name => author_name,
|
17
|
-
# :author_email => author_email,
|
18
|
-
:author_img => author_img,
|
19
|
-
:author_url => author_url,
|
20
|
-
:content => content,
|
21
|
-
:timestamp => created_at.to_i,
|
22
|
-
# :created_at => created_at,
|
23
|
-
:created_ago => Timeago.since(created_at)
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
def author_img(size = 50)
|
28
|
-
id = Digest::MD5::hexdigest(author_email.strip.downcase)
|
29
|
-
"https://www.gravatar.com/avatar/#{id}.jpg?s=#{size}"
|
30
|
-
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end
|