rubyoverflow 1.0.2 → 2.0.2.pre1

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 (61) hide show
  1. data/.gitignore +5 -0
  2. data/.rvmrc +47 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE +1 -1
  6. data/README.rdoc +14 -20
  7. data/RELEASENOTES +1 -97
  8. data/Rakefile +7 -49
  9. data/lib/rubyoverflow.rb +46 -108
  10. data/lib/rubyoverflow/answers.rb +5 -57
  11. data/lib/rubyoverflow/base.rb +21 -68
  12. data/lib/rubyoverflow/questions.rb +5 -101
  13. data/lib/rubyoverflow/sites.rb +18 -0
  14. data/lib/rubyoverflow/stats.rb +8 -0
  15. data/lib/rubyoverflow/users.rb +5 -70
  16. data/lib/rubyoverflow/version.rb +3 -0
  17. data/rubyoverflow.gemspec +26 -0
  18. data/spec/answers_spec.rb +13 -0
  19. data/spec/questions_spec.rb +13 -0
  20. data/spec/sites_spec.rb +18 -0
  21. data/spec/spec_helper.rb +3 -0
  22. data/spec/stats_spec.rb +12 -0
  23. data/spec/users_spec.rb +23 -0
  24. metadata +94 -121
  25. data/VERSION +0 -1
  26. data/lib/rubyoverflow/answer.rb +0 -61
  27. data/lib/rubyoverflow/apiSite.rb +0 -32
  28. data/lib/rubyoverflow/apiSites.rb +0 -25
  29. data/lib/rubyoverflow/apiVersion.rb +0 -6
  30. data/lib/rubyoverflow/badge.rb +0 -44
  31. data/lib/rubyoverflow/badgeCounts.rb +0 -22
  32. data/lib/rubyoverflow/badges.rb +0 -59
  33. data/lib/rubyoverflow/comment.rb +0 -41
  34. data/lib/rubyoverflow/comments.rb +0 -115
  35. data/lib/rubyoverflow/errors.rb +0 -17
  36. data/lib/rubyoverflow/pagedBase.rb +0 -27
  37. data/lib/rubyoverflow/pagedDash.rb +0 -7
  38. data/lib/rubyoverflow/postTimelineEvent.rb +0 -93
  39. data/lib/rubyoverflow/postTimelineEvents.rb +0 -39
  40. data/lib/rubyoverflow/question.rb +0 -110
  41. data/lib/rubyoverflow/repChange.rb +0 -34
  42. data/lib/rubyoverflow/repChanges.rb +0 -41
  43. data/lib/rubyoverflow/revision.rb +0 -62
  44. data/lib/rubyoverflow/revisions.rb +0 -52
  45. data/lib/rubyoverflow/statistics.rb +0 -57
  46. data/lib/rubyoverflow/styling.rb +0 -19
  47. data/lib/rubyoverflow/tag.rb +0 -27
  48. data/lib/rubyoverflow/tags.rb +0 -46
  49. data/lib/rubyoverflow/user.rb +0 -181
  50. data/lib/rubyoverflow/userTimelineEvent.rb +0 -43
  51. data/lib/rubyoverflow/userTimelineEvents.rb +0 -35
  52. data/test/apiKey.rb +0 -5
  53. data/test/helper.rb +0 -159
  54. data/test/test_answer.rb +0 -20
  55. data/test/test_answers.rb +0 -32
  56. data/test/test_badge.rb +0 -18
  57. data/test/test_badges.rb +0 -30
  58. data/test/test_base.rb +0 -63
  59. data/test/test_statistics.rb +0 -26
  60. data/test/test_user.rb +0 -56
  61. data/test/test_users.rb +0 -37
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .rspec
data/.rvmrc ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # This is an RVM Project .rvmrc file, used to automatically load the ruby
4
+ # development environment upon cd'ing into the directory
5
+
6
+ # First we specify our desired <ruby>[@<gemset>], the @gemset name is optional.
7
+ environment_id="ruby-1.9.2-p290@rubyoverflow"
8
+
9
+ #
10
+ # Uncomment following line if you want options to be set only for given project.
11
+ #
12
+ # PROJECT_JRUBY_OPTS=( --1.9 )
13
+
14
+ #
15
+ # First we attempt to load the desired environment directly from the environment
16
+ # file. This is very fast and efficient compared to running through the entire
17
+ # CLI and selector. If you want feedback on which environment was used then
18
+ # insert the word 'use' after --create as this triggers verbose mode.
19
+ #
20
+ if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
21
+ && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
22
+ then
23
+ \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
24
+
25
+ if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
26
+ then
27
+ . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
28
+ fi
29
+ else
30
+ # If the environment file has not yet been created, use the RVM CLI to select.
31
+ if ! rvm --create use "$environment_id"
32
+ then
33
+ echo "Failed to create RVM environment '${environment_id}'."
34
+ exit 1
35
+ fi
36
+ fi
37
+
38
+ #
39
+ # If you use an RVM gemset file to install a list of gems (*.gems), you can have
40
+ # it be automatically loaded. Uncomment the following and adjust the filename if
41
+ # necessary.
42
+ #
43
+ # filename=".gems"
44
+ # if [[ -s "$filename" ]] ; then
45
+ # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
46
+ # fi
47
+
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ - 1.9.3
5
+
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "http://rubygems.org"
2
+ gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 phsr
1
+ Copyright (c) 2010 Dan Seaver
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -2,33 +2,27 @@
2
2
 
3
3
  rubyoverflow is a library for querying the Stack Overflow API
4
4
 
5
- == Configuration
5
+ == Build Status
6
+ {<img src="https://secure.travis-ci.org/danseaver/rubyoverflow.png" />}[http://travis-ci.org/danseaver/rubyoverflow]
7
+
8
+ == Dependency Status
9
+ {<img src="https://gemnasium.com/danseaver/rubyoverflow.png" alt="Dependency Status Gemnasium" />}[https://gemnasium.com/danseaver/rubyoverflow]
6
10
 
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
12
11
 
13
12
  == Example
14
13
 
15
14
  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
15
+
16
+ c = Rubyoverflow::Client.new
17
+ result = c.users.fetch(:id => 53587) # By default, this will query StackOverflow.com
18
+ me = result.users.first # Get the first user out of the results
19
+ puts me.display_name # => "Dan Seaver"
28
20
 
29
21
 
22
+ c = Rubyoverflow::Client.new :host => "http://api.serverfault.com" # Query ServerFault.com
23
+
30
24
  == Note on Patches/Pull Requests
31
-
25
+
32
26
  * Fork the project.
33
27
  * Make your feature addition or bug fix.
34
28
  * Add tests for it. This is important so I don't break it in a
@@ -39,5 +33,5 @@ rubyoverflow is a library for querying the Stack Overflow API
39
33
 
40
34
  == Copyright
41
35
 
42
- Copyright (c) 2010 phsr. See LICENSE for details.
36
+ Copyright (c) 2011 Dan Seaver. See LICENSE for details.
43
37
 
@@ -1,98 +1,2 @@
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
-
67
1
  [0.5.0]
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
2
+ Restarting rubyoverflow development, paths /sites and /users (only, no sub-paths) covered
data/Rakefile CHANGED
@@ -1,52 +1,10 @@
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
-
1
+ require 'bundler/gem_tasks'
24
2
 
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
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'
37
8
  end
38
9
 
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
10
+ task :default => :spec
@@ -1,119 +1,67 @@
1
1
  path = File.expand_path(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
3
3
 
4
- require 'httparty'
5
- require 'zlib'
4
+ require 'faraday'
6
5
  require 'ostruct'
7
- require 'hashie'
6
+ require 'zlib'
8
7
 
8
+ require 'hashie'
9
+ require 'json'
9
10
  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'
11
+ require 'rubyoverflow/sites'
12
+ require 'rubyoverflow/stats'
23
13
  require 'rubyoverflow/users'
24
-
25
- require 'rubyoverflow/answer'
26
14
  require 'rubyoverflow/answers'
27
-
28
- require 'rubyoverflow/question'
29
15
  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'
16
+ require "rubyoverflow/version"
49
17
 
50
18
  module Rubyoverflow
51
19
  class Client
52
- include HTTParty
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
57
20
  HOST = 'http://api.stackoverflow.com'
58
21
  VERSION = '1.1'
59
22
 
60
- attr_reader :host
61
- attr_reader :api_key
62
-
63
- def initialize(options = OpenStruct.new)
64
- if options.kind_of? OpenStruct
65
- @host = options.host || HOST
66
- @version = options.version || VERSION
67
- @api_key = options.api_key if options.api_key
23
+ Rubyoverflow.constants.select {|c| Class === Rubyoverflow.const_get(c) and Rubyoverflow.const_get(c) < Rubyoverflow::Base}.each do |class_sym|
24
+ send :attr_reader, class_sym.downcase
25
+ send "define_method", class_sym.downcase do
26
+ instance_variable_set("@#{class_sym.downcase}", Rubyoverflow.const_get(class_sym).new(self)) unless instance_variable_get("@#{class_sym.downcase}")
27
+ instance_variable_get "@#{class_sym.downcase}"
68
28
  end
69
-
70
-
71
29
  end
72
-
73
-
74
-
75
- def request(path, parameters)
76
- parameters['key'] = @api_key if @api_key
77
- url = host_path + normalize(path) + query_string(parameters)
78
- response = self.class.get url
79
- return response.parsed_response, url
80
- end
81
-
82
- def host_path
83
- normalize(@host) + normalize(@version)
30
+
31
+ attr_accessor :host
32
+ attr_accessor :api_key
33
+
34
+ def initialize(options = {})
35
+ @host = options[:host] || HOST
36
+ @version = options[:version] || VERSION
37
+ @api_key = options[:api_key] if options[:api_key]
84
38
  end
85
-
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
39
 
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)
40
+ def request(path, parameters = {})
41
+ conn = Faraday.new(:url => host_path) do |builder|
42
+ builder.request :url_encoded
43
+ builder.request :json
44
+ builder.adapter :net_http
107
45
  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
46
+ parameters[:key] = @api_key unless @api_key.nil? || @api_key.empty?
47
+ parameters['Accept-Encoding'] = 'gzip'
48
+ response = conn.get do |req|
49
+ req.url normalize(path), parameters
115
50
  end
116
-
51
+ rep_string = response.body
52
+ begin
53
+ gz = Zlib::GzipReader.new(StringIO.new(response.body.to_s))
54
+ rep_string = gz.read
55
+ rescue Zlib::GzipFile::Error
56
+ end
57
+ return JSON.parse(rep_string), response.env[:url]
58
+ end
59
+
60
+ def host_path
61
+ "#{normalize(@host)}#{normalize(@version)}"
62
+ end
63
+
64
+ class << self
117
65
  def stackauth_client(api_key = '')
118
66
  options = OpenStruct.new
119
67
  options.host = 'http://stackauth.com/'
@@ -123,19 +71,9 @@ module Rubyoverflow
123
71
  end
124
72
 
125
73
  private
74
+
126
75
  def normalize(path)
127
- path.end_with?('/') ? path : path+ '/'
76
+ path.end_with?('/') ? path : path + '/'
128
77
  end
129
-
130
- def query_string(parameters)
131
- if !parameters.empty?
132
- params = parameters.sort_by { |k, v| k.to_s }
133
- pairs = params.map { |key, value| "#{key}=#{value}" }
134
-
135
- '?' + pairs.join('&') + "&jsonp"
136
- else
137
- ''
138
- end
139
- end
140
78
  end
141
- end
79
+ end