serel 1.0.0.rc2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  # Utilities
2
+ require 'date'
2
3
  require 'logger'
3
4
  require 'serel/exts'
4
5
  require 'serel/relation'
@@ -5,7 +5,8 @@ module Serel
5
5
  # Creating a new AccessToken provides a couple of helper methods to access authorized methods and
6
6
  # identify who a user is.
7
7
  class AccessToken < Base
8
- attributes :token
8
+ attribute :token, String
9
+
9
10
  finder_methods :none
10
11
 
11
12
  # Create a new instance of AccessToken.
@@ -17,8 +18,8 @@ module Serel
17
18
  end
18
19
 
19
20
  # Retrieve the users' inbox items.
20
- # Serel::AccessToken.new(token).inbox.request
21
- # Serel::AccessToken.new(token).scoping_methods.inbox.request
21
+ # Serel::AccessToken.new(token).inbox.get
22
+ # Serel::AccessToken.new(token).scoping_methods.inbox.get
22
23
  #
23
24
  # This is a scoping method and can be combined with other scoping methods.
24
25
  # @return [Serel::Response] A list of {Serel::Inbox Inbox} items wrapped in our Response wrapper.
@@ -27,7 +28,7 @@ module Serel
27
28
  end
28
29
 
29
30
  # Retrieve the users' unread inbox items.
30
- # Serel::AccessToken.new(token).unread_inbox.request
31
+ # Serel::AccessToken.new(token).unread_inbox.get
31
32
  #
32
33
  # This is a scoping method and can be combined with other scoping methods.
33
34
  # @return [Serel::Response] A list of {Serel::Inbox Inbox} wrapped in our Response wrapper.
@@ -38,7 +39,7 @@ module Serel
38
39
  # Invalidates the access token
39
40
  # Serel::AccessToken.new(token).invalidate
40
41
  def invalidate
41
- network.url("access-tokens/#{token}/invalidate").request
42
+ network.url("access-tokens/#{token}/invalidate").get
42
43
  end
43
44
 
44
45
  # Retrieve the user associated with this access token.
@@ -48,7 +49,7 @@ module Serel
48
49
  #
49
50
  # @return [Serel::User] The user associated with the access token.
50
51
  def user
51
- type(:user, :singular).access_token(self.token).url("me").request
52
+ type(:user, :singular).access_token(self.token).url("me").get
52
53
  end
53
54
  end
54
55
  end
@@ -39,9 +39,23 @@ module Serel
39
39
  #
40
40
  # Retrieves answers by a given user
41
41
  class Answer < Base
42
- attributes :answer_id, :body, :community_owned_date, :creation_date, :down_vote_count, :is_accepted, :last_activity_date, :last_edit_date, :link, :locked_date, :question_id, :score, :title, :up_vote_count
42
+ attribute :answer_id, Integer
43
43
  alias :id :answer_id
44
44
 
45
+ attribute :body, String
46
+ attribute :community_owned_date, DateTime
47
+ attribute :creation_date, DateTime
48
+ attribute :down_vote_count, Integer
49
+ attribute :is_accepted, Boolean
50
+ attribute :last_activity_date, DateTime
51
+ attribute :last_edit_date, DateTime
52
+ attribute :link, String
53
+ attribute :locked_date, DateTime
54
+ attribute :question_id, Integer
55
+ attribute :score, Integer
56
+ attribute :title, String
57
+ attribute :up_vote_count, Integer
58
+
45
59
  associations :comments => :comment, :owner => :user
46
60
  finder_methods :every
47
61
 
@@ -57,7 +71,7 @@ module Serel
57
71
  #
58
72
  # @return [Serel::Question] The parent {Question} for this answer.
59
73
  def question
60
- type(:question, :singular).url("questions/#{question_id}").request
74
+ type(:question, :singular).url("questions/#{question_id}").get
61
75
  end
62
76
 
63
77
  # Get the revisions on an answer.
@@ -25,33 +25,40 @@ module Serel
25
25
  # Retrieves a page of badge results, applying any scopes that have previously been defined.
26
26
  #
27
27
  # == {named}
28
- # Serel::Badge.named.request
28
+ # Serel::Badge.named.get
29
29
  #
30
30
  # See the documentation for {named} below.
31
31
  #
32
32
  # == {recipients}
33
- # Serel::Badge.recipients.request
34
- # Serel::Badge.recipients(1).request
35
- # Serel::Badge.recipients(1,2,3).request
33
+ # Serel::Badge.recipients.get
34
+ # Serel::Badge.recipients(1).get
35
+ # Serel::Badge.recipients(1,2,3).get
36
36
  #
37
37
  # See the documentation for {recipients} below.
38
38
  #
39
39
  # == {tags}
40
- # Serel::Badge.tags.request
40
+ # Serel::Badge.tags.get
41
41
  #
42
42
  # See the documentation for {tags} below.
43
43
  class Badge < Base
44
- attributes :badge_id, :badge_type, :description, :link, :name, :rank
44
+ attribute :badge_id, Integer
45
45
  alias :id :badge_id
46
46
 
47
+ attribute :rank, String
48
+ attribute :name, String
49
+ attribute :description, String
50
+ attribute :award_count, Integer
51
+ attribute :badge_type, String
52
+ attribute :link, String
53
+
47
54
  associations :user => :user
48
55
  finder_methods :every
49
56
 
50
57
  # Retrieves only badges that are explicitly defined.
51
58
  # This is a scoping method, meaning that it can be used around/with other scoping methods, for
52
59
  # example:
53
- # Serel::Badge.pagesize(5).named.request
54
- # Serel::Badge.named.sort('gold').request
60
+ # Serel::Badge.pagesize(5).named.get
61
+ # Serel::Badge.named.sort('gold').get
55
62
  #
56
63
  # @return [Serel::Relation] A relation scoped to the named URL.
57
64
  def self.named
@@ -59,9 +66,9 @@ module Serel
59
66
  end
60
67
 
61
68
  # Retrieves recently awarded badges.
62
- # Serel::Badge.recipients.request
63
- # Serel::Badge.recipients(1).request
64
- # Serel::Badge.recipients(1,2,3).request
69
+ # Serel::Badge.recipients.get
70
+ # Serel::Badge.recipients(1).get
71
+ # Serel::Badge.recipients(1,2,3).get
65
72
  #
66
73
  # This is a scoping method and can be combined with other scoping methods.
67
74
  #
@@ -78,7 +85,7 @@ module Serel
78
85
  end
79
86
 
80
87
  # Retrieves only badges that have been awarded due to participation in a tag.
81
- # Serel::Badge.tags.request
88
+ # Serel::Badge.tags.get
82
89
  #
83
90
  # This is a scoping method and can be combined with other scoping methods.
84
91
  # @return [Serel::Relation] A relation scoped to the tags URL.
@@ -5,7 +5,7 @@ module Serel
5
5
 
6
6
  def initialize(data)
7
7
  @data = {}
8
- attributes.each { |k| @data[k] = data[k.to_s] }
8
+ attributes.each { |k,v| @data[k] = data[k.to_s] }
9
9
  if associations
10
10
  associations.each do |k,v|
11
11
  if data[k.to_s]
@@ -18,7 +18,7 @@ module Serel
18
18
  # Internal: Provides access to the internal data
19
19
  # Rather than store data using attr_writers (problems) we use a hash.
20
20
  def [](attr)
21
- @data[attr]
21
+ format_attribute(attr)
22
22
  end
23
23
 
24
24
  def []=(attr, value)
@@ -38,6 +38,7 @@ module Serel
38
38
  self.logger.formatter = proc { |severity, datetime, progname, msg|
39
39
  %([#{severity}][#{datetime.strftime("%Y-%m-%d %H:%M:%S")}] #{msg}\n)
40
40
  }
41
+ nil # Return nothing, rather than that proc
41
42
  end
42
43
 
43
44
  # Public: Provides a nice and quick way to inspec the properties of a
@@ -46,7 +47,7 @@ module Serel
46
47
  # Returns a String representation of the class
47
48
  def inspect
48
49
  attribute_collector = {}
49
- self.class.attributes.each { |attr| attribute_collector[attr] = self.send(attr) }
50
+ self.class.attributes.each { |attr, type| attribute_collector[attr] = self.send(attr) }
50
51
  inspected_attributes = attribute_collector.select { |k,v| v != nil }.collect { |k,v| "@#{k}=#{v}" }.join(", ")
51
52
  association_collector = {}
52
53
  self.class.associations.each { |name, type| association_collector[name] = self[name] }
@@ -55,17 +56,15 @@ module Serel
55
56
  end
56
57
  alias :to_s :inspect
57
58
 
58
- # Internal: Defines the attributes for a subclass of Serel::Base
59
- #
60
- # *splat - The Array or List of attributes for the class
61
- #
62
- # Returns nothing.
63
- def self.attributes(*splat)
64
- self.attributes = splat
65
- splat.each do |meth|
66
- define_method(meth) { self[meth.to_sym] }
67
- define_method("#{meth}=") { |val| self[meth.to_sym] = val }
68
- end
59
+ # Defines an attribute on a subclass of Serel::Base
60
+ # @param [Symbol] name The name of the attribute
61
+ # @param [Class] klass The type of the returned attributed
62
+ # @return Nothing of value
63
+ def self.attribute(name, klass)
64
+ self.attributes = {} unless self.attributes
65
+ self.attributes[name] = klass
66
+ define_method(name) { self[name.to_sym] }
67
+ define_method("#{name}=") { |val| self[name.to_sym] = val }
69
68
  end
70
69
 
71
70
  # Internal: Defines the associations for a subclass of Serel::Base
@@ -156,18 +155,18 @@ module Serel
156
155
 
157
156
  def get
158
157
  if self.respond_to?(:get)
159
- new_relation.get
158
+ new_relation(name.split('::').last.to_snake, :plural).get
160
159
  else
161
160
  raise NoMethodError
162
161
  end
163
162
  end
164
163
 
165
- ## Pass these methods direct to a new Relation
164
+ ## Pass these methods direct to a new Relation, which should *not* be singular. >:
166
165
  # TODO: clean these up
167
166
  %w(access_token filter fromdate inname intitle min max nottagged order page pagesize since sort tagged title todate url).each do |meth|
168
167
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
169
168
  def self.#{meth}(val)
170
- new_relation.#{meth}(val)
169
+ new_relation(name.split('::').last.to_snake, :plural).#{meth}(val)
171
170
  end
172
171
  RUBY
173
172
  end
@@ -183,5 +182,27 @@ module Serel
183
182
  # relation side.
184
183
  new_relation.send(sym, *attrs, &block)
185
184
  end
185
+
186
+ private
187
+
188
+ # Returns a formatted attribute. Used interally to cast attributes into their appropriate types.
189
+ # Currently only handles DateTime attributes, since Ruby automatically handles all other known
190
+ # types for us.
191
+ def format_attribute(attribute)
192
+ # Handle nil values
193
+ if @data[attribute] == nil
194
+ nil
195
+ else
196
+ # Use class names as types otherwise case will look at the type of the
197
+ # arg, which would otherwise always be Class.
198
+ type = self.attributes[attribute].to_s
199
+ case type
200
+ when "DateTime"
201
+ Time.at(@data[attribute])
202
+ else
203
+ @data[attribute]
204
+ end
205
+ end
206
+ end
186
207
  end
187
208
  end
@@ -25,35 +25,43 @@ module Serel
25
25
  # Retrieves a page of comment results, applying any scopes that have previously been defined.
26
26
  #
27
27
  # == {Answer#comments}
28
- # Serel::Answer.find(id).comments.request
28
+ # Serel::Answer.find(id).comments.get
29
29
  #
30
30
  # Retrieves a page of comments on the specified answer.
31
31
  #
32
32
  # == {Post#comments}
33
- # Serel::Post.find(id).comments.request
33
+ # Serel::Post.find(id).comments.get
34
34
  #
35
35
  # Retrieves a page of comments on the specified post.
36
36
  #
37
37
  # == {Question#comments}
38
- # Serel::Question.find(id).comments.request
38
+ # Serel::Question.find(id).comments.get
39
39
  #
40
40
  # Retrieves a page of comments on the specified question.
41
41
  #
42
42
  # == {User#comments}
43
- # Serel::User.find(id).comments.request
44
- # Serel::User.find(id).comments(other_id).request
43
+ # Serel::User.find(id).comments.get
44
+ # Serel::User.find(id).comments(other_id).get
45
45
  #
46
46
  # Retrieves a page of comments by the specified user. If the optional +other_id+ parameter is passed
47
47
  # then only comments in reply to +other_id+ are included.
48
48
  #
49
49
  # == {User#mentioned}
50
- # Serel::User.find(id).mentioned.request
50
+ # Serel::User.find(id).mentioned.get
51
51
  #
52
52
  # Retrieves a page of comments mentioning the specified user.
53
53
  class Comment < Base
54
- attributes :comment_id, :body, :creation_date, :edited, :link, :post_id, :post_type, :score
54
+ attribute :comment_id, Integer
55
55
  alias :id :comment_id
56
56
 
57
+ attribute :post_id, Integer
58
+ attribute :creation_date, DateTime
59
+ attribute :post_type, String
60
+ attribute :score, Integer
61
+ attribute :edited, Boolean
62
+ attribute :body, String
63
+ attribute :link, String
64
+
57
65
  associations :owner => :user, :reply_to_user => :user
58
66
  finder_methods :every
59
67
 
@@ -62,7 +70,7 @@ module Serel
62
70
  # Note that this returns the post, rather than returning a {Serel::Response} wrapped array.
63
71
  # @return [Serel::Post] The post the comment is on.
64
72
  def post
65
- type(:post, :singular).url("posts/#{post_id}").request
73
+ type(:post, :singular).url("posts/#{post_id}").get
66
74
  end
67
75
  end
68
76
  end
@@ -19,7 +19,11 @@ module Serel
19
19
  # Retrieves a page of Events. As per the +all+ method above, this defaults to events in the last 5
20
20
  # minutes.
21
21
  class Event < Base
22
- attributes :event_type, :event_id, :creation_date, :link, :excerpt
22
+ attribute :event_type, String
23
+ attribute :event_id, Integer
24
+ attribute :creation_date, DateTime
25
+ attribute :link, String
26
+ attribute :excerpt, String
23
27
  finder_methods :all, :get
24
28
  end
25
29
  end
@@ -85,4 +85,8 @@ class String
85
85
  tr("-", "_").
86
86
  downcase
87
87
  end
88
+ end
89
+
90
+ # Dummy class used to make our attributes clearer.
91
+ class Boolean
88
92
  end
@@ -1,6 +1,15 @@
1
1
  module Serel
2
2
  class Inbox < Base
3
- attributes :item_type, :question_id, :answer_id, :comment_id, :title, :creation_date, :is_unread, :site, :body, :link
3
+ attribute :item_type, String
4
+ attribute :question_id, Integer
5
+ attribute :answer_id, Integer
6
+ attribute :comment_id, Integer
7
+ attribute :title, String
8
+ attribute :creation_date, DateTime
9
+ attribute :is_unread, Boolean
10
+ attribute :site, Hash
11
+ attribute :body, String
12
+ attribute :link, String
4
13
  finder_methods :none
5
14
  end
6
15
  end
@@ -5,7 +5,20 @@ module Serel
5
5
  # The +/info+ route accepts no parameters and requires no IDs, so the default finder methods cannot be
6
6
  # used. We therefore have a custom finder defined, {.get_info}.
7
7
  class Info < Base
8
- attributes :total_questions, :total_unanswered, :total_accepted, :total_answers, :questions_per_minute, :answers_per_minute, :total_comments, :total_votes, :total_badges, :badges_per_minute, :total_users, :new_active_users, :api_revision
8
+ attribute :total_questions, Integer
9
+ attribute :total_unanswered, Integer
10
+ attribute :total_accepted, Integer
11
+ attribute :total_answers, Integer
12
+ attribute :questions_per_minute, Float
13
+ attribute :answers_per_minute, Float
14
+ attribute :total_comments, Integer
15
+ attribute :total_votes, Integer
16
+ attribute :total_badges, Integer
17
+ attribute :badges_per_minute, Float
18
+ attribute :total_users, Integer
19
+ attribute :new_active_users, Integer
20
+ attribute :api_revision, String
21
+
9
22
  associations :site => :site
10
23
  finder_methods :none
11
24
 
@@ -15,7 +28,7 @@ module Serel
15
28
  #
16
29
  # @return [Serel::Info] Information about the site
17
30
  def self.get_info
18
- new_relation(:info, :singular).url("info").request
31
+ new_relation(:info, :singular).url("info").get
19
32
  end
20
33
  end
21
34
  end
@@ -1,8 +1,17 @@
1
1
  module Serel
2
2
  class Post < Base
3
- attributes :post_id, :post_type, :body, :creation_date, :last_activity_date, :last_edit_date, :score, :up_vote_count, :down_vote_count
3
+ attribute :post_id, Integer
4
4
  alias :id :post_id
5
5
 
6
+ attribute :post_type, String
7
+ attribute :body, String
8
+ attribute :creation_date, DateTime
9
+ attribute :last_activity_date, DateTime
10
+ attribute :last_edit_date, DateTime
11
+ attribute :score, Integer
12
+ attribute :up_vote_count, Integer
13
+ attribute :down_vote_count, Integer
14
+
6
15
  associations :comments => :comment, :owner => :user
7
16
  finder_methods :every
8
17
 
@@ -1,6 +1,8 @@
1
1
  module Serel
2
2
  class Privilege < Base
3
- attributes :short_description, :description, :reputation
3
+ attribute :short_description, String
4
+ attribute :description, String
5
+ attribute :reputation, Integer
4
6
  finder_methods :all
5
7
  end
6
8
  end
@@ -1,8 +1,34 @@
1
1
  module Serel
2
2
  class Question < Base
3
- attributes :question_id, :accepted_answer_id, :answer_count, :body, :bounty_amount, :bounty_closes_date, :closed_reason, :community_owned_date, :creation_date, :down_vote_count, :favourite_count, :last_activity_date, :last_edit_date, :link, :locked_date, :migrated_to, :migrated_from, :protected_date, :score, :tags, :title, :up_vote_count, :view_count
4
- associations :answers => :answer, :comments => :comment, :owner => :user
3
+ attribute :question_id, Integer
5
4
  alias :id :question_id
5
+
6
+ attribute :last_edit_date, DateTime
7
+ attribute :creation_date, DateTime
8
+ attribute :last_activity_date, DateTime
9
+ attribute :locked_date, DateTime
10
+ attribute :score, Integer
11
+ attribute :community_owned_date, DateTime
12
+ attribute :answer_count, Integer
13
+ attribute :accepted_answer_id, Integer
14
+ attribute :migrated_to, Hash
15
+ attribute :migrated_from, Hash
16
+ attribute :bounty_closes_date, DateTime
17
+ attribute :bounty_amount, Integer
18
+ attribute :closed_date, DateTime
19
+ attribute :protected_date, DateTime
20
+ attribute :body, String
21
+ attribute :title, String
22
+ attribute :tags, Array
23
+ attribute :closed_reason, String
24
+ attribute :up_vote_count, Integer
25
+ attribute :down_vote_count, Integer
26
+ attribute :favorite_count, Integer
27
+ attribute :view_count, Integer
28
+ attribute :link, String
29
+ attribute :is_answered, Boolean
30
+ associations :answers => :answer, :comments => :comment, :owner => :user
31
+
6
32
  finder_methods :every
7
33
 
8
34
  def self.featured
@@ -50,7 +50,8 @@ module Serel
50
50
  #
51
51
  #
52
52
  # Scope methods
53
- %w(access_token filter fromdate inname intitle min max nottagged order page pagesize since sort tagged title todate url).each do |meth|
53
+ # 'Standard' methods. These should not need coercing.
54
+ %w(access_token filter inname intitle min max nottagged order page pagesize sort tagged title url).each do |meth|
54
55
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
55
56
  def #{meth}(val)
56
57
  @scope[:#{meth}] = val.to_s
@@ -58,6 +59,19 @@ module Serel
58
59
  end
59
60
  RUBY
60
61
  end
62
+ # These methods are for dates. They can take all sorts of values. Time, DateTime, Integer. The whole kaboodle.
63
+ # Unfortunately there's no easy cross class method to go from Time/DateTime -> Integer,
64
+ # so we must convert DateTime into Time before converting to Integer.
65
+ %w(fromdate since todate).each do |meth|
66
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
67
+ def #{meth}(val)
68
+ if val.is_a?(DateTime)
69
+ val = val.to_time
70
+ end
71
+ @scope[:#{meth}] = val.to_i
72
+ end
73
+ RUBY
74
+ end
61
75
 
62
76
  def network
63
77
  @network = true
@@ -92,11 +106,18 @@ module Serel
92
106
  end
93
107
  end
94
108
 
109
+ # Makes a request. If the URL is already set we just call {request}, else
110
+ # we set the URL to the plural of the type and make the request.
95
111
  def get
96
- if klass.respond_to?(:get)
97
- url("#{@type}s").request
112
+ if scoping[:url]
113
+ request
98
114
  else
99
- raise NoMethodError
115
+ # Best check that the generic page getter is enabled here.
116
+ if klass.respond_to?(:get)
117
+ url("#{@type}s").request
118
+ else
119
+ raise NoMethodError
120
+ end
100
121
  end
101
122
  end
102
123
 
@@ -1,6 +1,14 @@
1
1
  module Serel
2
2
  class Reputation < Base
3
- attributes :user_id, :post_id, :post_type, :vote_type, :title, :link, :reputation_change, :on_date
3
+ attribute :user_id, Integer
4
+ attribute :post_id, Integer
5
+ attribute :post_type, String
6
+ attribute :vote_type, String
7
+ attribute :title, String
8
+ attribute :link, String
9
+ attribute :reputation_change, Integer
10
+ attribute :on_date, DateTime
11
+
4
12
  finder_methods :none
5
13
  end
6
14
  end
@@ -48,9 +48,11 @@ module Serel
48
48
  result.page ||= (@scope[:page] || 1)
49
49
  result.page_size ||= (@scope[:pagesize] || 30)
50
50
 
51
- # Insert into the response array the items returned
52
- body["items"].each do |item|
53
- result << find_constant(@type).new(item)
51
+ # If any items were returned, iterate over the results and populate the response
52
+ if body["items"]
53
+ body["items"].each do |item|
54
+ result << find_constant(@type).new(item)
55
+ end
54
56
  end
55
57
 
56
58
  if (@qty == :plural) || (result.length > 1)
@@ -1,8 +1,23 @@
1
1
  module Serel
2
2
  class Revision < Base
3
- attributes :revision_guid, :revision_number, :revision_type, :post_type, :post_id, :comment, :creation_date, :is_rollback, :last_body, :last_title, :last_tags, :body, :title, :tags, :set_community_wiki
3
+ attribute :revision_guid, String
4
4
  alias :id :revision_guid
5
5
 
6
+ attribute :revision_number, Integer
7
+ attribute :revision_type, String
8
+ attribute :post_type, String
9
+ attribute :post_id, Integer
10
+ attribute :comment, String
11
+ attribute :creation_date, DateTime
12
+ attribute :is_rollback, Boolean
13
+ attribute :last_body, String
14
+ attribute :last_title, String
15
+ attribute :last_tags, Array
16
+ attribute :body, String
17
+ attribute :title, String
18
+ attribute :tags, Array
19
+ attribute :set_community_wiki, Boolean
20
+
6
21
  associations :user => :user
7
22
  finder_methods :find
8
23
  end
@@ -15,7 +15,24 @@ module Serel
15
15
  #
16
16
  # Retrieves a page of sites, applying any scopes that have previously been defined.
17
17
  class Site < Base
18
- attributes :site_type, :name, :logo_url, :api_site_parameter, :site_url, :audience, :icon_url, :aliases, :site_state, :styling, :closed_beta_date, :open_beta_date, :launch_date, :favicon_url, :related_sites, :twitter_account, :markdown_extensions
18
+ attribute :site_type, String
19
+ attribute :name, String
20
+ attribute :logo_url, String
21
+ attribute :api_site_parameter, String
22
+ attribute :site_url, String
23
+ attribute :audience, String
24
+ attribute :icon_url, String
25
+ attribute :aliases, Array
26
+ attribute :site_state, String
27
+ attribute :styling, Hash
28
+ attribute :closed_beta_date, DateTime
29
+ attribute :open_beta_date, DateTime
30
+ attribute :launch_date, DateTime
31
+ attribute :favicon_url, String
32
+ attribute :related_sites, Hash
33
+ attribute :twitter_account, String
34
+ attribute :markdown_extensions, Array
35
+
19
36
  finder_methods :all, :get
20
37
  network_wide
21
38
  end
@@ -1,7 +1,18 @@
1
1
  module Serel
2
2
  class SuggestedEdit < Base
3
- attributes :suggested_edit_id, :post_id, :post_type, :body, :title, :tags, :comment, :creation_date, :approval_date, :rejection_date
3
+ attribute :suggested_edit_id, Integer
4
4
  alias :id :suggested_edit_id
5
+
6
+ attribute :post_id, Integer
7
+ attribute :post_type, String
8
+ attribute :body, String
9
+ attribute :title, String
10
+ attribute :tags, Array
11
+ attribute :comment, String
12
+ attribute :creation_date, DateTime
13
+ attribute :approval_date, DateTime
14
+ attribute :rejection_date, DateTime
15
+
5
16
  associations :proposing_user => :user
6
17
  finder_methods :every
7
18
  end
@@ -1,17 +1,24 @@
1
1
  module Serel
2
2
  class Tag < Base
3
- attributes :name, :count, :is_required, :is_moderator_only, :user_id, :has_synonyms, :last_activity_date
3
+ attribute :name, String
4
+ attribute :count, Integer
5
+ attribute :is_required, Boolean
6
+ attribute :is_moderator_only, Boolean
7
+ attribute :user_id, Integer
8
+ attribute :has_synonyms, Boolean
9
+ attribute :last_activity_date, DateTime
10
+
4
11
  finder_methods :all, :get
5
12
 
6
13
  # Finds a tag by name
7
14
  # @param [String] name The name of the tag you wish to find
8
15
  # @return [Serel::Tag] The tag returned by the Stack Exchange API
9
16
  def self.find_by_name(name)
10
- url("tags/#{name}/info").request
17
+ new_relation('tag', :singular).url("tags/#{name}/info").get
11
18
  end
12
19
 
13
20
  # Retrieves tags which can only be added or removed by a moderator
14
- # Serel::Tag.moderator_only.request
21
+ # Serel::Tag.moderator_only.get
15
22
  #
16
23
  # This is a scoping method and can be combined with other scoping methods
17
24
  # @return [Serel::Relation] A relation scoped to the moderator only URL.
@@ -20,7 +27,7 @@ module Serel
20
27
  end
21
28
 
22
29
  # Retrieves tags that are required on the site
23
- # Serel::Tag.required.request
30
+ # Serel::Tag.required.get
24
31
  #
25
32
  # This is a scoping method and can be combined with other scoping methods.
26
33
  # @return [Serel::Relation] A relation scoped to the required URL.
@@ -29,7 +36,7 @@ module Serel
29
36
  end
30
37
 
31
38
  # Retrieves all the tag synonyms on the site
32
- # Serel::Tag.synonyms.request
39
+ # Serel::Tag.synonyms.get
33
40
  #
34
41
  # This is a scoping method and can be combined with other scoping methods.
35
42
  # @return [Serel::Relation] A relation scoped to {Serel::TagSynonym TagSynonym} and the synonym URL.
@@ -37,8 +44,12 @@ module Serel
37
44
  new_relation(:tag_synonym).url("tags/synonyms")
38
45
  end
39
46
 
47
+ def faq
48
+ type(:tag).url("tags/#{name}/faq")
49
+ end
50
+
40
51
  # Retrieves related tags.
41
- # Serel::Tag.find(1).related.request
52
+ # Serel::Tag.find(1).related.get
42
53
  #
43
54
  # This is a scoping method and can be combined with other scoping methods.
44
55
  # @return [Serel::Relation] A relation scoped to the related URL
@@ -57,7 +68,7 @@ module Serel
57
68
  end
58
69
 
59
70
  def wiki
60
- type(:tag_wiki, :singular).url("tags/#{name}/wikis").request
71
+ type(:tag_wiki, :singular).url("tags/#{name}/wikis").get
61
72
  end
62
73
  end
63
74
  end
@@ -1,6 +1,8 @@
1
1
  module Serel
2
2
  class TagScore < Base
3
- attributes :score, :post_count
3
+ attribute :score, Integer
4
+ attribute :post_count, Integer
5
+
4
6
  associations :user => :user
5
7
  finder_methods :none
6
8
  end
@@ -1,6 +1,11 @@
1
1
  module Serel
2
2
  class TagSynonym < Base
3
- attributes :from_tag, :to_tag, :applied_count, :last_applied_date, :creation_date
3
+ attribute :from_tag, String
4
+ attribute :to_tag, String
5
+ attribute :applied_count, Integer
6
+ attribute :last_applied_date, DateTime
7
+ attribute :creation_date, DateTime
8
+
4
9
  finder_methods :none
5
10
  end
6
11
  end
@@ -1,6 +1,11 @@
1
1
  module Serel
2
2
  class TagWiki < Base
3
- attributes :tag_name, :body, :excerpt, :body_last_edit_date, :excerpt_last_edit_date
3
+ attribute :tag_name, String
4
+ attribute :body, String
5
+ attribute :excerpt, String
6
+ attribute :body_last_edit_date, DateTime
7
+ attribute :excerpt_last_edit_date, DateTime
8
+
4
9
  associations :last_body_editor => :user, :last_excerpt_editor => :user
5
10
  finder_methods :none
6
11
  end
@@ -1,6 +1,14 @@
1
1
  module Serel
2
2
  class Timeline < Base
3
- attributes :timeline_type, :question_id, :post_id, :comment_id, :revision_guid, :up_vote_count, :down_vote_count, :creation_date
3
+ attribute :comment_id, Integer
4
+ attribute :creation_date, DateTime
5
+ attribute :down_vote_count, Integer
6
+ attribute :post_id, Integer
7
+ attribute :question_id, Integer
8
+ attribute :revision_guid, String
9
+ attribute :timeline_type, String
10
+ attribute :up_vote_count, Integer
11
+
4
12
  associations :user => :user, :owner => :user
5
13
  finder_methods :every
6
14
  end
@@ -1,7 +1,36 @@
1
1
  module Serel
2
2
  class User < Base
3
- attributes :user_id, :user_type, :creation_date, :display_name, :profile_image, :reputation, :reputation_change_day, :reputation_change_week, :reputation_change_month, :reputation_change_quarter, :reputation_change_year, :age, :last_access_date, :last_modified_date, :is_employee, :link, :website_url, :location, :account_id, :timed_penalty_date, :badge_counts, :question_counts, :answer_count, :up_vote_count, :down_vote_count, :about_me, :view_count, :accept_rate
3
+ attribute :user_id, Integer
4
4
  alias :id :user_id
5
+
6
+ attribute :user_type, String
7
+ attribute :creation_date, DateTime
8
+ attribute :display_name, String
9
+ attribute :profile_image, String
10
+ attribute :reputation, Integer
11
+ attribute :reputation_change_day, Integer
12
+ attribute :reputation_change_week, Integer
13
+ attribute :reputation_change_month, Integer
14
+ attribute :reputation_change_quarter, Integer
15
+ attribute :reputation_change_year, Integer
16
+ attribute :age, Integer
17
+ attribute :last_access_date, DateTime
18
+ attribute :last_modified_date, DateTime
19
+ attribute :is_employee, Boolean
20
+ attribute :link, String
21
+ attribute :website_url, String
22
+ attribute :location, String
23
+ attribute :account_id, Integer
24
+ attribute :timed_penalty_date, DateTime
25
+ attribute :badge_counts, Hash
26
+ attribute :question_count, Integer
27
+ attribute :answer_count, Integer
28
+ attribute :up_vote_count, Integer
29
+ attribute :down_vote_count, Integer
30
+ attribute :about_me, String
31
+ attribute :view_count, Integer
32
+ attribute :accept_rate, Float
33
+
5
34
  finder_methods :every
6
35
 
7
36
  def self.moderators
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc2
5
- prerelease: 6
4
+ version: 1.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thomas McDonald
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-01 00:00:00.000000000 Z
12
+ date: 2012-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70098120062280 !ruby/object:Gem::Requirement
16
+ requirement: &70150175755460 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70098120062280
24
+ version_requirements: *70150175755460
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: vcr
27
- requirement: &70098120061100 !ruby/object:Gem::Requirement
27
+ requirement: &70150175754200 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70098120061100
35
+ version_requirements: *70150175754200
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: webmock
38
- requirement: &70098120060060 !ruby/object:Gem::Requirement
38
+ requirement: &70150175751380 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70098120060060
46
+ version_requirements: *70150175751380
47
47
  description:
48
48
  email: tom@conceptcoding.co.uk
49
49
  executables: []
@@ -92,14 +92,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
92
92
  required_rubygems_version: !ruby/object:Gem::Requirement
93
93
  none: false
94
94
  requirements:
95
- - - ! '>'
95
+ - - ! '>='
96
96
  - !ruby/object:Gem::Version
97
- version: 1.3.1
97
+ version: '0'
98
98
  requirements: []
99
99
  rubyforge_project:
100
- rubygems_version: 1.8.12
100
+ rubygems_version: 1.8.11
101
101
  signing_key:
102
102
  specification_version: 3
103
103
  summary: A Ruby library for the Stack Exchange API
104
104
  test_files: []
105
- has_rdoc: