cachai 0.0.2 → 0.0.3
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 +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
|