reddit_bot 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|