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,179 @@
1
+ require 'redditkit/moderator_action'
2
+
3
+ module RedditKit
4
+ class Client
5
+
6
+ # Methods for moderating subreddits.
7
+ module Moderation
8
+
9
+ # Ban a user. This requires moderator privileges on the specified subreddit.
10
+ #
11
+ # @param user [String, RedditKit::User] The user's username, or a RedditKit::User.
12
+ # @param subreddit [String, RedditKit::Subreddit] The subreddit's name, or a RedditKit::Subreddit.
13
+ # @note If a subreddit's name is passed as the :subreddit option, a second HTTP request will be made to get the RedditKit::Subreddit object.
14
+ def ban(user, subreddit)
15
+ ban_or_unban_user true, user, subreddit
16
+ end
17
+
18
+ # Lift the ban on a user. This requires moderator privileges on the specified subreddit.
19
+ #
20
+ # @param user [String, RedditKit::User] The user's username, or a RedditKit::User.
21
+ # @param subreddit [String, RedditKit::Subreddit] The subreddit's name, or a RedditKit::Subreddit.
22
+ def unban(user, subreddit)
23
+ ban_or_unban_user false, user, subreddit
24
+ end
25
+
26
+ # Approves an unmoderated link.
27
+ #
28
+ # @param link [String, RedditKit::Link] A link's full name, or a RedditKit::Link.
29
+ def approve(link)
30
+ full_name = extract_full_name link
31
+ post('api/approve', { :id => full_name, :api_type => :json })
32
+ end
33
+
34
+ # Removes a link or comment.
35
+ #
36
+ # @param object [String, RedditKit::Comment, RedditKit::Link] The full name of a link/comment, a RedditKit::Comment, or a RedditKit::Link.
37
+ def remove(object)
38
+ full_name = extract_full_name object
39
+ post('api/remove', { :id => full_name, :api_type => :json })
40
+ end
41
+
42
+ # Ignores the reports on a link or comment.
43
+ #
44
+ # @param object [String, RedditKit::Comment, RedditKit::Link] The full name of a link/comment, a RedditKit::Comment, or a RedditKit::Link.
45
+ def ignore_reports(object)
46
+ full_name = extract_full_name object
47
+ post('api/ignore_reports', { :id => full_name, :api_type => :json })
48
+ end
49
+
50
+ # Unignores the reports on a link or comment.
51
+ #
52
+ # @param object [String, RedditKit::Comment, RedditKit::Link] The full name of a link/comment, a RedditKit::Comment, or a RedditKit::Link.
53
+ def unignore_reports(object)
54
+ full_name = extract_full_name object
55
+ post('api/unignore_reports', { :id => full_name, :api_type => :json })
56
+ end
57
+
58
+ # Distinguishes a comment as being posted by a moderator or admin.
59
+ #
60
+ # @option options [String, RedditKit::Comment] comment The full name of a comment, or a RedditKit::Comment.
61
+ # @option options [yes, no, admin, special] distinguish How to distinguish the comment. Defaults to yes.
62
+ # @note admin and special values may only be used if the current user has the right privileges.
63
+ def distinguish(options)
64
+ full_name = extract_full_name options[:comment]
65
+ how = options[:distinguish] || :yes
66
+ parameters = { :id => full_name, :api_type => :json }
67
+
68
+ post("api/distinguish/#{how}", parameters)
69
+ end
70
+
71
+ # Sets a post as have its contest mode enabled or disabled.
72
+ #
73
+ # @param link [String, RedditKit::Link] The full name of a link, or a RedditKit::Link.
74
+ # @param contest_mode [Boolean] Whether to enable contest mode for the link's comments. Defaults to true.
75
+ def set_contest_mode(link, contest_mode = true)
76
+ full_name = extract_full_name link
77
+ set_as_contest = contest_mode ? 'True' : 'False'
78
+
79
+ post('api/set_contest_mode', { :id => full_name, :state => set_as_contest, :api_type => :json })
80
+ end
81
+
82
+ # Sets a post as sticky within its parent subreddit. This will replace the existing sticky post, if there is one.
83
+ #
84
+ # @param link [String, RedditKit::Link] The full name of a link, or a RedditKit::Link.
85
+ # @param sticky [Boolean] Whether to mark the post as sticky or unsticky. Defaults to true.
86
+ def set_sticky_post(link, sticky = true)
87
+ full_name = extract_full_name link
88
+ set_as_sticky = sticky ? 'True' : 'False'
89
+
90
+ post('api/set_subreddit_sticky', { :id => full_name, :state => set_as_sticky, :api_type => :json })
91
+ end
92
+
93
+ # Get the moderators of a subreddit.
94
+ #
95
+ # @param subreddit [String, RedditKit::Subreddit] The display name of a subreddit, or a RedditKit::Subreddit.
96
+ # @return [Array<OpenStruct>]
97
+ def moderators_of_subreddit(subreddit)
98
+ members_in_subreddit subreddit, 'moderators'
99
+ end
100
+
101
+ # Get the contributors to a subreddit.
102
+ #
103
+ # @param subreddit [String, RedditKit::Subreddit] The display name of a subreddit, or a RedditKit::Subreddit.
104
+ # @return [Array<OpenStruct>]
105
+ def contributors_to_subreddit(subreddit)
106
+ members_in_subreddit subreddit, 'contributors'
107
+ end
108
+
109
+ # Accepts an invitation to become a moderator of a subreddit.
110
+ #
111
+ # @param subreddit [String, RedditKit::Subreddit] The display name of the subreddit, or a RedditKit::Subreddit.
112
+ def accept_moderator_invitation(subreddit)
113
+ subreddit_name = extract_string(subreddit, :display_name)
114
+ post('api/accept_moderator_invite', { :r => subreddit_name })
115
+ end
116
+
117
+ # Resign as a contributor to a subreddit.
118
+ #
119
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's full name, or a RedditKit::Subreddit.
120
+ def resign_as_contributor(subreddit)
121
+ full_name = extract_full_name subreddit
122
+ post('api/leavecontributor', { :id => full_name })
123
+ end
124
+
125
+ # Resign as a moderator of a subreddit.
126
+ #
127
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's full name, or a RedditKit::Subreddit.
128
+ def resign_as_moderator(subreddit)
129
+ full_name = extract_full_name subreddit
130
+ post('api/leavemoderator', { :id => full_name })
131
+ end
132
+
133
+ # Resets a subreddit's header image.
134
+ #
135
+ # @param subreddit [String, RedditKit::Subreddit] The display name of the subreddit, or a RedditKit::Subreddit.
136
+ def reset_subreddit_header(subreddit)
137
+ subreddit_name = extract_string(subreddit, :display_name)
138
+ post('api/delete_sr_header', { :r => subreddit_name })
139
+ end
140
+
141
+ # Gets the moderation log for a subreddit.
142
+ #
143
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's display name, or a RedditKit::Subreddit.
144
+ # @return [RedditKit::PaginatedResponse]
145
+ def moderation_log(subreddit)
146
+ display_name = extract_string subreddit, :display_name
147
+ objects_from_response(:get, "r/#{display_name}/about/log.json", nil)
148
+ end
149
+
150
+ private
151
+
152
+ # Lift the ban on a user. This requires moderator privileges on the specified subreddit.
153
+ #
154
+ # @param ban_or_unban [true, false] Whether to ban or unban the user.
155
+ # @param user [String, RedditKit::User] The user's username, or a RedditKit::User.
156
+ # @param subreddit [String, RedditKit::Subreddit] The subreddit's name, or a RedditKit::Subreddit.
157
+ def ban_or_unban_user(ban, user, subreddit)
158
+ username = extract_string(user, :username)
159
+ subreddit_object = (subreddit.is_a? String) ? subreddit(subreddit) : subreddit
160
+ friend_request_type = ban ? 'friend' : 'unfriend'
161
+
162
+ friend_request friend_request_type, :container => subreddit_object.full_name, :name => username, :subreddit => subreddit_object.name, :type => :banned
163
+ end
164
+
165
+ # Gets members of a given type in a subreddit.
166
+ #
167
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's display name, or a RedditKit::Subreddit.
168
+ # @param member_type [moderators, contributors] The type of members.
169
+ def members_in_subreddit(subreddit, member_type)
170
+ subreddit_name = extract_string(subreddit, :display_name)
171
+ response = get("r/#{subreddit_name}/about/#{member_type}.json", nil)
172
+
173
+ members = response[:body][:data][:children]
174
+ members.collect { |member| OpenStruct.new(member) }
175
+ end
176
+
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,207 @@
1
+ require 'json'
2
+ require 'redditkit/multireddit'
3
+ require 'redditkit/multireddit_description'
4
+
5
+ module RedditKit
6
+ class Client
7
+
8
+ # Methods for interacting with multireddits.
9
+ module Multireddits
10
+
11
+ # Fetch the current user's multireddits.
12
+ #
13
+ # @return [Array<RedditKit::Multireddit>]
14
+ def my_multireddits
15
+ objects_from_response(:get, 'api/multi/mine.json', nil)
16
+ end
17
+
18
+ # Fetch a single multireddit.
19
+ #
20
+ # @overload multireddit(path)
21
+ # @param path [String] The multireddit's path.
22
+ # @overload multireddit(username, multireddit_name)
23
+ # @param username [String] The username of the user who owns the multireddit.
24
+ # @param multireddit_name [String] The multireddit's name.
25
+ # @return [RedditKit::Multireddit]
26
+ def multireddit(*args)
27
+ path = "api/multi"
28
+
29
+ if args.length == 1
30
+ path << args.first
31
+ else
32
+ path << path_for_multireddit(args.first, args.last << '.json')
33
+ end
34
+
35
+ object_from_response(:get, path, nil)
36
+ end
37
+
38
+ # Fetches the description for a multireddit.
39
+ #
40
+ # @overload multireddit_description(multireddit)
41
+ # @param multireddit [RedditKit::Multireddit] A RedditKit::Multireddit object.
42
+ # @overload multireddit_description(user, multireddit_name)
43
+ # @param user [String, RedditKit::User] The name of the user who owns the multireddit.
44
+ # @param multireddit_name [String] The name of the multireddit.
45
+ # @raise [RedditKit::NotAuthenticated] if there is not a user signed in.
46
+ def multireddit_description(*args)
47
+ raise RedditKit::NotAuthenticated unless signed_in?
48
+
49
+ multireddit = args.pop
50
+ user = args.first
51
+ multireddit_path = nil
52
+
53
+ if user.nil?
54
+ multireddit_path = multireddit.path
55
+ else
56
+ username = extract_string(user, :username)
57
+ multireddit_path = path_for_multireddit username, multireddit
58
+ end
59
+
60
+ object_from_response(:get, "api/multi#{multireddit_path}/description", nil)
61
+ end
62
+
63
+ # Sets the description for a multireddit.
64
+ #
65
+ # @param multireddit [String, RedditKit::Multireddit] The name of the multireddit, or a RedditKit::Multireddit.
66
+ # @param description [String] The new description for the subreddit.
67
+ # @return [RedditKit::MultiredditDescription] The updated multireddit description.
68
+ def set_multireddit_description(multireddit, description)
69
+ multireddit_name = extract_string(multireddit, :name)
70
+ multireddit_path = path_for_multireddit username, multireddit_name
71
+
72
+ model = { :body_md => description }
73
+ parameters = { :multipath => multireddit_path, :model => model.to_json }
74
+ path = "api/multi#{multireddit_path}/description"
75
+
76
+ response = put path, parameters
77
+
78
+ RedditKit::MultiredditDescription.new response[:body]
79
+ end
80
+
81
+ # Creates a new multireddit.
82
+ #
83
+ # @param multireddit [String, RedditKit::Multireddit] The name of the multireddit, or a RedditKit::Multireddit.
84
+ # @param subreddits [Array] An array of subreddit names or RedditKit::Subreddit objects.
85
+ # @param visibility [public, private] An array of subreddit names to be added to the multireddit.
86
+ def create_multireddit(multireddit, subreddits = [], visibility = 'private')
87
+ create_or_update_multireddit(:post, multireddit, subreddits, visibility)
88
+ end
89
+
90
+ # Updates an existing multireddit.
91
+ #
92
+ # @param multireddit [String, RedditKit::Multireddit] The name of the multireddit, or a RedditKit::Multireddit.
93
+ # @param subreddits [Array] An array of subreddit names or RedditKit::Subreddit objects.
94
+ # @param visibility [public, private] An array of subreddit names to be added to the multireddit.
95
+ def update_multireddit(multireddit, subreddits = [], visibility = 'private')
96
+ create_or_update_multireddit(:put, multireddit, subreddits, visibility)
97
+ end
98
+
99
+ # Copies a multireddit.
100
+ #
101
+ # @overload copy_multireddit(multireddit, copied_name)
102
+ # @param multireddit [String, RedditKit::Multireddit] The name of the multireddit, or a RedditKit::Multireddit.
103
+ # @param copied_name [String] The copied name for the multireddit.
104
+ # @overload copy_multireddit(user, multireddit_name, copied_name)
105
+ # @param user [String, RedditKit::User] The name of the user who owns the multireddit.
106
+ # @param multireddit_name [String] The name of the multireddit.
107
+ # @param copied_name [String] The copied name for the multireddit.
108
+ def copy_multireddit(*args)
109
+ copied_name = args.pop
110
+ multireddit_name = extract_string(args.pop, :name)
111
+ user = args.first
112
+
113
+ if user.nil?
114
+ user = @username
115
+ else
116
+ user = extract_string(user, :username)
117
+ end
118
+
119
+ target_multireddit_path = path_for_multireddit user, multireddit_name
120
+ destination_multireddit_path = path_for_multireddit user, copied_name
121
+ parameters = { :from => target_multireddit_path, :to => destination_multireddit_path }
122
+
123
+ post('api/multi/copy', parameters)
124
+ end
125
+
126
+ # Rename a multireddit owned by the current user.
127
+ #
128
+ # @param from [String] The multireddit's current name.
129
+ # @param to [String] The new name for the multireddit.
130
+ def rename_multireddit(from, to)
131
+ old_multireddit_path = path_for_multireddit @username, from
132
+ new_multireddit_path = path_for_multireddit @username, to
133
+
134
+ parameters = { :from => old_multireddit_path, :to => new_multireddit_path }
135
+ response = post('api/multi/rename', parameters)
136
+
137
+ RedditKit::Multireddit.new response[:body]
138
+ end
139
+
140
+ # Delete a multireddit.
141
+ #
142
+ # @param multireddit [String, RedditKit::Multireddit] A multireddit's name, or a RedditKit::Multireddit.
143
+ def delete_multireddit(multireddit)
144
+ multireddit_name = extract_string(multireddit, :name)
145
+
146
+ multireddit_path = path_for_multireddit @username, multireddit_name
147
+ path = "api/multi#{multireddit_path}"
148
+ parameters = { :multireddit => path_for_multireddit(@username, multireddit_name) }
149
+
150
+ delete_path(path, parameters)
151
+ end
152
+
153
+ # Add a subreddit to a multireddit owned by the current user.
154
+ #
155
+ # @param multireddit [String, RedditKit::Multireddit] The multireddit's name, or a RedditKit::Multireddit.
156
+ # @param subreddit [String, RedditKit::Subreddit] The subreddit's name, or a RedditKit::Subreddit.
157
+ def add_subreddit_to_multireddit(multireddit, subreddit)
158
+ multireddit_name = extract_string multireddit, :name
159
+ subreddit_name = extract_string subreddit, :name
160
+
161
+ multireddit_path = path_for_multireddit @username, multireddit_name
162
+ path = "api/multi#{multireddit_path}/r/#{subreddit_name}"
163
+ model = { :name => subreddit_name }
164
+
165
+ put(path, { :model => model.to_json })
166
+ end
167
+
168
+ # Removes a subreddit from a multireddit owned by the current user.
169
+ #
170
+ # @param multireddit [String, RedditKit::Multireddit] The multireddit's name, or a RedditKit::Multireddit.
171
+ # @param subreddit [String, RedditKit::Subreddit] The subreddit's name, or a RedditKit::Subreddit.
172
+ def remove_subreddit_from_multireddit(multireddit, subreddit)
173
+ multireddit_name = extract_string multireddit, :name
174
+ subreddit_name = extract_string subreddit, :name
175
+
176
+ multireddit_path = path_for_multireddit @username, multireddit_name
177
+ path = "api/multi#{multireddit_path}/r/#{subreddit_name}"
178
+
179
+ delete_path(path, nil)
180
+ end
181
+
182
+ private
183
+
184
+ # Creates or updates a multireddit.
185
+ #
186
+ # @param method [post, put] The HTTP method for the request. POST creates a multireddit, PUT updates one.
187
+ # @param multireddit [String, RedditKit::Multireddit] The name of the multireddit, or a RedditKit::Multireddit.
188
+ # @param subreddits [Array] An array of subreddit names or RedditKit::Subreddit objects.
189
+ # @param visibility [public, private] An array of subreddit names to be added to the multireddit.
190
+ def create_or_update_multireddit(method, multireddit, subreddits = [], visibility = 'private')
191
+ multireddit_name = extract_string(multireddit, :name)
192
+ multireddit_path = path_for_multireddit @username, multireddit_name
193
+ path = "api/multi#{multireddit_path}"
194
+
195
+ subreddit_hashes = subreddits.collect do |subreddit|
196
+ { :name => extract_string(subreddit, :name) }
197
+ end
198
+
199
+ model = { :visibility => visibility, :subreddits => subreddit_hashes }
200
+ parameters = { :multipath => multireddit_path, :model => model.to_json }
201
+
202
+ request(method, path, parameters, connection)
203
+ end
204
+
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,74 @@
1
+ require 'redditkit/private_message'
2
+
3
+ module RedditKit
4
+ class Client
5
+
6
+ # Methods for retrieving and sending private messages.
7
+ module PrivateMessages
8
+
9
+ # Gets the current user's private messages or comment replies.
10
+ #
11
+ # @option options [inbox, unread, sent, messages, mentions, moderator, comments, selfreply] :category The category from which to return messages.
12
+ # @option options [1..100] :limit The number of messages to return.
13
+ # @option options [String] :before Only return subreddits before this id.
14
+ # @option options [String] :after Only return subreddits after this id.
15
+ # @option options [Boolean] :mark Whether to mark requested messages as read.
16
+ # @return [RedditKit::PaginatedResponse]
17
+ def messages(options = {})
18
+ category = options[:category] || 'inbox'
19
+ path = "message/#{category}.json"
20
+ options.delete :category
21
+
22
+ objects_from_response(:get, path, options)
23
+ end
24
+
25
+ # Send a message to another reddit user.
26
+ #
27
+ # @param message [String] The text of the message.
28
+ # @param recipient [String, RedditKit::User] The recipient of the message.
29
+ # @option options [String] :subject The subject of the message.
30
+ # @option options [String] :captcha_identifier A CAPTCHA identifier to send with the message, if the current user is required to fill one out.
31
+ # @option options [String] :captcha_value The value of the CAPTCHA to send with the message, if the current user is required to fill one out.
32
+ def send_message(message, recipient, options = {})
33
+ username = extract_string(recipient, :username)
34
+ parameters = { :to => username, :text => message, :subject => options[:subject], :captcha => options[:captcha_value], :iden => options[:captcha_identifier] }
35
+
36
+ post('api/compose', parameters)
37
+ end
38
+
39
+ # Marks a message as read.
40
+ #
41
+ # @param message [String, RedditKit::PrivateMessage] A private message's full name, or a RedditKit::PrivateMessage.
42
+ def mark_as_read(message)
43
+ parameters = { :id => extract_full_name(message) }
44
+ post('api/read_message', parameters)
45
+ end
46
+
47
+ # Marks a message as unread.
48
+ #
49
+ # @param message [String, RedditKit::PrivateMessage] A private message's full name, or a RedditKit::PrivateMessage.
50
+ def mark_as_unread(message)
51
+ parameters = { :id => extract_full_name(message) }
52
+ post('api/unread_message', parameters)
53
+ end
54
+
55
+ # Blocks the author of a private message or comment.
56
+ # Users cannot be blocked based on username as reddit only allows you to block those who have harassed you (thus leaving a message in your inbox).
57
+ #
58
+ # @param message [String, RedditKit::PrivateMessage] A private message's full name, or a RedditKit::PrivateMessage.
59
+ def block_author_of_message(message)
60
+ parameters = { :id => extract_full_name(message) }
61
+ post('api/block', parameters)
62
+ end
63
+
64
+ # Unblocks a user.
65
+ #
66
+ # @param user [String, RedditKit::User] A user's username, or a RedditKit::User.
67
+ def unblock(user)
68
+ enemy_name = extract_string(user, :username)
69
+ friend_request 'unfriend', :container => current_user.full_name, :name => enemy_name, :type => :enemy
70
+ end
71
+
72
+ end
73
+ end
74
+ end