redditkit 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +22 -0
  3. data/README.md +155 -0
  4. data/Rakefile +8 -0
  5. data/lib/redditkit.rb +26 -0
  6. data/lib/redditkit/base.rb +60 -0
  7. data/lib/redditkit/client.rb +142 -0
  8. data/lib/redditkit/client/account.rb +73 -0
  9. data/lib/redditkit/client/apps.rb +63 -0
  10. data/lib/redditkit/client/captcha.rb +36 -0
  11. data/lib/redditkit/client/comments.rb +54 -0
  12. data/lib/redditkit/client/flair.rb +148 -0
  13. data/lib/redditkit/client/links.rb +134 -0
  14. data/lib/redditkit/client/miscellaneous.rb +50 -0
  15. data/lib/redditkit/client/moderation.rb +179 -0
  16. data/lib/redditkit/client/multireddits.rb +207 -0
  17. data/lib/redditkit/client/private_messages.rb +74 -0
  18. data/lib/redditkit/client/search.rb +25 -0
  19. data/lib/redditkit/client/subreddits.rb +120 -0
  20. data/lib/redditkit/client/users.rb +109 -0
  21. data/lib/redditkit/client/utilities.rb +137 -0
  22. data/lib/redditkit/client/voting.rb +41 -0
  23. data/lib/redditkit/client/wiki.rb +83 -0
  24. data/lib/redditkit/comment.rb +54 -0
  25. data/lib/redditkit/creatable.rb +17 -0
  26. data/lib/redditkit/error.rb +111 -0
  27. data/lib/redditkit/link.rb +140 -0
  28. data/lib/redditkit/moderator_action.rb +19 -0
  29. data/lib/redditkit/multireddit.rb +32 -0
  30. data/lib/redditkit/multireddit_description.rb +14 -0
  31. data/lib/redditkit/paginated_response.rb +22 -0
  32. data/lib/redditkit/private_message.rb +27 -0
  33. data/lib/redditkit/response/parse_json.rb +29 -0
  34. data/lib/redditkit/response/raise_error.rb +21 -0
  35. data/lib/redditkit/subreddit.rb +86 -0
  36. data/lib/redditkit/thing.rb +20 -0
  37. data/lib/redditkit/user.rb +30 -0
  38. data/lib/redditkit/version.rb +19 -0
  39. data/lib/redditkit/votable.rb +37 -0
  40. data/redditkit.gemspec +25 -0
  41. data/spec/cassettes/RedditKit_Client/should_raise_an_error_with_invalid_credentials.yml +39 -0
  42. data/spec/cassettes/RedditKit_Client_Account/_sign_in/signs_the_user_in.yml +132 -0
  43. data/spec/cassettes/RedditKit_Client_Account/_update_session/updates_the_current_session.yml +133 -0
  44. data/spec/cassettes/RedditKit_Client_Captcha/_captcha_url/returns_a_CAPTCHA_url_from_an_identifier.yml +38 -0
  45. data/spec/cassettes/RedditKit_Client_Captcha/_needs_captcha_/checks_if_the_current_account_needs_a_CAPTCHA.yml +44 -0
  46. data/spec/cassettes/RedditKit_Client_Captcha/_new_captcha_identifier/returns_a_new_CAPTCHA_identifier.yml +38 -0
  47. data/spec/cassettes/RedditKit_Client_Comments/_comment/requests_the_correct_resource.yml +47 -0
  48. data/spec/cassettes/RedditKit_Client_Comments/_comments/with_a_RedditKit_Link/returns_comments_on_a_link.yml +140 -0
  49. data/spec/cassettes/RedditKit_Client_Comments/_comments/with_a_link_identifier/returns_comments_on_a_link.yml +89 -0
  50. data/spec/cassettes/RedditKit_Client_Comments/_submit_comment/requests_the_correct_resource.yml +313 -0
  51. data/spec/cassettes/RedditKit_Client_Flair/_apply_flair_template/clears_flair_templates.yml +52 -0
  52. data/spec/cassettes/RedditKit_Client_Flair/_clear_flair_templates/clears_flair_templates.yml +49 -0
  53. data/spec/cassettes/RedditKit_Client_Flair/_create_flair_template/creates_a_flair_template.yml +46 -0
  54. data/spec/cassettes/RedditKit_Client_Flair/_create_flair_template/raises_InvalidClassName.yml +46 -0
  55. data/spec/cassettes/RedditKit_Client_Flair/_create_flair_template/raises_TooManyClassNames.yml +47 -0
  56. data/spec/cassettes/RedditKit_Client_Flair/_delete_user_flair/requests_the_correct_resource.yml +60 -0
  57. data/spec/cassettes/RedditKit_Client_Flair/_flair_list/returns_the_list_of_flair.yml +44 -0
  58. data/spec/cassettes/RedditKit_Client_Flair/_set_flair/requests_the_correct_resource.yml +49 -0
  59. data/spec/cassettes/RedditKit_Client_Flair/_set_flair_options/sets_flair_options.yml +49 -0
  60. data/spec/cassettes/RedditKit_Client_Flair/_set_flair_with_csv/requests_the_correct_resource.yml +51 -0
  61. data/spec/cassettes/RedditKit_Client_Flair/_toggle_flair/requests_the_correct_resource.yml +49 -0
  62. data/spec/cassettes/RedditKit_Client_Links/_front_page/requests_the_correct_category.yml +498 -0
  63. data/spec/cassettes/RedditKit_Client_Links/_front_page/requests_the_correct_resource.yml +603 -0
  64. data/spec/cassettes/RedditKit_Client_Links/_hide/requests_the_correct_resource.yml +46 -0
  65. data/spec/cassettes/RedditKit_Client_Links/_link/returns_a_link.yml +55 -0
  66. data/spec/cassettes/RedditKit_Client_Links/_links/contains_pagination_information.yml +402 -0
  67. data/spec/cassettes/RedditKit_Client_Links/_links/requests_a_certain_number_of_links.yml +186 -0
  68. data/spec/cassettes/RedditKit_Client_Links/_links/requests_front_page_links_if_no_subreddit_is_present.yml +603 -0
  69. data/spec/cassettes/RedditKit_Client_Links/_links/requests_links_with_the_correct_time_frame.yml +375 -0
  70. data/spec/cassettes/RedditKit_Client_Links/_links/requests_the_correct_subreddit_and_category.yml +402 -0
  71. data/spec/cassettes/RedditKit_Client_Links/_links_with_domain/returns_links_with_a_specific_domain.yml +99 -0
  72. data/spec/cassettes/RedditKit_Client_Links/_mark_nsfw/requests_the_correct_resource.yml +46 -0
  73. data/spec/cassettes/RedditKit_Client_Links/_random_link/returns_a_random_link.yml +91 -0
  74. data/spec/cassettes/RedditKit_Client_Links/_submit/raises_RedditKit_InvalidCaptcha_if_no_CAPTCHA_is_filled_out.yml +54 -0
  75. data/spec/cassettes/RedditKit_Client_Links/_unhide/requests_the_correct_resource.yml +46 -0
  76. data/spec/cassettes/RedditKit_Client_Links/_unmark_nsfw/requests_the_correct_resource.yml +46 -0
  77. data/spec/cassettes/RedditKit_Client_Miscellaneous/_delete/requests_the_correct_resource.yml +46 -0
  78. data/spec/cassettes/RedditKit_Client_Miscellaneous/_edit/requests_the_correct_resource.yml +52 -0
  79. data/spec/cassettes/RedditKit_Client_Miscellaneous/_save/saves_an_object.yml +46 -0
  80. data/spec/cassettes/RedditKit_Client_Miscellaneous/_unsave/unsaves_an_object.yml +89 -0
  81. data/spec/cassettes/RedditKit_Client_Moderation/_accept_moderator_invitation/requests_the_correct_resource.yml +53 -0
  82. data/spec/cassettes/RedditKit_Client_Moderation/_ban/requests_the_correct_resource.yml +103 -0
  83. data/spec/cassettes/RedditKit_Client_Moderation/_contributors_to_subreddit/requests_the_correct_resource.yml +47 -0
  84. data/spec/cassettes/RedditKit_Client_Moderation/_ignore_reports/requests_the_correct_resource.yml +46 -0
  85. data/spec/cassettes/RedditKit_Client_Moderation/_moderation_log/returns_RedditKit_ModeratorAction_objects.yml +153 -0
  86. data/spec/cassettes/RedditKit_Client_Moderation/_moderators_of_subreddit/requests_the_correct_resource.yml +48 -0
  87. data/spec/cassettes/RedditKit_Client_Moderation/_reset_subreddit_header/requests_the_correct_resource.yml +55 -0
  88. data/spec/cassettes/RedditKit_Client_Moderation/_set_contest_mode/requests_the_correct_resource.yml +46 -0
  89. data/spec/cassettes/RedditKit_Client_Moderation/_set_sticky_post/requests_the_correct_resource.yml +46 -0
  90. data/spec/cassettes/RedditKit_Client_Moderation/_unban/requests_the_correct_resource.yml +54 -0
  91. data/spec/cassettes/RedditKit_Client_Moderation/_unignore_reports/requests_the_correct_resource.yml +46 -0
  92. data/spec/cassettes/RedditKit_Client_Multireddits/_add_subreddit_to_multireddit/adds_a_subreddit_to_a_multireddit.yml +177 -0
  93. data/spec/cassettes/RedditKit_Client_Multireddits/_create_multireddit/creates_a_multireddit.yml +137 -0
  94. data/spec/cassettes/RedditKit_Client_Multireddits/_create_multireddit/raises_RedditKit_Conflict_when_using_an_existing_name.yml +133 -0
  95. data/spec/cassettes/RedditKit_Client_Multireddits/_delete_multireddit/deletes_a_multireddit.yml +134 -0
  96. data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit/with_a_path/returns_a_multireddit.yml +39 -0
  97. data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit/without_a_path/returns_a_multireddit.yml +39 -0
  98. data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit_description/with_a_multireddit/returns_a_multireddit_description.yml +81 -0
  99. data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit_description/with_a_username_and_multireddit_name/returns_a_multireddit_description.yml +45 -0
  100. data/spec/cassettes/RedditKit_Client_Multireddits/_my_multireddits/return_s_the_user_s_multireddits.yml +47 -0
  101. data/spec/cassettes/RedditKit_Client_Multireddits/_remove_subreddit_from_multireddit/removes_a_subreddit_from_a_multireddit.yml +175 -0
  102. data/spec/cassettes/RedditKit_Client_Multireddits/_rename_multireddit/renames_a_multireddit.yml +134 -0
  103. data/spec/cassettes/RedditKit_Client_Multireddits/_set_multireddit_description/returns_a_multireddit_description.yml +48 -0
  104. data/spec/cassettes/RedditKit_Client_Multireddits/_update_multireddit/updates_a_multireddit.yml +184 -0
  105. data/spec/cassettes/RedditKit_Client_PrivateMessages/_block_author_of_message/requests_the_correct_resource.yml +46 -0
  106. data/spec/cassettes/RedditKit_Client_PrivateMessages/_mark_as_read/requests_the_correct_resource.yml +51 -0
  107. data/spec/cassettes/RedditKit_Client_PrivateMessages/_mark_as_unread/requests_the_correct_resource.yml +51 -0
  108. data/spec/cassettes/RedditKit_Client_PrivateMessages/_messages/requests_the_correct_resource.yml +187 -0
  109. data/spec/cassettes/RedditKit_Client_PrivateMessages/_unblock/requests_the_correct_resource.yml +46 -0
  110. data/spec/cassettes/RedditKit_Client_Search/_search/restricts_searches_to_a_specific_subreddit.yml +878 -0
  111. data/spec/cassettes/RedditKit_Client_Search/_search/returns_a_specific_number_of_results.yml +130 -0
  112. data/spec/cassettes/RedditKit_Client_Search/_search/returns_search_results.yml +844 -0
  113. data/spec/cassettes/RedditKit_Client_Subreddits/_random_subreddit/returns_a_random_subreddit.yml +181 -0
  114. data/spec/cassettes/RedditKit_Client_Subreddits/_recommended_subreddits/returns_subreddit_names.yml +37 -0
  115. data/spec/cassettes/RedditKit_Client_Subreddits/_search_subreddits_by_name/returns_subreddit_names.yml +875 -0
  116. data/spec/cassettes/RedditKit_Client_Subreddits/_subreddit/returns_a_specified_subreddit.yml +100 -0
  117. data/spec/cassettes/RedditKit_Client_Subreddits/_subreddits/returns_a_specified_number_of_subreddits.yml +505 -0
  118. data/spec/cassettes/RedditKit_Client_Subreddits/_subreddits/returns_subreddits_from_a_specific_category.yml +510 -0
  119. data/spec/cassettes/RedditKit_Client_Subreddits/_subreddits_by_topic/returns_subreddit_names.yml +41 -0
  120. data/spec/cassettes/RedditKit_Client_Subreddits/_subscribe/requests_the_correct_resource.yml +46 -0
  121. data/spec/cassettes/RedditKit_Client_Subreddits/_subscribed_subreddits/returns_a_specified_number_of_subreddits.yml +415 -0
  122. data/spec/cassettes/RedditKit_Client_Subreddits/_subscribed_subreddits/returns_subreddits_from_a_specific_category.yml +58 -0
  123. data/spec/cassettes/RedditKit_Client_Subreddits/_subscribed_subreddits/returns_the_user_s_subscribed_subreddits.yml +3469 -0
  124. data/spec/cassettes/RedditKit_Client_Subreddits/_unsubscribe/requests_the_correct_resource.yml +46 -0
  125. data/spec/cassettes/RedditKit_Client_Users/_friends/returns_the_user_s_friends.yml +48 -0
  126. data/spec/cassettes/RedditKit_Client_Users/_my_content/returns_the_user_s_content.yml +60 -0
  127. data/spec/cassettes/RedditKit_Client_Users/_user/requests_the_correct_resource.yml +48 -0
  128. data/spec/cassettes/RedditKit_Client_Users/_user/returns_a_specified_user.yml +48 -0
  129. data/spec/cassettes/RedditKit_Client_Users/_user/returns_the_authenticated_user.yml +48 -0
  130. data/spec/cassettes/RedditKit_Client_Users/_user_content/returns_the_user_s_content.yml +41 -0
  131. data/spec/cassettes/RedditKit_Client_Users/_username_available_/returns_false_for_an_unavailable_username.yml +36 -0
  132. data/spec/cassettes/RedditKit_Client_Users/_username_available_/returns_true_for_an_available_username.yml +36 -0
  133. data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_comment_full_name_passed/downvotes_the_comment.yml +100 -0
  134. data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_comment_passed/downvotes_the_comment.yml +154 -0
  135. data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_link_full_name_passed/downvotes_the_link.yml +106 -0
  136. data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_link_passed/downvotes_the_link.yml +166 -0
  137. data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_comment_full_name_passed/upvotes_the_comment.yml +100 -0
  138. data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_comment_passed/upvotes_the_comment.yml +154 -0
  139. data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_link_full_name_passed/upvotes_the_link.yml +106 -0
  140. data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_link_passed/upvotes_the_link.yml +166 -0
  141. data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_comment_full_name_passed/withdraws_the_vote_on_the_comment.yml +154 -0
  142. data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_comment_passed/withdraws_the_vote_on_the_comment.yml +208 -0
  143. data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_link_full_name_passed/withdraws_the_vote_on_the_link.yml +166 -0
  144. data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_link_passed/withdraws_the_vote_on_the_link.yml +226 -0
  145. data/spec/cassettes/RedditKit_Client_Wiki/_add_wiki_editor/requests_the_correct_resource.yml +46 -0
  146. data/spec/cassettes/RedditKit_Client_Wiki/_edit_wiki_page/requests_the_correct_resource.yml +48 -0
  147. data/spec/cassettes/RedditKit_Client_Wiki/_hide_wiki_revision/requests_the_correct_resource.yml +46 -0
  148. data/spec/cassettes/RedditKit_Client_Wiki/_remove_wiki_editor/requests_the_correct_resource.yml +46 -0
  149. data/spec/cassettes/RedditKit_Client_Wiki/_revert_to_revision/requests_the_correct_resource.yml +46 -0
  150. data/spec/cassettes/RedditKit_Comment/should_not_be_deleted_if_neither_author_and_comment_attributes_are_set_to_deleted_.yml +90 -0
  151. data/spec/cassettes/RedditKit_Comment/should_return_replies.yml +90 -0
  152. data/spec/cassettes/authenticated_client.yml +87 -0
  153. data/spec/redditkit/base_spec.rb +45 -0
  154. data/spec/redditkit/client/account_spec.rb +50 -0
  155. data/spec/redditkit/client/apps_spec.rb +58 -0
  156. data/spec/redditkit/client/captcha_spec.rb +30 -0
  157. data/spec/redditkit/client/comments_spec.rb +40 -0
  158. data/spec/redditkit/client/flair_spec.rb +92 -0
  159. data/spec/redditkit/client/links_spec.rb +103 -0
  160. data/spec/redditkit/client/miscellaneous_spec.rb +40 -0
  161. data/spec/redditkit/client/moderation_spec.rb +141 -0
  162. data/spec/redditkit/client/multireddits_spec.rb +158 -0
  163. data/spec/redditkit/client/private_messages_spec.rb +51 -0
  164. data/spec/redditkit/client/search_spec.rb +25 -0
  165. data/spec/redditkit/client/subreddits_spec.rb +83 -0
  166. data/spec/redditkit/client/users_spec.rb +92 -0
  167. data/spec/redditkit/client/voting_spec.rb +99 -0
  168. data/spec/redditkit/client/wiki_spec.rb +40 -0
  169. data/spec/redditkit/client_spec.rb +46 -0
  170. data/spec/redditkit/comment_spec.rb +26 -0
  171. data/spec/redditkit/creatable_spec.rb +24 -0
  172. data/spec/redditkit/error_spec.rb +61 -0
  173. data/spec/redditkit/link_spec.rb +33 -0
  174. data/spec/redditkit/multireddit_spec.rb +27 -0
  175. data/spec/redditkit/paginated_response_spec.rb +23 -0
  176. data/spec/redditkit/thing_spec.rb +18 -0
  177. data/spec/redditkit/votable_spec.rb +52 -0
  178. data/spec/redditkit_spec.rb +21 -0
  179. data/spec/spec_helper.rb +124 -0
  180. metadata +390 -0
@@ -0,0 +1,54 @@
1
+ require 'redditkit/thing'
2
+ require 'redditkit/creatable'
3
+ require 'redditkit/votable'
4
+
5
+ module RedditKit
6
+
7
+ # A class representing a comment.
8
+ class Comment < RedditKit::Thing
9
+ include RedditKit::Creatable
10
+ include RedditKit::Votable
11
+
12
+ attr_reader :approved_by
13
+ attr_reader :author
14
+ attr_reader :author_flair_css_class
15
+ attr_reader :author_flair_text
16
+ attr_reader :author_id
17
+ attr_reader :banned_by
18
+ attr_reader :body
19
+ attr_reader :body_html
20
+ attr_reader :distinguished
21
+ attr_reader :edited
22
+ attr_reader :gilded
23
+ attr_reader :link_id
24
+ attr_reader :num_reports
25
+ attr_reader :score_hidden
26
+ attr_reader :subreddit
27
+ attr_reader :subreddit_id
28
+
29
+ alias text body
30
+ alias posted_at created_at
31
+
32
+ # Whether a comment has been deleted by its submitter or a moderator.
33
+ def deleted?
34
+ author == '[deleted]' and body == '[deleted]'
35
+ end
36
+
37
+ # The replies to a comment.
38
+ def replies
39
+ replies_listing = @attributes[:replies]
40
+ return Array.new if replies_listing.empty?
41
+
42
+ replies_array = replies_listing[:data][:children]
43
+
44
+ @comment_objects ||= replies_array.map do |comment|
45
+ RedditKit::Comment.new(comment)
46
+ end
47
+ end
48
+
49
+ # Whether the comment has any replies.
50
+ def replies?
51
+ !replies.empty?
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,17 @@
1
+ require 'time'
2
+
3
+ module RedditKit
4
+
5
+ # Methods which return the time of creation for objects.
6
+ module Creatable
7
+
8
+ # The time when the object was created on reddit.
9
+ #
10
+ # @return [Time]
11
+ def created_at
12
+ created = @attributes[:created_utc]
13
+ @created_at ||= Time.at(created) if created
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,111 @@
1
+ require 'json'
2
+
3
+ module RedditKit
4
+ class Error < StandardError
5
+ class << self
6
+
7
+ def from_status_code_and_body(status_code, body)
8
+ error_value = extract_error_value body
9
+ return if status_code == 200 and error_value.nil?
10
+
11
+ case status_code
12
+ when 200
13
+ if error_value =~ /WRONG_PASSWORD/i
14
+ RedditKit::InvalidCredentials
15
+ elsif error_value =~ /BAD_CAPTCHA/i
16
+ RedditKit::InvalidCaptcha
17
+ elsif error_value =~ /RATELIMIT/i
18
+ RedditKit::RateLimited
19
+ elsif error_value =~ /BAD_CSS_NAME/i
20
+ RedditKit::InvalidClassName
21
+ elsif error_value =~ /TOO_OLD/i
22
+ RedditKit::Archived
23
+ elsif error_value =~ /TOO_MUCH_FLAIR_CSS/i
24
+ RedditKit::TooManyClassNames
25
+ elsif error_value =~ /USER_REQUIRED/i
26
+ RedditKit::AuthenticationRequired
27
+ end
28
+ when 400
29
+ if error_value =~ /BAD_MULTI_NAME/i
30
+ RedditKit::InvalidMultiredditName
31
+ end
32
+ when 403
33
+ if error_value =~ /USER_REQUIRED/i
34
+ RedditKit::AuthenticationRequired
35
+ else
36
+ RedditKit::PermissionDenied
37
+ end
38
+ when 409
39
+ RedditKit::Conflict
40
+ when 500
41
+ RedditKit::InternalServerError
42
+ when 502
43
+ RedditKit::BadGateway
44
+ when 503
45
+ RedditKit::ServiceUnavailable
46
+ when 504
47
+ RedditKit::TimedOut
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def extract_error_value(body)
54
+ return nil unless body.instance_of? Hash
55
+
56
+ if body.key?(:json) and body[:json].key?(:errors)
57
+ body[:json][:errors].to_s
58
+ elsif body.key?(:jquery)
59
+ body[:jquery].to_s
60
+ end
61
+ end
62
+
63
+ end
64
+ end
65
+
66
+ # Raised when there should be an authenticated user, but there isn't.
67
+ class AuthenticationRequired < Error; end
68
+
69
+ # Raised when the user passes an invalid CAPTCHA identifier or value.
70
+ class InvalidCaptcha < Error; end
71
+
72
+ # Raised when reddit returns a 503 status code.
73
+ class BadGateway < Error; end
74
+
75
+ # Raised when the user attempts to create a multireddit with an invalid name.
76
+ class InvalidMultiredditName < Error; end
77
+
78
+ # Raised when reddit returns a 409 status code.
79
+ class Conflict < Error; end
80
+
81
+ # Raised when reddit returns a 500 status code.
82
+ class InternalServerError < Error; end
83
+
84
+ # Raised when the user passes an invalid CSS class name.
85
+ class InvalidClassName < Error; end
86
+
87
+ # Raised when the user attempts to sign in with an incorrect username or password.
88
+ class InvalidCredentials < Error; end
89
+
90
+ # Raised when the user attempts to access a resource without the appropriate permissions.
91
+ class PermissionDenied < Error; end
92
+
93
+ # Raised when the user has been rate limited.
94
+ class RateLimited < Error; end
95
+
96
+ # Raised when RedditKit encounters an error with one of its own requests.
97
+ class RequestError < Error; end
98
+
99
+ # Raised when reddit is unavailable.
100
+ class ServiceUnavailable < Error; end
101
+
102
+ # Raised when too many CSS class names are passed.
103
+ class TooManyClassNames < Error; end
104
+
105
+ # Raised when the user attempts to interact with an item that has been archived.
106
+ class Archived < Error; end
107
+
108
+ # Raised when reddit's returns a 504 status code.
109
+ class TimedOut < Error; end
110
+
111
+ end
@@ -0,0 +1,140 @@
1
+ require 'redditkit/thing'
2
+ require 'redditkit/creatable'
3
+ require 'redditkit/votable'
4
+
5
+ module RedditKit
6
+
7
+ # A class representing a link.
8
+ class Link < RedditKit::Thing
9
+ include RedditKit::Creatable
10
+ include RedditKit::Votable
11
+
12
+ # The username of the moderator who approved this link, if it has been approved.
13
+ attr_reader :approved_by
14
+
15
+ # The username of the link's author.
16
+ attr_reader :author
17
+
18
+ # The author's flair CSS class, if they have flair assigned to them.
19
+ attr_reader :author_flair_css_class
20
+
21
+ # The author's flair text, if they have flair assigned to them.
22
+ attr_reader :author_flair_text
23
+
24
+ # The username of the moderator who banned this link, if it was banned.
25
+ attr_reader :banned_by
26
+
27
+ # The distinguished status of the link. This is either 'yes', 'no', 'admin' or 'special'.
28
+ attr_reader :distinguished
29
+
30
+ # The link's domain.
31
+ attr_reader :domain
32
+
33
+ # The time of the link's most recent edit, or nil if it has never been edited.
34
+ attr_reader :edited
35
+
36
+ # Whether the current user has hidden this link.
37
+ attr_reader :hidden
38
+
39
+ # Whether the link is a self post.
40
+ attr_reader :is_self
41
+
42
+ # The link's flair CSS class, if it has flair assigned to it.
43
+ attr_reader :link_flair_css_class
44
+
45
+ # The link's flair text, if it has flair assigned to it.
46
+ attr_reader :link_flair_text
47
+
48
+ # A hash containing further information about the link's media. For example, this could contain details about a YouTube video.
49
+ attr_reader :media
50
+
51
+ # A hash contains details for embedding the content in a web page.
52
+ attr_reader :media_embed
53
+
54
+ # The number of comments on the link.
55
+ attr_reader :num_comments
56
+
57
+ # The number of reports on the link.
58
+ attr_reader :num_reports
59
+
60
+ # Whether the link has been marked as NSFW.
61
+ attr_reader :over_18
62
+
63
+ # The link to the post on reddit.
64
+ attr_reader :permalink
65
+
66
+ # Whether the current user has saved this link.
67
+ attr_reader :saved
68
+
69
+ # The text for the link, if it is a self post, in Markdown.
70
+ attr_reader :selftext
71
+
72
+ # The text for the link, if it is a self post, in HTML.
73
+ attr_reader :selftext_html
74
+
75
+ # Whether the link has been marked as sticky.
76
+ attr_reader :stickied
77
+
78
+ # The name of the subreddit to which the link was posted.
79
+ attr_reader :subreddit
80
+
81
+ # The full name of the subreddit to which the link was posted.
82
+ attr_reader :subreddit_id
83
+
84
+ # The URL to the thumbnail for the link.
85
+ attr_reader :thumbnail
86
+
87
+ # The title of the link.
88
+ attr_reader :title
89
+
90
+ # The link's URL. This will be a link to the post on reddit if the link is a self post.
91
+ attr_reader :url
92
+
93
+ # Whether the link has been visited by the current user. Requires that the current user have reddit gold.
94
+ attr_reader :visited
95
+
96
+ alias approved? approved_by
97
+ alias banned? banned_by
98
+ alias nsfw? over_18
99
+ alias self_post? is_self
100
+ alias sticky? stickied
101
+ alias subreddit_full_name subreddit_id
102
+ alias text selftext
103
+ alias text_html selftext_html
104
+ alias thumbnail_url thumbnail
105
+ alias total_comments num_comments
106
+ alias total_reports num_reports
107
+
108
+ # Determines whether a link is showing its score. reddit doesn't display scores for links less than two hours old.
109
+ #
110
+ # @return [Boolean]
111
+ def showing_link_score?
112
+ current_time = Time.now
113
+ submission_time = created_at
114
+
115
+ difference = (current_time - submission_time) / 60 / 60
116
+ difference >= 2
117
+ end
118
+
119
+ # Determines whether a link has an image URL.
120
+ #
121
+ # @return [Boolean]
122
+ def image_link?
123
+ extensions = %w(.png .jpg .jpeg .gif)
124
+ extensions.any?{ |extension| url.end_with? extension }
125
+ end
126
+
127
+ def permalink
128
+ @permalink ||= "http://reddit.com/" << @attributes[:permalink]
129
+ end
130
+
131
+ # Returns the short URL for a link.
132
+ #
133
+ # @return [String]
134
+ # @example http://redd.it/link-id.
135
+ def short_link
136
+ 'http://redd.it/' << id
137
+ end
138
+
139
+ end
140
+ end
@@ -0,0 +1,19 @@
1
+ module RedditKit
2
+
3
+ # A class representing actions taken by moderators of subreddits.
4
+ class ModeratorAction < RedditKit::Thing
5
+
6
+ attr_reader :action
7
+ attr_reader :details
8
+ attr_reader :mod
9
+ attr_reader :mod_id36
10
+ attr_reader :subreddit
11
+ attr_reader :sub_id36
12
+
13
+ alias moderator_username mod
14
+ alias moderator_identifier mod_id36
15
+ alias subreddit_name subreddit
16
+ alias subreddit_identifier sub_id36
17
+
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ require 'ostruct'
2
+ require 'redditkit/creatable'
3
+
4
+ module RedditKit
5
+
6
+ # A class representing a multireddit.
7
+ class Multireddit < RedditKit::Base
8
+ include RedditKit::Creatable
9
+
10
+ attr_reader :name
11
+ attr_reader :can_edit
12
+ attr_reader :visibility
13
+ attr_reader :path
14
+
15
+ alias editable? can_edit
16
+
17
+ # An array of subreddit display names.
18
+ #
19
+ # @return [Array<String>]
20
+ def subreddits
21
+ @subreddits ||= @attributes[:subreddits].collect { |subreddit| subreddit[:name] }
22
+ end
23
+
24
+ # The username of the multireddit's owner.
25
+ #
26
+ # @return [String] The owner's username.
27
+ def username
28
+ @username ||= path[/\/user\/(.*)\/m\//, 1]
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,14 @@
1
+ require 'redditkit/base'
2
+
3
+ module RedditKit
4
+
5
+ # A class representing a multireddit description.
6
+ class MultiredditDescription < RedditKit::Base
7
+
8
+ attr_reader :body_html
9
+ attr_reader :body_md
10
+
11
+ alias text body_md
12
+
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ require 'forwardable'
2
+
3
+ module RedditKit
4
+
5
+ # A response object for paginated requests, allowing users to access both results and pagination data.
6
+ class PaginatedResponse
7
+ extend Forwardable
8
+ include Enumerable
9
+ def_delegators :@results, :each, :length, :empty?
10
+
11
+ attr_reader :results
12
+ attr_reader :before
13
+ attr_reader :after
14
+
15
+ def initialize(before, after, results)
16
+ @before = before
17
+ @after = after
18
+ @results = results
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ require 'redditkit/thing'
2
+ require 'redditkit/creatable'
3
+
4
+ module RedditKit
5
+
6
+ # A class representing a private message.
7
+ class PrivateMessage < RedditKit::Thing
8
+ include RedditKit::Creatable
9
+
10
+ attr_reader :author
11
+ attr_reader :body
12
+ attr_reader :body_html
13
+ attr_reader :context
14
+ attr_reader :dest
15
+ attr_reader :first_message
16
+ attr_reader :first_message_name
17
+ attr_reader :new
18
+ attr_reader :parent_id
19
+ attr_reader :replies
20
+ attr_reader :subject
21
+ attr_reader :subreddit
22
+ attr_reader :was_comment
23
+
24
+ alias unread? new
25
+ alias recipient dest
26
+ end
27
+ end