redditkit 1.0.0

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 (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