reddit_bot 1.2.2 → 1.3.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 +4 -4
- data/examples/boilerplate.rb +6 -6
- data/examples/councilofricks/Gemfile.lock +2 -2
- data/examples/mlgtv/Gemfile +1 -1
- data/examples/mlgtv/Gemfile.lock +0 -7
- data/examples/mlgtv/main.rb +6 -3
- data/examples/net_http_utils.rb +146 -0
- data/examples/yayornay/main.rb +1 -0
- data/lib/reddit_bot.rb +19 -19
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd7aa171b0722398964a733d385b956e488758fc
|
|
4
|
+
data.tar.gz: 94a8959747d7d93c27722be9f4bf279ea69fe75b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1b1f6ecf337874ef91c24f8ab25ec2a6037739c22faecb27ba0b35932e655b5ea13af3ee3f1b94fb29400a51693b20ea2e93e89d46cb2d9787bb49ec23358eb9
|
|
7
|
+
data.tar.gz: 68ae0ad1d581fdc6932ec56049f4afe73de1d183dfb807326c0909d2a3e0221f98fd91ef9f5a7ef7b60ed35b42a82b5717a4f7254776f7c45eadc2635472d2aa
|
data/examples/boilerplate.rb
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
STDOUT.sync = true
|
|
2
2
|
require "pp"
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if ENV["DEV"]
|
|
7
|
-
require_relative "../lib/reddit_bot"
|
|
4
|
+
if Gem.loaded_specs.include? "net_http_utils"
|
|
5
|
+
require "net_http_utils"
|
|
8
6
|
else
|
|
9
|
-
|
|
7
|
+
require_relative "net_http_utils"
|
|
10
8
|
end
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
require "reddit_bot"
|
|
11
|
+
|
|
12
|
+
require_relative "#{Dir.home}/beat" unless Gem::Platform.local.os == "darwin"
|
|
13
13
|
|
|
14
14
|
require "yaml"
|
data/examples/mlgtv/Gemfile
CHANGED
data/examples/mlgtv/Gemfile.lock
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
GIT
|
|
2
|
-
remote: https://gist.github.com/97549ceb58d21e1fcbc0e6cdaf92fce8.git
|
|
3
|
-
revision: 54c47ab3f9665f3e35a8e94fdd267e3743c736a9
|
|
4
|
-
specs:
|
|
5
|
-
net_http_utils (0)
|
|
6
|
-
|
|
7
1
|
GEM
|
|
8
2
|
remote: https://rubygems.org/
|
|
9
3
|
specs:
|
|
@@ -15,7 +9,6 @@ PLATFORMS
|
|
|
15
9
|
ruby
|
|
16
10
|
|
|
17
11
|
DEPENDENCIES
|
|
18
|
-
net_http_utils (= 0)!
|
|
19
12
|
reddit_bot (~> 1.2.0)
|
|
20
13
|
|
|
21
14
|
BUNDLED WITH
|
data/examples/mlgtv/main.rb
CHANGED
|
@@ -43,7 +43,10 @@ loop do
|
|
|
43
43
|
"Call of Duty 4: Modern Warfare",
|
|
44
44
|
].each do |game|
|
|
45
45
|
(begin
|
|
46
|
-
|
|
46
|
+
begin
|
|
47
|
+
t = NetHTTPUtils.get_response "https://api.twitch.tv/kraken/streams?game=#{CGI::escape game}&access_token=#{File.read("twitch.token").strip}&client_id=#{File.read("client.id").strip}&channel=Ricky,ACHES,Lacefield,Clayster,Enable,Zoomaa,Attach,TheFEARS,MiRx1,SaintsRF,StuDyy,SpaceLyTV,NAMELESS,Scump,FORMAL,Crimsix,Karma,Loony,Slacked,Octane,MJChino,Diabolic_TV,ImTheIvy,Senderxz,Jkap,John,SlasheRAL,Apathy,ColtHavok,MikeSwarley,ParasiteTV,TyreeLegal,Silly,Blfire,methodz,TwiZzyTV,Mochila,Remy,Xotic16,AquA,Faccento,Nagafen,Tylerfelo,TheoryCoD,ColeChanTV,happyy97,goonjar,Burns,Dedo,Neslo,TeeCM,K1lla93,NeLsoNNaTeR,ProoFy,Whea7s,MBoZe,Merk,Nadeshot,ReeP,Sharp,TeePee,Braaain2015,Nolsonn,QwiKeRTHaNu,Zedenyer1,Jurd,Tommey,Swanny,MadCatEU,Rated_EU1,BsportJoshh,Sy_Vortex,TheMarkyB,Peatie95,urbandm,TreiZer0,iDqvee,Tojor,MethodZ_TV,Gotaga,WailersWL,TCM_Moose,skrapzq,Reedy,fighta71,Swiftazor,BacabecNZ,Zeuss_Gaming,Hopeyy,GuydraCOD,mattmrx,Maven,CouRageJD,Revan,BriceyHD,Benson,PHILWHI7,MLG,mlgbravo,Multiplay_CoD,UMGEvents,GfinityTV,WorldGaming,FemaleProLeague,Arcitys,Prestinni,Maux,priestahh,Vilesyder,benbance"
|
|
48
|
+
end while t.code == 500
|
|
49
|
+
JSON.parse t.body
|
|
47
50
|
rescue JSON::ParserError
|
|
48
51
|
puts "JSON::ParserError"
|
|
49
52
|
sleep 60
|
|
@@ -72,12 +75,12 @@ loop do
|
|
|
72
75
|
settings["allow_top"] = settings["allow_top"]
|
|
73
76
|
settings.delete "default_set"
|
|
74
77
|
|
|
75
|
-
prefix, postfix = settings["description"].split(/(?<=\n#####)\s*Live Streams.+?(?=\n#+)/im)
|
|
78
|
+
prefix, postfix = CGI.unescapeHTML(settings["description"]).split(/(?<=\n#####)\s*Live Streams.+?(?=\n#+)/im)
|
|
76
79
|
unless postfix
|
|
77
80
|
puts "!!! can't parse sidebar !!!"
|
|
78
81
|
throw :loop
|
|
79
82
|
end
|
|
80
|
-
next puts "nothing to change" if prefix + text + postfix == settings["description"]
|
|
83
|
+
next puts "nothing to change" if prefix + text + postfix == CGI.unescapeHTML(settings["description"])
|
|
81
84
|
|
|
82
85
|
puts "updating sidebar..."
|
|
83
86
|
settings["description"] = prefix + text + postfix
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "openssl"
|
|
3
|
+
|
|
4
|
+
require "logger"
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
module NetHTTPUtils
|
|
8
|
+
class << self
|
|
9
|
+
|
|
10
|
+
attr_accessor :logger
|
|
11
|
+
|
|
12
|
+
# private?
|
|
13
|
+
def get_response url, mtd = :get, form: {}, header: [], auth: nil, timeout: 30, patch_request: nil, &block
|
|
14
|
+
# form = Hash[form.map{ |k, v| [k.to_s, v] }]
|
|
15
|
+
uri = URI.parse url
|
|
16
|
+
cookies = {}
|
|
17
|
+
prepare_request = lambda do |uri|
|
|
18
|
+
case mtd
|
|
19
|
+
when :get ; Net::HTTP::Get
|
|
20
|
+
when :post ; Net::HTTP::Post
|
|
21
|
+
when :put ; Net::HTTP::Put
|
|
22
|
+
when :delete ; Net::HTTP::Delete
|
|
23
|
+
else ; raise "unknown method #{mtd}"
|
|
24
|
+
end.new(uri).tap do |request| # somehow Get eats even raw url, not URI object
|
|
25
|
+
patch_request.call uri, form, request if patch_request
|
|
26
|
+
request.basic_auth *auth if auth
|
|
27
|
+
header.each{ |k, v| request[k] = v }
|
|
28
|
+
request["cookie"] = [*request["cookie"], cookies.map{ |k, v| "#{k}=#{v}" }].join "; " unless cookies.empty?
|
|
29
|
+
request.set_form_data form unless form.empty?
|
|
30
|
+
stack = caller.reverse.map do |level|
|
|
31
|
+
/((?:[^\/:]+\/)?[^\/:]+):([^:]+)/.match(level).captures
|
|
32
|
+
end.chunk(&:first).map do |file, group|
|
|
33
|
+
"#{file}:#{group.map(&:last).chunk{|_|_}.map(&:first).join(",")}"
|
|
34
|
+
end
|
|
35
|
+
logger.info request.path
|
|
36
|
+
logger.debug request.each_header.to_a.to_s
|
|
37
|
+
logger.debug stack.join " -> "
|
|
38
|
+
logger.debug request
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
request = prepare_request[uri]
|
|
42
|
+
start_http = lambda do |uri|
|
|
43
|
+
begin
|
|
44
|
+
Net::HTTP.start(
|
|
45
|
+
uri.host, uri.port,
|
|
46
|
+
use_ssl: uri.scheme == "https",
|
|
47
|
+
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
|
48
|
+
# read_timeout: 5,
|
|
49
|
+
).tap do |http|
|
|
50
|
+
http.read_timeout = timeout #if timeout
|
|
51
|
+
http.open_timeout = timeout #if timeout
|
|
52
|
+
http.set_debug_output STDERR if logger.level == Logger::DEBUG # use `logger.debug?`?
|
|
53
|
+
end
|
|
54
|
+
rescue Errno::ECONNREFUSED => e
|
|
55
|
+
e.message.concat " to #{uri}" # puts "#{e} to #{uri}"
|
|
56
|
+
raise e
|
|
57
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ECONNRESET, SocketError, OpenSSL::SSL::SSLError => e
|
|
58
|
+
logger.warn "retrying in 5 seconds because of #{e.class}"
|
|
59
|
+
sleep 5
|
|
60
|
+
retry
|
|
61
|
+
rescue Errno::ETIMEDOUT
|
|
62
|
+
logger.warn "ETIMEDOUT, retrying in 5 minutes"
|
|
63
|
+
sleep 300
|
|
64
|
+
retry
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
http = start_http[uri]
|
|
68
|
+
do_request = lambda do |request|
|
|
69
|
+
response = begin
|
|
70
|
+
http.request request, &block
|
|
71
|
+
rescue Errno::ECONNRESET, Errno::ECONNREFUSED, Net::ReadTimeout, Net::OpenTimeout, Zlib::BufError, OpenSSL::SSL::SSLError => e
|
|
72
|
+
logger.error "retrying in 30 seconds because of #{e.class} at: #{request.uri}"
|
|
73
|
+
sleep 30
|
|
74
|
+
retry
|
|
75
|
+
end
|
|
76
|
+
response.to_hash.fetch("set-cookie", []).each{ |c| k, v = c.split(?=); cookies[k] = v[/[^;]+/] }
|
|
77
|
+
case response.code
|
|
78
|
+
when /\A3\d\d$/
|
|
79
|
+
logger.info "redirect: #{response["location"]}"
|
|
80
|
+
new_uri = URI.join(request.uri, response["location"])
|
|
81
|
+
new_host = new_uri.host
|
|
82
|
+
if http.address != new_host ||
|
|
83
|
+
http.port != new_uri.port ||
|
|
84
|
+
http.use_ssl? != (new_uri.scheme == "https")
|
|
85
|
+
logger.debug "changing host from '#{http.address}' to '#{new_host}'"
|
|
86
|
+
http = start_http[new_uri]
|
|
87
|
+
end
|
|
88
|
+
do_request.call prepare_request[new_uri]
|
|
89
|
+
when "404"
|
|
90
|
+
logger.error "404 at #{request.method} #{request.uri} with body: #{
|
|
91
|
+
response.body.is_a?(Net::ReadAdapter) ? "impossible to reread Net::ReadAdapter -- check the IO you've used in block form" : response.body.tap do |body|
|
|
92
|
+
body.replace body.strip.gsub(/<[^>]*>/, "") if body["<html>"]
|
|
93
|
+
end.inspect
|
|
94
|
+
}"
|
|
95
|
+
response
|
|
96
|
+
when /\A50\d$/
|
|
97
|
+
logger.error "#{response.code} at #{request.method} #{request.uri} with body: #{response.body.inspect}"
|
|
98
|
+
response
|
|
99
|
+
else
|
|
100
|
+
logger.info "code #{response.code} at #{request.method} #{request.uri}#{
|
|
101
|
+
" and so #{url}" if request.uri.to_s != url
|
|
102
|
+
} from #{
|
|
103
|
+
[__FILE__, caller.map{ |i| i[/\d+/] }].join ?:
|
|
104
|
+
} with body: #{
|
|
105
|
+
response.body.tap do |body|
|
|
106
|
+
body.replace body.strip.gsub(/<[^>]*>/, "") if body["<html>"]
|
|
107
|
+
end.inspect
|
|
108
|
+
}" unless response.code.start_with? "20"
|
|
109
|
+
response
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
do_request[request].tap do |response|
|
|
113
|
+
cookies.each{ |k, v| response.add_field "Set-Cookie", "#{k}=#{v};" }
|
|
114
|
+
logger.debug response.to_hash
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def request_data *args
|
|
119
|
+
response = get_response *args
|
|
120
|
+
throw :"404" if "404" == response.code
|
|
121
|
+
throw :"500" if "500" == response.code
|
|
122
|
+
response.body
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
end
|
|
126
|
+
self.logger = Logger.new STDOUT
|
|
127
|
+
self.logger.level = ENV["LOGLEVEL_#{name}"] ? Logger.const_get(ENV["LOGLEVEL_#{name}"]) : Logger::WARN
|
|
128
|
+
self.logger.formatter = lambda do |severity, datetime, progname, msg|
|
|
129
|
+
"#{severity.to_s[0]} #{datetime.strftime "%y%m%d %H%M%S"} : #{name} : #{msg}\n"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
if $0 == __FILE__
|
|
135
|
+
print "self testing... "
|
|
136
|
+
|
|
137
|
+
fail unless NetHTTPUtils.request_data("http://httpstat.us/200") == "200 OK"
|
|
138
|
+
fail unless NetHTTPUtils.get_response("http://httpstat.us/404").body == "404 Not Found"
|
|
139
|
+
catch(:"404"){ fail NetHTTPUtils.request_data "http://httpstat.us/404" }
|
|
140
|
+
# TODO raise?
|
|
141
|
+
fail unless NetHTTPUtils.request_data("http://httpstat.us/400") == "400 Bad Request"
|
|
142
|
+
fail unless NetHTTPUtils.get_response("http://httpstat.us/500").body == "500 Internal Server Error"
|
|
143
|
+
catch(:"500"){ fail NetHTTPUtils.request_data "http://httpstat.us/500" }
|
|
144
|
+
|
|
145
|
+
puts "OK #{__FILE__}"
|
|
146
|
+
end
|
data/examples/yayornay/main.rb
CHANGED
|
@@ -12,6 +12,7 @@ loop do
|
|
|
12
12
|
nay = []
|
|
13
13
|
comments.each do |comment|
|
|
14
14
|
yay |= [comment["author"]] if comment["body"][/\A\s*yay/i]
|
|
15
|
+
yay |= [comment["author"]] if comment["body"][/\A\s*yea/i]
|
|
15
16
|
nay |= [comment["author"]] if comment["body"][/\A\s*nay/i]
|
|
16
17
|
end
|
|
17
18
|
p [post["id"], yay, nay] if Gem::Platform.local.os == "darwin"
|
data/lib/reddit_bot.rb
CHANGED
|
@@ -8,7 +8,7 @@ require "json"
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
module RedditBot
|
|
11
|
-
VERSION = "1.
|
|
11
|
+
VERSION = "1.3.0" # :nodoc:
|
|
12
12
|
|
|
13
13
|
class Bot
|
|
14
14
|
|
|
@@ -16,12 +16,12 @@ module RedditBot
|
|
|
16
16
|
attr_reader :name
|
|
17
17
|
|
|
18
18
|
# [secrets] +Hash+ with keys :client_id, :client_secret, :password: and :login
|
|
19
|
-
# [kwargs] keyword params may include :
|
|
19
|
+
# [kwargs] keyword params may include :subreddit for clever methods
|
|
20
20
|
def initialize secrets, **kwargs
|
|
21
21
|
@secrets = secrets.values_at *%i{ client_id client_secret password login }
|
|
22
22
|
@name = secrets[:login]
|
|
23
|
-
@ignore_captcha = true
|
|
24
|
-
@ignore_captcha = kwargs[:ignore_captcha] if kwargs.has_key?(:ignore_captcha)
|
|
23
|
+
# @ignore_captcha = true
|
|
24
|
+
# @ignore_captcha = kwargs[:ignore_captcha] if kwargs.has_key?(:ignore_captcha)
|
|
25
25
|
@subreddit = kwargs[:subreddit]
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -38,11 +38,11 @@ module RedditBot
|
|
|
38
38
|
puts "error: #{[error, description]}"
|
|
39
39
|
case error
|
|
40
40
|
when "ALREADY_SUB" ; puts "was rejected by moderator if you didn't see in dups"
|
|
41
|
-
when "BAD_CAPTCHA" ; update_captcha
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
# when "BAD_CAPTCHA" ; update_captcha
|
|
42
|
+
# json mtd, path, form.merger( {
|
|
43
|
+
# iden: @iden_and_captcha[0],
|
|
44
|
+
# captcha: @iden_and_captcha[1],
|
|
45
|
+
# } ) unless @ignore_captcha
|
|
46
46
|
else ; fail error
|
|
47
47
|
end
|
|
48
48
|
end
|
|
@@ -174,19 +174,19 @@ module RedditBot
|
|
|
174
174
|
fail response.inspect
|
|
175
175
|
end
|
|
176
176
|
puts "new token is: #{@token_cached}"
|
|
177
|
-
update_captcha if "true" == resp_with_token(:get, "/api/needs_captcha", {})
|
|
177
|
+
# update_captcha if "true" == resp_with_token(:get, "/api/needs_captcha", {})
|
|
178
178
|
@token_cached
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
-
def update_captcha
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
end
|
|
181
|
+
# def update_captcha
|
|
182
|
+
# return if @ignore_captcha
|
|
183
|
+
# pp iden_json = json(:post, "/api/new_captcha")
|
|
184
|
+
# iden = iden_json["json"]["data"]["iden"]
|
|
185
|
+
# # return @iden_and_captcha = [iden, "\n"] if @ignore_captcha
|
|
186
|
+
# # pp resp_with_token(:get, "/captcha/#{iden_json["json"]["data"]["iden"]}", {})
|
|
187
|
+
# puts "CAPTCHA: https://reddit.com/captcha/#{iden}"
|
|
188
|
+
# @iden_and_captcha = [iden, gets.strip]
|
|
189
|
+
# end
|
|
190
190
|
|
|
191
191
|
def resp_with_token mtd, path, form
|
|
192
192
|
nil until _ = catch(:"401") do
|
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.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Victor Maslov
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-06-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -55,6 +55,7 @@ files:
|
|
|
55
55
|
- examples/mlgtv/Gemfile
|
|
56
56
|
- examples/mlgtv/Gemfile.lock
|
|
57
57
|
- examples/mlgtv/main.rb
|
|
58
|
+
- examples/net_http_utils.rb
|
|
58
59
|
- examples/oneplus/Gemfile
|
|
59
60
|
- examples/oneplus/Gemfile.lock
|
|
60
61
|
- examples/oneplus/main.rb
|
|
@@ -94,4 +95,3 @@ signing_key:
|
|
|
94
95
|
specification_version: 4
|
|
95
96
|
summary: Library for Reddit bots
|
|
96
97
|
test_files: []
|
|
97
|
-
has_rdoc:
|