reddit_bot 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -14
- data/examples/yayornay/Gemfile.lock +19 -0
- data/lib/reddit_bot.rb +65 -33
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d2ed897b55ef286ce14857b2d4cfd82c69ed861
|
4
|
+
data.tar.gz: 40c30c1b24122c3f964ec2e6d447a08eeeb1a9cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 667e9d3cb500e53e4c3f5eac0374ee6e71e116a02292df4517d90ba6904f642e67785f0e990df0cd3c724dd4cfb972cf8a23c7ac35a8027878c8e7e6d149570c
|
7
|
+
data.tar.gz: 8dde680bd8addba2765e8a849660465cc8460c21867ca1b48ad451b00ce51b60310097266bce7d6d155b6b15ed4d7b48a3e9924c36301b0bd152f2ffe30ae9a3
|
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# RedditBot
|
2
2
|
|
3
|
-
[![Join the chat at https://gitter.im/Nakilon/reddit_bot](https://badges.gitter.im/Nakilon/reddit_bot.svg)](https://gitter.im/Nakilon/reddit_bot
|
4
|
-
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/reddit_bot.svg)](http://badge.fury.io/rb/mll)
|
3
|
+
[![Join the chat at https://gitter.im/Nakilon/reddit_bot](https://badges.gitter.im/Nakilon/reddit_bot.svg)](https://gitter.im/Nakilon/reddit_bot)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/reddit_bot.svg)](http://badge.fury.io/rb/reddit_bot)
|
6
5
|
|
7
6
|
#### What
|
8
7
|
|
@@ -26,17 +25,17 @@ The [examples folder](examples) includes:
|
|
26
25
|
It calculates quality of x-posts from different subreddits based on mods activity (remove/approve).
|
27
26
|
For example, this shows that it would be ok to ignore /r/pics from now:
|
28
27
|
|
29
|
-
pics Total: 98 Quality: 19%
|
30
|
-
wallpapers Total: 69 Quality: 52%
|
31
|
-
wallpaper Total: 45 Quality: 51%
|
32
|
-
woahdude Total: 30 Quality: 66%
|
33
|
-
CityPorn Total: 17 Quality: 82%
|
34
|
-
FoodPorn Total: 13 Quality: 7%
|
35
|
-
MapPorn Total: 13 Quality: 46%
|
36
|
-
SkyPorn Total: 11 Quality: 45%
|
37
|
-
carporn Total: 11 Quality: 45%
|
38
|
-
InfrastructurePorn Total: 9 Quality: 77%
|
39
|
-
|
28
|
+
pics Total: 98 Quality: 19%
|
29
|
+
wallpapers Total: 69 Quality: 52%
|
30
|
+
wallpaper Total: 45 Quality: 51%
|
31
|
+
woahdude Total: 30 Quality: 66%
|
32
|
+
CityPorn Total: 17 Quality: 82%
|
33
|
+
FoodPorn Total: 13 Quality: 7%
|
34
|
+
MapPorn Total: 13 Quality: 46%
|
35
|
+
SkyPorn Total: 11 Quality: 45%
|
36
|
+
carporn Total: 11 Quality: 45%
|
37
|
+
InfrastructurePorn Total: 9 Quality: 77%
|
38
|
+
|
40
39
|
You obviously can't run these examples as is, because they have some dependencies that are not in this repo. Like `secrets.yaml` file for authorization of the following format:
|
41
40
|
|
42
41
|
:client_id: Kb9.......6wBw
|
data/lib/reddit_bot.rb
CHANGED
@@ -8,35 +8,38 @@ require "json"
|
|
8
8
|
|
9
9
|
|
10
10
|
module RedditBot
|
11
|
-
VERSION = "1.1.
|
11
|
+
VERSION = "1.1.3" # :nodoc:
|
12
12
|
|
13
13
|
class Bot
|
14
14
|
|
15
|
+
# bot's Reddit username; set via constructor parameter secrets[:login]
|
16
|
+
attr_reader :name
|
17
|
+
|
18
|
+
# [secrets] +Hash+ with keys :client_id, :client_secret, :password: and :login
|
19
|
+
# [kwargs] keyword params may include :ignore_captcha that is true by default and :subreddit for clever methods
|
15
20
|
def initialize secrets, **kwargs
|
16
21
|
@secrets = secrets.values_at *%i{ client_id client_secret password login }
|
22
|
+
@name = secrets[:login]
|
17
23
|
@ignore_captcha = true
|
18
24
|
@ignore_captcha = kwargs[:ignore_captcha] if kwargs.has_key?(:ignore_captcha)
|
19
25
|
@subreddit = kwargs[:subreddit]
|
20
26
|
end
|
21
27
|
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
|
26
|
-
# attr_accessor :secrets
|
27
|
-
|
28
|
-
def json mtd, url, _form = []
|
28
|
+
# [mtd] +Symbol+ :get or :post
|
29
|
+
# [path] +String+ an API method
|
30
|
+
# [_form] +Array+ or +Hash+ API method params
|
31
|
+
def json mtd, path, _form = []
|
29
32
|
form = Hash[_form]
|
30
|
-
response = JSON.parse resp_with_token mtd,
|
33
|
+
response = JSON.parse resp_with_token mtd, path, form.merge({api_type: "json"})
|
31
34
|
if response.is_a?(Hash) && response["json"] # for example, flairlist.json and {"error": 403} do not have it
|
32
|
-
puts "ERROR OCCURED on #{[mtd,
|
35
|
+
puts "ERROR OCCURED on #{[mtd, path]}" unless response["json"]["errors"].empty?
|
33
36
|
# pp response["json"]
|
34
37
|
response["json"]["errors"].each do |error, description|
|
35
38
|
puts "error: #{[error, description]}"
|
36
39
|
case error
|
37
40
|
when "ALREADY_SUB" ; puts "was rejected by moderator if you didn't see in dups"
|
38
41
|
when "BAD_CAPTCHA" ; update_captcha
|
39
|
-
json mtd,
|
42
|
+
json mtd, path, form.merger( {
|
40
43
|
iden: @iden_and_captcha[0],
|
41
44
|
captcha: @iden_and_captcha[1],
|
42
45
|
} ) unless @ignore_captcha
|
@@ -47,7 +50,11 @@ module RedditBot
|
|
47
50
|
response
|
48
51
|
end
|
49
52
|
|
53
|
+
# [subreddit] +String+ subreddit name without "/r" prefix
|
54
|
+
# [page] +String+ page name without "/wiki/" prefix
|
55
|
+
# [text] :nodoc:
|
50
56
|
def wiki_edit subreddit, page, text
|
57
|
+
puts "editing wiki page '/r/#{subreddit}/wiki/#{page}'"
|
51
58
|
json :post,
|
52
59
|
"/r/#{subreddit}/api/wiki/edit",
|
53
60
|
page: page,
|
@@ -55,28 +62,48 @@ module RedditBot
|
|
55
62
|
# ["previous", result["data"]["children"].last["id"]],
|
56
63
|
end
|
57
64
|
|
65
|
+
# [reason] :nodoc:
|
66
|
+
# [thing_id] +String+ fullname of a "link, commenr or message"
|
58
67
|
def report reason, thing_id
|
68
|
+
puts "reporting '#{thing_id}'"
|
59
69
|
json :post, "/api/report",
|
60
70
|
reason: "other",
|
61
71
|
other_reason: reason,
|
62
72
|
thing_id: thing_id
|
63
73
|
end
|
64
74
|
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
75
|
+
# [post] JSON object of a post of self.post
|
76
|
+
# [link_flair_css_class] :nodoc:
|
77
|
+
# [link_flair_text] :nodoc:
|
78
|
+
def set_post_flair post, link_flair_css_class, link_flair_text
|
79
|
+
puts "setting flair '#{link_flair_css_class}' with text '#{link_flair_text}' to post '#{post["name"]}'"
|
80
|
+
json :post, "/api/selectflair",
|
81
|
+
link: post["name"],
|
82
|
+
text: link_flair_text,
|
83
|
+
flair_template_id: (@flairselector_choices ||=
|
84
|
+
json :post, "/r/#{@subreddit}/api/flairselector", link: post["name"]
|
85
|
+
)["choices"].find{ |i| i["flair_css_class"] == link_flair_css_class }.tap{ |flair|
|
86
|
+
fail "can't find '#{link_flair_css_class}' flair class at https://www.reddit.com/r/#{@subreddit}/about/flair/#link_templates" unless flair
|
87
|
+
}["flair_template_id"]
|
88
|
+
end
|
72
89
|
|
90
|
+
# [thing_id] +String+ fullname of a post (or self.post?), comment (and private message?)
|
91
|
+
# [text] :nodoc:
|
92
|
+
def leave_a_comment thing_id, text
|
93
|
+
puts "leaving a comment on '#{thing_id}'"
|
94
|
+
json(:post, "/api/comment",
|
95
|
+
thing_id: thing_id,
|
96
|
+
text: text,
|
97
|
+
).tap do |result|
|
98
|
+
fail result["json"]["errors"].to_s unless result["json"]["errors"].empty?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# :yields: JSON objects: ["data"] part of post or self.post, top level comment (["children"] element)
|
73
103
|
def each_new_post_with_top_level_comments
|
74
104
|
json(:get, "/r/#{@subreddit}/new")["data"]["children"].each do |post|
|
75
105
|
fail "unknown type post['kind']: #{post["kind"]}" unless post["kind"] == "t3"
|
76
|
-
t =
|
77
|
-
# sort: "top",
|
78
|
-
depth: 1,
|
79
|
-
limit: 100500
|
106
|
+
t = json :get, "/comments/#{post["data"]["id"]}", depth: 1, limit: 100500#, sort: "top"
|
80
107
|
fail "smth weird about /comments/<id> response" unless t.size == 2
|
81
108
|
yield post["data"], t[1]["data"]["children"].map{ |child|
|
82
109
|
fail "unknown type child['kind']: #{child["kind"]}" unless child["kind"] == "t1"
|
@@ -85,15 +112,20 @@ module RedditBot
|
|
85
112
|
end
|
86
113
|
end
|
87
114
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
115
|
+
# [article] +String+ ID36 of a post or self.post
|
116
|
+
def each_comment_of_the_post_thread article
|
117
|
+
Enumerator.new do |e|
|
118
|
+
f = lambda do |smth|
|
119
|
+
smth["data"]["children"].each do |child|
|
120
|
+
f[child["data"]["replies"]] if child["data"]["replies"].is_a? Hash
|
121
|
+
fail "unknown type child['kind']: #{child["kind"]}" unless child["kind"] == "t1"
|
122
|
+
e << [child["data"]["name"], child["data"]]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
f[ json(:get, "/comments/#{article}", depth: 100500, limit: 100500).tap do |t|
|
126
|
+
fail "smth weird about /comments/<id> response" unless t.size == 2
|
127
|
+
end[1] ]
|
128
|
+
end
|
97
129
|
end
|
98
130
|
|
99
131
|
private
|
@@ -125,9 +157,9 @@ module RedditBot
|
|
125
157
|
@iden_and_captcha = [iden, gets.strip]
|
126
158
|
end
|
127
159
|
|
128
|
-
def resp_with_token mtd,
|
160
|
+
def resp_with_token mtd, path, form
|
129
161
|
nil until _ = catch(:"401") do
|
130
|
-
reddit_resp mtd, "https://oauth.reddit.com" +
|
162
|
+
reddit_resp mtd, "https://oauth.reddit.com" + path, form, [
|
131
163
|
["Authorization", "bearer #{token}"],
|
132
164
|
["User-Agent", "bot/#{@username}/0.0.0 by /u/nakilon"],
|
133
165
|
], nil # base auth
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reddit_bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Maslov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- examples/pokemon_trading/Gemfile.lock
|
53
53
|
- examples/pokemon_trading/main.rb
|
54
54
|
- examples/yayornay/Gemfile
|
55
|
+
- examples/yayornay/Gemfile.lock
|
55
56
|
- examples/yayornay/main.rb
|
56
57
|
- lib/reddit_bot.rb
|
57
58
|
- reddit_bot.gemspec
|