stacked 0.5.0 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +43 -0
- data/LICENSE +1 -1
- data/README.markdown +58 -25
- data/Rakefile +6 -45
- data/genddoc.sh +4 -1
- data/lib/stacked.rb +11 -9
- data/lib/stacked/answer.rb +10 -27
- data/lib/stacked/badge.rb +15 -11
- data/lib/stacked/base.rb +59 -92
- data/lib/stacked/client.rb +31 -0
- data/lib/stacked/comment.rb +13 -18
- data/lib/stacked/parser.rb +47 -0
- data/lib/stacked/post_timeline.rb +17 -0
- data/lib/stacked/question.rb +52 -51
- data/lib/stacked/{reputation.rb → rep_change.rb} +5 -3
- data/lib/stacked/tag.rb +10 -2
- data/lib/stacked/user.rb +29 -161
- data/lib/stacked/{usertimeline.rb → user_timeline.rb} +5 -5
- data/lib/stacked/version.rb +4 -0
- data/spec/fakes/answers/1237127 +0 -0
- data/spec/fakes/answers/2272830 +0 -0
- data/spec/fakes/answers/2558700 +0 -0
- data/spec/fakes/badges/index +0 -0
- data/spec/fakes/badges/name +0 -0
- data/spec/fakes/badges/tags +0 -0
- data/spec/fakes/comments/1063043 +0 -0
- data/spec/fakes/comments/2561833 +0 -0
- data/spec/fakes/questions/1236996 +0 -0
- data/spec/fakes/questions/1236996-answers +0 -0
- data/spec/fakes/questions/1236996-comments +0 -0
- data/spec/fakes/questions/1236996-timeline +0 -0
- data/spec/fakes/questions/4839321/answers +0 -0
- data/spec/fakes/questions/index +0 -0
- data/spec/fakes/questions/search +0 -0
- data/spec/fakes/questions/tagged +0 -0
- data/spec/fakes/questions/unanswered +0 -0
- data/spec/fakes/questions/withcomments +0 -0
- data/spec/fakes/stats/index +0 -0
- data/spec/fakes/tags/activity +0 -0
- data/spec/fakes/tags/index +0 -0
- data/spec/fakes/tags/name +0 -0
- data/spec/fakes/tags/popular +0 -0
- data/spec/fakes/users/148722 +0 -0
- data/spec/fakes/users/148722-comments +0 -0
- data/spec/fakes/users/148722-comments-by-creation +0 -0
- data/spec/fakes/users/148722-comments-by-votes +0 -0
- data/spec/fakes/users/22656 +0 -0
- data/spec/fakes/users/22656-answers +0 -0
- data/spec/fakes/users/22656-answers-by-activity +0 -0
- data/spec/fakes/users/22656-answers-by-creation +0 -0
- data/spec/fakes/users/22656-answers-by-views +0 -0
- data/spec/fakes/users/22656-answers-by-votes +0 -0
- data/spec/fakes/users/22656-badges +0 -0
- data/spec/fakes/users/22656-comments-mentioning-by-creation +0 -0
- data/spec/fakes/users/22656-comments-mentioning-by-votes +0 -0
- data/spec/fakes/users/22656-favorites +0 -0
- data/spec/fakes/users/22656-favorites-by-activity +0 -0
- data/spec/fakes/users/22656-favorites-by-added +0 -0
- data/spec/fakes/users/22656-favorites-by-creation +0 -0
- data/spec/fakes/users/22656-favorites-by-views +0 -0
- data/spec/fakes/users/22656-mentioned +0 -0
- data/spec/fakes/users/22656-questions +0 -0
- data/spec/fakes/users/22656-questions-by-activity +0 -0
- data/spec/fakes/users/22656-questions-by-creation +0 -0
- data/spec/fakes/users/22656-questions-by-views +0 -0
- data/spec/fakes/users/22656-questions-by-votes +0 -0
- data/spec/fakes/users/22656-reputation +0 -0
- data/spec/fakes/users/22656-reputation-ranged +0 -0
- data/spec/fakes/users/22656-tags +0 -0
- data/spec/fakes/users/22656-timeline +0 -0
- data/spec/fakes/users/filter +0 -0
- data/spec/fakes/users/index +0 -0
- data/spec/fakes/users/index-page2 +0 -0
- data/spec/fakes/users/index-pagesize1 +0 -0
- data/spec/fakes/users/name +0 -0
- data/spec/fakes/users/newest +0 -0
- data/spec/fakes/users/oldest +0 -0
- data/spec/sorted_by_spec.rb +2 -2
- data/spec/spec_helper.rb +10 -8
- data/spec/stacked/answer_spec.rb +9 -8
- data/spec/stacked/badge_spec.rb +11 -3
- data/spec/stacked/base_spec.rb +24 -2
- data/spec/stacked/comment_spec.rb +11 -9
- data/spec/stacked/question_spec.rb +49 -61
- data/spec/stacked/{reputation_spec.rb → rep_change_spec.rb} +9 -5
- data/spec/stacked/tag_spec.rb +13 -6
- data/spec/stacked/user_spec.rb +99 -70
- data/spec/stacked/{usertimeline_spec.rb → user_timeline_spec.rb} +1 -1
- data/spec/support/fakes.rb +28 -0
- data/spec/support/{sorted_by.rb → matchers/sorted_by.rb} +7 -6
- data/spec/support/{within.rb → matchers/within.rb} +3 -3
- data/spec/within_spec.rb +2 -2
- data/stacked.gemspec +23 -112
- metadata +248 -54
- data/README.rdoc +0 -18
- data/VERSION +0 -1
- data/doc/Stacked.html +0 -155
- data/doc/Stacked/Answer.html +0 -1394
- data/doc/Stacked/Badge.html +0 -480
- data/doc/Stacked/Base.html +0 -1124
- data/doc/Stacked/Comment.html +0 -1037
- data/doc/Stacked/NotImplemented.html +0 -162
- data/doc/Stacked/Posttimeline.html +0 -543
- data/doc/Stacked/Question.html +0 -1763
- data/doc/Stacked/Reputation.html +0 -606
- data/doc/Stacked/Tag.html +0 -267
- data/doc/Stacked/User.html +0 -2787
- data/doc/Stacked/Usertimeline.html +0 -630
- data/doc/_index.html +0 -246
- data/doc/file.README.html +0 -54
- data/doc/index.html +0 -54
- data/doc/method_list.html +0 -1203
- data/doc/top-level-namespace.html +0 -87
- data/lib/stacked/posttimeline.rb +0 -10
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stacked (1.0.0)
|
5
|
+
activesupport (~> 3.0.3)
|
6
|
+
httparty (~> 0.7.3)
|
7
|
+
i18n (~> 0.5.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activesupport (3.0.3)
|
13
|
+
addressable (2.2.3)
|
14
|
+
crack (0.1.8)
|
15
|
+
diff-lcs (1.1.2)
|
16
|
+
httparty (0.7.3)
|
17
|
+
crack (= 0.1.8)
|
18
|
+
i18n (0.5.0)
|
19
|
+
rake (0.8.7)
|
20
|
+
rspec (2.4.0)
|
21
|
+
rspec-core (~> 2.4.0)
|
22
|
+
rspec-expectations (~> 2.4.0)
|
23
|
+
rspec-mocks (~> 2.4.0)
|
24
|
+
rspec-core (2.4.0)
|
25
|
+
rspec-expectations (2.4.0)
|
26
|
+
diff-lcs (~> 1.1.2)
|
27
|
+
rspec-mocks (2.4.0)
|
28
|
+
webmock (1.6.2)
|
29
|
+
addressable (>= 2.2.2)
|
30
|
+
crack (>= 0.1.7)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
activesupport (~> 3.0.3)
|
37
|
+
bundler (~> 1.0)
|
38
|
+
httparty (~> 0.7.3)
|
39
|
+
i18n (~> 0.5.0)
|
40
|
+
rake (~> 0.8)
|
41
|
+
rspec (~> 2.4)
|
42
|
+
stacked!
|
43
|
+
webmock (~> 1.6.2)
|
data/LICENSE
CHANGED
data/README.markdown
CHANGED
@@ -1,37 +1,70 @@
|
|
1
|
-
# Stacked - A Ruby wrapper for the Stack
|
1
|
+
# Stacked - A Ruby wrapper for the Stack Exchange API (v1.0)
|
2
2
|
|
3
|
-
|
3
|
+
# Note: This code is being actively developed and will be merged with master when ready.
|
4
|
+
|
5
|
+
While a lot of the core code has remained unchanged, this fork has went through many updates to get it working with the latest version (1.0) of the Stack Exchange API. Many thanks to radar for this initial work on this project.
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
7
|
-
|
9
|
+
# Currently installs outdated version of the gem
|
10
|
+
# sudo gem install stacked
|
8
11
|
|
9
|
-
|
12
|
+
## Usage
|
10
13
|
|
11
|
-
|
14
|
+
Stacked is configurable to work with any of the Stack Exchange sites. When setting up the client, just specify the site you wish to access, the API version number, and your api key. By default, Stacked will access Stack Overflow API version 1.0. Note: You must still supply your own api key in the config.
|
12
15
|
|
13
|
-
|
14
|
-
Stacked::
|
16
|
+
# Access Stack Overflow API v1.0
|
17
|
+
Stacked::Client.configure do |config|
|
18
|
+
config.api_key = 'yourapikey'
|
19
|
+
end
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
# Access Server Fault API v1.0
|
22
|
+
Stacked::Client.configure do |config|
|
23
|
+
config.site = 'serverfault.com',
|
24
|
+
config.version = '1.0',
|
25
|
+
config.api_key = 'yourapikey'
|
26
|
+
end
|
21
27
|
|
22
|
-
|
28
|
+
Methods that are designed to take options in the API are designed that way in the wrapper also, as you'd expect. For more details, read the Stack Overflow API [documentation](http://api.stackoverflow.com/1.0/help).
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
require 'stacked'
|
31
|
+
|
32
|
+
# - - Questions / Answers / Comments
|
33
|
+
|
34
|
+
# Setup the client
|
35
|
+
Stacked::Client.configure do |config|
|
36
|
+
config.api_key = 'yourapikey' # required
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns 30 (default page size) questions based on activity (default sort option)
|
40
|
+
Stacked::Question.all
|
41
|
+
|
42
|
+
# Returns questions tagged with 'ruby', including the question body and comments
|
43
|
+
Stacked::Question.all(:tagged => 'ruby', :body => true, :comments => true)
|
44
|
+
|
45
|
+
# Returns a individual question by id
|
46
|
+
question = Stacked::Question.find(151338)
|
47
|
+
|
48
|
+
# Returns paged answers for the question
|
49
|
+
answers = question.answers
|
50
|
+
|
51
|
+
# Returns paged comments for the question
|
52
|
+
comments = question.comments
|
53
|
+
|
54
|
+
# You can also specify multiple ids as an array for all find requests
|
55
|
+
questions = Stacked::Question.find([151338, 4579074])
|
56
|
+
|
57
|
+
# Returns paged questions based on search criteria
|
58
|
+
Stacked::Question.search(:intitle => 'github', :tagged => 'ruby')
|
59
|
+
|
60
|
+
# - - Users
|
34
61
|
|
35
|
-
|
62
|
+
# Returns the specified user
|
63
|
+
skeet = Stacked::User.find(22656)
|
64
|
+
|
65
|
+
# Returns all badges awarded to the user
|
66
|
+
skeet.badges
|
67
|
+
|
68
|
+
## Documentation
|
36
69
|
|
37
|
-
|
70
|
+
For additional details, checkout the latest generated [documentation](http://raid5.github.com/stacked).
|
data/Rakefile
CHANGED
@@ -1,51 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
+
require 'bundler'
|
4
|
+
Bundler::GemHelper.install_tasks
|
3
5
|
|
4
6
|
begin
|
5
|
-
require '
|
6
|
-
|
7
|
-
|
8
|
-
gem.summary = %Q{Ruby wrapper for the Stack Overflow API}
|
9
|
-
gem.description = %Q{Ruby wrapper for the Stack Overflow API}
|
10
|
-
gem.email = "ryan@getup.org.au"
|
11
|
-
gem.homepage = "http://github.com/radar/stacked"
|
12
|
-
gem.authors = ["Ryan Bigg"]
|
13
|
-
gem.add_development_dependency "rspec"
|
14
|
-
gem.add_dependency('httparty', '~> 0.4.5')
|
15
|
-
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
-
end
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
[:spec, :rcov].each { |task| RSpec::Core::RakeTask.new(task) }
|
9
|
+
task :default => :spec
|
17
10
|
rescue LoadError
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
Jeweler::GemcutterTasks.new
|
22
|
-
|
23
|
-
require 'spec/rake/spectask'
|
24
|
-
Spec::Rake::SpecTask.new(:spec) do |spec|
|
25
|
-
spec.libs << 'lib' << 'spec'
|
26
|
-
spec.spec_files = FileList['spec/**/*_spec.rb']
|
27
|
-
end
|
28
|
-
|
29
|
-
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
30
|
-
spec.libs << 'lib' << 'spec'
|
31
|
-
spec.pattern = 'spec/**/*_spec.rb'
|
32
|
-
spec.rcov = true
|
33
|
-
end
|
34
|
-
|
35
|
-
task :spec => :check_dependencies
|
36
|
-
|
37
|
-
task :default => :spec
|
38
|
-
|
39
|
-
require 'rake/rdoctask'
|
40
|
-
Rake::RDocTask.new do |rdoc|
|
41
|
-
if File.exist?('VERSION')
|
42
|
-
version = File.read('VERSION')
|
43
|
-
else
|
44
|
-
version = ""
|
45
|
-
end
|
46
|
-
|
47
|
-
rdoc.rdoc_dir = 'rdoc'
|
48
|
-
rdoc.title = "stacked #{version}"
|
49
|
-
rdoc.rdoc_files.include('README*')
|
50
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
11
|
+
raise 'RSpec could not be loaded. Run `bundle install` to get all development dependencies.'
|
51
12
|
end
|
data/genddoc.sh
CHANGED
@@ -4,8 +4,11 @@ rm -rf ../stacked-doc &&
|
|
4
4
|
mkdir -p ../stacked-doc &&
|
5
5
|
mv doc/* ../stacked-doc &&
|
6
6
|
git checkout gh-pages &&
|
7
|
-
|
7
|
+
cd .. &&
|
8
|
+
rm -rf stacked/* &&
|
9
|
+
cd stacked/ &&
|
8
10
|
mv ../stacked-doc/* . &&
|
11
|
+
rm -rf ../stacked-doc &&
|
9
12
|
git add . &&
|
10
13
|
git commit -m "Updated documentation." &&
|
11
14
|
git push origin gh-pages &&
|
data/lib/stacked.rb
CHANGED
@@ -5,8 +5,9 @@ rescue LoadError
|
|
5
5
|
Bundler.setup!
|
6
6
|
end
|
7
7
|
|
8
|
-
require 'active_support'
|
8
|
+
require 'active_support/all'
|
9
9
|
|
10
|
+
# The Stacked module.
|
10
11
|
module Stacked
|
11
12
|
# TODO: Use this coupled with autoload_under when AS 3.0 becomes "stable":
|
12
13
|
# extend ActiveSupport::Autoload
|
@@ -20,23 +21,24 @@ module Stacked
|
|
20
21
|
# Instead of:
|
21
22
|
#
|
22
23
|
# autoload :Base, 'stacked/base'
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
24
|
+
extend ActiveSupport::Autoload
|
25
|
+
|
26
|
+
autoload :Client
|
28
27
|
autoload :Answer
|
29
28
|
autoload :Base
|
30
29
|
autoload :Badge
|
31
30
|
autoload :Comment
|
32
|
-
autoload :
|
31
|
+
autoload :PostTimeline
|
32
|
+
autoload :Parser
|
33
33
|
autoload :Question
|
34
|
-
autoload :
|
34
|
+
autoload :RepChange
|
35
35
|
autoload :Tag
|
36
36
|
autoload :User
|
37
|
-
autoload :
|
37
|
+
autoload :UserTimeline
|
38
38
|
|
39
|
+
# NotImplemented::StandardError class.
|
39
40
|
class NotImplemented < StandardError
|
41
|
+
# Default message for trying to call all/find on unsupported resources.
|
40
42
|
def message
|
41
43
|
"The requested action is not available in the API."
|
42
44
|
end
|
data/lib/stacked/answer.rb
CHANGED
@@ -1,43 +1,26 @@
|
|
1
1
|
module Stacked
|
2
|
+
# Stacked::Answer class.
|
2
3
|
class Answer < Base
|
3
|
-
|
4
|
-
:answer_id,
|
5
|
-
:body,
|
6
|
-
:comments,
|
7
|
-
:community_owned,
|
8
|
-
:creation_date,
|
9
|
-
:down_vote_count,
|
10
|
-
:last_edit_date,
|
11
|
-
:owner_display_name,
|
12
|
-
:owner_user_id,
|
13
|
-
:question_id,
|
14
|
-
:score,
|
15
|
-
:title,
|
16
|
-
:up_vote_count,
|
17
|
-
:view_count
|
18
|
-
|
4
|
+
|
19
5
|
class << self
|
20
6
|
def all(*args)
|
21
7
|
raise Stacked::NotImplemented
|
22
8
|
end
|
23
9
|
end
|
24
10
|
|
25
|
-
#
|
26
|
-
def
|
27
|
-
|
11
|
+
# Comments for the answer.
|
12
|
+
def comments(options={})
|
13
|
+
parse_comments(request(singular(answer_id) + "/comments", options))
|
14
|
+
end
|
15
|
+
|
16
|
+
# Helper method for creating Stacked::User object when initializing new Stacked::Answer objects.
|
17
|
+
def owner=(attributes)
|
18
|
+
@owner = User.new(attributes)
|
28
19
|
end
|
29
20
|
|
30
21
|
# A Stacked::Question object representing the question the answer is in response to.
|
31
22
|
def question
|
32
23
|
@question ||= Question.find(question_id)
|
33
24
|
end
|
34
|
-
|
35
|
-
alias_method :created_at, :creation_date
|
36
|
-
alias_method :updated_at, :last_edit_date
|
37
|
-
alias_method :id, :answer_id
|
38
|
-
alias_method :up_votes, :up_vote_count
|
39
|
-
alias_method :views, :view_count
|
40
|
-
alias_method :user, :owner
|
41
25
|
end
|
42
|
-
|
43
26
|
end
|
data/lib/stacked/badge.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
module Stacked
|
2
|
+
# Stacked::Badge class.
|
2
3
|
class Badge < Base
|
3
|
-
attr_accessor :award_count,
|
4
|
-
:badge_id,
|
5
|
-
:class,
|
6
|
-
:description,
|
7
|
-
:name
|
8
|
-
|
9
|
-
collection :tags
|
10
|
-
|
11
|
-
alias_method :id, :badge_id
|
12
|
-
|
13
4
|
class << self
|
14
|
-
|
5
|
+
# All users who have been awarded the specific badge.
|
6
|
+
def find(id, options = {})
|
7
|
+
parse_users(request(singular(id), options))
|
8
|
+
end
|
9
|
+
|
10
|
+
# All standard, non-tag-based badges.
|
11
|
+
def name(options={})
|
12
|
+
records(path + "/name", options)
|
13
|
+
end
|
14
|
+
|
15
|
+
# All tag-based badges
|
16
|
+
def tags(options={})
|
17
|
+
records(path + "/tags", options)
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
end
|
data/lib/stacked/base.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'httparty'
|
2
|
-
require '
|
2
|
+
require 'zlib'
|
3
3
|
|
4
4
|
module Stacked
|
5
|
+
# Stacked::Base class.
|
5
6
|
class Base
|
6
7
|
include HTTParty
|
8
|
+
extend Stacked::Parser
|
7
9
|
|
8
10
|
delegate :request, :singular, :parse, :to => "self.class"
|
9
11
|
|
@@ -11,17 +13,32 @@ module Stacked
|
|
11
13
|
|
12
14
|
# Return the stats provided by the API.
|
13
15
|
def stats
|
14
|
-
request(base + "stats")["
|
16
|
+
request(base + "stats")["statistics"].first
|
15
17
|
end
|
16
18
|
|
17
|
-
# All the
|
19
|
+
# All the of records for current class (depends on pagesize).
|
18
20
|
def all(options = {})
|
19
21
|
records(path, options)
|
20
22
|
end
|
21
23
|
|
22
|
-
# A single record belonging to the current class.
|
23
|
-
def find(
|
24
|
-
|
24
|
+
# A single (or multiple depending on number of ids) record belonging to the current class.
|
25
|
+
def find(*args)
|
26
|
+
# Determine ids (single or multiple)
|
27
|
+
ids = []
|
28
|
+
if args.first.instance_of? Fixnum
|
29
|
+
ids << args.first
|
30
|
+
elsif args.first.instance_of? Array
|
31
|
+
ids.concat(args.first)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Options hash supplied? Merge in options
|
35
|
+
options = {}
|
36
|
+
if args.last.instance_of? Hash
|
37
|
+
options.merge!(args.last)
|
38
|
+
end
|
39
|
+
|
40
|
+
recs = records(path_with_ids(ids), options)
|
41
|
+
recs.size == 1 ? recs.first : recs
|
25
42
|
end
|
26
43
|
|
27
44
|
# All records for a given request path.
|
@@ -29,50 +46,37 @@ module Stacked
|
|
29
46
|
parse(request(p, options)[resource])
|
30
47
|
end
|
31
48
|
|
32
|
-
#
|
49
|
+
# Makes request to StackExchange server and decodes it from gzip.
|
33
50
|
def request(p = path, options = {})
|
34
|
-
get(p, :query => { :key => key }.merge!(options))
|
35
|
-
|
36
|
-
|
37
|
-
# Define collection methods, such as newest.
|
38
|
-
def collection(*names)
|
39
|
-
# Forgive me Matz for I have sinned.
|
40
|
-
for name in names
|
41
|
-
eval <<-EVAL
|
42
|
-
def self.#{name}(options = {})
|
43
|
-
records(path + "#{name}", options)
|
44
|
-
end
|
45
|
-
EVAL
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# Defines association methods for things such as comments on questions.
|
50
|
-
def association(assoc)
|
51
|
-
instance_eval do
|
52
|
-
assoc = assoc.to_s
|
53
|
-
define_method("#{assoc}=") do |records|
|
54
|
-
instance_variable_set("@#{assoc}", records.map { |record| "Stacked::#{assoc.classify}".constantize.new(record) })
|
55
|
-
end
|
56
|
-
|
57
|
-
define_method(assoc) { instance_variable_get("@#{assoc}") }
|
58
|
-
end
|
51
|
+
result = StringIO.new(get(p, :query => { :key => key }.merge!(options)).body)
|
52
|
+
JSON.parse(Zlib::GzipReader.new(result).read)
|
59
53
|
end
|
60
54
|
|
61
55
|
# The path to the singular resource.
|
62
56
|
def singular(id)
|
63
|
-
path + id.to_s
|
57
|
+
path + '/' + id.to_s
|
58
|
+
end
|
59
|
+
|
60
|
+
# The path to either a singular or multiple resources.
|
61
|
+
def path_with_ids(ids)
|
62
|
+
path + '/' + ids.join(';')
|
63
|
+
end
|
64
|
+
|
65
|
+
# Convert a user result into a collection of Stacked::User objects.
|
66
|
+
def parse_users(result)
|
67
|
+
parse(result['users'], "Stacked::User".constantize)
|
64
68
|
end
|
65
69
|
|
66
70
|
private
|
67
71
|
|
68
|
-
# The root URL of the API
|
72
|
+
# The root URL of the API.
|
69
73
|
def base
|
70
|
-
|
74
|
+
Stacked::Client.base_url
|
71
75
|
end
|
72
76
|
|
73
|
-
# The key to let us in.
|
77
|
+
# The api key to let us in.
|
74
78
|
def key
|
75
|
-
|
79
|
+
Stacked::Client.api_key
|
76
80
|
end
|
77
81
|
|
78
82
|
# Convert the records into actual objects.
|
@@ -82,9 +86,7 @@ module Stacked
|
|
82
86
|
|
83
87
|
# The path to this particular part of the API.
|
84
88
|
# Example if the class is Stacked::Question:
|
85
|
-
#
|
86
|
-
# http://api.stackoverflow.com/0.5/questions
|
87
|
-
|
89
|
+
# http://api.stackoverflow.com/1.0/questions
|
88
90
|
def path
|
89
91
|
base + resource
|
90
92
|
end
|
@@ -94,66 +96,31 @@ module Stacked
|
|
94
96
|
self.to_s.demodulize.downcase.pluralize
|
95
97
|
end
|
96
98
|
end
|
97
|
-
|
98
|
-
# Convert an answers result into a collection of Stacked::Answer objects.
|
99
|
-
def parse_answers(result)
|
100
|
-
parse_type(result, "answer")
|
101
|
-
end
|
102
|
-
|
103
|
-
# Convert a badges result into a collection of Stacked::Badge objects.
|
104
|
-
def parse_badges(result)
|
105
|
-
parse_type(result, "badge")
|
106
|
-
end
|
107
|
-
|
108
|
-
# Convert a comments result into a collection of Stacked::Comment objects.
|
109
|
-
def parse_comments(result)
|
110
|
-
parse_type(result, "comment")
|
111
|
-
end
|
112
|
-
|
113
|
-
# Convert a post timeline result into a collection of Stacked::Posttimeline objects.
|
114
|
-
def parse_post_timeline(result)
|
115
|
-
parse_type(result, "posttimeline")
|
116
|
-
end
|
117
|
-
|
118
|
-
# Convert a questions result into a collection of Stacked::Question objects.
|
119
|
-
def parse_questions(result)
|
120
|
-
parse_type(result, "question")
|
121
|
-
end
|
122
|
-
|
123
|
-
# Convert a reputation result into a collection of Stacked::Reputation objects.
|
124
|
-
def parse_reputations(result)
|
125
|
-
parse_type(result, "reputation")
|
126
|
-
end
|
127
|
-
|
128
|
-
# Convert a tags result into a collection of Stacked::Tag objects.
|
129
|
-
def parse_tags(result)
|
130
|
-
parse_type(result, "tag")
|
131
|
-
end
|
132
|
-
|
133
|
-
# Convert a user timeline result into a collection of Stacked::Usertimeline objects.
|
134
|
-
def parse_user_timeline(result)
|
135
|
-
parse_type(result, "usertimeline")
|
136
|
-
end
|
137
99
|
|
138
|
-
#
|
139
|
-
def
|
140
|
-
|
100
|
+
# Builds attr_accessor for each attribute found in the reponse.
|
101
|
+
def define_attributes(hash={})
|
102
|
+
hash.each_pair do |key, value|
|
103
|
+
self.class.send(:attr_writer, key) unless respond_to?("#{key}=".to_sym)
|
104
|
+
self.class.send(:attr_reader, key) unless respond_to?("#{key}".to_sym)
|
105
|
+
send "#{key}=".to_sym, value
|
106
|
+
end
|
141
107
|
end
|
142
108
|
|
143
109
|
public
|
144
110
|
|
145
|
-
# Finds a post based on the +post_type+ and +post_id+
|
146
|
-
def post
|
147
|
-
"Stacked::#{post_type.classify}".constantize.find(post_id)
|
148
|
-
end
|
149
|
-
|
150
111
|
# Creates a new object of the given class based on the attributes passed in.
|
151
|
-
def initialize(attributes)
|
152
|
-
|
153
|
-
|
112
|
+
def initialize(attributes={})
|
113
|
+
define_attributes(attributes)
|
114
|
+
|
154
115
|
attributes.each do |k, v|
|
155
|
-
|
116
|
+
attr_sym = "#{k}=".to_sym
|
117
|
+
self.send(attr_sym, v) if self.respond_to?(attr_sym)
|
156
118
|
end
|
157
119
|
end
|
120
|
+
|
121
|
+
# Finds a post based on the +post_type+ and +post_id+
|
122
|
+
def post
|
123
|
+
"Stacked::#{post_type.classify}".constantize.find(post_id)
|
124
|
+
end
|
158
125
|
end
|
159
126
|
end
|