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