redditkit 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.md +22 -0
- data/README.md +155 -0
- data/Rakefile +8 -0
- data/lib/redditkit.rb +26 -0
- data/lib/redditkit/base.rb +60 -0
- data/lib/redditkit/client.rb +142 -0
- data/lib/redditkit/client/account.rb +73 -0
- data/lib/redditkit/client/apps.rb +63 -0
- data/lib/redditkit/client/captcha.rb +36 -0
- data/lib/redditkit/client/comments.rb +54 -0
- data/lib/redditkit/client/flair.rb +148 -0
- data/lib/redditkit/client/links.rb +134 -0
- data/lib/redditkit/client/miscellaneous.rb +50 -0
- data/lib/redditkit/client/moderation.rb +179 -0
- data/lib/redditkit/client/multireddits.rb +207 -0
- data/lib/redditkit/client/private_messages.rb +74 -0
- data/lib/redditkit/client/search.rb +25 -0
- data/lib/redditkit/client/subreddits.rb +120 -0
- data/lib/redditkit/client/users.rb +109 -0
- data/lib/redditkit/client/utilities.rb +137 -0
- data/lib/redditkit/client/voting.rb +41 -0
- data/lib/redditkit/client/wiki.rb +83 -0
- data/lib/redditkit/comment.rb +54 -0
- data/lib/redditkit/creatable.rb +17 -0
- data/lib/redditkit/error.rb +111 -0
- data/lib/redditkit/link.rb +140 -0
- data/lib/redditkit/moderator_action.rb +19 -0
- data/lib/redditkit/multireddit.rb +32 -0
- data/lib/redditkit/multireddit_description.rb +14 -0
- data/lib/redditkit/paginated_response.rb +22 -0
- data/lib/redditkit/private_message.rb +27 -0
- data/lib/redditkit/response/parse_json.rb +29 -0
- data/lib/redditkit/response/raise_error.rb +21 -0
- data/lib/redditkit/subreddit.rb +86 -0
- data/lib/redditkit/thing.rb +20 -0
- data/lib/redditkit/user.rb +30 -0
- data/lib/redditkit/version.rb +19 -0
- data/lib/redditkit/votable.rb +37 -0
- data/redditkit.gemspec +25 -0
- data/spec/cassettes/RedditKit_Client/should_raise_an_error_with_invalid_credentials.yml +39 -0
- data/spec/cassettes/RedditKit_Client_Account/_sign_in/signs_the_user_in.yml +132 -0
- data/spec/cassettes/RedditKit_Client_Account/_update_session/updates_the_current_session.yml +133 -0
- data/spec/cassettes/RedditKit_Client_Captcha/_captcha_url/returns_a_CAPTCHA_url_from_an_identifier.yml +38 -0
- data/spec/cassettes/RedditKit_Client_Captcha/_needs_captcha_/checks_if_the_current_account_needs_a_CAPTCHA.yml +44 -0
- data/spec/cassettes/RedditKit_Client_Captcha/_new_captcha_identifier/returns_a_new_CAPTCHA_identifier.yml +38 -0
- data/spec/cassettes/RedditKit_Client_Comments/_comment/requests_the_correct_resource.yml +47 -0
- data/spec/cassettes/RedditKit_Client_Comments/_comments/with_a_RedditKit_Link/returns_comments_on_a_link.yml +140 -0
- data/spec/cassettes/RedditKit_Client_Comments/_comments/with_a_link_identifier/returns_comments_on_a_link.yml +89 -0
- data/spec/cassettes/RedditKit_Client_Comments/_submit_comment/requests_the_correct_resource.yml +313 -0
- data/spec/cassettes/RedditKit_Client_Flair/_apply_flair_template/clears_flair_templates.yml +52 -0
- data/spec/cassettes/RedditKit_Client_Flair/_clear_flair_templates/clears_flair_templates.yml +49 -0
- data/spec/cassettes/RedditKit_Client_Flair/_create_flair_template/creates_a_flair_template.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Flair/_create_flair_template/raises_InvalidClassName.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Flair/_create_flair_template/raises_TooManyClassNames.yml +47 -0
- data/spec/cassettes/RedditKit_Client_Flair/_delete_user_flair/requests_the_correct_resource.yml +60 -0
- data/spec/cassettes/RedditKit_Client_Flair/_flair_list/returns_the_list_of_flair.yml +44 -0
- data/spec/cassettes/RedditKit_Client_Flair/_set_flair/requests_the_correct_resource.yml +49 -0
- data/spec/cassettes/RedditKit_Client_Flair/_set_flair_options/sets_flair_options.yml +49 -0
- data/spec/cassettes/RedditKit_Client_Flair/_set_flair_with_csv/requests_the_correct_resource.yml +51 -0
- data/spec/cassettes/RedditKit_Client_Flair/_toggle_flair/requests_the_correct_resource.yml +49 -0
- data/spec/cassettes/RedditKit_Client_Links/_front_page/requests_the_correct_category.yml +498 -0
- data/spec/cassettes/RedditKit_Client_Links/_front_page/requests_the_correct_resource.yml +603 -0
- data/spec/cassettes/RedditKit_Client_Links/_hide/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Links/_link/returns_a_link.yml +55 -0
- data/spec/cassettes/RedditKit_Client_Links/_links/contains_pagination_information.yml +402 -0
- data/spec/cassettes/RedditKit_Client_Links/_links/requests_a_certain_number_of_links.yml +186 -0
- data/spec/cassettes/RedditKit_Client_Links/_links/requests_front_page_links_if_no_subreddit_is_present.yml +603 -0
- data/spec/cassettes/RedditKit_Client_Links/_links/requests_links_with_the_correct_time_frame.yml +375 -0
- data/spec/cassettes/RedditKit_Client_Links/_links/requests_the_correct_subreddit_and_category.yml +402 -0
- data/spec/cassettes/RedditKit_Client_Links/_links_with_domain/returns_links_with_a_specific_domain.yml +99 -0
- data/spec/cassettes/RedditKit_Client_Links/_mark_nsfw/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Links/_random_link/returns_a_random_link.yml +91 -0
- data/spec/cassettes/RedditKit_Client_Links/_submit/raises_RedditKit_InvalidCaptcha_if_no_CAPTCHA_is_filled_out.yml +54 -0
- data/spec/cassettes/RedditKit_Client_Links/_unhide/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Links/_unmark_nsfw/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Miscellaneous/_delete/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Miscellaneous/_edit/requests_the_correct_resource.yml +52 -0
- data/spec/cassettes/RedditKit_Client_Miscellaneous/_save/saves_an_object.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Miscellaneous/_unsave/unsaves_an_object.yml +89 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_accept_moderator_invitation/requests_the_correct_resource.yml +53 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_ban/requests_the_correct_resource.yml +103 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_contributors_to_subreddit/requests_the_correct_resource.yml +47 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_ignore_reports/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_moderation_log/returns_RedditKit_ModeratorAction_objects.yml +153 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_moderators_of_subreddit/requests_the_correct_resource.yml +48 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_reset_subreddit_header/requests_the_correct_resource.yml +55 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_set_contest_mode/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_set_sticky_post/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_unban/requests_the_correct_resource.yml +54 -0
- data/spec/cassettes/RedditKit_Client_Moderation/_unignore_reports/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_add_subreddit_to_multireddit/adds_a_subreddit_to_a_multireddit.yml +177 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_create_multireddit/creates_a_multireddit.yml +137 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_create_multireddit/raises_RedditKit_Conflict_when_using_an_existing_name.yml +133 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_delete_multireddit/deletes_a_multireddit.yml +134 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit/with_a_path/returns_a_multireddit.yml +39 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit/without_a_path/returns_a_multireddit.yml +39 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit_description/with_a_multireddit/returns_a_multireddit_description.yml +81 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_multireddit_description/with_a_username_and_multireddit_name/returns_a_multireddit_description.yml +45 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_my_multireddits/return_s_the_user_s_multireddits.yml +47 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_remove_subreddit_from_multireddit/removes_a_subreddit_from_a_multireddit.yml +175 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_rename_multireddit/renames_a_multireddit.yml +134 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_set_multireddit_description/returns_a_multireddit_description.yml +48 -0
- data/spec/cassettes/RedditKit_Client_Multireddits/_update_multireddit/updates_a_multireddit.yml +184 -0
- data/spec/cassettes/RedditKit_Client_PrivateMessages/_block_author_of_message/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_PrivateMessages/_mark_as_read/requests_the_correct_resource.yml +51 -0
- data/spec/cassettes/RedditKit_Client_PrivateMessages/_mark_as_unread/requests_the_correct_resource.yml +51 -0
- data/spec/cassettes/RedditKit_Client_PrivateMessages/_messages/requests_the_correct_resource.yml +187 -0
- data/spec/cassettes/RedditKit_Client_PrivateMessages/_unblock/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Search/_search/restricts_searches_to_a_specific_subreddit.yml +878 -0
- data/spec/cassettes/RedditKit_Client_Search/_search/returns_a_specific_number_of_results.yml +130 -0
- data/spec/cassettes/RedditKit_Client_Search/_search/returns_search_results.yml +844 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_random_subreddit/returns_a_random_subreddit.yml +181 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_recommended_subreddits/returns_subreddit_names.yml +37 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_search_subreddits_by_name/returns_subreddit_names.yml +875 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subreddit/returns_a_specified_subreddit.yml +100 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subreddits/returns_a_specified_number_of_subreddits.yml +505 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subreddits/returns_subreddits_from_a_specific_category.yml +510 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subreddits_by_topic/returns_subreddit_names.yml +41 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subscribe/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subscribed_subreddits/returns_a_specified_number_of_subreddits.yml +415 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subscribed_subreddits/returns_subreddits_from_a_specific_category.yml +58 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_subscribed_subreddits/returns_the_user_s_subscribed_subreddits.yml +3469 -0
- data/spec/cassettes/RedditKit_Client_Subreddits/_unsubscribe/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Users/_friends/returns_the_user_s_friends.yml +48 -0
- data/spec/cassettes/RedditKit_Client_Users/_my_content/returns_the_user_s_content.yml +60 -0
- data/spec/cassettes/RedditKit_Client_Users/_user/requests_the_correct_resource.yml +48 -0
- data/spec/cassettes/RedditKit_Client_Users/_user/returns_a_specified_user.yml +48 -0
- data/spec/cassettes/RedditKit_Client_Users/_user/returns_the_authenticated_user.yml +48 -0
- data/spec/cassettes/RedditKit_Client_Users/_user_content/returns_the_user_s_content.yml +41 -0
- data/spec/cassettes/RedditKit_Client_Users/_username_available_/returns_false_for_an_unavailable_username.yml +36 -0
- data/spec/cassettes/RedditKit_Client_Users/_username_available_/returns_true_for_an_available_username.yml +36 -0
- data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_comment_full_name_passed/downvotes_the_comment.yml +100 -0
- data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_comment_passed/downvotes_the_comment.yml +154 -0
- data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_link_full_name_passed/downvotes_the_link.yml +106 -0
- data/spec/cassettes/RedditKit_Client_Voting/_downvote/with_a_link_passed/downvotes_the_link.yml +166 -0
- data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_comment_full_name_passed/upvotes_the_comment.yml +100 -0
- data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_comment_passed/upvotes_the_comment.yml +154 -0
- data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_link_full_name_passed/upvotes_the_link.yml +106 -0
- data/spec/cassettes/RedditKit_Client_Voting/_upvote/with_a_link_passed/upvotes_the_link.yml +166 -0
- data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_comment_full_name_passed/withdraws_the_vote_on_the_comment.yml +154 -0
- data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_comment_passed/withdraws_the_vote_on_the_comment.yml +208 -0
- data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_link_full_name_passed/withdraws_the_vote_on_the_link.yml +166 -0
- data/spec/cassettes/RedditKit_Client_Voting/_withdraw_vote/with_a_link_passed/withdraws_the_vote_on_the_link.yml +226 -0
- data/spec/cassettes/RedditKit_Client_Wiki/_add_wiki_editor/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Wiki/_edit_wiki_page/requests_the_correct_resource.yml +48 -0
- data/spec/cassettes/RedditKit_Client_Wiki/_hide_wiki_revision/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Wiki/_remove_wiki_editor/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Client_Wiki/_revert_to_revision/requests_the_correct_resource.yml +46 -0
- data/spec/cassettes/RedditKit_Comment/should_not_be_deleted_if_neither_author_and_comment_attributes_are_set_to_deleted_.yml +90 -0
- data/spec/cassettes/RedditKit_Comment/should_return_replies.yml +90 -0
- data/spec/cassettes/authenticated_client.yml +87 -0
- data/spec/redditkit/base_spec.rb +45 -0
- data/spec/redditkit/client/account_spec.rb +50 -0
- data/spec/redditkit/client/apps_spec.rb +58 -0
- data/spec/redditkit/client/captcha_spec.rb +30 -0
- data/spec/redditkit/client/comments_spec.rb +40 -0
- data/spec/redditkit/client/flair_spec.rb +92 -0
- data/spec/redditkit/client/links_spec.rb +103 -0
- data/spec/redditkit/client/miscellaneous_spec.rb +40 -0
- data/spec/redditkit/client/moderation_spec.rb +141 -0
- data/spec/redditkit/client/multireddits_spec.rb +158 -0
- data/spec/redditkit/client/private_messages_spec.rb +51 -0
- data/spec/redditkit/client/search_spec.rb +25 -0
- data/spec/redditkit/client/subreddits_spec.rb +83 -0
- data/spec/redditkit/client/users_spec.rb +92 -0
- data/spec/redditkit/client/voting_spec.rb +99 -0
- data/spec/redditkit/client/wiki_spec.rb +40 -0
- data/spec/redditkit/client_spec.rb +46 -0
- data/spec/redditkit/comment_spec.rb +26 -0
- data/spec/redditkit/creatable_spec.rb +24 -0
- data/spec/redditkit/error_spec.rb +61 -0
- data/spec/redditkit/link_spec.rb +33 -0
- data/spec/redditkit/multireddit_spec.rb +27 -0
- data/spec/redditkit/paginated_response_spec.rb +23 -0
- data/spec/redditkit/thing_spec.rb +18 -0
- data/spec/redditkit/votable_spec.rb +52 -0
- data/spec/redditkit_spec.rb +21 -0
- data/spec/spec_helper.rb +124 -0
- metadata +390 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module RedditKit
|
2
|
+
class Client
|
3
|
+
|
4
|
+
# Methods for searching reddit's links.
|
5
|
+
module Search
|
6
|
+
|
7
|
+
# Search for links.
|
8
|
+
#
|
9
|
+
# @param query [String] The search query.
|
10
|
+
# @option options [true, false] :restrict_to_subreddit Whether to search only in a specified subreddit.
|
11
|
+
# @option options [String, RedditKit::Subreddit] :subreddit The optional subreddit to search.
|
12
|
+
# @option options [1..100] limit The number of links to return.
|
13
|
+
# @option options [String] before Only return links before this full name.
|
14
|
+
# @option options [String] after Only return links after this full name.
|
15
|
+
# @return [RedditKit::PaginatedResponse]
|
16
|
+
def search(query, options = {})
|
17
|
+
path = "%s/search.json" % ('r/' + options[:subreddit] if options[:subreddit])
|
18
|
+
parameters = { :q => query, :restrict_sr => options[:restrict_to_subreddit], :limit => options[:limit] }
|
19
|
+
|
20
|
+
objects_from_response(:get, path, parameters)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'redditkit/subreddit'
|
2
|
+
|
3
|
+
module RedditKit
|
4
|
+
class Client
|
5
|
+
|
6
|
+
# Methods for interacting with subreddits.
|
7
|
+
module Subreddits
|
8
|
+
|
9
|
+
# Gets subreddits from a specified category.
|
10
|
+
#
|
11
|
+
# @option options [new, popular, banned] category The category of subreddits. Defaults to popular.
|
12
|
+
# @option options [1..100] limit The number of subreddits 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
|
+
# @return [RedditKit::PaginatedResponse]
|
16
|
+
def subreddits(options = {})
|
17
|
+
category = options[:category] or 'popular'
|
18
|
+
path = "reddits/#{category}.json"
|
19
|
+
options.delete :category
|
20
|
+
|
21
|
+
objects_from_response(:get, path, options)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Gets the current user's subscribed subreddits.
|
25
|
+
#
|
26
|
+
# @option options [subscriber, contributor, moderator] category The category from which to return subreddits. Defaults to subscriber.
|
27
|
+
# @option options [1..100] limit The number of subreddits to return.
|
28
|
+
# @option options [String] before Only return subreddits before this id.
|
29
|
+
# @option options [String] after Only return subreddits after this id.
|
30
|
+
# @return [RedditKit::PaginatedResponse]
|
31
|
+
def subscribed_subreddits(options = {})
|
32
|
+
category = options[:category] or 'subscriber'
|
33
|
+
path = "subreddits/mine/#{category}.json"
|
34
|
+
options.delete :category
|
35
|
+
|
36
|
+
objects_from_response(:get, path, options)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Gets a subreddit object.
|
40
|
+
#
|
41
|
+
# @param subreddit_name [String] A subreddit's display name.
|
42
|
+
# @return [RedditKit::Subreddit]
|
43
|
+
# @example client.subreddit "programming"
|
44
|
+
def subreddit(subreddit_name)
|
45
|
+
object_from_response(:get, "r/#{subreddit_name}/about.json", nil)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Subscribes to a subreddit.
|
49
|
+
#
|
50
|
+
# @param subreddit [String, RedditKit::Subreddit] A subreddit's full name, or a RedditKit::Subreddit.
|
51
|
+
def subscribe(subreddit)
|
52
|
+
full_name = extract_full_name subreddit
|
53
|
+
parameters = { :action => 'sub', :sr => full_name }
|
54
|
+
|
55
|
+
post("api/subscribe", parameters)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Unsubscribes from a subreddit.
|
59
|
+
#
|
60
|
+
# @param subreddit [String, RedditKit::Subreddit] A subreddit's full name, or a RedditKit::Subreddit.
|
61
|
+
def unsubscribe(subreddit)
|
62
|
+
full_name = extract_full_name subreddit
|
63
|
+
parameters = { :action => 'unsub', :sr => full_name }
|
64
|
+
|
65
|
+
post("api/subscribe", parameters)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Gets a random subreddit.
|
69
|
+
#
|
70
|
+
# @return [RedditKit::Subreddit]
|
71
|
+
def random_subreddit
|
72
|
+
response = get('r/random', nil)
|
73
|
+
headers = response[:response_headers]
|
74
|
+
location = headers[:location]
|
75
|
+
|
76
|
+
subreddit_name = location[/\/r\/(.*)\//, 1]
|
77
|
+
subreddit subreddit_name
|
78
|
+
end
|
79
|
+
|
80
|
+
# Searches for subreddits with a specific name.
|
81
|
+
#
|
82
|
+
# @param name [String] The name to search for.
|
83
|
+
# @return [RedditKit::PaginatedResponse]
|
84
|
+
def search_subreddits_by_name(name)
|
85
|
+
parameters = { :q => name }
|
86
|
+
objects_from_response :get, 'subreddits/search.json', parameters
|
87
|
+
end
|
88
|
+
|
89
|
+
# Gets an array of subreddit names by topic.
|
90
|
+
#
|
91
|
+
# @param topic [String] The desired topic.
|
92
|
+
# @return [Array<String>] An array of subreddit names.
|
93
|
+
# @example RedditKit.subreddits_by_topic 'programming'
|
94
|
+
def subreddits_by_topic(topic)
|
95
|
+
parameters = { :query => topic }
|
96
|
+
|
97
|
+
response = get('api/subreddits_by_topic.json', parameters)
|
98
|
+
body = response[:body]
|
99
|
+
|
100
|
+
body.collect { |subreddit| subreddit[:name] }
|
101
|
+
end
|
102
|
+
|
103
|
+
# Gets an array of recommended subreddits.
|
104
|
+
#
|
105
|
+
# @param subreddits [Array<String>] An array of subreddit names.
|
106
|
+
# @return [Array<String>] An array of recommended subreddit names.
|
107
|
+
# @example RedditKit.recommended_subreddits %w(ruby programming)
|
108
|
+
def recommended_subreddits(subreddits)
|
109
|
+
names = subreddits.join(',')
|
110
|
+
parameters = { :srnames => names }
|
111
|
+
|
112
|
+
response = get('api/subreddit_recommendations.json', parameters)
|
113
|
+
body = response[:body]
|
114
|
+
|
115
|
+
body.collect { |subreddit| subreddit[:sr_name] }
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'redditkit/user'
|
2
|
+
|
3
|
+
module RedditKit
|
4
|
+
class Client
|
5
|
+
|
6
|
+
# Methods for interacting with reddit users.
|
7
|
+
module Users
|
8
|
+
|
9
|
+
# Gets a user object.
|
10
|
+
#
|
11
|
+
# @param username [String] A reddit account's username. Gets the current user if this is nil.
|
12
|
+
# @return [RedditKit::User]
|
13
|
+
# @example current_user = client.user
|
14
|
+
# @example user = client.user 'amberlynns'
|
15
|
+
def user(username = nil)
|
16
|
+
if username
|
17
|
+
object_from_response(:get, "user/#{username}/about.json", nil)
|
18
|
+
else
|
19
|
+
object_from_response(:get, "api/me.json", nil)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Gets links and comments for the current user.
|
24
|
+
#
|
25
|
+
# @option options [overview, comments, submitted, liked, disliked] :category The category from which to return links and comments. Defaults to overview.
|
26
|
+
# @option options [1..100] :limit The number of links and comments to return.
|
27
|
+
# @option options [String] :before Only return links and comments before this id.
|
28
|
+
# @option options [String] :after Only return links and comments after this id.
|
29
|
+
# @return [RedditKit::PaginatedResponse]
|
30
|
+
def my_content(options = {})
|
31
|
+
category = options[:category] || :overview
|
32
|
+
path = "user/#{@username}/#{category}.json"
|
33
|
+
options.delete :category
|
34
|
+
|
35
|
+
objects_from_response(:get, path, options)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Gets links and comments for a user.
|
39
|
+
#
|
40
|
+
# @option options [overview, comments, submitted, liked, disliked] :category The category from which to return links and comments. Defaults to overview.
|
41
|
+
# @option options [1..100] :limit The number of links and comments to return.
|
42
|
+
# @option options [String] :before Only return links and comments before this id.
|
43
|
+
# @option options [String] :after Only return links and comments after this id.
|
44
|
+
# @return [RedditKit::PaginatedResponse]
|
45
|
+
# @note Public access to the liked and disliked categories is disabled by default, so this will return an empty array for most users.
|
46
|
+
def user_content(user, options = {})
|
47
|
+
username = user
|
48
|
+
|
49
|
+
path = "user/#{username}/%s.json" % (options[:category] if options[:category])
|
50
|
+
options.delete :category
|
51
|
+
|
52
|
+
objects_from_response(:get, path, options)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Gets the current user's friends.
|
56
|
+
#
|
57
|
+
# @return [Array<OpenStruct>]
|
58
|
+
def friends
|
59
|
+
response = request(:get, 'prefs/friends.json', nil, https_connection)
|
60
|
+
body = response[:body]
|
61
|
+
friends = body[0][:data][:children]
|
62
|
+
|
63
|
+
friends.collect { |friend| OpenStruct.new(friend) }
|
64
|
+
end
|
65
|
+
|
66
|
+
# Adds a user to the current user's friend list.
|
67
|
+
#
|
68
|
+
# @param user [String, RedditKit::User] A user's username, or a RedditKit::User.
|
69
|
+
def friend(user)
|
70
|
+
friend_name = extract_string(user, :username)
|
71
|
+
friend_request 'friend', :container => current_user.full_name, :name => friend_name, :type => :friend
|
72
|
+
end
|
73
|
+
|
74
|
+
# Removes a user from the current user's friend list.
|
75
|
+
#
|
76
|
+
# @param user [String, RedditKit::User] A user's ID, or a RedditKit::User.
|
77
|
+
def unfriend(user)
|
78
|
+
friend_name = extract_string(user, :username)
|
79
|
+
friend_request 'unfriend', :container => current_user.full_name, :name => friend_name, :type => :friend
|
80
|
+
end
|
81
|
+
|
82
|
+
# Checks whether a specific username is available.
|
83
|
+
#
|
84
|
+
# @param username [String] A username for which to check availability.
|
85
|
+
# @return [Boolean]
|
86
|
+
# @example puts "Username is available" if client.username_available? 'some_username'
|
87
|
+
def username_available?(username)
|
88
|
+
response = get('api/username_available.json', :user => username)
|
89
|
+
available = response[:body]
|
90
|
+
|
91
|
+
available == 'true'
|
92
|
+
end
|
93
|
+
|
94
|
+
# Registers a new reddit account.
|
95
|
+
#
|
96
|
+
# @option options [String] username The username to register.
|
97
|
+
# @option options [String] password The password for the account.
|
98
|
+
# @option options [String] email The optional email address for the account.
|
99
|
+
# @option options [String] captcha_identifier The identifier for the CAPTCHA challenge solved by the user.
|
100
|
+
# @option options [String] captcha The user's response to the CAPTCHA challenge.
|
101
|
+
# @option options [Boolean] remember Whether to keep the user's session cookie beyond the current session.
|
102
|
+
def register(username, password, options = {})
|
103
|
+
parameters = { :user => username, :passwd => password, :passwd2 => password, :captcha => options[:captcha], :iden => options[:captcha_identifier] }
|
104
|
+
post('api/register', parameters)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'redditkit/paginated_response'
|
2
|
+
|
3
|
+
module RedditKit
|
4
|
+
class Client
|
5
|
+
|
6
|
+
# Methods for streamlining requests to reddit's servers.
|
7
|
+
module Utilities
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Return an id from a string or a RedditKit::Thing object.
|
12
|
+
#
|
13
|
+
# @param object [String, RedditKit::Thing] A string or object.
|
14
|
+
# @return [String]
|
15
|
+
def extract_id(object)
|
16
|
+
extract_string object, :id
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return a full name from a string or a RedditKit::Thing object.
|
20
|
+
#
|
21
|
+
# @param object [String, RedditKit::Thing] A string or object.
|
22
|
+
# @return [String]
|
23
|
+
def extract_full_name(object)
|
24
|
+
extract_string object, :full_name
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract_string(object, attribute_name)
|
28
|
+
case object
|
29
|
+
when ::String
|
30
|
+
object
|
31
|
+
else
|
32
|
+
object.send attribute_name if object.respond_to? attribute_name
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Return the class of an object from a response.
|
37
|
+
#
|
38
|
+
# @param response [Faraday::Response] A response.
|
39
|
+
# @return [Class]
|
40
|
+
def object_class_from_response(response)
|
41
|
+
kind = object_kind_from_response(response)
|
42
|
+
object_class_from_kind(kind)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return the class of an object of a given kind.
|
46
|
+
#
|
47
|
+
# @param kind [String] The object's kind.
|
48
|
+
# @return [Class]
|
49
|
+
def object_class_from_kind(kind)
|
50
|
+
case kind
|
51
|
+
when "t1"
|
52
|
+
RedditKit::Comment
|
53
|
+
when "t2"
|
54
|
+
RedditKit::User
|
55
|
+
when "t3"
|
56
|
+
RedditKit::Link
|
57
|
+
when "t4"
|
58
|
+
RedditKit::PrivateMessage
|
59
|
+
when "t5"
|
60
|
+
RedditKit::Subreddit
|
61
|
+
when "LabeledMulti"
|
62
|
+
RedditKit::Multireddit
|
63
|
+
when "LabeledMultiDescription"
|
64
|
+
RedditKit::MultiredditDescription
|
65
|
+
when "modaction"
|
66
|
+
RedditKit::ModeratorAction
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def object_kind_from_response(response)
|
71
|
+
response[:kind]
|
72
|
+
end
|
73
|
+
|
74
|
+
def object_from_response(request_type, path, parameters = {})
|
75
|
+
response = send(request_type.to_sym, path, parameters)
|
76
|
+
body = response[:body]
|
77
|
+
|
78
|
+
object_class = object_class_from_response(body)
|
79
|
+
object_class.new(body) if object_class
|
80
|
+
end
|
81
|
+
|
82
|
+
def objects_from_response(request_type, path, parameters = {})
|
83
|
+
response = send(request_type.to_sym, path, parameters)
|
84
|
+
body = response[:body]
|
85
|
+
|
86
|
+
if body.is_a?(Hash) and body[:kind] == 'Listing'
|
87
|
+
data = body[:data]
|
88
|
+
results = objects_from_listing(body)
|
89
|
+
|
90
|
+
RedditKit::PaginatedResponse.new(data[:before], data[:after], results)
|
91
|
+
elsif body.is_a?(Array)
|
92
|
+
objects_from_array body
|
93
|
+
elsif body.is_a?(Hash)
|
94
|
+
objects_from_array body[:data]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def objects_from_listing(listing)
|
99
|
+
children = listing[:data][:children]
|
100
|
+
objects_from_array children
|
101
|
+
end
|
102
|
+
|
103
|
+
def objects_from_array(array)
|
104
|
+
array.map do |thing|
|
105
|
+
object_class = object_class_from_response(thing)
|
106
|
+
object_class.new(thing) if object_class
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def comments_from_response(request_type, path, parameters = {})
|
111
|
+
response = send(request_type.to_sym, path, parameters)
|
112
|
+
body = response[:body]
|
113
|
+
comments_listing = body.last
|
114
|
+
|
115
|
+
objects_from_listing(comments_listing)
|
116
|
+
end
|
117
|
+
|
118
|
+
def path_for_multireddit(username, multireddit_name)
|
119
|
+
"/user/#{username}/m/#{multireddit_name}"
|
120
|
+
end
|
121
|
+
|
122
|
+
# Performs a friend or unfriend request.
|
123
|
+
#
|
124
|
+
# @param type [friend, unfriend] The type of request.
|
125
|
+
# @param options Any parameters to send with the request.
|
126
|
+
def friend_request(type, options)
|
127
|
+
if options[:subreddit]
|
128
|
+
options[:r] = options[:subreddit]
|
129
|
+
options.delete :subreddit
|
130
|
+
end
|
131
|
+
|
132
|
+
post("api/#{type}", options)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module RedditKit
|
2
|
+
class Client
|
3
|
+
|
4
|
+
# Methods for voting on links and comments.
|
5
|
+
module Voting
|
6
|
+
|
7
|
+
# Upvotes a link or comment.
|
8
|
+
#
|
9
|
+
# @param link_or_comment [String, RedditKit::Comment, RedditKit::Link] The link or comment to upvote.
|
10
|
+
def upvote(link_or_comment)
|
11
|
+
vote link_or_comment, 1
|
12
|
+
end
|
13
|
+
|
14
|
+
# Downvotes a link or comment.
|
15
|
+
#
|
16
|
+
# @param link_or_comment [String, RedditKit::Comment, RedditKit::Link] The link or comment to downvote.
|
17
|
+
def downvote(link_or_comment)
|
18
|
+
vote link_or_comment, -1
|
19
|
+
end
|
20
|
+
|
21
|
+
# Withdraws a vote on a link or comment.
|
22
|
+
#
|
23
|
+
# @param link_or_comment [String, RedditKit::Comment, RedditKit::Link] The link or comment from which to withdraw the vote.
|
24
|
+
def withdraw_vote(link_or_comment)
|
25
|
+
vote link_or_comment, 0
|
26
|
+
end
|
27
|
+
|
28
|
+
# Votes on a link or comment.
|
29
|
+
#
|
30
|
+
# @param link_or_comment [String, RedditKit::Comment, RedditKit::Link] The link or comment from which to withdraw the vote.
|
31
|
+
# @param direction [-1, 0, 1] Downvote, no vote, and upvote respectively.
|
32
|
+
def vote(link_or_comment, direction)
|
33
|
+
full_name = extract_full_name(link_or_comment)
|
34
|
+
parameters = { :id => full_name, :dir => direction, :api_type => 'json' }
|
35
|
+
|
36
|
+
post('api/vote', parameters)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module RedditKit
|
2
|
+
class Client
|
3
|
+
|
4
|
+
# Methods for interacting with a subreddit's wiki.
|
5
|
+
module Wiki
|
6
|
+
|
7
|
+
# Adds a user as an approved editor of a wiki page.
|
8
|
+
#
|
9
|
+
# @param subreddit [String, RedditKit::Subreddit] A subreddit's display name, or a RedditKit::Subreddit.
|
10
|
+
# @param user [String, RedditKit::User] A user's full name, or a RedditKit::User.
|
11
|
+
# @param page [String] page The name of an existing wiki page.
|
12
|
+
def add_wiki_editor(subreddit, user, page)
|
13
|
+
toggle_wiki_editor(subreddit, user, page, 'add')
|
14
|
+
end
|
15
|
+
|
16
|
+
# Removes a user from being an approved editor of a wiki page.
|
17
|
+
#
|
18
|
+
# @param subreddit [String, RedditKit::Subreddit] A subreddit's display name, or a RedditKit::Subreddit.
|
19
|
+
# @param user [String, RedditKit::User] A user's full name, or a RedditKit::User.
|
20
|
+
# @param page [String] page The name of an existing wiki page.
|
21
|
+
def remove_wiki_editor(subreddit, user, page)
|
22
|
+
toggle_wiki_editor(subreddit, user, page, 'del')
|
23
|
+
end
|
24
|
+
|
25
|
+
# Edits a wiki page.
|
26
|
+
#
|
27
|
+
# @option options [String, RedditKit::Subreddit] subreddit A subreddit's display name, or a RedditKit::Subreddit.
|
28
|
+
# @option options [String] page The name of an existing wiki page.
|
29
|
+
# @option options [String] content The contents of the edit.
|
30
|
+
# @option options [String] reason The reason for the edit.
|
31
|
+
# @option options [String] previous_revision The starting revision for this edit.
|
32
|
+
def edit_wiki_page(options)
|
33
|
+
subreddit_name = extract_string(options[:subreddit], :display_name)
|
34
|
+
parameters = { :page => options[:page], :previous => options[:previous_revision], :content => options[:content], :reason => options[:reason] }
|
35
|
+
|
36
|
+
post("r/#{subreddit_name}/api/wiki/edit", parameters)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Hides a wiki page revision. If the revision is already hidden, this will unhide it.
|
40
|
+
#
|
41
|
+
# @option options [String, RedditKit::Subreddit] subreddit A subreddit's display name, or a RedditKit::Subreddit.
|
42
|
+
# @option options [String] page The name of an existing wiki page.
|
43
|
+
# @option options [String] revision The revision to hide.
|
44
|
+
# @return [Boolean] True if the revision is now hidden, false if it is not hidden.
|
45
|
+
def hide_wiki_revision(options)
|
46
|
+
subreddit_name = extract_string(options[:subreddit], :display_name)
|
47
|
+
options.delete :subreddit
|
48
|
+
|
49
|
+
response = post("r/#{subreddit_name}/api/wiki/hide", options)
|
50
|
+
response[:body][:status]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Reverts to a specific wiki page revision.
|
54
|
+
#
|
55
|
+
# @option options [String, RedditKit::Subreddit] subreddit A subreddit's display name, or a RedditKit::Subreddit.
|
56
|
+
# @option options [String] page The name of an existing wiki page.
|
57
|
+
# @option options [String] revision The revision to revert to.
|
58
|
+
def revert_to_revision(options)
|
59
|
+
subreddit_name = extract_string(options[:subreddit], :display_name)
|
60
|
+
options.delete :subreddit
|
61
|
+
|
62
|
+
post("r/#{subreddit_name}/api/wiki/revert", options)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Adds or removes a user as an approved editor of a wiki page.
|
68
|
+
#
|
69
|
+
# @param subreddit [String, RedditKit::Subreddit] A subreddit's display name, or a RedditKit::Subreddit.
|
70
|
+
# @param user [String, RedditKit::User] A user's full name, or a RedditKit::User.
|
71
|
+
# @param page [String] page The name of an existing wiki page.
|
72
|
+
# @param status [add, del] Whether to add or delete a user.
|
73
|
+
def toggle_wiki_editor(subreddit, user, page, status)
|
74
|
+
subreddit_name = extract_string(subreddit, :display_name)
|
75
|
+
username = extract_string(user, :username)
|
76
|
+
parameters = { :page => page, :username => username }
|
77
|
+
|
78
|
+
post("r/#{subreddit_name}/api/wiki/alloweditor/#{status}", parameters)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|