reddit_bot 1.7.2 → 1.7.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 72f9dc552d1471c35792e1633fd4fd2e466a2ee9
4
- data.tar.gz: feb6cfce26ffc0fbbe6bff80ea3e776398143f69
3
+ metadata.gz: 678fcb0251bf04be23802b62ddea29f5ea338386
4
+ data.tar.gz: b65667dea035f15f24a40f2c26017374b959780d
5
5
  SHA512:
6
- metadata.gz: 5127199b9b40bb025a31deb32ed724f56e1d3ea9932980b33374751702214f0a399db95d9a2609ac4b5feaa1fd76c82a027414f6efe87a15b6d8c0e9becfb673
7
- data.tar.gz: 7d2a70330ddcb412a0a3288d55ef020cb99f0ad565f39a47133c18bfd4b12efc39a7870b2f3be65de64fe646d9178755bfe1ab3683aacfa151873d2a43a9036b
6
+ metadata.gz: 384b4e42c38453c2a3ceb90892e144824f078f81dcc91e2c2ba65c39e22ed5e95d4b7ebc8bcba080d7113a10c654295768c8c6fcf32f7089495cd4395fafd80c
7
+ data.tar.gz: 24b3318a50e0ad0b784a8b8b1689ab3eef7dbebc1461760bc42a8fa920d6a223e2414910d2dfc38e5b50f394a1c032632d2aca87c12ba50141c1f07d941188dd
@@ -0,0 +1,5 @@
1
+ /examples/*/twitter.token
2
+ temp
3
+ *secret*
4
+ .byebug_history
5
+ /pkg
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
2
 
4
- RSpec::Core::RakeTask.new(:spec)
3
+ # require "rspec/core/rake_task"
4
+ # RSpec::Core::RakeTask.new(:spec)
5
5
 
6
6
  task :default => :spec
@@ -10,7 +10,7 @@ loop do
10
10
  next logger.info "bad destination: #{msg["data"]["dest"]}" unless msg["data"]["dest"] == "CPTFlairBot3"
11
11
  case msg["data"]["subject"]
12
12
  when "casualpokemontrades"
13
- unless /^(?<name>\S+( \S+)*) ?\n(?<id>\d\d\d\d-\d\d\d\d-\d\d\d\d)\n(?<css_class>\S+)$/ =~ msg["data"]["body"]
13
+ unless /^(?<name>\S+( \S+)*) ?\n(?<id>\d\d\d\d-\d\d\d\d-\d\d\d\d)\n(?<css_class>[a-z2-]+)$/ =~ msg["data"]["body"]
14
14
  logger.info "invalid message for #{msg["data"]["subject"]}: %p" % msg["data"]["body"] unless Google::Cloud.env.compute_engine?
15
15
  # puts "marking invalid message as read: %p" % msg["data"]["body"]
16
16
  # BOT.json :post, "/api/read_message", {id: msg["data"]["name"]} unless Gem::Platform.local.os == "darwin"
@@ -34,7 +34,7 @@ loop do
34
34
  JSON.parse( begin
35
35
  NetHTTPUtils.request_data "https://www.reddit.com/r/#{subreddit}/comments.json", header: ["User-Agent", "ajsdjasdasd"]
36
36
  rescue NetHTTPUtils::Error => e
37
- raise unless [503, 504, 500].include? e.code
37
+ raise unless [500, 502, 503, 504].include? e.code
38
38
  sleep 60
39
39
  retry
40
40
  end )["data"]["children"].each do |comment|
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ ruby ">=2.2"
3
+
4
+ gem "reddit_bot"
@@ -0,0 +1,24 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.7.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
+ json (2.3.1)
7
+ nethttputils (0.4.0.0)
8
+ addressable
9
+ public_suffix (4.0.5)
10
+ reddit_bot (1.7.6)
11
+ json
12
+ nethttputils (~> 0.4.0.0)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ reddit_bot
19
+
20
+ RUBY VERSION
21
+ ruby 2.3.8p459
22
+
23
+ BUNDLED WITH
24
+ 2.0.2
@@ -0,0 +1,41 @@
1
+ require "reddit_bot"
2
+ subreddit = "dut".freeze
3
+ bot = RedditBot::Bot.new YAML.load(File.read "secrets.yaml"), subreddit: subreddit
4
+ RedditBot::Twitter.init_twitter "DUT_Tweets"
5
+
6
+ loop do
7
+ bot.json(:get, "/message/unread")["data"]["children"].each do |msg|
8
+ next unless %w{ nakilon technomod }.include? msg["data"]["author"]
9
+ abort "ordered to die" if %w{ die die } == msg["data"].values_at("subject", "body")
10
+ end
11
+
12
+ id = bot.new_posts.flat_map do |post|
13
+ post["selftext"].scan(/\(https:\/\/twitter\.com\/#{RedditBot::Twitter::TWITTER_ACCOUNT}\/status\/(\d{18,})\)/i).flatten.map(&:to_i).max
14
+ end.find(&:itself)
15
+ abort "no tweets found in subreddit" if id.zero? unless ENV["FIRST_RUN"]
16
+ abort "flair isn't available" unless flair = bot.json(:get, "/r/#{subreddit}/api/link_flair").find{ |flair| flair["text"] == "Twitter" }
17
+
18
+ timeline = RedditBot::Twitter.user_timeline
19
+ timeline.replace timeline.take 2 if ENV["FIRST_RUN"] # against 200 posts long flood
20
+ timeline.reverse_each do |tweet|
21
+ next if tweet["id"] <= id
22
+ title, text, _ = RedditBot::Twitter.tweet2titleNtext tweet
23
+ result = bot.json :post, "/api/submit", {
24
+ sr: subreddit,
25
+ kind: "self",
26
+ title: title,
27
+ text: text,
28
+ flair_id: flair["id"],
29
+ }
30
+ p result
31
+ if result["json"]["errors"].empty?
32
+ abort "OK" if ENV["ONCE"]
33
+ next
34
+ end
35
+ fail unless result["json"]["errors"].map(&:first) == ["ALREADY_SUB"]
36
+ puts "ALREADY_SUB error for #{tweet["id"]}"
37
+ end
38
+
39
+ puts "END LOOP #{Time.now}"
40
+ sleep 300
41
+ end
@@ -7,5 +7,5 @@ gem "nokogiri"
7
7
  gem "nethttputils", git: "git@github.com:nakilon/nethttputils.git"
8
8
  gem "directlink", git: "git@github.com:nakilon/directlink.git"
9
9
 
10
- gem "gcplogger", git: "git@github.com:nakilon/gcplogger.git", tag: "v0.1.1.0"
10
+ gem "gcplogger", git: "git@github.com:nakilon/gcplogger.git"
11
11
  gem "google-cloud-error_reporting"
@@ -1,15 +1,3 @@
1
- GIT
2
- remote: git@github.com:nakilon/directlink.git
3
- revision: a1645d3abca0182e6de80f1a7b37b6ad0513b672
4
- specs:
5
- directlink (0.0.6.0)
6
- addressable
7
- fastimage (~> 2.1.3)
8
- kramdown
9
- nethttputils (~> 0.3.2.3)
10
- nokogiri
11
- reddit_bot (~> 1.7.0)
12
-
13
1
  GIT
14
2
  remote: git@github.com:nakilon/gcplogger.git
15
3
  revision: 7c1451fac49bd0d242c6de43315ae6e9a70d8f7f
@@ -19,20 +7,21 @@ GIT
19
7
  google-cloud-logging (~> 1.4.0)
20
8
  public_suffix (~> 2.0)
21
9
 
22
- GIT
23
- remote: git@github.com:nakilon/nethttputils.git
24
- revision: 6450111a35803b474c2331d8e12da6546101c887
25
- specs:
26
- nethttputils (0.3.2.6)
27
-
28
10
  GEM
29
11
  remote: https://rubygems.org/
30
12
  specs:
31
- addressable (2.6.0)
32
- public_suffix (>= 2.0.2, < 4.0)
13
+ addressable (2.7.0)
14
+ public_suffix (>= 2.0.2, < 5.0)
15
+ directlink (0.0.9.0)
16
+ addressable
17
+ fastimage (~> 2.1.3)
18
+ kramdown
19
+ nethttputils (~> 0.4.0.0)
20
+ nokogiri
21
+ reddit_bot (~> 1.7.0)
33
22
  faraday (0.14.0)
34
23
  multipart-post (>= 1.2, < 3)
35
- fastimage (2.1.5)
24
+ fastimage (2.1.7)
36
25
  google-cloud-core (1.2.0)
37
26
  google-cloud-env (~> 1.0)
38
27
  google-cloud-env (1.0.1)
@@ -72,7 +61,8 @@ GEM
72
61
  googleauth (>= 0.5.1, < 0.7)
73
62
  json (2.2.0)
74
63
  jwt (2.1.0)
75
- kramdown (2.1.0)
64
+ kramdown (2.3.0)
65
+ rexml
76
66
  little-plugger (1.1.4)
77
67
  logging (2.2.2)
78
68
  little-plugger (~> 1.1)
@@ -81,13 +71,16 @@ GEM
81
71
  mini_portile2 (2.4.0)
82
72
  multi_json (1.13.1)
83
73
  multipart-post (2.0.0)
84
- nokogiri (1.10.2)
74
+ nethttputils (0.4.0.0)
75
+ addressable
76
+ nokogiri (1.10.8)
85
77
  mini_portile2 (~> 2.4.0)
86
78
  os (0.9.6)
87
79
  public_suffix (2.0.5)
88
- reddit_bot (1.7.1)
80
+ reddit_bot (1.7.6)
89
81
  json
90
- nethttputils (~> 0.3.2.0)
82
+ nethttputils (~> 0.4.0.0)
83
+ rexml (3.2.4)
91
84
  rly (0.2.3)
92
85
  signet (0.8.1)
93
86
  addressable (~> 2.3)
@@ -101,12 +94,12 @@ PLATFORMS
101
94
  ruby
102
95
 
103
96
  DEPENDENCIES
104
- directlink!
97
+ directlink (~> 0.0.9.0)
105
98
  gcplogger!
106
99
  google-cloud-error_reporting
107
100
  json
108
- nethttputils!
101
+ nethttputils
109
102
  nokogiri
110
103
 
111
104
  BUNDLED WITH
112
- 1.17.1
105
+ 2.0.2
@@ -16,21 +16,21 @@ require "directlink"
16
16
  require "nokogiri"
17
17
 
18
18
  require "../boilerplate"
19
- BOT = RedditBot::Bot.new YAML.load_file "secrets.yaml"
19
+ bot = RedditBot::Bot.new YAML.load_file "secrets.yaml"
20
20
 
21
21
  INCLUDE = %w{
22
22
  user/kjoneslol/m/sfwpornnetwork
23
23
 
24
24
  r/woahdude
25
+ r/pic
25
26
 
26
27
  r/highres
27
28
  r/wallpapers
28
29
  r/wallpaper
29
30
  r/WQHD_Wallpaper
30
31
 
31
- r/pic
32
-
33
32
  r/oldmaps
33
+ r/telephotolandscapes
34
34
  }
35
35
  EXCLUDE = %w{ foodporn powerwashingporn }
36
36
 
@@ -40,7 +40,7 @@ search_url = lambda do |url|
40
40
  JSON.load( begin
41
41
  NetHTTPUtils.request_data "https://www.reddit.com/r/largeimages/search.json", form: {q: "url:#{url}", restrict_sr: "on"}, header: ["User-Agent", "ajsdjasdasd"]
42
42
  rescue NetHTTPUtils::Error => e
43
- raise unless [503].include? e.code
43
+ raise unless [500, 503].include? e.code
44
44
  sleep 60
45
45
  retry
46
46
  end )["data"]["children"]
@@ -74,7 +74,7 @@ loop do
74
74
  ]
75
75
  end ) ],
76
76
  [:source_reddit, 30000000, ( INCLUDE.flat_map do |sortasub|
77
- BOT.new_posts(sortasub).take(100).map do |child|
77
+ bot.new_posts(sortasub).take(100).map do |child|
78
78
  next if child["is_self"]
79
79
  next if EXCLUDE.include? child["subreddit"].downcase
80
80
  child.values_at(
@@ -85,37 +85,43 @@ loop do
85
85
  ].each do |source, min_resolution, entries|
86
86
  logger.warn "#{source}.size: #{entries.size}"
87
87
  entries.each do |id, url, title, subreddit, author, permalink|
88
+ author.downcase!
88
89
  next if checked.include? id
89
90
  checked << id
90
91
  # next if Gem::Platform.local.os == "darwin" # prevent concurrent posting
91
92
  logger.debug "image url for #{id}: #{url}"
92
- next logger.warn "skipped a post by /u/sjhill" if author == "sjhill" # opt-out
93
- next logger.warn "skipped a post by /u/redisforever" if author == "redisforever" # opt-out
94
- next logger.warn "skipped a post by /u/bekalaki" if author == "bekalaki" # 9 ways to divide a karmawhore
93
+ next logger.warn "skipped a post by /u/sjhill" if author == "sjhill" # opt-out
94
+ next logger.warn "skipped a post by /u/redisforever" if author == "redisforever" # opt-out
95
+ next logger.warn "skipped a post by /u/bekalaki" if author == "bekalaki" # 9 ways to divide a karmawhore
96
+ next logger.warn "skipped a post by /u/cherryblackeyes" if author == "cherryblackeyes" # he's not nice
97
+ next logger.warn "skipped a post by /u/abel_a_kay" if author == "abel_a_kay" # posting very similar images of the same thing for the history
98
+ next logger.warn "skipped gifv" if ( begin
99
+ URI url
100
+ rescue URI::InvalidURIError
101
+ require "addressable"
102
+ URI Addressable::URI.escape url
103
+ end ).host.split(?.) == %w{ v redd it }
95
104
 
96
105
  t = begin
97
106
  DirectLink url, 60
98
- rescue SocketError,
99
- Net::OpenTimeout,
100
- Errno::ECONNRESET,
101
- NetHTTPUtils::Error,
102
- FastImage::UnknownImageType,
103
- FastImage::ImageFetchFailure,
104
- DirectLink::ErrorNotFound,
105
- DirectLink::ErrorBadLink => e
107
+ rescue *DirectLink::NORMAL_EXCEPTIONS => e
106
108
  next logger.error "skipped (#{e}) #{url} from http://redd.it/#{id}"
107
109
  end
108
- logger.info "DirectLink: #{t.inspect}"
110
+ logger.debug "DirectLink: #{t.inspect}"
109
111
  tt = t.is_a?(Array) ? t : [t]
110
112
  next logger.error "probably crosspost of a self post: http://redd.it/#{id}" if tt.empty?
111
- unless min_resolution <= tt.first.width * tt.first.height
112
- next logger.debug "skipped low resolution #{source}"
113
- end
113
+ next logger.info "skipped low resolution #{source}" unless min_resolution <= tt.first.width * tt.first.height
114
114
  # puts "https://www.reddit.com/r/LargeImages/search.json?q=url%3A#{CGI.escape url}&restrict_sr=on"
115
115
  resolution = "[#{tt.first.width}x#{tt.first.height}]"
116
- next logger.warn "already submitted #{resolution} #{id}: '#{url}'" unless
117
- Gem::Platform.local.os == "darwin" || search_url[url].empty?
118
- logger.warn "resolution #{resolution} got from #{id}: #{url}"
116
+ next logger.warn "already submitted #{resolution} #{id}: '#{url}'" unless Gem::Platform.local.os == "darwin" || search_url[url].empty?
117
+
118
+ system "curl -s '#{tt.first.url}' -o temp --retry 5" or fail
119
+ next logger.warn "skipped <2mb id=#{id}" if 2000000 > File.size("temp")
120
+ if "mapporn" == subreddit.downcase
121
+ `vips pngsave temp temp.png`
122
+ next logger.warn "skipped /r/mapporn <10mb PNG id=#{id}" if 10000000 > File.size("temp.png")
123
+ end
124
+
119
125
  title = "#{resolution}#{
120
126
  " [#{tt.size} images]" if tt.size > 1
121
127
  } #{
@@ -124,7 +130,7 @@ loop do
124
130
  } /r/#{subreddit}".gsub(/\s+\(\s+\)\s+/, " ").sub(/(?<=.{297}).+/, "...")
125
131
  logger.warn "new post #{source}: #{url} #{title.inspect}"
126
132
  unless Gem::Platform.local.os == "darwin"
127
- result = BOT.json :post,
133
+ result = bot.json :post,
128
134
  "/api/submit",
129
135
  {
130
136
  kind: "link",
@@ -151,7 +157,7 @@ loop do
151
157
  text = [line1, line2, line3].compact.join(" \n")
152
158
  logger.info "new comment: #{text.inspect}"
153
159
  unless Gem::Platform.local.os == "darwin"
154
- result = BOT.leave_a_comment "#{result["json"]["data"]["name"]}", text.sub(/(?<=.{9000}).+/m, "...")
160
+ result = bot.leave_a_comment "#{result["json"]["data"]["name"]}", text.sub(/(?<=.{9000}).+/m, "...")
155
161
  unless result["json"]["errors"].empty?
156
162
  logger.error result.inspect
157
163
  fail "failed to leave comment"
@@ -37,11 +37,11 @@ tweet2titleNtext = lambda do |tweet|
37
37
  [CGI::unescapeHTML(tweet["full_text"]).sub(/( https:\/\/t\.co\/[0-9a-zA-Z]{10})*\z/, ""), text, contains_media]
38
38
  end
39
39
  [
40
- [905764294687633408, true, "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 ^1941 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^""September ^7, ^2017](https://twitter.com/#{TWITTER}/status/905764294687633408)"],
41
- [915534673471733760, true, "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 ^1941 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "October ^4, ^2017](https://twitter.com/#{TWITTER}/status/915534673471733760)"],
42
- [915208866408824832, true, "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 ^1941 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "October ^3, ^2017](https://twitter.com/#{TWITTER}/status/915208866408824832)"],
43
- [914577848891006978, true, "\"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 ^1941 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "October ^1, ^2017](https://twitter.com/#{TWITTER}/status/914577848891006978)"],
44
- [926581977372942336, false, "Finland rejects Soviet demand to surrender land near Leningrad & give Red Navy base in Hanko; Soviets now claim Finns' manner \"warlike\".", "^- ^WW2 ^Tweets ^from ^1941 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "November ^3, ^2017](https://twitter.com/#{TWITTER}/status/926581977372942336)"],
40
+ [905764294687633408, true, "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 ^1942 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^""September ^7, ^2017](https://twitter.com/#{TWITTER}/status/905764294687633408)"],
41
+ [915534673471733760, true, "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 ^1942 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "October ^4, ^2017](https://twitter.com/#{TWITTER}/status/915534673471733760)"],
42
+ [915208866408824832, true, "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 ^1942 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "October ^3, ^2017](https://twitter.com/#{TWITTER}/status/915208866408824832)"],
43
+ [914577848891006978, true, "\"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 ^1942 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "October ^1, ^2017](https://twitter.com/#{TWITTER}/status/914577848891006978)"],
44
+ [926581977372942336, false, "Finland rejects Soviet demand to surrender land near Leningrad & give Red Navy base in Hanko; Soviets now claim Finns' manner \"warlike\".", "^- ^WW2 ^Tweets ^from ^1942 [^\\(@#{TWITTER}\\)](https://twitter.com/#{TWITTER}) ^| [^" "November ^3, ^2017](https://twitter.com/#{TWITTER}/status/926581977372942336)"],
45
45
  ].each do |id, contains_media_, title_, text_|
46
46
  title, text, contains_media = tweet2titleNtext[ JSON.load NetHTTPUtils.request_data(
47
47
  "https://api.twitter.com/1.1/statuses/show.json",
@@ -101,7 +101,7 @@ loop do
101
101
  sleep t
102
102
  end
103
103
  rescue NetHTTPUtils::Error => e
104
- fail if e.code != 503
104
+ fail unless [500, 503].include? e.code
105
105
  sleep timeout
106
106
  timeout *= 2
107
107
  retry
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+ ruby ">=2.2"
3
+
4
+ gem "reddit_bot"#, git: "git@github.com:nakilon/reddit_bot.git"
@@ -0,0 +1,24 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.7.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
+ json (2.3.1)
7
+ nethttputils (0.4.0.0)
8
+ addressable
9
+ public_suffix (4.0.5)
10
+ reddit_bot (1.7.6)
11
+ json
12
+ nethttputils (~> 0.4.0.0)
13
+
14
+ PLATFORMS
15
+ ruby
16
+
17
+ DEPENDENCIES
18
+ reddit_bot
19
+
20
+ RUBY VERSION
21
+ ruby 2.3.8p459
22
+
23
+ BUNDLED WITH
24
+ 2.0.2
@@ -0,0 +1,41 @@
1
+ require "reddit_bot"
2
+ subreddit = "unisa".freeze
3
+ bot = RedditBot::Bot.new YAML.load(File.read "secrets.yaml"), subreddit: subreddit
4
+ RedditBot::Twitter.init_twitter "unisa"
5
+
6
+ loop do
7
+ bot.json(:get, "/message/unread")["data"]["children"].each do |msg|
8
+ next unless %w{ nakilon technomod }.include? msg["data"]["author"]
9
+ abort "ordered to die" if %w{ die die } == msg["data"].values_at("subject", "body")
10
+ end
11
+
12
+ id = bot.new_posts.flat_map do |post|
13
+ post["selftext"].scan(/\(https:\/\/twitter\.com\/#{RedditBot::Twitter::TWITTER_ACCOUNT}\/status\/(\d{18,})\)/i).flatten.map(&:to_i).max
14
+ end.find(&:itself)
15
+ abort "no tweets found in subreddit" if id.zero? unless ENV["FIRST_RUN"]
16
+ abort "flair isn't available" unless flair = bot.json(:get, "/r/#{subreddit}/api/link_flair").find{ |flair| flair["text"] == "Twitter" }
17
+
18
+ timeline = RedditBot::Twitter.user_timeline
19
+ timeline.replace timeline.take 2 if ENV["FIRST_RUN"] # against 200 posts long flood
20
+ timeline.reverse_each do |tweet|
21
+ next if tweet["id"] <= id
22
+ title, text, _ = RedditBot::Twitter.tweet2titleNtext tweet
23
+ result = bot.json :post, "/api/submit", {
24
+ sr: subreddit,
25
+ kind: "self",
26
+ title: title,
27
+ text: text,
28
+ flair_id: flair["id"],
29
+ }
30
+ p result
31
+ if result["json"]["errors"].empty?
32
+ abort "OK" if ENV["ONCE"]
33
+ next
34
+ end
35
+ fail unless result["json"]["errors"].map(&:first) == ["ALREADY_SUB"]
36
+ puts "ALREADY_SUB error for #{tweet["id"]}"
37
+ end
38
+
39
+ puts "END LOOP #{Time.now}"
40
+ sleep 300
41
+ end
@@ -1,5 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "nokogiri", "~>1.6.7" # Ruby 2.0
3
+ gem "nokogiri", "~>1.10.4"
4
4
  gem "public_suffix", "<3.0" # Ruby 2.0
5
5
  gem "directlink"
@@ -1,33 +1,34 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- addressable (2.5.2)
5
- public_suffix (>= 2.0.2, < 4.0)
6
- directlink (0.0.4.7)
4
+ addressable (2.7.0)
5
+ public_suffix (>= 2.0.2, < 5.0)
6
+ directlink (0.0.8.7)
7
7
  addressable
8
8
  fastimage (~> 2.1.3)
9
9
  kramdown
10
+ nethttputils (~> 0.3.3.0)
10
11
  nokogiri
11
- reddit_bot (~> 1.6.13)
12
- fastimage (2.1.5)
13
- json (2.1.0)
14
- kramdown (1.17.0)
15
- mini_portile2 (2.1.0)
16
- nethttputils (0.2.5.1)
17
- nokogiri (1.6.8.1)
18
- mini_portile2 (~> 2.1.0)
12
+ reddit_bot (~> 1.7.0)
13
+ fastimage (2.1.7)
14
+ json (2.3.0)
15
+ kramdown (2.1.0)
16
+ mini_portile2 (2.4.0)
17
+ nethttputils (0.3.3.0)
18
+ nokogiri (1.10.4)
19
+ mini_portile2 (~> 2.4.0)
19
20
  public_suffix (2.0.5)
20
- reddit_bot (1.6.13)
21
+ reddit_bot (1.7.3)
21
22
  json
22
- nethttputils (~> 0.2.5.1)
23
+ nethttputils (~> 0.3.3.0)
23
24
 
24
25
  PLATFORMS
25
26
  ruby
26
27
 
27
28
  DEPENDENCIES
28
29
  directlink
29
- nokogiri (~> 1.6.7)
30
+ nokogiri (~> 1.10.4)
30
31
  public_suffix (< 3.0)
31
32
 
32
33
  BUNDLED WITH
33
- 1.17.1
34
+ 2.0.2
@@ -3,11 +3,10 @@ STDOUT.sync = true
3
3
 
4
4
  require "openssl"
5
5
  require "json"
6
+ require "yaml"
6
7
 
7
8
  require "nethttputils"
8
9
 
9
- require_relative "reddit_bot/version" # TODO: deprecate this
10
-
11
10
  module RedditBot
12
11
  require "logger"
13
12
  class << self
@@ -204,7 +203,7 @@ module RedditBot
204
203
  username: @name,
205
204
  password: @secret_password,
206
205
  }, {
207
- "User-Agent" => "bot/#{@user_agent || @name}/#{RedditBot::VERSION} by /u/nakilon",
206
+ "User-Agent" => "bot/#{@user_agent || @name}/#{Gem::Specification::load("#{__dir__}/../reddit_bot.gemspec").version} by /u/nakilon",
208
207
  }, @secret_auth
209
208
  unless @token_cached = response["access_token"]
210
209
  fail "bot #{@name} isn't a 'developer' of app at https://www.reddit.com/prefs/apps/" if response == {"error"=>"invalid_grant"}
@@ -231,13 +230,13 @@ module RedditBot
231
230
  begin
232
231
  reddit_resp mtd, "https://oauth.reddit.com" + path, form, {
233
232
  "Authorization" => "bearer #{token}",
234
- "User-Agent" => "bot/#{@user_agent || @name}/#{RedditBot::VERSION} by /u/nakilon",
233
+ "User-Agent" => "bot/#{@user_agent || @name}/#{Gem::Specification::load("#{__dir__}/../reddit_bot.gemspec").version} by /u/nakilon",
235
234
  }
236
235
  rescue NetHTTPUtils::Error => e
236
+ raise unless e.code == 401
237
237
  sleep timeout
238
238
  Module.nesting[1].logger.info "sleeping #{timeout} seconds because of #{e.code}"
239
239
  timeout *= 2
240
- raise unless e.code == 401
241
240
  @token_cached = nil
242
241
  retry
243
242
  end
@@ -247,21 +246,7 @@ module RedditBot
247
246
  mtd, url, form, headers, basic_auth = *args
248
247
  headers["Cookie:"] = "over18=1"
249
248
  begin
250
- NetHTTPUtils.request_data(url, mtd, form: form, header: headers, auth: basic_auth) do |response|
251
- next unless remaining = response.to_hash["x-ratelimit-remaining"]
252
- if Gem::Platform.local.os == "darwin"
253
- Module.nesting[1].logger.debug %w{
254
- x-ratelimit-remaining
255
- x-ratelimit-used
256
- x-ratelimit-reset
257
- }.map{ |key| "#{key}=#{response.to_hash[key]}" }.join ", "
258
- end
259
- fail remaining[0] if remaining[0].size < 4
260
- next if remaining[0].size > 4
261
- t = (response.to_hash["x-ratelimit-reset"][0].to_f + 1) / [remaining[0].to_f - 10, 1].max + 1
262
- Module.nesting[1].logger.info "sleeping #{t} seconds because of x-ratelimit"
263
- sleep t
264
- end
249
+ NetHTTPUtils.request_data url, mtd, form: form, header: headers, auth: basic_auth
265
250
  rescue NetHTTPUtils::Error => e
266
251
  sleep 5
267
252
  raise unless e.code.to_s.start_with? "50"
@@ -271,4 +256,59 @@ module RedditBot
271
256
  end
272
257
 
273
258
  end
259
+
260
+ module Twitter
261
+ require "json"
262
+
263
+ def self.init_twitter twitter
264
+ const_set :TWITTER_ACCOUNT, twitter
265
+ const_set :TWITTER_ACCESS_TOKEN, JSON.load(
266
+ NetHTTPUtils.request_data "https://api.twitter.com/oauth2/token", :post,
267
+ auth: File.read("twitter.token").split,
268
+ form: {grant_type: :client_credentials}
269
+ )["access_token"]
270
+ end
271
+
272
+ require "cgi"
273
+ def self.tweet2titleNtext tweet
274
+ text = ""
275
+ contains_media = false
276
+ up = ->s{ s.split.map{ |w| "^#{w}" }.join " " }
277
+ if tweet["extended_entities"] && !tweet["extended_entities"]["media"].empty?
278
+ contains_media = true
279
+ tweet["extended_entities"]["media"].each_with_index do |media, i|
280
+ text.concat "* [Image #{i + 1}](#{media["media_url_https"]})\n\n"
281
+ end
282
+ end
283
+ if !tweet["entities"]["urls"].empty?
284
+ contains_media = true
285
+ tweet["entities"]["urls"].each_with_index do |url, i|
286
+ text.concat "* [Link #{i + 1}](#{url["expanded_url"]})\n\n"
287
+ end
288
+ end
289
+ text.concat "^- #{
290
+ up[tweet["user"]["name"]]
291
+ } [^\\(@#{TWITTER_ACCOUNT}\\)](https://twitter.com/#{TWITTER_ACCOUNT}) ^| [#{
292
+ up[Date.parse(tweet["created_at"]).strftime "%B %-d, %Y"]
293
+ }](https://twitter.com/#{TWITTER_ACCOUNT}/status/#{tweet["id"]})"
294
+ [CGI::unescapeHTML(tweet["full_text"]).sub(/( https:\/\/t\.co\/[0-9a-zA-Z]{10})*\z/, ""), text, contains_media]
295
+ end
296
+
297
+ def self.user_timeline
298
+ timeout = 1
299
+ JSON.load begin
300
+ NetHTTPUtils.request_data(
301
+ "https://api.twitter.com/1.1/statuses/user_timeline.json",
302
+ form: { screen_name: TWITTER_ACCOUNT, count: 200, tweet_mode: "extended" },
303
+ header: { Authorization: "Bearer #{TWITTER_ACCESS_TOKEN}" }
304
+ )
305
+ rescue NetHTTPUtils::Error => e
306
+ fail unless [500, 503].include? e.code
307
+ sleep timeout
308
+ timeout *= 2
309
+ retry
310
+ end
311
+ end
312
+ end
313
+
274
314
  end
@@ -1,8 +1,6 @@
1
- require_relative "lib/reddit_bot/version"
2
-
3
1
  Gem::Specification.new do |spec|
4
2
  spec.name = "reddit_bot"
5
- spec.version = RedditBot::VERSION
3
+ spec.version = "1.7.7"
6
4
  spec.authors = ["Victor Maslov"]
7
5
  spec.email = ["nakilon@gmail.com"]
8
6
 
@@ -15,7 +13,7 @@ Gem::Specification.new do |spec|
15
13
  # spec.require_paths = ["lib"]
16
14
 
17
15
  spec.add_runtime_dependency "json"
18
- spec.add_runtime_dependency "nethttputils", "~>0.3.2.0"
16
+ spec.add_runtime_dependency "nethttputils", "~>0.4.1.0"
19
17
  # spec.add_development_dependency "bundler", "~> 1.11"
20
18
  # spec.add_development_dependency "rake", "~> 10.0"
21
19
  # spec.add_development_dependency "rspec", "~> 3.0"
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.7.2
4
+ version: 1.7.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Maslov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-02 00:00:00.000000000 Z
11
+ date: 2020-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.2.0
33
+ version: 0.4.1.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.2.0
40
+ version: 0.4.1.0
41
41
  description: better than PRAW
42
42
  email:
43
43
  - nakilon@gmail.com
@@ -45,6 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".gitignore"
48
49
  - Gemfile
49
50
  - LICENSE.txt
50
51
  - README.md
@@ -72,6 +73,9 @@ files:
72
73
  - examples/devflairbot/Gemfile
73
74
  - examples/devflairbot/Gemfile.lock
74
75
  - examples/devflairbot/main.rb
76
+ - examples/dut/Gemfile
77
+ - examples/dut/Gemfile.lock
78
+ - examples/dut/main.rb
75
79
  - examples/get_dimensions.rb
76
80
  - examples/iostroubleshooting/Gemfile
77
81
  - examples/iostroubleshooting/Gemfile.lock
@@ -101,6 +105,9 @@ files:
101
105
  - examples/sexypizza/Gemfile
102
106
  - examples/sexypizza/Gemfile.lock
103
107
  - examples/sexypizza/main.rb
108
+ - examples/unisa/Gemfile
109
+ - examples/unisa/Gemfile.lock
110
+ - examples/unisa/main.rb
104
111
  - examples/wallpaper/Gemfile
105
112
  - examples/wallpaper/Gemfile.lock
106
113
  - examples/wallpaper/main.rb
@@ -108,7 +115,6 @@ files:
108
115
  - examples/yayornay/Gemfile.lock
109
116
  - examples/yayornay/main.rb
110
117
  - lib/reddit_bot.rb
111
- - lib/reddit_bot/version.rb
112
118
  - reddit_bot.gemspec
113
119
  homepage: https://github.com/Nakilon/reddit_bot
114
120
  licenses:
@@ -130,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
136
  version: '0'
131
137
  requirements: []
132
138
  rubyforge_project:
133
- rubygems_version: 2.5.2
139
+ rubygems_version: 2.5.2.3
134
140
  signing_key:
135
141
  specification_version: 4
136
142
  summary: Library for Reddit bots
@@ -1,3 +0,0 @@
1
- module RedditBot
2
- VERSION = "1.7.2" # :nodoc:
3
- end