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,63 @@
1
+ module RedditKit
2
+ class Client
3
+
4
+ # Methods for operating on apps in the current user's account.
5
+ module Apps
6
+
7
+ # Create or update an app.
8
+ #
9
+ # @param name [String] The app's name.
10
+ # @option options [String] description The app's description.
11
+ # @option options [String] about_url The app's URL.
12
+ # @option options [String] redirect_url The app's redirect URL.
13
+ # @option options [String] app_identifier The identifier of the app, if you are updating an existing one.
14
+ def create_app(name, options = {})
15
+ description = options[:description]
16
+ about_url = options[:about_url]
17
+ redirect_url = options[:redirect_url]
18
+ app_identifier = options[:app_identifier]
19
+ parameters = { :client_id => app_identifier, :name => name, :description => description, :about_url => about_url, :redirect_uri => redirect_url }
20
+
21
+ post('api/updateapp', parameters)
22
+ end
23
+ alias update_app create_app
24
+
25
+ # Delete an app.
26
+ #
27
+ # @param app_identifier [String] The identifier of the app.
28
+ def delete_app(app_identifier)
29
+ post('api/deleteapp', { :client_id => app_identifier })
30
+ end
31
+
32
+ # Revoke an app.
33
+ #
34
+ # @param app_identifier [String] The identifier of the app.
35
+ def revoke_app(app_identifier)
36
+ post('api/revokeapp', { :client_id => app_identifier })
37
+ end
38
+
39
+ # Add a user as a developer of an app.
40
+ #
41
+ # @param user [String, RedditKit::User] The username of the user to add, or a RedditKit::User.
42
+ # @param app_identifier [String] The identifier of the app.
43
+ def add_developer(user, app_identifier)
44
+ username = extract_string user, :username
45
+ parameters = { :name => username, :client_id => app_identifier }
46
+
47
+ post('api/adddeveloper', parameters)
48
+ end
49
+
50
+ # Remove an app's developer.
51
+ #
52
+ # @param user [String, RedditKit::User] The username of the user to add, or a RedditKit::User.
53
+ # @param app_identifier [String] The identifier of the app.
54
+ def remove_developer(user, app_identifier)
55
+ username = extract_string user, :username
56
+ parameters = { :name => username, :client_id => app_identifier }
57
+
58
+ post('api/removedeveloper', parameters)
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,36 @@
1
+ module RedditKit
2
+ class Client
3
+
4
+ # Methods for retrieving and submitting CAPTCHAs.
5
+ module Captcha
6
+
7
+ # Whether the current user will need to answer a CAPTCHA for methods which may require one.
8
+ #
9
+ # @return [Boolean]
10
+ def needs_captcha?
11
+ response = get('api/needs_captcha.json', nil)
12
+ needs_captcha = response[:body]
13
+
14
+ needs_captcha == 'true'
15
+ end
16
+
17
+ # Returns a new CATPCHA identifier.
18
+ #
19
+ # @return [String] The CAPTCHA identifier.
20
+ def new_captcha_identifier
21
+ response = post('api/new_captcha', { :api_type => :json })
22
+ data = response[:body][:json][:data]
23
+
24
+ data[:iden]
25
+ end
26
+
27
+ # Returns the URL for a CAPTCHA image with a given identifier.
28
+ #
29
+ # @return [String]
30
+ def captcha_url(captcha_identifier)
31
+ "http://reddit.com/captcha/#{captcha_identifier}.png"
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,54 @@
1
+ require 'redditkit/comment'
2
+
3
+ module RedditKit
4
+ class Client
5
+
6
+ # Methods for interacting with comment threads.
7
+ module Comments
8
+
9
+ # Get a comment object from its full name.
10
+ #
11
+ # @param comment_full_name [String] The full name of the comment.
12
+ # @return [RedditKit::Comment]
13
+ # @note This method does not include any replies to the comment.
14
+ def comment(comment_full_name)
15
+ comments = objects_from_response(:get, 'api/info.json', { :id => comment_full_name })
16
+ comments.first
17
+ end
18
+
19
+ # Get comments on a link.
20
+ #
21
+ # @param link [String, RedditKit::Link] The identifier of the link, or a RedditKit::Link.
22
+ # @option options [Integer] :limit The number of comments to return.
23
+ # @return [Array<RedditKit::Comment>]
24
+ def comments(link, options = {})
25
+ return nil unless link
26
+
27
+ link_id = extract_id link
28
+ path = "comments/#{link_id}.json"
29
+
30
+ comments_from_response(:get, path, options)
31
+ end
32
+
33
+ # Submit a comment on a link or comment.
34
+ #
35
+ # @param link_or_comment [String, RedditKit::Comment, RedditKit::Link] The object to comment on.
36
+ # @param text [String] The text of the comment, formatted as Markdown.
37
+ # @return [RedditKit::Comment] The new comment object.
38
+ def submit_comment(link_or_comment, text)
39
+ object_full_name = extract_full_name link_or_comment
40
+ parameters = { :text => text, :thing_id => object_full_name, :api_type => :json }
41
+
42
+ response = post('/api/comment', parameters)
43
+ response_data = response[:body][:json][:data]
44
+
45
+ full_comment_data = response_data[:things].first
46
+ comment_data = full_comment_data[:data]
47
+ comment_full_name = comment_data[:id]
48
+
49
+ comment comment_full_name
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,148 @@
1
+ require 'ostruct'
2
+
3
+ module RedditKit
4
+ class Client
5
+
6
+ # Methods for interacting with flair in subreddits.
7
+ module Flair
8
+
9
+ # Lists users and their flair in a subreddit.
10
+ #
11
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's name, or a RedditKit::Subreddit.
12
+ # @option options [1..1000] :limit The number of items to return.
13
+ # @option options [String] :before Only return objects before this id.
14
+ # @option options [String] :after Only return objects after this id.
15
+ def flair_list(subreddit, options = {})
16
+ subreddit_name = extract_string(subreddit, :display_name)
17
+ list = get("/r/#{subreddit_name}/api/flairlist.json", options)
18
+ users = list[:body][:users]
19
+
20
+ users.collect { |user| OpenStruct.new(user) }
21
+ end
22
+
23
+ # Creates a flair template in a subreddit.
24
+ #
25
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's name, or a RedditKit::Subreddit.
26
+ # @param type [user, link] The template's type. Defaults to user.
27
+ # @option options [String] text The text value for the template.
28
+ # @option options [String] css_class The CSS class for the template.
29
+ # @option options [Boolean] user_editable Whether the template should be editable by users.
30
+ def create_flair_template(subreddit, type, options = {})
31
+ subreddit_name = extract_string(subreddit, :display_name)
32
+ flair_type = (type.to_s == 'link') ? 'LINK_FLAIR' : 'USER_FLAIR'
33
+
34
+ parameters = { :r => subreddit_name, :flair_type => flair_type, :text => options[:text], :css_class => options[:css_class], :api_type => :json }
35
+ parameters[:text_editable] = 'on' if options[:user_editable]
36
+
37
+ post('api/flairtemplate', parameters)
38
+ end
39
+
40
+ # Deletes a flair template.
41
+ #
42
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's name, or a RedditKit::Subreddit.
43
+ # @param template_identifier [String] The template's identifier.
44
+ def delete_flair_template(subreddit, template_identifier)
45
+ subreddit_name = extract_string(subreddit, :display_name)
46
+ parameters = { :flair_template_id => template_identifier, :r => subreddit_name }
47
+
48
+ post('api/deleteflairtemplate', parameters)
49
+ end
50
+
51
+ # Toggles flair for a subreddit.
52
+ #
53
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's name, or a RedditKit::Subreddit.
54
+ # @param flair_enabled [Boolean] Whether to enable flair for the subreddit.
55
+ def toggle_flair(subreddit, flair_enabled)
56
+ post('api/setflairenabled', { :r => subreddit, :flair_enabled => flair_enabled })
57
+ end
58
+
59
+ # Sets flair on a link or user.
60
+ #
61
+ # @option options [String, RedditKit::Subreddit] subreddit A subreddit's name, or a RedditKit::Subreddit.
62
+ # @option options [String] text The text value for the template.
63
+ # @option options [String] css_class The CSS class for the template.
64
+ # @option options [String, RedditKit::Link] link A link's full name, or a RedditKit::Link.
65
+ # @option options [String, RedditKit::User] user A user's username, or a RedditKit::User.
66
+ # @note Raises RedditKit::BadClassName if any CSS classes contain invalid characters, or RedditKit::TooManyClassNames if there are too many.
67
+ def set_flair(options)
68
+ subreddit_name = extract_string(options[:subreddit], :display_name)
69
+ link_full_name = extract_full_name options[:link]
70
+ username = extract_string options[:user], :username
71
+
72
+ parameters = { :r => subreddit_name, :text => options[:text], :css_class => options[:css_class], :name => username, :link => link_full_name }
73
+
74
+ post('api/flair', parameters)
75
+ end
76
+
77
+ # Sets a subreddit's flair using a string formatted as CSV.
78
+ #
79
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's name, or a RedditKit::Subreddit.
80
+ # @param csv_string [String] A string in CSV format.
81
+ # @note Each line in the string should be in the format 'user,flair-text,css_class'.
82
+ def set_flair_with_csv(subreddit, csv_string)
83
+ subreddit_name = extract_string(subreddit, :display_name)
84
+ parameters = { :r => subreddit_name, :flair_csv => csv_string }
85
+
86
+ post('api/flaircsv', parameters)
87
+ end
88
+
89
+ # Clears a user's flair.
90
+ #
91
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's name, or a RedditKit::Subreddit.
92
+ # @param user [String, RedditKit::User] A subreddit's name, or a RedditKit::Subreddit.
93
+ def delete_user_flair(subreddit, user)
94
+ subreddit_name = extract_string(subreddit, :display_name)
95
+ username = extract_string(user, :username)
96
+ parameters = { :name => username, :r => subreddit_name }
97
+
98
+ post('api/deleteflair', parameters)
99
+ end
100
+
101
+ # Clears all flair templates of a certain type.
102
+ #
103
+ # @option options [String, RedditKit::Subreddit] subreddit A subreddit's name, or a RedditKit::Subreddit.
104
+ # @option options [user, link] type The template's type. Defaults to user.
105
+ def clear_flair_templates(options)
106
+ subreddit_name = extract_string(options[:subreddit], :display_name)
107
+ flair_type = 'USER_FLAIR'
108
+ flair_type = 'LINK_FLAIR' if options[:type].to_s == 'link'
109
+
110
+ parameters = { :r => subreddit_name, :flair_type => flair_type, :text => options[:text], :css_class => options[:css_class] }
111
+
112
+ post('api/clearflairtemplates', parameters)
113
+ end
114
+
115
+ # Applys a flair template to a link or user.
116
+ #
117
+ # @option options [String, RedditKit::Subreddit] subreddit A subreddit's name, or a RedditKit::Subreddit.
118
+ # @option options [String] template_id The template's identifier.
119
+ # @option options [String, RedditKit::Link] link A link's full name, or a RedditKit::Link.
120
+ # @option options [String, RedditKit::User] user A user's username, or a RedditKit::User.
121
+ def apply_flair_template(options)
122
+ subreddit_name = extract_string(options[:subreddit], :display_name)
123
+ link_full_name = extract_full_name options[:link]
124
+ username = extract_string options[:user], :username
125
+
126
+ parameters = { :flair_template_id => options[:template_id], :r => subreddit_name, :name => username, :link => link_full_name }
127
+
128
+ post('api/selectflair', parameters)
129
+ end
130
+
131
+ # Sets flair options for a subreddit.
132
+ #
133
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's name, or a RedditKit::Subreddit.
134
+ # @option options [Boolean] flair_enabled Whether to enable flair for the subreddit.
135
+ # @option options [left, right] flair_position The position of user flair.
136
+ # @option options [left, right] link_flair_position The position of link flair.
137
+ # @option options [Boolean] flair_self_assign_enabled Whether users may assign their own flair.
138
+ # @option options [Boolean] link_flair_self_assign_enabled Whether users may assign their own link flair.
139
+ def set_flair_options(subreddit, options = {})
140
+ subreddit_name = extract_string(subreddit, :display_name)
141
+ options.merge!({ :r => subreddit_name, :uh => @modhash })
142
+
143
+ post('api/flairconfig', options)
144
+ end
145
+
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,134 @@
1
+ require 'redditkit/link'
2
+
3
+ module RedditKit
4
+ class Client
5
+
6
+ # Methods for retrieving, submitting and interacting with links.
7
+ module Links
8
+
9
+ # Gets the links currently on the front page.
10
+ #
11
+ # @option options [hot, new, rising, controversial, top] :category The category from which to retrieve links.
12
+ # @option options [hour, day, week, month, year, all] :time The time from which to retrieve links. Defaults to all time.
13
+ # @option options [1..100] :limit The number of links to return.
14
+ # @option options [String] :before Only return links before this identifier.
15
+ # @option options [String] :after Only return links after this identifier.
16
+ # @return [RedditKit::PaginatedResponse]
17
+ def front_page(options = {})
18
+ links nil, options
19
+ end
20
+
21
+ # Gets an array of links from a specific subreddit.
22
+ #
23
+ # @param subreddit [String, RedditKit::Subreddit] The display name of the subreddit, or a RedditKit::Subreddit.
24
+ # @option options [hot, new, rising, controversial, top] :category The category from which to retrieve links.
25
+ # @option options [hour, day, week, month, year, all] :time The time from which to retrieve links. Defaults to all time.
26
+ # @option options [1..100] :limit The number of links to return.
27
+ # @option options [String] :before Only return links before this identifier.
28
+ # @option options [String] :after Only return links after this identifier.
29
+ # @return [RedditKit::PaginatedResponse]
30
+ def links(subreddit, options = {})
31
+ subreddit_name = extract_string(subreddit, :display_name) if subreddit
32
+ category = options[:category] || :hot
33
+
34
+ path = "%s/#{category.to_s}.json" % ('r/' + subreddit_name if subreddit_name)
35
+
36
+ options[:t] = options[:time] if options[:time]
37
+ options.delete :category
38
+ options.delete :time
39
+
40
+ objects_from_response(:get, path, options)
41
+ end
42
+
43
+ # Gets a link object from its full name.
44
+ #
45
+ # @param link_full_name [String] The full name of the link.
46
+ # @return [RedditKit::Link]
47
+ # @note This method will return nil if there is not a user currently signed in.
48
+ def link(link_full_name)
49
+ links = objects_from_response(:get, 'api/info.json', { :id => link_full_name })
50
+ links.first
51
+ end
52
+
53
+ # Gets links with a specific domain.
54
+ #
55
+ # @param domain [String] The domain for which to get links.
56
+ # @option options [hour, day, week, month, year] :time The time from which to retrieve links. Defaults to all time.
57
+ # @option options [1..100] :limit The number of links to return.
58
+ # @option options [String] :before Only return links before this identifier.
59
+ # @option options [String] :after Only return links after this identifier.
60
+ # @return [RedditKit::PaginatedResponse]
61
+ # @example links = RedditKit.links_with_domain "github.com"
62
+ def links_with_domain(domain, options = {})
63
+ parameters = { :url => domain, :t => options[:time] }
64
+ options.merge! parameters
65
+ options.delete :t
66
+
67
+ objects_from_response(:get, 'api/info.json', options)
68
+ end
69
+
70
+ # Submits a link or self post to reddit.
71
+ #
72
+ # @param title [String] The title of the post.
73
+ # @param subreddit [String, RedditKit::Subreddit] A subreddit's display name, or a RedditKit::Subreddit.
74
+ # @option options [String] :url The URL for the post. Note that if this value is present, :text will be ignored.
75
+ # @option options [String] :text The text value for the post, as Markdown.
76
+ # @option options [String] :captcha_identifier An identifier for a CAPTCHA, if the current user is required to fill one out.
77
+ # @option options [String] :captcha_value The value for the CAPTCHA with the given identifier, as filled out by the user.
78
+ def submit(title, subreddit, options = {})
79
+ subreddit_name = extract_string subreddit, :display_name
80
+ parameters = { :title => title, :sr => subreddit_name, :iden => options[:captcha_identifier], :captcha => options[:captcha_value] }
81
+
82
+ if options[:url]
83
+ parameters[:url] = options[:url]
84
+ else
85
+ parameters[:text] = options[:text]
86
+ end
87
+
88
+ post('api/submit', parameters)
89
+ end
90
+
91
+ # Marks a link as not safe for work.
92
+ #
93
+ # @param link [String, RedditKit::Link] A link's full name, or a RedditKit::Link.
94
+ def mark_nsfw(link)
95
+ post('api/marknsfw', { :id => extract_full_name(link) })
96
+ end
97
+
98
+ # Marks a link as safe for work.
99
+ #
100
+ # @param link [String, RedditKit::Subreddit] A link's full name, or a RedditKit::Link.
101
+ def mark_sfw(link)
102
+ post('api/unmarknsfw', { :id => extract_full_name(link) })
103
+ end
104
+ alias unmark_nsfw mark_sfw
105
+
106
+ # Hides a link.
107
+ #
108
+ # @param link [String, RedditKit::Link] A link's full name, or a RedditKit::Link.
109
+ def hide(link)
110
+ post('api/hide', { :id => extract_full_name(link) })
111
+ end
112
+
113
+ # Unhides a link.
114
+ #
115
+ # @param link [String, RedditKit::Link] A link's full name, or a RedditKit::Link.
116
+ def unhide(link)
117
+ post('api/unhide', { :id => extract_full_name(link) })
118
+ end
119
+
120
+ # Gets a random link.
121
+ #
122
+ # @return [RedditKit::Link]
123
+ def random_link
124
+ response = get('/random', nil)
125
+ headers = response[:response_headers]
126
+ location = headers[:location]
127
+
128
+ link_id = location[/\/tb\/(.*)/, 1]
129
+ link "t3_#{link_id}"
130
+ end
131
+
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,50 @@
1
+ module RedditKit
2
+ class Client
3
+
4
+ # Methods which don't belong in any clear categroy, such as editing and deleting items on reddit.
5
+ module Miscellaneous
6
+
7
+ # Edit the text or a self post or comment.
8
+ #
9
+ # @param object [String, RedditKit::Comment, RedditKit::Link] A link or comment's full name, a RedditKit::Link, or a RedditKit::Subreddit.
10
+ # @option options [String] text The new text for the link or comment.
11
+ def edit(object, options)
12
+ parameters = { :text => options[:text], :thing_id => extract_full_name(object) }
13
+ post('/api/editusertext', parameters)
14
+ end
15
+
16
+ # Deletes a link or comment.
17
+ #
18
+ # @param object [String, RedditKit::Comment, RedditKit::Link] A link or comment's full name, a RedditKit::Link, or a RedditKit::Subreddit.
19
+ def delete(object)
20
+ full_name = extract_full_name object
21
+ post('api/del', { :id => full_name })
22
+ end
23
+
24
+ # Saves a link or comment.
25
+ #
26
+ # @param object [String, RedditKit::Link, RedditKit::Subreddit] A link or comment's full name, a RedditKit::Link, or a RedditKit::Subreddit.
27
+ def save(object)
28
+ full_name = extract_full_name object
29
+ post('api/save', { :id => full_name })
30
+ end
31
+
32
+ # Unsaves a link or comment.
33
+ #
34
+ # @param object [String, RedditKit::Link, RedditKit::Subreddit] A link or comment's full name, a RedditKit::Link, or a RedditKit::Subreddit.
35
+ def unsave(object)
36
+ full_name = extract_full_name object
37
+ post('api/unsave', { :id => full_name })
38
+ end
39
+
40
+ # Reports a link or comment. The reddit API will also hide the link or comment.
41
+ #
42
+ # @param object [String, RedditKit::Link, RedditKit::Comment] A link or comment's full name, a RedditKit::Link, or a RedditKit::Subreddit.
43
+ def report(object)
44
+ full_name = extract_full_name object
45
+ post('api/report', { :id => full_name })
46
+ end
47
+
48
+ end
49
+ end
50
+ end