rubyoverflow 0.5 → 1.0.2

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.
Files changed (56) hide show
  1. data/README.rdoc +22 -11
  2. data/RELEASENOTES +97 -1
  3. data/Rakefile +49 -7
  4. data/VERSION +1 -1
  5. data/lib/rubyoverflow.rb +92 -18
  6. data/lib/rubyoverflow/answer.rb +61 -0
  7. data/lib/rubyoverflow/answers.rb +60 -0
  8. data/lib/rubyoverflow/apiSite.rb +32 -0
  9. data/lib/rubyoverflow/apiSites.rb +25 -0
  10. data/lib/rubyoverflow/apiVersion.rb +6 -0
  11. data/lib/rubyoverflow/badge.rb +44 -0
  12. data/lib/rubyoverflow/badgeCounts.rb +22 -0
  13. data/lib/rubyoverflow/badges.rb +59 -0
  14. data/lib/rubyoverflow/base.rb +76 -0
  15. data/lib/rubyoverflow/comment.rb +41 -0
  16. data/lib/rubyoverflow/comments.rb +115 -0
  17. data/lib/rubyoverflow/errors.rb +17 -0
  18. data/lib/rubyoverflow/pagedBase.rb +27 -0
  19. data/lib/rubyoverflow/pagedDash.rb +7 -0
  20. data/lib/rubyoverflow/postTimelineEvent.rb +93 -0
  21. data/lib/rubyoverflow/postTimelineEvents.rb +39 -0
  22. data/lib/rubyoverflow/question.rb +110 -0
  23. data/lib/rubyoverflow/questions.rb +104 -0
  24. data/lib/rubyoverflow/repChange.rb +34 -0
  25. data/lib/rubyoverflow/repChanges.rb +41 -0
  26. data/lib/rubyoverflow/revision.rb +62 -0
  27. data/lib/rubyoverflow/revisions.rb +52 -0
  28. data/lib/rubyoverflow/statistics.rb +57 -0
  29. data/lib/rubyoverflow/styling.rb +19 -0
  30. data/lib/rubyoverflow/tag.rb +27 -0
  31. data/lib/rubyoverflow/tags.rb +46 -0
  32. data/lib/rubyoverflow/user.rb +181 -0
  33. data/lib/rubyoverflow/userTimelineEvent.rb +43 -0
  34. data/lib/rubyoverflow/userTimelineEvents.rb +35 -0
  35. data/lib/rubyoverflow/users.rb +67 -18
  36. data/test/apiKey.rb +5 -0
  37. data/test/helper.rb +159 -0
  38. data/test/test_answer.rb +20 -0
  39. data/test/test_answers.rb +32 -0
  40. data/test/test_badge.rb +18 -0
  41. data/test/test_badges.rb +30 -0
  42. data/test/test_base.rb +63 -0
  43. data/test/test_statistics.rb +26 -0
  44. data/test/test_user.rb +56 -0
  45. data/test/test_users.rb +37 -0
  46. metadata +122 -87
  47. data/.gitignore +0 -4
  48. data/.rvmrc +0 -47
  49. data/.travis.yml +0 -5
  50. data/Gemfile +0 -3
  51. data/lib/rubyoverflow/sites.rb +0 -20
  52. data/lib/rubyoverflow/version.rb +0 -3
  53. data/rubyoverflow.gemspec +0 -26
  54. data/spec/sites_spec.rb +0 -18
  55. data/spec/spec_helper.rb +0 -3
  56. data/spec/users_spec.rb +0 -23
@@ -1,23 +1,34 @@
1
1
  = rubyoverflow
2
2
 
3
- {<img src="https://secure.travis-ci.org/phsr/rubyoverflow.png" />}[http://travis-ci.org/phsr/rubyoverflow]
4
-
5
3
  rubyoverflow is a library for querying the Stack Overflow API
6
4
 
7
- == Example
5
+ == Configuration
8
6
 
9
- require 'rubyoverflow'
7
+ Rubyoverflow::Client.config do |options|
8
+ options.host = 'http://api.superuser.com' # optional, defaults to stackoverflow, queries super user
9
+ options.api_key = 'api_key_here' # optional, sets the api key
10
+ options.version = '0.8' # optional, defaults to 0.8,sets the api version
11
+ end
10
12
 
11
- c = Rubyoverflow::Client.new
12
- result = c.users.fetch(:id => 53587) # By default, this will query StackOverflow.com
13
- me = result.users.first # Get the first user out of the results
14
- puts me.display_name # => "Dan Seaver"
13
+ == Example
15
14
 
15
+ require 'rubyoverflow'
16
+ include Rubyoverflow
17
+ # Tags Example
18
+ tagsSet = Tags.retrieve_all({:sort=>'name',:order=>'asc',:pagesize=>'5'}) # gets the first 5 tags in alphabetical order by name
19
+ firstTag = tagsSet.tags.first # gets the first tag
20
+ secondTagSet = tagsSet.get_next_set #gets the next page of tags using the prior parameters
21
+ thirdTagSet = secondTagSet.get_next_set #gets the third page of tags using the prior parameters
22
+ puts firstTag.name # => tag's name
23
+ puts tag.count # => # of questions with tag
24
+
25
+ #User Example
26
+ me = Users.retrieve_by_id(53587).users.first #gets me
27
+ myquestions = me.get_questions #gets the questions I asked
16
28
 
17
- c = Rubyoverflow::Client.new :host => "api.serverfault.com" # Query ServerFault.com
18
29
 
19
30
  == Note on Patches/Pull Requests
20
-
31
+
21
32
  * Fork the project.
22
33
  * Make your feature addition or bug fix.
23
34
  * Add tests for it. This is important so I don't break it in a
@@ -28,5 +39,5 @@ rubyoverflow is a library for querying the Stack Overflow API
28
39
 
29
40
  == Copyright
30
41
 
31
- Copyright (c) 2011 Dan Seaver. See LICENSE for details.
42
+ Copyright (c) 2010 phsr. See LICENSE for details.
32
43
 
@@ -1,2 +1,98 @@
1
+ [1.0.1]
2
+ Minor formatting refactorings
3
+ Setup tests with rspec
4
+ Updated Client.new to accept an ApiSite
5
+ Added Styling class
6
+ Added styling and state to ApiSite (was previously missing)
7
+ Added change_end_point to Client and Base classes (accessible from any querying class)
8
+ Removed display_name from Statistics
9
+ Added site, total_accepted, and view_per_day from Statistics (was previously missing)
10
+ Added tests for Answer and Answers
11
+ Added tests for Base and got Base.convert_if_array working correctly
12
+ Replaced convert_if_array to convert_to_id_list
13
+ Added User#item_id
14
+ Added tests for Badge and Badges
15
+ Completed check_badge_set stub in test/helper
16
+ Added item_id to badge so that you can pass an array containing badges to a method
17
+ Updated convert_if_array to append the id of an item if that class defines the item_id method
18
+ Added protected_date to Question (previously missing)
19
+ Removed parameters from User#get_badges, as the route doesn't support parameters
20
+ Update Users.retrieve_by_badge to support a Badge as a parameter
21
+ Stubbed out test helper methods for checking class sets
22
+ Completed unit tests for Users and User classes
23
+
24
+
25
+ [1.0.0]
26
+ Updated PostTimelineEvent to implement new property, question_id
27
+ Updated get_post to properly handle the post being a question or answer
28
+ Added get_parent_question to PostTimelineEvent
29
+
30
+ [0.9.1]
31
+ Switched from using Open-URI+GZIP+JSON to HTTParty
32
+
33
+ [0.9.0]
34
+ Updated API_VERSION to match the Stack Exchange API version
35
+
36
+ [0.8.4]
37
+ Added ApiSite and ApiSites as well as ApiSites.retrieve_sites to retrieve all API endpoints known to the Stack Exchange API
38
+ Added the class method Users.retrieve_associated_accounts and the instance method User.retrieve_associated_accounts, which calls the Users.retrieve_associated_accounts method with the instance's associated_id
39
+
40
+ [0.8.3]
41
+ Added Badge#get_recipients
42
+ Added Answer#get_comments
43
+ Added Users.get_moderators
44
+ Added PostTimelineEvent#get_post, PostTimelineEvent#get_post_comment, and PostTimelineEvent#get_revision
45
+ Added Question#get_timeline, Question#get_answers, Question#get_comments
46
+
47
+ [0.8.2]
48
+ Added get_next_set to paged results, retrieve the next set using the same parameters that were used to retrieve the initial set
49
+ Added methods to get answers, questions, favorites, etc from a user that has been retrieved
50
+
51
+ [0.8.1]
52
+ All classes moved into the Rubyoverflow module
53
+
54
+ [0.8.0]
55
+ Added Revision and Revisions, along with revision retrieval methods
56
+ Added Questions.search which maps to '/search'
57
+ Added Errors
58
+
59
+ [0.6.0]
60
+ Added RepChange and RepChanges with RepChanges.retrieve_by_user
61
+ Added UserTimeLineEvent and UserTimeLineEvents with UserTimeLineEvent.retrieve_by_user
62
+ Added PostTimeLineEvent and PostTimeLineEvents with PostTimeLineEvent.retrieve_by_question
63
+
64
+ [0.5.1]
65
+ Removed @dash member from classes, as it is only used in initialize, shrinking memory usage of classes
66
+
1
67
  [0.5.0]
2
- Restarting rubyoverflow development, paths /sites and /users (only, no sub-paths) covered
68
+ Added Question and Questions with question retrieval methods
69
+
70
+ [0.4.1]
71
+ Added Users and retrieve, retrieve_by_id and retrieve_by_badge
72
+
73
+ [0.4.0]
74
+ Added Comment and Answer wrappers
75
+ Added retrieval methods for comments and answers
76
+
77
+ [0.3.2]
78
+ Update Badges.retrieve_by_user(id) and Tags.retrieve_by_user(id) to accept an array of ids
79
+
80
+ [0.3.1]
81
+ Added Badges.retrieve_by_user(id)
82
+ Fixed User class (added if to creation of BadgesCount member)
83
+
84
+ [0.3.0]
85
+ Mapped User, Badge, BadgeCount, Badges
86
+ Added PagedBase and PagedDash to reuse common properties of paged queries
87
+ Added Badges.retrieve_all, retrieve_all_non_tag_based and retrieve_all_tag_based
88
+ Refactored Tags to use new PagedBase and PagedDash classes
89
+
90
+ [0.2.3]
91
+ Tags.retrieve_by_user(id,parameters) gets tags that the user has participated in
92
+
93
+ [0.2.0-2]
94
+ Added support for query string, api key, other stack overflow sites
95
+ Added support for Tag retrieval
96
+
97
+ [0.1]
98
+ Initial Release, retrieves stack overflow statistics
data/Rakefile CHANGED
@@ -1,10 +1,52 @@
1
- require 'bundler/gem_tasks'
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rspec'
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rubyoverflow"
8
+ gem.summary = %Q{rubyoverflow is a library for querying the Stack Overflow API}
9
+ gem.description = %Q{rubyoverflow is a library for querying the Stack Overflow API}
10
+ gem.email = "phasor@phsr.org"
11
+ gem.homepage = "http://github.com/phsr/rubyoverflow"
12
+ gem.authors = ["phsr"]
13
+ gem.add_dependency 'httparty', '>=0'
14
+ gem.add_dependency 'hashie', '>=0'
15
+ gem.add_development_dependency "rspec", ">= 0"
16
+ gem.files.include FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
17
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
2
24
 
3
- require 'rspec/core/rake_task'
4
-
5
- RSpec::Core::RakeTask.new(:spec) do |t|
6
- t.pattern = 'spec/**/*_spec.rb'
7
- t.rspec_opts = '--format progress'
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/test_*.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
36
+ end
8
37
  end
9
38
 
10
- task :default => :spec
39
+
40
+ task :default => :test
41
+
42
+ task :doc => :rdoc
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "rubyoverflow #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5
1
+ 1.0.2
@@ -2,44 +2,118 @@ path = File.expand_path(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
3
3
 
4
4
  require 'httparty'
5
+ require 'zlib'
5
6
  require 'ostruct'
6
-
7
7
  require 'hashie'
8
- require 'json'
9
- require 'rubyoverflow/sites'
8
+
9
+ require 'rubyoverflow/base'
10
+ require 'rubyoverflow/pagedBase'
11
+ require 'rubyoverflow/pagedDash'
12
+
13
+ require 'rubyoverflow/apiVersion'
14
+ require 'rubyoverflow/badge'
15
+ require 'rubyoverflow/badges'
16
+ require 'rubyoverflow/comments'
17
+ require 'rubyoverflow/comment'
18
+ require 'rubyoverflow/badgeCounts'
19
+ require 'rubyoverflow/statistics'
20
+ require 'rubyoverflow/tag'
21
+ require 'rubyoverflow/tags'
22
+ require 'rubyoverflow/user'
10
23
  require 'rubyoverflow/users'
11
- require "rubyoverflow/version"
24
+
25
+ require 'rubyoverflow/answer'
26
+ require 'rubyoverflow/answers'
27
+
28
+ require 'rubyoverflow/question'
29
+ require 'rubyoverflow/questions'
30
+
31
+ require 'rubyoverflow/repChange'
32
+ require 'rubyoverflow/repChanges'
33
+
34
+ require 'rubyoverflow/userTimelineEvent'
35
+ require 'rubyoverflow/userTimelineEvents'
36
+
37
+ require 'rubyoverflow/postTimelineEvent'
38
+ require 'rubyoverflow/postTimelineEvents'
39
+
40
+ require 'rubyoverflow/revision'
41
+ require 'rubyoverflow/revisions'
42
+
43
+ require 'rubyoverflow/errors'
44
+
45
+ require 'rubyoverflow/styling'
46
+
47
+ require 'rubyoverflow/apiSite'
48
+ require 'rubyoverflow/apiSites'
12
49
 
13
50
  module Rubyoverflow
14
51
  class Client
15
52
  include HTTParty
16
- format :plain
53
+ format :json
54
+ #Most of this class is borrowed from the Pilha (http://github.com/dlt/pilha) project because a) it works, b) a lot of this code would be the same regardless of implementation
55
+ # (especially the open => gzip code, query string, and normalize), and c) I'm new to ruby, so I'm going to skip pass some of the more 'boring' stuff and get to the
56
+ # interesting parts. I plan to re-examine this at a later point
17
57
  HOST = 'http://api.stackoverflow.com'
18
58
  VERSION = '1.1'
19
59
 
20
- attr_accessor :host
21
- attr_accessor :api_key
22
-
60
+ attr_reader :host
61
+ attr_reader :api_key
62
+
23
63
  def initialize(options = OpenStruct.new)
24
64
  if options.kind_of? OpenStruct
25
65
  @host = options.host || HOST
26
66
  @version = options.version || VERSION
27
67
  @api_key = options.api_key if options.api_key
28
68
  end
69
+
70
+
29
71
  end
30
-
31
- def request(path, parameters = {})
32
- parameters['key'] = @api_key unless @api_key.nil? || @api_key.empty?
72
+
73
+
74
+
75
+ def request(path, parameters)
76
+ parameters['key'] = @api_key if @api_key
33
77
  url = host_path + normalize(path) + query_string(parameters)
34
78
  response = self.class.get url
35
- return JSON.parse(response.body), url
79
+ return response.parsed_response, url
36
80
  end
37
-
81
+
38
82
  def host_path
39
83
  normalize(@host) + normalize(@version)
40
84
  end
41
-
85
+
42
86
  class << self
87
+ # this specifically works well, and I don't fully understand it, so I borrowed this from Pilha more than anything else
88
+ # If you want to explain why I only have to configure this once than forget about it, please do, because this stuff is currently over my head
89
+ def config &block
90
+ options = OpenStruct.new
91
+ yield options if block_given?
92
+ init_client! Client.new(options)
93
+ end
94
+
95
+ def change_end_point(val = nil)
96
+ options = OpenStruct.new
97
+ if val.kind_of? ApiSite
98
+ options.host = val.api_endpoint
99
+ end
100
+
101
+ if val.kind_of? String
102
+ options.host = val
103
+ end
104
+ options.api_key = Base.client.api_key
105
+
106
+ init_client! Client.new(options)
107
+ end
108
+
109
+ def init_client!(client)
110
+ base_eigenclass = class << Base; self; end
111
+ base_eigenclass.send :define_method, :client do
112
+ @client = client
113
+ end
114
+ client
115
+ end
116
+
43
117
  def stackauth_client(api_key = '')
44
118
  options = OpenStruct.new
45
119
  options.host = 'http://stackauth.com/'
@@ -52,16 +126,16 @@ module Rubyoverflow
52
126
  def normalize(path)
53
127
  path.end_with?('/') ? path : path+ '/'
54
128
  end
55
-
129
+
56
130
  def query_string(parameters)
57
131
  if !parameters.empty?
58
132
  params = parameters.sort_by { |k, v| k.to_s }
59
133
  pairs = params.map { |key, value| "#{key}=#{value}" }
60
-
61
- '?' + pairs.join('&')
134
+
135
+ '?' + pairs.join('&') + "&jsonp"
62
136
  else
63
137
  ''
64
138
  end
65
139
  end
66
140
  end
67
- end
141
+ end
@@ -0,0 +1,61 @@
1
+ module Rubyoverflow
2
+ class Answer < Base
3
+ attr_reader :answer_id, :accepted, :answer_comments_url, :question_id, :locked_date, :owner,
4
+ :creation_date, :last_edit_date, :last_activity_date, :up_vote_count, :down_vote_count,
5
+ :view_count, :score, :community_owned, :title, :body, :comments
6
+
7
+ def initialize(hash, request_path = '')
8
+ dash = AnswerDash.new hash
9
+
10
+ @answer_id = dash.answer_id
11
+ @accepted = dash.accepted
12
+ @answer_comments_url = dash.answer_comments_url
13
+ @question_id = dash.question_id
14
+ @locked_date = dash.locked_date
15
+ @owner = User.new dash.owner
16
+ @creation_date = dash.creation_date
17
+ @last_edit_date = dash.last_edit_date
18
+ @last_activity_date = dash.last_activity_date
19
+ @up_vote_count = dash.up_vote_count
20
+ @down_vote_count = dash.down_vote_count
21
+ @view_count = dash.view_count
22
+ @score = dash.score
23
+ @community_owned = dash.community_owned
24
+ @title = dash.title
25
+ @body = dash.body
26
+ @comments = Comments.new dash.comments if dash.comments
27
+ end
28
+
29
+ #Gets the comments made on the answer
30
+ def get_comments(parameters = {})
31
+ if @answer_comments_url
32
+ hash,url =request(@answer_comments_url, parameters)
33
+ Comments.new hash, url
34
+ else
35
+ nil
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ class AnswerDash < BaseDash
42
+
43
+ property :answer_id
44
+ property :accepted
45
+ property :answer_comments_url
46
+ property :question_id
47
+ property :locked_date
48
+ property :owner
49
+ property :creation_date
50
+ property :last_edit_date
51
+ property :last_activity_date
52
+ property :up_vote_count
53
+ property :down_vote_count
54
+ property :view_count
55
+ property :score
56
+ property :community_owned
57
+ property :title
58
+ property :body
59
+ property :comments
60
+ end
61
+ end
@@ -0,0 +1,60 @@
1
+ module Rubyoverflow
2
+ class Answers < PagedBase
3
+ attr_reader :answers
4
+
5
+ def initialize(hash, request_path = '')
6
+ dash = AnswersDash.new hash
7
+
8
+ @answers = Array.new
9
+ dash.answers.each {|answerHash| @answers.push(Answer.new answerHash)}
10
+
11
+ super(dash, request_path)
12
+ end
13
+
14
+ #Retrieves the next set of answers using the same parameters used to retrieve the current set
15
+ def get_next_set
16
+ hash,url = perform_next_page_request
17
+ Answers.new hash,url
18
+ end
19
+
20
+ class << self
21
+
22
+ #Retrieves a set of questions by their id(s)
23
+ #
24
+ #id can be an int, string, or an array of ints or strings
25
+ #
26
+ #Maps to '/answers/{id}'
27
+ def retrieve_by_id(id, parameters = {})
28
+ id = convert_to_id_list(id)
29
+ hash,url = request('answers/'+id.to_s, parameters)
30
+ Answers.new hash,url
31
+ end
32
+
33
+ #Retrieves a set of answers made by a set of users by their ids
34
+ #
35
+ #id can be an int, string, or an array of ints or strings
36
+ #
37
+ #Maps to 'users/{id}/answers'
38
+ def retrieve_by_user(id, parameters={})
39
+ id = convert_to_id_list(id)
40
+ hash, url = request('users/'+id.to_s+"/answers", parameters)
41
+ Answers.new hash, url
42
+ end
43
+
44
+ #Retrieves a set of answers from a set of questions by the questions' ids
45
+ #
46
+ #id can be an int, string, or an array of ints or strings
47
+ #
48
+ #Maps to 'questions/{id}/answers'
49
+ def retrieve_by_question(id, parameters={})
50
+ id = convert_to_id_list(id)
51
+ hash, url = request('questions/'+id.to_s+"/answers", parameters)
52
+ Answers.new hash, url
53
+ end
54
+ end
55
+ end
56
+
57
+ class AnswersDash < PagedDash
58
+ property :answers
59
+ end
60
+ end