reddit_bot 1.3.1 → 1.4.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/Gemfile +2 -0
- data/examples/realtimeww2/Gemfile +1 -1
- data/examples/realtimeww2/Gemfile.lock +5 -5
- data/examples/realtimeww2/main.rb +49 -18
- data/lib/reddit_bot.rb +6 -38
- data/lib/reddit_bot/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 68928fa5ea284f33c94d19a8fc4ee0593c3e0ae3
|
|
4
|
+
data.tar.gz: 67c8d3e031f36c88d2c16e5c2101d0480e30700c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f73e132f29c57c0cd11cb6c37b6aa75427467c090c630018bd1a14c98608b38291619bda73d48df0e480764ad93ed3ad2346c672bcc53afbfd0e5e39d63d442
|
|
7
|
+
data.tar.gz: 5af0b844cf35e5356079121f15496af2e3639855be4a166cd857fb98f82d63a81bcaf3e01a5dfe5dc465e3cd0e074edf327a9da91cf78efe0590bf85b3a935e8
|
data/Gemfile
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
GIT
|
|
2
2
|
remote: git@github.com:Nakilon/nethttputils.git
|
|
3
|
-
revision:
|
|
4
|
-
tag: v0.0.1.
|
|
3
|
+
revision: 10ae857b46a5db16e0193ca6e53cebbe2c499811
|
|
4
|
+
tag: v0.0.1.4
|
|
5
5
|
specs:
|
|
6
|
-
nethttputils (0.0.1.
|
|
6
|
+
nethttputils (0.0.1.4)
|
|
7
7
|
|
|
8
8
|
GEM
|
|
9
9
|
remote: https://rubygems.org/
|
|
10
10
|
specs:
|
|
11
11
|
json (2.1.0)
|
|
12
|
-
reddit_bot (1.3.
|
|
12
|
+
reddit_bot (1.3.1)
|
|
13
13
|
json
|
|
14
14
|
|
|
15
15
|
PLATFORMS
|
|
@@ -20,4 +20,4 @@ DEPENDENCIES
|
|
|
20
20
|
reddit_bot
|
|
21
21
|
|
|
22
22
|
BUNDLED WITH
|
|
23
|
-
1.
|
|
23
|
+
1.15.4
|
|
@@ -9,37 +9,66 @@ TWITTER_ACCESS_TOKEN = JSON.load(
|
|
|
9
9
|
|
|
10
10
|
SUBREDDIT = "RealTimeWW2"
|
|
11
11
|
BOT = RedditBot::Bot.new YAML.load(File.read "secrets.yaml"), subreddit: SUBREDDIT
|
|
12
|
-
|
|
13
12
|
TWITTER = "RealTimeWWII"
|
|
14
|
-
|
|
13
|
+
|
|
14
|
+
tweet2titleNtext = lambda do |tweet|
|
|
15
|
+
pp tweet if Gem::Platform.local.os == "darwin"
|
|
15
16
|
text = ""
|
|
16
17
|
contains_media = false
|
|
17
18
|
up = ->s{ s.split.map{ |w| "^#{w}" }.join " " }
|
|
18
|
-
if tweet["
|
|
19
|
+
if tweet["extended_entities"] && tweet["extended_entities"]["media"]
|
|
19
20
|
contains_media = true
|
|
20
|
-
tweet["
|
|
21
|
+
tweet["extended_entities"]["media"].each_with_index do |media, i|
|
|
21
22
|
text.concat "* [Image #{i + 1}](#{media["media_url_https"]})\n\n"
|
|
22
23
|
end
|
|
23
24
|
end
|
|
25
|
+
if tweet["entities"]["urls"]
|
|
26
|
+
contains_media = true
|
|
27
|
+
tweet["entities"]["urls"].each_with_index do |url, i|
|
|
28
|
+
text.concat "* [Link #{i + 1}](#{url["expanded_url"]})\n\n"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
24
31
|
text.concat "^- #{
|
|
25
32
|
up[tweet["user"]["name"]]
|
|
26
33
|
} [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [#{
|
|
27
34
|
up[Date.parse(tweet["created_at"]).strftime "%B %-d, %Y"]
|
|
28
35
|
}](https://twitter.com/#{TWITTER}/status/#{tweet["id"]})"
|
|
29
|
-
|
|
36
|
+
require "cgi"
|
|
37
|
+
[CGI::unescapeHTML(tweet["full_text"]).sub(/( https:\/\/t\.co\/[0-9a-zA-Z]{10})*\z/, ""), text, contains_media]
|
|
30
38
|
end
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"https://
|
|
34
|
-
|
|
35
|
-
) ).
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
[
|
|
40
|
+
[905764294687633408, "The Polish government & military high command is now evacuating Warsaw for Brest, 120 miles east: German armies are too close to the capital", "* [Image 1](https://pbs.twimg.com/media/DJHq71BXYAA6KJ0.jpg)\n\n" "^- ^WW2 ^Tweets ^from ^1939 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^September ^7, ^2017](https://twitter.com/#{TWITTER}/status/905764294687633408)"],
|
|
41
|
+
[915534673471733760, "In east Poland (now Soviet Ukraine) industry & farms to be collectivised, political parties banned, aristocrats & capitalists \"re-educated\".", "* [Image 1](https://pbs.twimg.com/media/DLSh2J9W4AACcOG.jpg)\n\n* [Image 2](https://pbs.twimg.com/media/DLSh4sKX0AEBaXq.jpg)\n\n^- ^WW2 ^Tweets ^from ^1939 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| ""[^October ^4, ^2017](https://twitter.com/#{TWITTER}/status/915534673471733760)"],
|
|
42
|
+
[915208866408824832, "For 1st time, RAF planes dropping propaganda leaflets on Berlin itself, entitled \"Germans: these are your leaders!\"", "* [Image 1](https://pbs.twimg.com/media/DLN5jJ-XkAEUz9M.jpg)\n\n* [Link 1](https://www.psywar.org/product_1939EH158.php)\n\n" "^- ^WW2 ^Tweets ^from ^1939 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| ""[^October ^3, ^2017](https://twitter.com/#{TWITTER}/status/915208866408824832)"],
|
|
43
|
+
[914577848891006978, "\"In Poland, Russia pursued a cold policy of selfinterest. But clearly necessary for Russia… against Nazi menace.\"", "* [Link 1](https://www.youtube.com/watch?v=ygmP5A3n2JA)\n\n" "^- ^WW2 ^Tweets ^from ^1939 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| ""[^October ^1, ^2017](https://twitter.com/#{TWITTER}/status/914577848891006978)"],
|
|
44
|
+
].each do |id, title_, text_|
|
|
45
|
+
title, text, contains_media = tweet2titleNtext[ JSON.load NetHTTPUtils.request_data(
|
|
46
|
+
"https://api.twitter.com/1.1/statuses/show.json?id=#{id}&tweet_mode=extended",
|
|
47
|
+
header: { Authorization: "Bearer #{TWITTER_ACCESS_TOKEN}" }
|
|
48
|
+
) ]
|
|
49
|
+
unless title_ == title
|
|
50
|
+
puts "expected:\n#{title_.inspect}"
|
|
51
|
+
puts "got:\n#{title.inspect}"
|
|
52
|
+
abort "TITLE FORMATTING ERROR"
|
|
53
|
+
end
|
|
54
|
+
unless text_ == text
|
|
55
|
+
puts "expected:\n#{text_.inspect}"
|
|
56
|
+
puts "got:\n#{text.inspect}"
|
|
57
|
+
abort "TEXT FORMATTING ERROR"
|
|
58
|
+
end
|
|
59
|
+
if ENV["TEST_POST"]
|
|
60
|
+
pp BOT.json :post, "/api/submit", {
|
|
61
|
+
sr: "RealTimeWW2_TEST",
|
|
62
|
+
kind: "self",
|
|
63
|
+
title: title,
|
|
64
|
+
text: text,
|
|
65
|
+
}.tap{ |h| h.merge!({ flair_id: BOT.json(:get, "/r/RealTimeWW2_TEST/api/link_flair").find{ |flair|
|
|
66
|
+
flair["text"] == "Contains Media"
|
|
67
|
+
}["id"] }) if contains_media }
|
|
68
|
+
end
|
|
39
69
|
end
|
|
40
70
|
abort "OK" if ENV["TEST"]
|
|
41
71
|
|
|
42
|
-
require "cgi"
|
|
43
72
|
loop do
|
|
44
73
|
id = BOT.new_posts.find do |post|
|
|
45
74
|
/\(https:\/\/twitter\.com\/#{TWITTER}\/status\/(\d{18,})\)/i =~ post["selftext"] and break $1
|
|
@@ -63,16 +92,18 @@ loop do
|
|
|
63
92
|
end ).reverse_each do |tweet|
|
|
64
93
|
next if tweet["id"] <= id
|
|
65
94
|
# next unless tweet["id"] == 905724018996772865 # two media files
|
|
66
|
-
|
|
67
|
-
text, contains_media = tweet2text[tweet]
|
|
95
|
+
title, text, contains_media = tweet2titleNtext[tweet]
|
|
68
96
|
result = BOT.json :post, "/api/submit", {
|
|
69
97
|
sr: SUBREDDIT,
|
|
70
98
|
kind: "self",
|
|
71
|
-
title:
|
|
99
|
+
title: title,
|
|
72
100
|
text: text,
|
|
73
101
|
}.tap{ |h| h.merge!({ flair_id: flair["id"] }) if contains_media }
|
|
74
102
|
pp result
|
|
75
|
-
|
|
103
|
+
if result["json"]["errors"].empty?
|
|
104
|
+
abort if ENV["ONCE"]
|
|
105
|
+
next
|
|
106
|
+
end
|
|
76
107
|
fail unless result["json"]["errors"].map(&:first) == ["ALREADY_SUB"]
|
|
77
108
|
puts "ALREADY_SUB error for #{tweet["id"]}"
|
|
78
109
|
end
|
data/lib/reddit_bot.rb
CHANGED
|
@@ -5,6 +5,8 @@ require "net/http"
|
|
|
5
5
|
require "openssl"
|
|
6
6
|
require "json"
|
|
7
7
|
|
|
8
|
+
require "nethttputils"
|
|
9
|
+
|
|
8
10
|
require_relative "reddit_bot/version"
|
|
9
11
|
module RedditBot
|
|
10
12
|
class Bot
|
|
@@ -96,7 +98,7 @@ module RedditBot
|
|
|
96
98
|
end
|
|
97
99
|
|
|
98
100
|
# :yields: JSON objects: ["data"] part of post or self.post
|
|
99
|
-
def new_posts caching = false
|
|
101
|
+
def new_posts subreddit = nil, caching = false
|
|
100
102
|
cache = lambda do |id, &block|
|
|
101
103
|
next block.call unless caching
|
|
102
104
|
require "fileutils"
|
|
@@ -110,7 +112,7 @@ module RedditBot
|
|
|
110
112
|
Enumerator.new do |e|
|
|
111
113
|
after = {}
|
|
112
114
|
loop do
|
|
113
|
-
args = [:get, "
|
|
115
|
+
args = [:get, "/#{subreddit || @subreddit || fail}/new", {limit: 100}.merge(after)]
|
|
114
116
|
result = cache.call(args){ json *args }
|
|
115
117
|
fail if result.keys != %w{ kind data }
|
|
116
118
|
fail if result["kind"] != "Listing"
|
|
@@ -186,6 +188,7 @@ module RedditBot
|
|
|
186
188
|
# end
|
|
187
189
|
|
|
188
190
|
def resp_with_token mtd, path, form
|
|
191
|
+
fail unless path.start_with? ?/
|
|
189
192
|
nil until _ = catch(:"401") do
|
|
190
193
|
reddit_resp mtd, "https://oauth.reddit.com" + path, form, {
|
|
191
194
|
"Authorization" => "bearer #{token}",
|
|
@@ -233,35 +236,7 @@ module RedditBot
|
|
|
233
236
|
end
|
|
234
237
|
|
|
235
238
|
def _resp mtd, url, form, headers, base_auth = nil
|
|
236
|
-
|
|
237
|
-
request = if mtd == :get
|
|
238
|
-
uri.query = URI.encode_www_form form # wtf OpenSSL::SSL::SSLError
|
|
239
|
-
Net::HTTP::Get.new(uri)
|
|
240
|
-
else
|
|
241
|
-
Net::HTTP::Post.new(uri).tap{ |r| r.set_form_data form }
|
|
242
|
-
end
|
|
243
|
-
request.basic_auth *base_auth if base_auth
|
|
244
|
-
headers.each{ |k, v| request[k] = v }
|
|
245
|
-
# puts request.path
|
|
246
|
-
# pp request.to_hash
|
|
247
|
-
# puts request.body
|
|
248
|
-
http = begin
|
|
249
|
-
Net::HTTP.start uri.host,
|
|
250
|
-
use_ssl: uri.scheme == "https",
|
|
251
|
-
verify_mode: OpenSSL::SSL::VERIFY_NONE,
|
|
252
|
-
open_timeout: 300
|
|
253
|
-
rescue OpenSSL::SSL::SSLError, SocketError, Errno::ECONNRESET, Net::OpenTimeout, Errno::ETIMEDOUT, Errno::EPIPE => e
|
|
254
|
-
puts "ERROR: #{e.class}: #{e}"
|
|
255
|
-
sleep 5
|
|
256
|
-
retry
|
|
257
|
-
end
|
|
258
|
-
response = begin
|
|
259
|
-
http.request request
|
|
260
|
-
rescue OpenSSL::SSL::SSLError, SocketError, Net::ReadTimeout, Errno::EPIPE, EOFError, Zlib::BufError, Errno::ECONNRESET => e
|
|
261
|
-
puts "ERROR: #{e}"
|
|
262
|
-
sleep 5
|
|
263
|
-
retry
|
|
264
|
-
end
|
|
239
|
+
response = NetHTTPUtils.get_response url, mtd, form: form, header: headers, auth: base_auth
|
|
265
240
|
puts %w{
|
|
266
241
|
x-ratelimit-remaining
|
|
267
242
|
x-ratelimit-used
|
|
@@ -275,13 +250,6 @@ module RedditBot
|
|
|
275
250
|
fail response.to_hash["x-ratelimit-remaining"][0] \
|
|
276
251
|
if response.to_hash["x-ratelimit-remaining"] &&
|
|
277
252
|
response.to_hash["x-ratelimit-remaining"][0].size < 5
|
|
278
|
-
|
|
279
|
-
# if response.code == "401"
|
|
280
|
-
# puts request.path
|
|
281
|
-
# puts request.body
|
|
282
|
-
# pp request.to_hash
|
|
283
|
-
# end
|
|
284
|
-
|
|
285
253
|
response
|
|
286
254
|
end
|
|
287
255
|
|
data/lib/reddit_bot/version.rb
CHANGED
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.4.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-10-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|