reddit_bot 1.7.2 → 1.7.7

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