ideaoforder-acts_as_disqusable 0.4.0
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.
- data/.gitignore +6 -0
- data/MIT-LICENSE +20 -0
- data/Manifest.txt +38 -0
- data/README.rdoc +149 -0
- data/Rakefile +14 -0
- data/VERSION +1 -0
- data/acts_as_disqusable.gemspec +80 -0
- data/lib/acts_as_disqusable.rb +155 -0
- data/lib/acts_as_disqusable/author.rb +27 -0
- data/lib/acts_as_disqusable/forum.rb +118 -0
- data/lib/acts_as_disqusable/post.rb +31 -0
- data/lib/acts_as_disqusable/thread.rb +38 -0
- data/lib/disqus.rb +52 -0
- data/tasks/rcov.rake +23 -0
- data/test/api_test.rb +80 -0
- data/test/config.yml.sample +3 -0
- data/test/forum_test.rb +70 -0
- data/test/merb_test.rb +15 -0
- data/test/post_test.rb +18 -0
- data/test/rails_test.rb +18 -0
- data/test/responses/bad_api_key.json +1 -0
- data/test/responses/create_post.json +23 -0
- data/test/responses/get_forum_api_key.json +1 -0
- data/test/responses/get_forum_list.json +12 -0
- data/test/responses/get_num_posts.json +11 -0
- data/test/responses/get_thread_by_url.json +18 -0
- data/test/responses/get_thread_list.json +16 -0
- data/test/responses/get_thread_posts.json +37 -0
- data/test/responses/thread_by_identifier.json +17 -0
- data/test/responses/update_thread.json +5 -0
- data/test/test_helper.rb +32 -0
- data/test/thread_test.rb +28 -0
- data/test/view_helpers_test.rb +37 -0
- data/test/widget_test.rb +58 -0
- metadata +107 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module Disqus
|
2
|
+
|
3
|
+
class BaseAuthor
|
4
|
+
attr_reader :url, :email_hash
|
5
|
+
end
|
6
|
+
|
7
|
+
class Author < BaseAuthor
|
8
|
+
attr_reader :id, :username, :display_name, :has_avatar
|
9
|
+
def initialize(id, username, display_name, url, email_hash, has_avatar)
|
10
|
+
@id, @username, @display_name, @url, @email_hash, @has_avatar = id, username, display_name, url, email_hash, has_avatar
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the user's <tt>display_name</tt> or <tt>username</tt> if <tt>display_name</tt> is blank.
|
14
|
+
def name
|
15
|
+
@display_name.blank? ? @username : @display_name
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class AnonymousAuthor < BaseAuthor
|
21
|
+
attr_reader :name
|
22
|
+
def initialize(name, url, email_hash)
|
23
|
+
@name, @url, @email_hash = name, url, email_hash
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Disqus
|
2
|
+
class Forum
|
3
|
+
|
4
|
+
attr_accessor :id, :shortname, :name, :created_at, :description
|
5
|
+
def initialize(data)
|
6
|
+
data.each { |k, v| send(:"#{k}=", v) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.all
|
10
|
+
@@all ||= begin
|
11
|
+
response = get('/get_forum_list')
|
12
|
+
response["succeeded"] ? response["message"].map { |data| Disqus::Forum.new(data) } : nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.find(id)
|
17
|
+
id = id.to_s if !id.is_a? String
|
18
|
+
grouped = self.all.group_by(&:id)
|
19
|
+
grouped[id].first if grouped[id]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the forum API Key for this forum.
|
23
|
+
def key(user_api_key = nil)
|
24
|
+
@key ||= begin
|
25
|
+
response = self.class.get('/get_forum_api_key', :query => {
|
26
|
+
:api_key => user_api_key,
|
27
|
+
:forum_id => id
|
28
|
+
})
|
29
|
+
response["succeeded"] ? response["message"] : nil
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns an array of threads belonging to this forum.
|
34
|
+
def self.threads(id, key)
|
35
|
+
response = self.get('/get_thread_list', :query => {
|
36
|
+
:forum_api_key => key,
|
37
|
+
:forum_id => id
|
38
|
+
})
|
39
|
+
response["succeeded"] ? response["message"].map { |data| Disqus::Thread.new(data) } : nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def threads
|
43
|
+
self.class.threads(self.id, self.key)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns a thread associated with the given URL.
|
47
|
+
#
|
48
|
+
# A thread will only have an associated URL if it was automatically
|
49
|
+
# created by Disqus javascript embedded on that page.
|
50
|
+
def self.get_thread_by_url(url, key)
|
51
|
+
response = self.get('/get_thread_by_url', :query => { :url => url, :forum_api_key => key })
|
52
|
+
response["succeeded"] ? Thread.new(response["message"]) : nil
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_thread_by_url(url)
|
56
|
+
self.class.get_thread_by_url(url, self.key)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.thread_by_identifier(identifier, title, key)
|
60
|
+
response = self.post('/thread_by_identifier', :query => {
|
61
|
+
:forum_api_key => key,
|
62
|
+
:identifier => identifier,
|
63
|
+
:title => title
|
64
|
+
})
|
65
|
+
|
66
|
+
response["succeeded"] ? Thread.new(response["message"]["thread"]) : nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def thread_by_identifier(identifier, title)
|
70
|
+
self.class.thread_by_identifier(identifier, title, self.key)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Sets the provided values on the thread object.
|
74
|
+
#
|
75
|
+
# Returns an empty success message.
|
76
|
+
#
|
77
|
+
# Options:
|
78
|
+
#
|
79
|
+
# * <tt>:title</tt> - the title of the thread
|
80
|
+
# * <tt>:slug</tt> - the per-forum-unique string used for identifying this thread in disqus.com URL's relating to this thread. Composed of underscore-separated alphanumeric strings.
|
81
|
+
# * <tt>:url</tt> - the URL this thread is on, if known.
|
82
|
+
# * <tt>:allow_comment</tt> - whether this thread is open to new comments
|
83
|
+
def self.update_thread(thread_id, key, opts = {})
|
84
|
+
response = self.post('/update_thread', :query => opts.merge(:forum_api_key => key))
|
85
|
+
response["succeeded"]
|
86
|
+
end
|
87
|
+
|
88
|
+
def update_thread(thread_id, opts = {})
|
89
|
+
self.class.update_thread(thread_id, self.key, opts = {})
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.posts_count(thread_ids, key)
|
93
|
+
response = self.get('/get_num_posts', :query => { :thread_ids => thread_ids, :forum_api_key => key })
|
94
|
+
out = Hash.new
|
95
|
+
response["message"].each { |id, data| out[id] = data.first }
|
96
|
+
if out.length == 1
|
97
|
+
return out.values.first
|
98
|
+
else
|
99
|
+
return out
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def posts_count(thread_ids)
|
104
|
+
self.class.posts_count(thread_ids, self.key)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns an array of posts belonging to this thread.
|
108
|
+
def self.posts(key, opts={:exclude => 'spam'})
|
109
|
+
response = self.get('/get_forum_posts', :query => opts.merge(:forum_api_key => key ))
|
110
|
+
out = Hash.new
|
111
|
+
response["message"].map { |data| Disqus::Post.new(data) }
|
112
|
+
end
|
113
|
+
|
114
|
+
def posts(opts={:exclude => 'spam'})
|
115
|
+
self.class.posts(self.key)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Disqus
|
2
|
+
class Post
|
3
|
+
attr_accessor :id, :forum, :thread, :created_at, :message, :parent_post, :shown, :is_anonymous, :anonymous_author, :author, :points, :status, :has_been_moderated, :ip_address
|
4
|
+
def initialize(data)
|
5
|
+
data.each { |k, v| send(:"#{k}=", v) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def author_name
|
9
|
+
if is_anonymous
|
10
|
+
anonymous_author["name"]
|
11
|
+
else
|
12
|
+
author["display_name"] || author["username"]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def linked_author(opts={})
|
17
|
+
"<a href=\"#{author['url']}\" target=\"#{opts[:target]}\" class=\"#{opts[:class]}\">#{self.author_name}</a>"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.create(opts={})
|
21
|
+
response = self.class.post('/create_post', :query => opts)
|
22
|
+
if response["success"]
|
23
|
+
Disqus::Post.new(response["message"])
|
24
|
+
else
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Disqus
|
2
|
+
class Thread
|
3
|
+
attr_accessor :id, :forum, :slug, :title, :created_at, :allow_comments, :url, :identifier, :hidden, :category
|
4
|
+
def initialize(data)
|
5
|
+
data.each { |k, v| send(:"#{k}=", v) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.find_or_create(title, identifier)
|
9
|
+
response = self.post('/thread_by_identifier', :body => { :title => title, :identifier => identifier }.merge(self.default_params))
|
10
|
+
Disqus::Thread.new(response["message"]["thread"])
|
11
|
+
end
|
12
|
+
|
13
|
+
def posts_count
|
14
|
+
response = self.class.get('/get_num_posts', :query => { :thread_ids => id })
|
15
|
+
response["message"][id].first.to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns an array of posts belonging to this thread.
|
19
|
+
# limit — Number of entries that should be included in the response. Default is 25.
|
20
|
+
# start — Starting point for the query. Default is 0.
|
21
|
+
# filter — Type of entries that should be returned (new, spam or killed).
|
22
|
+
# exclude — Type of entries that should be excluded from the response (new, spam or killed).
|
23
|
+
def self.posts(thread_id, opts={:exclude => 'spam'})
|
24
|
+
response = self.get('/get_thread_posts', :query => opts.merge(:thread_id => thread_id ))
|
25
|
+
response["message"].map { |data| Disqus::Post.new(data) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def posts(opts={:exclude => 'spam'})
|
29
|
+
self.class.posts(self.id)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Sets the provided values on the thread object.
|
33
|
+
def update(opts = {})
|
34
|
+
result = self.class.post('/update_thread', :query => opts.merge(:forum_api_key => forum.key))
|
35
|
+
return result["succeeded"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/disqus.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# == From the {Disqus Website}[http://disqus.com]:
|
2
|
+
|
3
|
+
# "Disqus, pronounced "discuss", is a service and tool for web comments and
|
4
|
+
# discussions. The Disqus comment system can be plugged into any website, blog,
|
5
|
+
# or application. Disqus makes commenting easier and more interactive, while
|
6
|
+
# connecting websites and commenters across a thriving discussion community."
|
7
|
+
#
|
8
|
+
# "Disqus is a free service to the general public with absolutely no inline
|
9
|
+
# advertisements."
|
10
|
+
|
11
|
+
# The Disqus gem helps you quickly and easily integrate Disqus's Javascript
|
12
|
+
# widgets into your Ruby-based website. Adding Disqus to your site literally
|
13
|
+
# takes only a few minutes. The Disqus gem also provides a complete
|
14
|
+
# implementation of the Disqus API for more complex applications.
|
15
|
+
|
16
|
+
# To use this code, please first create an account on Disqus[http://disqus.com].
|
17
|
+
require 'rubygems'
|
18
|
+
require 'httparty'
|
19
|
+
|
20
|
+
require 'acts_as_disqusable/forum'
|
21
|
+
require 'acts_as_disqusable/thread'
|
22
|
+
require 'acts_as_disqusable/post'
|
23
|
+
require 'acts_as_disqusable/author'
|
24
|
+
|
25
|
+
module Disqus
|
26
|
+
@defaults = {
|
27
|
+
:api_key => "",
|
28
|
+
:account => "",
|
29
|
+
:developer => false,
|
30
|
+
:api_version => '1.1',
|
31
|
+
:container_id => 'disqus_thread',
|
32
|
+
:avatar_size => 48,
|
33
|
+
:num_items => 5,
|
34
|
+
:forum_api_key => '', # optional--if you're just mapping one forum to your app, this is convenient
|
35
|
+
:forum_shortname => '', # ditto
|
36
|
+
:forum_id => '' # ditto
|
37
|
+
}
|
38
|
+
|
39
|
+
def self.defaults
|
40
|
+
@config = @defaults.merge(YAML::load(File.open("#{RAILS_ROOT}/config/disqus.yml")))
|
41
|
+
end
|
42
|
+
|
43
|
+
[Author, Forum, Post, Thread].each do |klass|
|
44
|
+
klass.class_eval "include HTTParty"
|
45
|
+
klass.class_eval "base_uri 'http://disqus.com/api'"
|
46
|
+
klass.class_eval "format :json"
|
47
|
+
klass.class_eval "default_params :user_api_key => '#{self.defaults[:api_key]}'"
|
48
|
+
klass.class_eval "default_params :forum_api_key => '#{self.defaults[:forum_api_key]}'"
|
49
|
+
klass.class_eval "default_params :forum_id => '#{self.defaults[:forum_id]}'"
|
50
|
+
klass.class_eval "default_params :api_version => '#{self.defaults[:api_version]}'"
|
51
|
+
end
|
52
|
+
end
|
data/tasks/rcov.rake
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
desc "Run RCov"
|
2
|
+
task :rcov do
|
3
|
+
run_coverage Dir["test/**/*_test.rb"]
|
4
|
+
end
|
5
|
+
|
6
|
+
def run_coverage(files)
|
7
|
+
rm_f "coverage"
|
8
|
+
rm_f "coverage.data"
|
9
|
+
if files.length == 0
|
10
|
+
puts "No files were specified for testing"
|
11
|
+
return
|
12
|
+
end
|
13
|
+
files = files.join(" ")
|
14
|
+
if PLATFORM =~ /darwin/
|
15
|
+
exclude = '--exclude "gems/"'
|
16
|
+
else
|
17
|
+
exclude = '--exclude "rubygems"'
|
18
|
+
end
|
19
|
+
rcov = "rcov -Ilib:test --sort coverage --text-report #{exclude} --no-validator-links"
|
20
|
+
cmd = "#{rcov} #{files}"
|
21
|
+
puts cmd
|
22
|
+
sh cmd
|
23
|
+
end
|
data/test/api_test.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ApiTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
require 'disqus'
|
7
|
+
Disqus.defaults[:api_key] = DISQUS_TEST["api_key"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_create_post
|
11
|
+
mock_post_response('create_post.json')
|
12
|
+
the_post = Disqus::Api::create_post()
|
13
|
+
assert_equal "This is a mock post", the_post["message"]["message"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_get_forum_list
|
17
|
+
mock_get_response('get_forum_list.json')
|
18
|
+
forum_list = Disqus::Api::get_forum_list
|
19
|
+
assert_equal "Disqus Test", forum_list["message"][0]["name"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_get_forum_api_key
|
23
|
+
mock_get_response('get_forum_api_key.json')
|
24
|
+
forum_api_key = Disqus::Api::get_forum_api_key(:forum_id => 1234, :user_api_key=>"FAKE_KEY")
|
25
|
+
assert_equal "FAKE_FORUM_API_KEY", forum_api_key["message"]
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_get_thread_list
|
29
|
+
mock_get_response('get_thread_list.json')
|
30
|
+
thread_list = Disqus::Api::get_thread_list(:forum_api_key=>"FAKE_KEY")
|
31
|
+
assert_equal "this_is_the_thread_identifier", thread_list["message"].first["identifier"]
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_get_num_posts
|
35
|
+
mock_get_response('get_num_posts.json')
|
36
|
+
nums = Disqus::Api::get_num_posts(:thread_ids => [123,456], :forum_api_key=>"FAKE_KEY")
|
37
|
+
assert_equal [10,12], nums["message"][nums["message"].keys.first]
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_get_thread_by_url
|
41
|
+
mock_get_response('get_thread_by_url.json')
|
42
|
+
thread = Disqus::Api::get_thread_by_url(:url => "FAKE_URL", :forum_api_key=>"FAKE_KEY")
|
43
|
+
assert_equal "test_thread", thread["message"]["slug"]
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_get_thread_posts
|
47
|
+
mock_get_response('get_thread_posts.json')
|
48
|
+
thread_posts = Disqus::Api::get_thread_posts(:thread_id =>1234, :forum_api_key => "FAKE_KEY")
|
49
|
+
assert_equal "This is a mock post", thread_posts["message"].first["message"]
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_thread_by_identifier
|
53
|
+
mock_post_response('thread_by_identifier.json')
|
54
|
+
thread = Disqus::Api::thread_by_identifier(:identifier =>'foo_bar', :title => "Foo Bar", :forum_api_key => "FAKE_KEY")
|
55
|
+
assert_equal "Test thread", thread["message"]["thread"]["title"]
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_update_thread
|
59
|
+
mock_post_response('update_thread.json')
|
60
|
+
result = Disqus::Api::thread_by_identifier(:thread_id =>123, :title => "Foo Bar", :forum_api_key => "FAKE_KEY")
|
61
|
+
assert result["succeeded"]
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_comment_form
|
65
|
+
c = Disqus::Api::comment_form("myforum", "mythread")
|
66
|
+
assert_match(/myforum/, c)
|
67
|
+
assert_match(/mythread/, c)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def mock_get_response(file)
|
73
|
+
Disqus::Api.expects(:get).returns(File.read(File.dirname(__FILE__) + "/responses/#{file}"))
|
74
|
+
end
|
75
|
+
|
76
|
+
def mock_post_response(file)
|
77
|
+
Disqus::Api.expects(:post).returns(File.read(File.dirname(__FILE__) + "/responses/#{file}"))
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
data/test/forum_test.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper'
|
2
|
+
|
3
|
+
class ForumTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
require 'disqus'
|
7
|
+
Disqus.defaults[:api_key] = DISQUS_TEST["api_key"]
|
8
|
+
stub_api_call(:get_forum_api_key).returns("FAKE_FORUM_API_KEY")
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_forum_list
|
12
|
+
mock_api_call(:get_forum_list)
|
13
|
+
list = Disqus::Forum.list
|
14
|
+
expected = [create_forum]
|
15
|
+
assert_equal 1, list.size
|
16
|
+
assert_equal expected, list
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_forum_find
|
20
|
+
mock_api_call(:get_forum_list)
|
21
|
+
forum = Disqus::Forum.find(1234)
|
22
|
+
assert_equal "disqus-test", forum.shortname
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_forum_find_bad_id
|
26
|
+
mock_api_call(:get_forum_list)
|
27
|
+
forum = Disqus::Forum.find(666)
|
28
|
+
assert_equal nil, forum
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_forum_find_no_forums
|
32
|
+
Disqus::Api.expects(:get_forum_list).returns({"succeeded"=>true, "code"=>"", "message" => []})
|
33
|
+
forum = Disqus::Forum.find(1234)
|
34
|
+
assert_equal nil, forum
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_key
|
38
|
+
mock_api_call(:get_forum_api_key)
|
39
|
+
forum = Disqus::Forum.new(1234, "disqus-test", "Disqus Test", "2008-01-03 14:44:07.627492")
|
40
|
+
assert_equal "FAKE_FORUM_API_KEY", forum.key
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_forum_threads
|
44
|
+
forum = create_forum
|
45
|
+
Disqus::Thread.expects(:list).with(forum).returns([thread = mock()])
|
46
|
+
assert_equal [thread], forum.forum_threads
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_get_thread_by_url
|
50
|
+
mock_api_call(:get_thread_by_url)
|
51
|
+
forum = create_forum
|
52
|
+
thread = forum.get_thread_by_url("http://www.example.com")
|
53
|
+
expected = Disqus::Thread.new("7651269", forum, "test_thread", "Test thread", "2008-11-28T01:47", true, "FAKE_URL", nil)
|
54
|
+
assert_equal expected, thread
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_thread_by_identifier
|
58
|
+
mock_api_call(:thread_by_identifier)
|
59
|
+
forum = create_forum
|
60
|
+
thread = forum.thread_by_identifier("FAKE_IDENTIFIER", "")
|
61
|
+
expected = Disqus::Thread.new("7651269", forum, "test_thread", "Test thread", "2008-11-28T01:47", true, "FAKE_URL", "FAKE_IDENTIFIER")
|
62
|
+
assert_equal expected, thread
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_update_thread
|
66
|
+
Disqus::Api.expects(:update_thread).with({:thread_id => 1234, :forum_api_key => "FAKE_FORUM_API_KEY", :title => 'Title', :slug => "a_slug", :url => "http://www.example.com", :allow_comments => true}).returns({"succeeded" => true})
|
67
|
+
forum = create_forum
|
68
|
+
forum.update_thread(1234, :title => 'Title', :slug => "a_slug", :url => "http://www.example.com", :allow_comments => true)
|
69
|
+
end
|
70
|
+
end
|