directlink 0.0.8.8 → 0.0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/directlink +5 -10
- data/directlink.gemspec +13 -11
- data/lib/directlink.rb +111 -63
- data/unit.test.rb +1548 -0
- metadata +19 -28
- data/.bashrc +0 -5
- data/.travis.yml +0 -37
- data/Gemfile +0 -3
- data/README.md +0 -198
- data/Rakefile +0 -1
- data/api_tokens_for_travis.sh +0 -8
- data/gplus.txt +0 -1454
- data/reddit_token_for_travis.yaml +0 -4
- data/test.rb +0 -827
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30657b1850442ca6f1267344dc356cdd3e0e55e8
|
4
|
+
data.tar.gz: b8dc86a2fb80cadb1583207934840fc28fdb6177
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d11e9b0f07127be8b711495f1496e527bd979c015a0376512e916c5f92fda19fcfd617d67584c768c1c223ebd41cb57c28bbf258b39659cdd12d5db4653f4120
|
7
|
+
data.tar.gz: 8d6beddd649ec2f1316009abe70c9224de3a34d8234443a040d492066b792b79d9f3fe3771b9906949982f1f5d12ff00a4dbebd9468bda2db63941e74e34f663
|
data/bin/directlink
CHANGED
@@ -68,18 +68,13 @@ begin
|
|
68
68
|
(t.is_a?(Array) ? t : [t]).each{ |s| puts "=> #{s.url}\n #{s.type} #{s.width}x#{s.height}" }
|
69
69
|
end
|
70
70
|
end
|
71
|
-
rescue
|
72
|
-
Net::OpenTimeout,
|
73
|
-
Errno::ECONNRESET,
|
74
|
-
NetHTTPUtils::Error,
|
75
|
-
FastImage::UnknownImageType,
|
76
|
-
FastImage::ImageFetchFailure,
|
77
|
-
# DirectLink::ErrorMissingEnvVar,
|
78
|
-
# DirectLink::ErrorAssert,
|
79
|
-
DirectLink::ErrorNotFound,
|
80
|
-
DirectLink::ErrorBadLink => e
|
71
|
+
rescue *DirectLink::NORMAL_EXCEPTIONS => e
|
81
72
|
puts e.backtrace if debug
|
82
73
|
cause = e.cause if e.cause if e.respond_to? :cause
|
83
74
|
c = e.class.to_s
|
84
75
|
abort "#{c}#{": #{e}" if c != e.to_s}#{": #{cause}" if cause && c != cause.to_s}"
|
76
|
+
rescue
|
77
|
+
raise unless $!.cause
|
78
|
+
raise $!.cause unless $!.cause.cause
|
79
|
+
raise $!.cause.cause
|
85
80
|
end
|
data/directlink.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = "directlink"
|
3
|
-
spec.version = "0.0.
|
4
|
-
spec.summary = "
|
3
|
+
spec.version = "0.0.11.0"
|
4
|
+
spec.summary = "obtains from any kind of hyperlink a link to an image, its format and resolution"
|
5
5
|
|
6
6
|
spec.author = "Victor Maslov aka Nakilon"
|
7
7
|
spec.email = "nakilon@gmail.com"
|
@@ -9,21 +9,23 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.homepage = "https://github.com/nakilon/directlink"
|
10
10
|
spec.metadata = {"source_code_uri" => "https://github.com/nakilon/directlink"}
|
11
11
|
|
12
|
-
spec.
|
13
|
-
|
14
|
-
spec.add_dependency "
|
15
|
-
spec.add_dependency "
|
12
|
+
spec.required_ruby_version = ">=2.3" # because <<~ heredocs in tests
|
13
|
+
|
14
|
+
spec.add_dependency "fastimage", "~>2.2.0"
|
15
|
+
spec.add_dependency "nokogiri", "<1.11" # 1.11 requires ruby 2.5
|
16
|
+
spec.add_dependency "nethttputils", "~>0.4.1.0"
|
17
|
+
spec.add_dependency "reddit_bot", "~>1.9.0"
|
16
18
|
spec.add_dependency "kramdown"
|
17
19
|
spec.add_dependency "addressable"
|
18
|
-
spec.add_development_dependency "minitest"
|
19
|
-
spec.add_development_dependency "
|
20
|
+
spec.add_development_dependency "minitest-around"
|
21
|
+
spec.add_development_dependency "webmock"
|
20
22
|
|
21
23
|
spec.require_path = "lib"
|
22
24
|
spec.bindir = "bin"
|
23
25
|
spec.executable = "directlink"
|
24
|
-
spec.test_file = "test.rb"
|
25
|
-
spec.files =
|
26
|
+
spec.test_file = "unit.test.rb"
|
27
|
+
spec.files = %w{ LICENSE directlink.gemspec lib/directlink.rb bin/directlink }
|
26
28
|
|
27
|
-
spec.requirements << "you may
|
29
|
+
spec.requirements << "you may want to create apps and provide API tokens:"
|
28
30
|
spec.requirements << "IMGUR_CLIENT_ID, FLICKR_API_KEY, REDDIT_SECRETS"
|
29
31
|
end
|
data/lib/directlink.rb
CHANGED
@@ -2,17 +2,16 @@ module DirectLink
|
|
2
2
|
|
3
3
|
class << self
|
4
4
|
attr_accessor :silent
|
5
|
-
end
|
6
|
-
self.silent = false
|
7
|
-
class << self
|
8
5
|
attr_accessor :logger
|
6
|
+
attr_accessor :timeout
|
9
7
|
end
|
8
|
+
self.silent = false
|
10
9
|
self.logger = Object.new
|
11
10
|
self.logger.define_singleton_method :error do |str|
|
12
11
|
puts str unless Module.nesting.first.silent
|
13
12
|
end
|
14
13
|
|
15
|
-
class ErrorAssert < RuntimeError
|
14
|
+
class ErrorAssert < RuntimeError # gem user should not face this error
|
16
15
|
def initialize msg
|
17
16
|
super "#{msg} -- consider reporting this issue to GitHub"
|
18
17
|
end
|
@@ -35,6 +34,22 @@ module DirectLink
|
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
37
|
+
require "nethttputils"
|
38
|
+
require "fastimage"
|
39
|
+
NORMAL_EXCEPTIONS = [
|
40
|
+
SocketError,
|
41
|
+
Net::OpenTimeout,
|
42
|
+
Errno::ECONNRESET,
|
43
|
+
Errno::ECONNREFUSED,
|
44
|
+
Errno::ETIMEDOUT, # from FastImage
|
45
|
+
NetHTTPUtils::Error,
|
46
|
+
NetHTTPUtils::EOFError_from_rbuf_fill,
|
47
|
+
FastImage::UnknownImageType,
|
48
|
+
FastImage::ImageFetchFailure,
|
49
|
+
DirectLink::ErrorNotFound,
|
50
|
+
DirectLink::ErrorBadLink,
|
51
|
+
] # all known exceptions that can be raised while using Directlink but not as its fault
|
52
|
+
|
38
53
|
|
39
54
|
def self.google src, width = 0
|
40
55
|
# this can handle links without schema because it's used for parsing community HTML pages
|
@@ -44,10 +59,10 @@ module DirectLink
|
|
44
59
|
"#{$1}s#{width}/"
|
45
60
|
when /\A(\/\/lh3\.googleusercontent\.com\/proxy\/[a-zA-Z0-9_-]{66,523}=)(?:w(?:[45]\d\d)-h\d\d\d-[np]|s530-p|s110-p-k)\z/
|
46
61
|
"https:#{$1}s#{width}/"
|
47
|
-
when /\A(\/\/lh3\.googleusercontent\.com\/
|
62
|
+
when /\A(\/\/lh3\.googleusercontent\.com\/[a-zA-Z0-9]{24}_[a-zA-Z]{30}7zGIDTJfkc1YZFX2MhgKnjA=)w530-h398-p\z/
|
48
63
|
"https:#{$1}s#{width}/"
|
49
64
|
when /\A(\/\/lh3\.googleusercontent\.com\/-[a-zA-Z0-9-]{11}\/[VW][a-zA-Z0-9_-]{9}I\/AAAAAAA[AC][a-zA-Z0-9]{3}\/[a-zA-Z0-9_-]{32}[gwAQ]CJoC\/)w530-h[23]\d\d-p\/[^\/]+\z/,
|
50
|
-
/\A(?:https?:)?(\/\/[1-4]\.bp\.blogspot\.com\/-[a-zA-Z0-9_-]{11}\/[UVWX][a-zA-Z0-9_-]{9}I\/AAAAAAAA[A-Z][a-zA-Z0-9_-]{2}\/[a-zA-Z0-9_-]{33}C(?:EwYBhgL|(?:Lc|Kg)BGAs)\/)(?:s640|w\d
|
65
|
+
/\A(?:https?:)?(\/\/[1-4]\.bp\.blogspot\.com\/-[a-zA-Z0-9_-]{11}\/[UVWX][a-zA-Z0-9_-]{9}I\/AAAAAAAA[A-Z][a-zA-Z0-9_-]{2}\/[a-zA-Z0-9_-]{33}C(?:EwYBhgL|(?:Lc|Kg)BGAs(?:YHQ)?)\/)(?:s640|w\d{2,4}-h\d\d\d?-p(?:-k-no-nu)?)\/[^\/]+\z/,
|
51
66
|
/\A(?:https?:)?(\/\/[1-4]\.bp\.blogspot\.com\/-[a-zA-Z0-9-]{11}\/[UV][a-zA-Z0-9_-]{9}I\/AAAAAAAA[A-Z][a-zA-Z0-9]{2}\/[a-zA-Z0-9-]{11}\/)w72-h72-p-k-no-nu\/[^\/]+\z/
|
52
67
|
"https:#{$1}s#{width}/"
|
53
68
|
when /\A(https:\/\/lh3\.googleusercontent\.com\/-[a-zA-Z0-9_]{11}\/AAAAAAAAAAI\/AAAAAAAAAAQ\/[a-zA-Z0-9_]{11}\/)w530-h[13]\d\d-n\/[^\/]+\z/,
|
@@ -65,18 +80,24 @@ module DirectLink
|
|
65
80
|
/\A(https:\/\/lh[356]\.googleusercontent\.com\/-[a-zA-Z0-9]{11}\/AAAAAAAAAAI\/AAAAAAAAAAA\/[a-zA-Z0-9_]{34}\/)s(?:46|64)-c(?:-k(?:-no)?)?-mo\/photo\.jpg\z/
|
66
81
|
"#{$1}s#{width}/"
|
67
82
|
# Google Keep
|
68
|
-
when /\A(https:\/\/lh\d\.googleusercontent\.com\/[a-zA-Z0-9_-]{104,106}=s)\d\d\d\d?\
|
83
|
+
when /\A(https:\/\/lh\d\.googleusercontent\.com\/[a-zA-Z0-9_-]{104,106}=s)\d\d\d\d?\z/
|
69
84
|
"#{$1}#{width}"
|
85
|
+
# opensea
|
86
|
+
when /\A(https:\/\/lh3\.googleusercontent\.com\/[a-zA-Z0-9]{78}-nGx_jf_XGqqiVANe_Jr8u2g=)w1400-k\z/
|
87
|
+
"#{$1}s#{width}"
|
70
88
|
# mp4
|
71
89
|
when /\A(https:\/\/lh3\.googleusercontent\.com\/-[a-zA-Z]{11}\/W[a-zA-Z0-9]{9}I\/AAAAAAAAODw\/[a-zA-Z0-9]{32}QCJoC\/)w530-h883-n-k-no\/[^\/]+\.mp4\z/
|
72
90
|
"#{$1}s#{width}/"
|
91
|
+
# something else
|
92
|
+
when /\A(https:\/\/lh3\.googleusercontent\.com\/-[a-zA-Z0-9_]{11}\/X-[a-zA-Z0-9]{8}I\/AAAAAAAAALE\/[a-zA-Z0-9]{23}_[a-zA-Z0-9]{19}\/)w1200-h630-p-k-no-nu\/[\d-]+\.png\z/
|
93
|
+
"#{$1}s#{width}/"
|
73
94
|
else
|
74
95
|
raise ErrorBadLink.new src
|
75
96
|
end
|
76
97
|
end
|
77
98
|
|
99
|
+
|
78
100
|
require "json"
|
79
|
-
require "nethttputils"
|
80
101
|
|
81
102
|
# TODO make the timeout handling respect the way the Directlink method works with timeouts
|
82
103
|
def self.imgur link, timeout = 1000
|
@@ -88,7 +109,7 @@ module DirectLink
|
|
88
109
|
NetHTTPUtils.request_data url, header: { Authorization: "Client-ID #{ENV["IMGUR_CLIENT_ID"]}" }
|
89
110
|
rescue NetHTTPUtils::Error => e
|
90
111
|
raise ErrorNotFound.new url.inspect if 404 == e.code
|
91
|
-
if t < timeout && [400, 500, 503].include?(e.code)
|
112
|
+
if t < timeout && [400, 500, 502, 503].include?(e.code)
|
92
113
|
logger.error "retrying in #{t} seconds because of Imgur HTTP ERROR #{e.code}"
|
93
114
|
sleep t
|
94
115
|
t *= 2
|
@@ -107,16 +128,16 @@ module DirectLink
|
|
107
128
|
elsif data["images"]
|
108
129
|
raise ErrorNotFound.new link.inspect if data["images"].empty?
|
109
130
|
data["images"]
|
110
|
-
elsif data["type"] && data["type"]
|
131
|
+
elsif data["type"] && %w{ image/jpeg image/png image/gif video/mp4 }.include?(data["type"])
|
111
132
|
# TODO check if this branch is possible at all
|
112
133
|
[ data ]
|
113
134
|
# elsif data["comment"]
|
114
135
|
# fi["https://imgur.com/" + data["image_id"]]
|
115
136
|
else
|
116
137
|
# one day single-video item should hit this but somehow it didn't yet
|
117
|
-
raise ErrorAssert.new "unknown data format #{
|
138
|
+
raise ErrorAssert.new "unknown data format #{json} for #{link}"
|
118
139
|
end
|
119
|
-
when /\Ahttps?:\/\/(?:(?:i|m|www)\.)?imgur\.com\/([a-zA-Z0-9]{7,8})(?:\.(?:gifv|
|
140
|
+
when /\Ahttps?:\/\/(?:(?:i|m|www)\.)?imgur\.com\/([a-zA-Z0-9]{7,8})(?:\.(?:gifv|jpe?g(?:\?fb)?|png))?\z/,
|
120
141
|
/\Ahttps?:\/\/(?:(?:i|m|www)\.)?imgur\.com\/([a-zA-Z0-9]{5})\.mp4\z/,
|
121
142
|
/\Ahttps?:\/\/imgur\.com\/([a-zA-Z0-9]{5}(?:[a-zA-Z0-9]{2})?)\z/,
|
122
143
|
/\Ahttps?:\/\/imgur\.com\/([a-zA-Z0-9]{7})(?:\?\S+)?\z/,
|
@@ -128,7 +149,7 @@ module DirectLink
|
|
128
149
|
raise ErrorBadLink.new link
|
129
150
|
end.map do |image|
|
130
151
|
case image["type"]
|
131
|
-
when
|
152
|
+
when *%w{ image/jpeg image/png image/gif video/mp4 }
|
132
153
|
image.values_at "link", "width", "height", "type"
|
133
154
|
else
|
134
155
|
raise ErrorAssert.new "unknown type of #{link}: #{image}"
|
@@ -137,9 +158,8 @@ module DirectLink
|
|
137
158
|
end
|
138
159
|
|
139
160
|
def self._500px link
|
140
|
-
raise ErrorBadLink.new link unless %r{\Ahttps://500px\.com/photo/(?<id>[^/]+)/[
|
161
|
+
raise ErrorBadLink.new link unless %r{\Ahttps://500px\.com/photo/(?<id>[^/]+)/[-[a-zA-Z0-9]%]+\/?\z} =~ link
|
141
162
|
require "nokogiri"
|
142
|
-
resp = NetHTTPUtils.request_data link
|
143
163
|
f = lambda do |form|
|
144
164
|
JSON.load(NetHTTPUtils.request_data "https://api.500px.com/v1/photos", form: form).fetch("photos").values.first
|
145
165
|
end
|
@@ -191,11 +211,11 @@ module DirectLink
|
|
191
211
|
attr_accessor :reddit_bot
|
192
212
|
end
|
193
213
|
def self.reddit link, timeout = 1000
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
214
|
+
return [true, link] if URI(link).host &&
|
215
|
+
URI(link).host.split(?.) == %w{ i redd it } &&
|
216
|
+
URI(link).path[/\A\/[a-z0-9]{12,13}\.(gif|jpg)\z/]
|
217
|
+
unless id = link[/\Ahttps:\/\/www\.reddit\.com\/gallery\/([0-9a-z]{5,6})\z/, 1]
|
218
|
+
raise DirectLink::ErrorBadLink.new link unless id = URI(link).path[/\A(?:\/r\/[0-9a-zA-Z_]+)?(?:\/comments|\/duplicates)?\/([0-9a-z]{5,6})(?:\/|\z)/, 1]
|
199
219
|
end
|
200
220
|
retry_on_json_parseerror = lambda do |&b|
|
201
221
|
t = 1
|
@@ -221,14 +241,21 @@ module DirectLink
|
|
221
241
|
raise ErrorAssert.new "our knowledge about Reddit API seems to be outdated" unless json.size == 2
|
222
242
|
json.find{ |_| _["data"]["children"].first["kind"] == "t3" }
|
223
243
|
end
|
244
|
+
# TODO: do we handle linking Imgur albums?
|
224
245
|
data = json["data"]["children"].first["data"]
|
225
|
-
if data["media"]
|
226
|
-
return [true, data["media"]["reddit_video"]["fallback_url"]]
|
227
|
-
else
|
246
|
+
if data["media"]
|
247
|
+
return [true, data["media"]["reddit_video"]["fallback_url"]] if data["media"]["reddit_video"]
|
228
248
|
raise ErrorAssert.new "our knowledge about Reddit API seems to be outdated" unless data["media"].keys.sort == %w{ oembed type } && %w{ youtube.com gfycat.com imgur.com }.include?(data["media"]["type"])
|
229
249
|
return [true, data["media"]["oembed"]["thumbnail_url"]]
|
230
|
-
end
|
231
|
-
|
250
|
+
end
|
251
|
+
if data["media_metadata"]
|
252
|
+
return [true, data["media_metadata"].values.map do |media|
|
253
|
+
next if media == {"status"=>"failed"} || media == {"status"=>"unprocessed"}
|
254
|
+
raise ErrorAssert.new "our knowledge about Reddit API seems to be outdated (media == #{media.inspect})" unless media["status"] == "valid"
|
255
|
+
[media["m"], *media["s"].values_at("x", "y"), CGI.unescapeHTML(media["s"][media["m"]=="image/gif" ? "gif" : "u"])]
|
256
|
+
end.compact]
|
257
|
+
end
|
258
|
+
return [true, "#{"https://www.reddit.com" if /\A\/r\/[0-9a-zA-Z_]+\/comments\/[0-9a-z]{5,6}\// =~ data["url"]}#{data["url"]}"] if data["crosspost_parent"]
|
232
259
|
return [true, data["url"]] unless data["is_self"]
|
233
260
|
raise ErrorAssert.new "our knowledge about Reddit API seems to be outdated" if data["url"] != "https://www.reddit.com" + data["permalink"]
|
234
261
|
return [false, data["selftext"]]
|
@@ -236,46 +263,54 @@ module DirectLink
|
|
236
263
|
|
237
264
|
def self.vk link
|
238
265
|
id, mtd, field, f = case link
|
239
|
-
when %r{\Ahttps://vk\.com/id(?<user_id>\d+)\?z=photo(?<id>\k<user_id>_\d+)(%2F(album\k<user_id>_0|photos\k<user_id>))
|
266
|
+
when %r{\Ahttps://vk\.com/id(?<user_id>\d+)\?z=photo(?<id>\k<user_id>_\d+)(%2F(album\k<user_id>_0|photos\k<user_id>))?\z},
|
240
267
|
%r{\Ahttps://vk\.com/[a-z_]+\?z=photo(?<_>)(?<id>(?<user_id>\d+)_\d+)%2Fphotos\k<user_id>\z},
|
241
|
-
%r{\Ahttps://vk\.com/photo(?<_>)(?<id>-?\d+_\d+)(\?all=1)?\z},
|
268
|
+
%r{\Ahttps://vk\.com/photo(?<_>)(?<id>-?\d+_\d+)(\?(?:all|rev)=1)?\z},
|
242
269
|
%r{\Ahttps://vk\.com/feed\?section=likes&z=photo(?<_>)(?<id>-(?<user_id>\d+)_\d+)%2F(liked\d+|album\k<user_id>_0)\z},
|
243
270
|
%r{\Ahttps://vk\.com/[a-z_]+\?z=photo(?<_>)(?<id>(?<user_id>-\d+)_\d+)%2F(wall\k<user_id>_\d+|album\k<user_id>_0)\z},
|
244
271
|
%r{\Ahttps://vk\.com/wall(?<user_id>-\d+)_\d+\?z=photo(?<id>\k<user_id>_\d+)%2F(wall\k<user_id>_\d+|album\k<user_id>_00%2Frev|\d+)\z}
|
245
272
|
[$2, :photos, :photos, lambda do |t|
|
246
273
|
raise ErrorAssert.new "our knowledge about VK API seems to be outdated" unless 1 == t.size
|
247
|
-
t
|
274
|
+
t
|
248
275
|
end ]
|
249
|
-
when %r{\Ahttps://vk\.com/wall(?<id
|
276
|
+
when %r{\Ahttps://vk\.com/wall(?<id>-?\d+_\d+)\z},
|
277
|
+
%r{\Ahttps://vk\.com/[a-z\.]+\?w=wall(?<id>-?\d+_\d+)\z}
|
250
278
|
[$1, :wall, :posts, lambda do |t|
|
251
|
-
t.first.fetch("attachments").
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
279
|
+
t.first.fetch("attachments").select do |item|
|
280
|
+
case item.keys
|
281
|
+
when %w{ type photo }
|
282
|
+
raise ErrorAssert.new "our knowledge about VK API seems to be outdated" unless item["type"] == "photo"
|
283
|
+
next true
|
284
|
+
when %w{ type audio }
|
285
|
+
raise ErrorAssert.new "our knowledge about VK API seems to be outdated" unless item["type"] == "audio"
|
286
|
+
else
|
287
|
+
raise ErrorAssert.new "our knowledge about VK API seems to be outdated"
|
288
|
+
end
|
289
|
+
end.map{ |i| i.fetch "photo" }
|
256
290
|
end ]
|
257
291
|
else
|
258
292
|
raise ErrorBadLink.new link
|
259
293
|
end
|
260
294
|
raise ErrorMissingEnvVar.new "define VK_ACCESS_TOKEN and VK_CLIENT_SECRET env vars" unless ENV["VK_ACCESS_TOKEN"] && ENV["VK_CLIENT_SECRET"]
|
261
|
-
sleep 0.25 # "error_msg"=>"Too many requests per second"
|
295
|
+
sleep 0.25 unless ENV["CI"] # "error_msg"=>"Too many requests per second"
|
262
296
|
f.call( JSON.load( NetHTTPUtils.request_data "https://api.vk.com/method/#{mtd}.getById",
|
263
297
|
:POST, form: { field => id, :access_token => ENV["VK_ACCESS_TOKEN"], :client_secret => ENV["VK_CLIENT_SECRET"], :v => "5.101" }
|
264
|
-
).fetch("response") ).
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
298
|
+
).fetch("response") ).map do |photos|
|
299
|
+
photos.fetch("sizes").map do |size|
|
300
|
+
size.values_at("width", "height", "url").tap do |whu|
|
301
|
+
w, h, u = whu
|
302
|
+
whu[0, 2] = FastImage.new(u, raise_on_failure: true).size if [w, h].include? 0 # wtf?
|
303
|
+
end
|
304
|
+
end.max_by{ |w, h, u| w * h }
|
305
|
+
end
|
270
306
|
end
|
271
307
|
|
272
308
|
class_variable_set :@@directlink, Struct.new(:url, :width, :height, :type)
|
273
309
|
end
|
274
310
|
|
275
311
|
|
276
|
-
|
277
|
-
|
278
|
-
def DirectLink link, timeout = nil, giveup: false, ignore_meta: false
|
312
|
+
def DirectLink link, timeout = nil, proxy = nil, giveup: false, ignore_meta: false
|
313
|
+
timeout ||= DirectLink.timeout
|
279
314
|
ArgumentError.new("link should be a <String>, not <#{link.class}>") unless link.is_a? String
|
280
315
|
begin
|
281
316
|
URI link
|
@@ -313,15 +348,16 @@ def DirectLink link, timeout = nil, giveup: false, ignore_meta: false
|
|
313
348
|
**( %w{ reddit com } == URI(link).host.split(?.).last(2) ||
|
314
349
|
%w{ redd it } == URI(link).host.split(?.) ? {Cookie: "over18=1"} : {} ),
|
315
350
|
}
|
316
|
-
head = NetHTTPUtils.request_data link, :
|
351
|
+
head = NetHTTPUtils.request_data link, :HEAD, header: header, **(proxy ? {proxy: proxy} : {}), **(timeout ? {
|
317
352
|
timeout: timeout,
|
318
353
|
max_start_http_retry_delay: timeout,
|
319
|
-
max_read_retry_delay: timeout
|
354
|
+
max_read_retry_delay: timeout,
|
320
355
|
} : {})
|
321
|
-
rescue Net::ReadTimeout
|
356
|
+
rescue Net::ReadTimeout, Errno::ETIMEDOUT
|
322
357
|
rescue NetHTTPUtils::Error => e
|
323
358
|
raise unless 418 == e.code
|
324
359
|
else
|
360
|
+
raise DirectLink::ErrorAssert.new "last_response.uri is not set" unless head.instance_variable_get(:@last_response).uri
|
325
361
|
link = head.instance_variable_get(:@last_response).uri.to_s
|
326
362
|
end
|
327
363
|
|
@@ -329,10 +365,10 @@ def DirectLink link, timeout = nil, giveup: false, ignore_meta: false
|
|
329
365
|
# because they can be hidden behind URL shorteners
|
330
366
|
# also it can resolve NetHTTPUtils::Error(404) before trying the adapter
|
331
367
|
|
332
|
-
t = google_without_schema_crutch[] and return t
|
368
|
+
t = google_without_schema_crutch[] and return t # TODO: why again?
|
333
369
|
|
334
370
|
begin
|
335
|
-
imgur = DirectLink.imgur(link).sort_by{ |u, w, h, t| - w * h }.map do |u, w, h, t|
|
371
|
+
imgur = DirectLink.imgur(link, timeout).sort_by{ |u, w, h, t| - w * h }.map do |u, w, h, t|
|
336
372
|
struct.new u, w, h, t
|
337
373
|
end
|
338
374
|
# `DirectLink.imgur` return value is always an Array
|
@@ -370,40 +406,51 @@ def DirectLink link, timeout = nil, giveup: false, ignore_meta: false
|
|
370
406
|
f = ->_{ _.type == :a ? _.attr["href"] : _.children.flat_map(&f) }
|
371
407
|
require "kramdown"
|
372
408
|
return f[Kramdown::Document.new(u).root].flat_map do |sublink|
|
373
|
-
DirectLink URI.join(link, sublink).to_s, timeout, giveup: giveup
|
409
|
+
DirectLink URI.join(link, sublink).to_s, timeout, giveup: giveup # TODO: maybe subtract from timeout the time we've already wasted
|
410
|
+
end
|
411
|
+
end
|
412
|
+
if u.is_a? Hash
|
413
|
+
return struct.new *u.values_at(*%w{ fallback_url width height }), "video"
|
414
|
+
elsif u.is_a? Array
|
415
|
+
return u.map do |t, x, y, u|
|
416
|
+
struct.new u, x, y, t
|
374
417
|
end
|
375
418
|
end
|
376
|
-
|
377
|
-
return DirectLink u
|
378
|
-
fail if link == u
|
419
|
+
raise DirectLink::ErrorNotFound.new link.inspect if link == u
|
420
|
+
return DirectLink u, timeout, giveup: giveup
|
379
421
|
rescue DirectLink::ErrorMissingEnvVar
|
380
422
|
end if %w{ reddit com } == URI(link).host.split(?.).last(2) ||
|
381
423
|
%w{ redd it } == URI(link).host.split(?.)
|
382
424
|
|
383
425
|
begin
|
384
|
-
w, h, u
|
385
|
-
|
426
|
+
return DirectLink.vk(link).map do |w, h, u|
|
427
|
+
struct.new u, w, h
|
428
|
+
end
|
386
429
|
rescue DirectLink::ErrorMissingEnvVar
|
387
430
|
end if %w{ vk com } == URI(link).host.split(?.)
|
388
431
|
|
389
432
|
begin
|
390
|
-
f = FastImage.new
|
433
|
+
f = FastImage.new link,
|
434
|
+
raise_on_failure: true,
|
435
|
+
timeout: timeout,
|
436
|
+
**(proxy ? {proxy: "http://#{proxy}"} : {}),
|
437
|
+
http_header: {"User-Agent" => "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"}
|
391
438
|
rescue FastImage::UnknownImageType
|
392
439
|
raise if giveup
|
393
440
|
require "nokogiri"
|
394
|
-
head = NetHTTPUtils.request_data link, :
|
441
|
+
head = NetHTTPUtils.request_data link, :HEAD, header: {"User-Agent" => "Mozilla"},
|
395
442
|
max_start_http_retry_delay: timeout,
|
396
443
|
timeout: timeout, # NetHTTPUtild passes this as read_timeout to Net::HTTP.start
|
397
444
|
max_read_retry_delay: timeout # and then compares accumulated delay to this
|
398
445
|
# if we use :get here we will download megabytes of files just to giveup on content_type we can't process
|
399
|
-
case head.instance_variable_get(:@last_response).content_type
|
446
|
+
case head.instance_variable_get(:@last_response).content_type # webmock should provide this
|
400
447
|
when "text/html" ; nil
|
401
448
|
else ; raise
|
402
449
|
end
|
403
|
-
html = Nokogiri::HTML NetHTTPUtils.request_data link, header: {"User-Agent" => "Mozilla"}
|
450
|
+
html = Nokogiri::HTML NetHTTPUtils.request_data link, :GET, header: {"User-Agent" => "Mozilla"}
|
404
451
|
if t = html.at_css("meta[@property='og:image']")
|
405
452
|
begin
|
406
|
-
return DirectLink URI.join(link, t[:content]), nil, giveup: true
|
453
|
+
return DirectLink URI.join(link, t[:content]).to_s, nil, *proxy, giveup: true
|
407
454
|
rescue URI::InvalidURIError
|
408
455
|
end
|
409
456
|
end unless ignore_meta
|
@@ -419,9 +466,10 @@ def DirectLink link, timeout = nil, giveup: false, ignore_meta: false
|
|
419
466
|
end
|
420
467
|
end
|
421
468
|
end
|
422
|
-
l[html].
|
423
|
-
raise if results.empty?
|
424
|
-
|
469
|
+
l[html].
|
470
|
+
tap{ |results| raise if results.empty? }.
|
471
|
+
group_by(&:first).map{ |k, v| [k.join(?>), v.map(&:last)] }.
|
472
|
+
max_by{ |_, v| v.map{ |i| i.width * i.height }.inject(:+) }.last
|
425
473
|
else
|
426
474
|
# TODO: maybe move this to right before `rescue` line
|
427
475
|
w, h = f.size
|
data/unit.test.rb
ADDED
@@ -0,0 +1,1548 @@
|
|
1
|
+
require "minitest/autorun"
|
2
|
+
require "minitest/around/spec"
|
3
|
+
require "minitest/mock"
|
4
|
+
require "webmock/minitest"
|
5
|
+
require_relative "webmock_patch"
|
6
|
+
|
7
|
+
require_relative "lib/directlink"
|
8
|
+
DirectLink.silent = true # TODO: remove?
|
9
|
+
DirectLink.timeout = 30 # TODO: tests about this attribute
|
10
|
+
|
11
|
+
describe DirectLink do
|
12
|
+
around{ |test| Timeout.timeout(4){ test.call } }
|
13
|
+
before{ WebMock.reset! }
|
14
|
+
|
15
|
+
describe "./lib" do
|
16
|
+
|
17
|
+
describe "google" do
|
18
|
+
|
19
|
+
# TODO: expand this for every branch in the lib
|
20
|
+
%w{
|
21
|
+
https_long_blogspot https://1.bp.blogspot.com/-__qsdLxNtcQ/XhaOQle-ECI/AAAAAAAABQ4/S_7SGG_abcDE6XIU2wyPvTj9OyBfr_1sQCLcBGAsYHQ/w1200-h630-p-k-no-nu/iceland_poppies_orange_flowers_field-wallpaper-3840x2160.jpg https://1.bp.blogspot.com/-__qsdLxNtcQ/XhaOQle-ECI/AAAAAAAABQ4/S_7SGG_abcDE6XIU2wyPvTj9OyBfr_1sQCLcBGAsYHQ/s0/
|
22
|
+
http_short_blogspot http://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/mabcDE6-v-g/w72-h72-p-k-no-nu/Top-24-Inspired-181.jpg https://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/mabcDE6-v-g/s0/
|
23
|
+
just_gplus https://lh3.googleusercontent.com/-NiGph3ObOPg/XE3DgnavXlI/AAAAAAABvgE/pcPPCe88rsU1r941wwP76TVf_abcDE6kwCJoC/w530-h353-n/DSCF0753.JPG https://lh3.googleusercontent.com/-NiGph3ObOPg/XE3DgnavXlI/AAAAAAABvgE/pcPPCe88rsU1r941wwP76TVf_abcDE6kwCJoC/s0/
|
24
|
+
google_keep https://lh5.googleusercontent.com/fRmAL_04p7oomNHCiV4tH4-agHSDBtLaWi_Tb6bgE5ZSHVu5OjQF3iRn06nNwP3ywZwdFP92zWM-abcDE6n6m0tDTBARuO6F9e0wYu_1=s685 https://lh5.googleusercontent.com/fRmAL_04p7oomNHCiV4tH4-agHSDBtLaWi_Tb6bgE5ZSHVu5OjQF3iRn06nNwP3ywZwdFP92zWM-abcDE6n6m0tDTBARuO6F9e0wYu_1=s0
|
25
|
+
}.each_slice 3 do |name, link, o|
|
26
|
+
it "replaces s0 and schema correctly #{name}" do
|
27
|
+
assert_equal o, DirectLink.google(link)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "does not fail" do
|
32
|
+
# TODO: also check the #google is being called
|
33
|
+
|
34
|
+
"
|
35
|
+
1 //1.bp.blogspot.com/-rYk_u-qROQc/WngolJ8M0LI/AAAAAAAAD-w/abcDE6IVzasBPG5C2T1t-VrWKRd_U6lMgCLcBGAs/w530-h278-p/i-469.jpg
|
36
|
+
2 //4.bp.blogspot.com/-1RlHbRShONs/Wngp9WfxbfI/AAAAAAAAD-8/abcDE6SZdvUMz4VjJPBpprLBrJ5QpBaqACLcBGAs/w530-h278-p/i-468.jpg
|
37
|
+
3 //4.bp.blogspot.com/-5kP8ndL0kuM/Wpt82UCqvmI/AAAAAAAAEjI/abcDE60-kgwRXEJ9JEGioR0bm6U8MOkvQCKgBGAs/w530-h278-p/IMG_20171223_093922.jpg
|
38
|
+
4 //4.bp.blogspot.com/-bS1SZxFkvek/Wnjz3D5Il4I/AAAAAAAAD_I/abcDE6GB7r4NGJ0aR1F-ugsbVm4HUjf5ACLcBGAs/w530-h278-p/i-466.jpg
|
39
|
+
5 //lh3.googleusercontent.com/-1CF2jge1MYI/Wmr_kfCQQUI/AAAAAAAClKs/abcDE64v0q0i5N7rgso6G8SrhJNzsHEagCJoC/w530-h352-p/2809525%2B%25D0%2593%25D0%2590%25D0%259B%25D0%259E%2B%25D0%259F%25D0%2590%25D0%25A0%25D0%2593%25D0%2595%25D0%259B%25D0%2598%25D0%2599%2B-%2B%25D0%25A7%25D0%25A3%25D0%259A%25D0%259E%25D0%25A2%25D0%259A%25D0%2590%2B-%2B%25D0%25AE%25D0%25A0%25D0%2598%25D0%2599%2B%25D0%25A5%25D0%2590%25D0%25A0%25D0%25A7%25D0%2595%25D0%259D%25D0%259A%25D0%259E.jpg
|
40
|
+
6 //lh3.googleusercontent.com/-h1siEcRFqJ8/Wiv1iDQhNVI/AAAAAAAAQV4/abcDE6mYkDMLyVTG_1EBCMmj-UhmclXWwCJoC/w530-h353-p/001
|
41
|
+
7 //lh3.googleusercontent.com/-qnZygRb-Tn8/Wlyj4UuKbaI/AAAAAAAATqE/abcDE6-XBZwsh843xJ3cSd0JPt1LedU9gCJoC/w530-h330-p/001
|
42
|
+
8 //lh3.googleusercontent.com/-rXO9PzbjNmk/WlNfjJkJBmI/AAAAAAAATNY/abcDE6tWBzUKWufNXWkK82etw3RKA6jVgCJoC/w530-h361-p/001
|
43
|
+
|
44
|
+
13 //lh3.googleusercontent.com/proxy/2fsWfEOeeCMNEP8MGvHiJPkBlg47Ifaf8DwpgDPJSPSYsh9iomTrfOA9OuwB60laZimtNr4-1GKA5J2csuVB6-1DLNO30K-abcDE656ivICWRFAUuOwzizaztBx5gQ=w530-h707-p
|
45
|
+
14 //lh3.googleusercontent.com/proxy/2qy3gOwhBT77Ie_qa9VgGz6kgN14tnOh1AMmV9FB65oiXOSAIll1_qmOZdupL3QCcJQL4701YskEgeDUnxJTnFGq4mFEzNFvjpNC-QMX9Jg7mdar3e89u_siA4AD-j1SJ6mrkl2MwSJSu1s2guYn0NR5ND1985lK34_iGiwzjoGHG2a65IbxKDSEzgSGbPQ_abcDE6BIvfcgvAxtS6E=s530-p
|
46
|
+
28 //lh3.googleusercontent.com/proxy/7N0QCidzIFysO6OhmrG8twRJ74-sboNenI3Nhy3mIWP8C0SSa8J6xFQU3iyBTw4k3QeleiAgXOME3abYutPvBrHGx-0TBUcI-_abcDE69Zaw6PAGdLndkxp5ReRJnsg=w530-h298-p
|
47
|
+
31 //lh3.googleusercontent.com/proxy/7pN3aTE159nEXXQb_KajU1vcnDDzJVpGOv9vlWWPd3CbVuCKu-v4ndr423Mmhx-Zn5vqkVf6-TfZgPA5NyHECsr4w7kaw1jTmQDJbWO-9jU-Cs7ywrzcIRhyYTTZT-abcDE6wI1oEdbooIk=w464-h640-p
|
48
|
+
48 //lh3.googleusercontent.com/proxy/DZtTi5KL7PqiBwJc8weNGLk_Wi2UTaQH0AC_abcDE6iu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n
|
49
|
+
74 //lh3.googleusercontent.com/proxy/P4FQdTYwWN8cU_PWmFja1cm3oYu57L_flea7LmKvFjx0Ibdxl3glxcp-abcDE6xMFTQ3gQkWsWzlrkyCm9QrSjCUcGIgnbsYBCXewnhEwSn0ZgT4XDg485GdXMoGWpNETrLYa8IGvG20_iw=w504-h597-p
|
50
|
+
137 //lh3.googleusercontent.com/proxy/kX1ABK6_VjHDU12p-zZN6ciTOzqFcXm7IV41uR9F2sveM2t148nmWBEN1clA-VHvowpkd9T4NOPrAfDaip1o-jJBtBnRBElJuCsKo8FviSIkToZWCY9nQFEj06nHkMNuReBtdbVBlIRSodNJM-_cmqiJ-DnmWNe4dk62EF_kGLS28OWmckDLWVG0YFiZ-lVi8JhgR-ZgRmYWTs8bb_u6v6ucgfo8eh7ewchuZAD9_CoxUlQChAqz0QIfuVuKvmcXE06Ylv2H330btswQotjKDf8AXPe6xcyE9X1JXDYQTsPv-7lftLG9WQp1Mlc9Wu1XbHV7f541L-smt--7YpkW6fbDFYk4_87-pIOcg9UqHKB__DWyMCtH3gs8rv6VCmVwL1a-oAeBWSWk0Tc9R6uSuyCjt0nEBGlZY35aW1Pchz0jXr4lq8Il9m-wbRN9E7Kff1JR89YFOrV2N86w_72YTefFerLFfEsgzmhx3WYwok-abcDE6H7MyiHBQt04uRnb58GA4vl5VBQ=w530-h398-p
|
51
|
+
|
52
|
+
245 https://lh3.googleusercontent.com/-2JzV0ErXvv8/Wsdr-m5Q_aI/AAAAAAAA_-I/Lw_e6qEMPUck4yW9yWhkC-abcDE6m8c3QCJoC/w530-h795-n/888052_800n.jpg
|
53
|
+
346 https://lh3.googleusercontent.com/-8YmBt-SUaJo/War0Un_7YTI/AAAAAAAB9xs/kgXp9QrHZX8mpDfyLwuS9cabcDE6oH6NgCL0BGAs/w530-d-h443-n/%25D0%259B%25D0%25B5%25D1%2581%2B%25D0%25BD%25D0%25B0%2B%25D0%25B8%25D1%2581%25D1%2585%25D0%25BE%25D0%25B4%25D0%25B5%2B%25D0%25BB%25D0%25B5%25D1%2582%25D0%25B0.JPG
|
54
|
+
1317 https://lh3.googleusercontent.com/-tGAyJv4S6gM/WSLy4A7AFaI/AAAAAAABxk4/eq0Aprp2koM6GEti9xEIn-abcDE6bRRdQCL0B/w530-d-h660-n/%25D0%2592%25D0%25B5%25D1%2581%25D0%25BD%25D1%258B%2B%25D1%2586%25D0%25B2%25D0%25B5%25D1%2582%25D0%25B5%25D0%25BD%25D0%25B8%25D0%25B5.JPG
|
55
|
+
|
56
|
+
178 https://lh3.googleusercontent.com/--Ggbfs9HJZM/Wog1DA2WcFI/AAAAAAAAbdQ/SZKPcnabcDE6Ffl9pddfiLPQnOiJ37muQCJoC/w409-h727-n/11a1c54f37c07d3c04588b40d108b4c2.jpg
|
57
|
+
260 https://lh3.googleusercontent.com/-3Fe6CL9RH4o/WnipWY4889I/AAAAAAAAI4I/CPqdKpabcDE6aBlCqGQ3RdZ9bLJ4nzBwwCJoC/w239-h318-n/gplus1855963830.jpg
|
58
|
+
303 https://lh3.googleusercontent.com/-5vPhLnUILsA/WqFhJhu7VlI/AAAAAAAAAhQ/wWSrC8abcDE6OuzeU3UoXJkNG19tqtAGwCJoC/w265-h353-n/DSC08260.JPG
|
59
|
+
668 https://lh3.googleusercontent.com/-NLW68hNxEzU/WrSNfBxFX2I/AAAAAAAAAT8/7cvRM-abcDE6dlb6CS8pL5-eJ3wbwohlQCJoC/w179-h318-n/23.03.2018%2B-%2B3
|
60
|
+
669 https://lh3.googleusercontent.com/-NVJgqmI_2Is/WqMM2OMYg-I/AAAAAAAALrk/5-p3JLabcDE6o9dOf_p3gpddzqwr3Wp0ACJoC/w424-h318-n/001
|
61
|
+
783 https://lh3.googleusercontent.com/-SqAvt_F__bg/Wq0huHcX2NI/AAAAAAAAVj0/XfnwCUabcDE60Knw8rcXA-bhpKYkI4hdwCJoC/w358-h318-n/IMG_20180317_120218-01-01.jpeg
|
62
|
+
830 https://lh3.googleusercontent.com/-VB3YlLVL_tQ/Wo21yTbKl_I/AAAAAAAAApU/3DURmsabcDE60kif2ZRjhoLG4mTHYf8OwCJoC/w254-h318-n/180218_00001.jpg
|
63
|
+
1002 https://lh3.googleusercontent.com/-d8FkfLWq-_4/WpQXzEfFgBI/AAAAAAAADww/J32xKSabcDE6c3pyrZnNmRec6kjdnJBHgCJoC/w239-h318-n/gplus-485739203.jpg
|
64
|
+
".scan(/(\S+) (\S+)/).each do |i, link| # some pre-May-2018 urls dump from a community
|
65
|
+
it "Google Plus community post image ##{i}" do
|
66
|
+
assert DirectLink.google link
|
67
|
+
end
|
68
|
+
end
|
69
|
+
%w{
|
70
|
+
https://lh3.googleusercontent.com/-abcDE62vWuE/AAAAAAAAAAI/AAAAAAAAAAQ/wVFZagieszU/w530-h176-n/photo.jpg
|
71
|
+
//lh3.googleusercontent.com/abcDE6v7EGo0QbuoKxoKZVZO_NcBzufuvPtzirMJfPmAzCzMtnEncfA7zGIDTJfkc1YZFX2MhgKnjA=w530-h398-p
|
72
|
+
//lh3.googleusercontent.com/-0Vt5HFpPTVQ/Wnh02Jb4SFI/AAAAAAAAbCU/MtusII6-abcDE6QWofAaWF01IBUVykMyACJoC/w530-h351-p/DSC_3804%2B-%2B%25D0%25BA%25D0%25BE%25D0%25BF%25D0%25B8%25D1%258F.JPG
|
73
|
+
https://lh3.googleusercontent.com/-abcDE6-b85c/WvOtHJn-DxI/AAAAAAAAAKg/A_PoO64o0VkX1erPKebiO7Xcs5Iy3idbACJoC/w424-h318-n/IMG_20180510_082023.jpg
|
74
|
+
https://lh3.googleusercontent.com/-abcDE6FntJY/Wvl8HLwfF_I/AAAAAAAAA20/mqOtMCFuBkkvtv7jdpVkJv2XSXlOLoXVQCJoC/w212-h318-n/DPP_0006.JPG
|
75
|
+
https://lh3.googleusercontent.com/-abcDE64EIiw/WuxqzXHQCHI/AAAAAAAABAI/rA0R2UsbxoswvH6nSePnwa5VHG2f5kNOQCJoC/w398-h318-n/Fox-Desktop-1024x1280.jpg
|
76
|
+
https://lh3.googleusercontent.com/-abcDE62-1OA/WvMUBWXI0PI/AAAAAAAAC60/gdtkQz9YI0knYkFB8VjC2CpKOD6-Zs6hQCJoC/w408-h318-n/%25D0%25BF%25D0%25BE%25D1%2581.jpg
|
77
|
+
https://lh3.googleusercontent.com/--abcDE6Gk-A/WveQe_YKbAI/AAAAAAAACkQ/eTz2maXvw7A0iKoPjfuwEgfTiZS3a3HSgCJoC/w318-h318-n/gplus1165736192.jpg
|
78
|
+
https://lh3.googleusercontent.com/-abcDE6hwMOg/WtOxVJ1DNxI/AAAAAAAAMGs/pJf8awKJcyMFlx2g89p9_QjqlyQDmYMmACJoC/w424-h318-n/DSC03178.JPG
|
79
|
+
https://lh3.googleusercontent.com/-abcDE67fY1o/WtaUJCaDGmI/AAAAAAAAmBQ/jZhatiBmHPEiAAABcY2DoJ6KuzVBvqGxQCJoC/w530-h150-n/%25D0%25A1%25D0%25BD%25D0%25B8%25D0%25BC%25D0%25BE%25D0%25BA%2B%25D1%258D%25D0%25BA%25D1%2580%25D0%25B0%25D0%25BD%25D0%25B0%2B2018-04-18%2B%25D0%25B2%2B3.32.42.png
|
80
|
+
https://lh3.googleusercontent.com/-40QwR_c58sw/WsLyS3a8uhI/AAAAAAAAAas/ojaQoF1-abcDE6S6c5kLs7bOl_TAOU6oACJoC/w424-h318-n/271091.jpg
|
81
|
+
https://lh3.googleusercontent.com/-abcDE6yNBjY/WvOtHOyaj_I/AAAAAAAAAKo/gOAn__a75NwYSgaBaEBGeCTAFI9MyjqlwCJoC/w239-h318-n/IMG_20180510_081956.jpg
|
82
|
+
https://lh3.googleusercontent.com/-R19p_abcDE6/Wwma1oEvD6I/AAAAAAAAEX8/tQc4JOq58REEWlukw2jDCTUjH3ejGZI8gCJoC/w486-h864-n/gplus1392977354.jpg
|
83
|
+
//2.bp.blogspot.com/-mOnRg-mkojA/W22m79XcT_I/AAAAAAAAHDs/C8yQaOA-ZeEAr3WBG--abcDE65nWV0p7QCEwYBhgL/w530-h353-p/_MG_8809-Edit.jpg
|
84
|
+
}.each_with_index do |link, i| # March contenstants
|
85
|
+
it "another (March) Google Plus community post image ##{i + 1}" do
|
86
|
+
assert DirectLink.google link
|
87
|
+
end
|
88
|
+
end
|
89
|
+
%w{
|
90
|
+
https://lh3.googleusercontent.com/-abRcDE6_gic/WwUz3_Www7I/AAAAAAAABio/MNYvB57tBvIl6Bxp0GsKHvg0hSyHyVWhwCJoC/w265-h353-n/IMG_20180522_210620_317.jpg
|
91
|
+
https://lh3.googleusercontent.com/-abAcDE61QVc/Wu4Khtduz-I/AAAAAAAAA_A/lvpwTuatrtkhL31co1n9xa7kwKEVwc6IwCJoC/w301-h318-n/gplus662578195.jpg
|
92
|
+
https://lh3.googleusercontent.com/-abKcDE6NG2Q/Wvt9mUDC1QI/AAAAAAAANEw/2uWvIzQmG-Y3CGHuB8-UU114z4Zr8lkLQCJoC/w530-h175-n/PANO_20180516_025747.jpg
|
93
|
+
https://lh3.googleusercontent.com/-abWcDE66_Ew/WwvJcNQ39BI/AAAAAAAABvI/xb1bdwuEZGM2SmbwamwiMmZKFOW44bhPgCJoC/w239-h318-n/DSC03627.JPG
|
94
|
+
https://lh3.googleusercontent.com/-abacDE67WWI/Wu4Khq0IkaI/AAAAAAAAA_A/Dxs9JYJ6f6sv_7jNWMdNl3eo2jh9nYqDwCJoC/w296-h318-n/gplus-328480287.jpg
|
95
|
+
https://lh3.googleusercontent.com/-ab3cDE6qjyo/Wu4Khr5ZKhI/AAAAAAAAA_A/725HNeKw2hYtuddakPreAkaucQR6HOYGgCJoC/w424-h318-n/20180317_085037.jpg
|
96
|
+
https://lh3.googleusercontent.com/-abYcDE6GABY/Wu4Khov2uGI/AAAAAAAAA_A/xFVaLt1emxUtOvys7Mw8QZIF2599lNV6ACJoC/w424-h318-n/20180317_085508.jpg
|
97
|
+
https://lh3.googleusercontent.com/-abMcDE6jtXg/Wu4KhkZD9nI/AAAAAAAAA_A/lBHtrho7HBQgkZNztMTdR3o1RSu47OnigCJoC/w239-h318-n/gplus1795981938.jpg
|
98
|
+
https://lh3.googleusercontent.com/-ab-cDE6kT88/Wu4Khs76OSI/AAAAAAAAA_A/2rsXBfNM4Isi3YBNWlgLnPgQpVN72dXiQCJoC/w318-h318-n/gplus-379421668.jpg
|
99
|
+
}.each_with_index do |link, i| # April contenstants
|
100
|
+
it "another (April) Google Plus community post image ##{i + 1}" do
|
101
|
+
assert DirectLink.google link
|
102
|
+
end
|
103
|
+
end
|
104
|
+
%w{
|
105
|
+
https://lh3.googleusercontent.com/-abcDE6XoL_k/WvMUBQ6TXMI/AAAAAAAAC60/XRgJlEr5hbgKzYzOQkM8b4_fq2Yp5vNbACJoC/w239-h318-n/%25D0%25B7%25D0%25B0%25D1%2581.jpg
|
106
|
+
https://lh3.googleusercontent.com/-abcDE6ZYF4Y/Wvl8HH7crSI/AAAAAAAAA20/0vaXtOyqDL0DLx841Gj45ePol01OCOAewCJoC/w212-h318-n/DPP_0007.JPG
|
107
|
+
https://lh3.googleusercontent.com/-abcDE6DAoH8/WyCS3fapzjI/AAAAAAAAB5M/hKzS0cR0MEgnM-YJENsL7dX8Tbch5Z04wCJoC/w265-h353-n/DSC03805.JPG
|
108
|
+
https://lh3.googleusercontent.com/-abcDE6hweSI/WvMUBS4uAJI/AAAAAAAAC60/tE7aakvztZgTqvRMcrk2FbrauU8LLhGPgCJoC/w239-h318-n/11.jpg
|
109
|
+
https://lh3.googleusercontent.com/-abcDE6T_v6g/WyCS3VJ-hVI/AAAAAAAAB5M/qeUFKiNXnwkJ-q2q2VoM2f9ukTqPOGhAACJoC/w265-h353-n/DSC03807.JPG
|
110
|
+
//2.bp.blogspot.com/-abcDE6kbjOk/WwlXLbeiF9I/AAAAAAAAKKE/zT7sAlaNYIc7lTxZMY1tyND0u3UH5DuKACLcBGAs/w530-h398-p/EdnjF3yEMM8.jpg
|
111
|
+
https://lh3.googleusercontent.com/-1_J-abcDE6E/Wx9lWOEXUjI/AAAAAAAAB34/183rqDWZipkaSWyV6qF_Fm7_XQrtYiwdACJoC/w265-h353-n/DSC03800.JPG
|
112
|
+
https://lh3.googleusercontent.com/-I72-abcDE64/Wx9lWLfINqI/AAAAAAAAB34/EIOySV-4ny8xMECMSC4TvHV43qUn0HLLwCJoC/w265-h353-n/DSC03797.JPG
|
113
|
+
https://lh3.googleusercontent.com/-L-RnabcDE6I/WxZnv-NRXWI/AAAAAAAARVw/Z3yVnOEDU7kDZ-WbRoLbEh8Tao1_DtQbACJoC/w179-h318-n/20160305_134926.jpg
|
114
|
+
//lh3.googleusercontent.com/-abcDE6HFM6E/WtRMPtqimXI/AAAAAAAACIo/txJyaoEvnEQu7r2-35SgwFYCWHGmXDQ3QCJoC/w530-h353-p/IMG_3695.jpg
|
115
|
+
}.each_with_index do |link, i| # May contenstants
|
116
|
+
it "another (May) Google Plus community post image ##{i + 1}" do
|
117
|
+
assert DirectLink.google link
|
118
|
+
end
|
119
|
+
end
|
120
|
+
%w{
|
121
|
+
https://lh3.googleusercontent.com/-dWul1-dnMGE/W1npdlvSenI/AAAAAAAAAJI/abcDE65xS98xvFJDNgMgcxrRzPd6gOp9QCJoC/w208-h318-n/alg3_1520-2.jpg
|
122
|
+
https://lh3.googleusercontent.com/-t_ab__91ChA/VeLaObkUlgI/AAAAAAAAL4s/abcDE6_lkRw/w530-h351-n/30.08.15%2B-%2B1
|
123
|
+
https://lh3.googleusercontent.com/-Ry3uDLjGG0E/W13DzrEntEI/AAAAAAAAAdY/abcDE6-2JPsnuqYq7qtif_eVWhTd0EmnwCJoC/w480-h853-n/gplus-790559743.jpg
|
124
|
+
}.each_with_index do |link, i| # June contenstants
|
125
|
+
it "another (June) Google Plus community post image ##{i + 1}" do
|
126
|
+
assert DirectLink.google link
|
127
|
+
end
|
128
|
+
end
|
129
|
+
%w{
|
130
|
+
https://lh3.googleusercontent.com/-s655sojwyvw/VcNB4YMCz-I/AAAAAAAALqo/abcDE6cJJ0g/w530-h398-n/06.08.15%2B-%2B1
|
131
|
+
//4.bp.blogspot.com/-TuMlpg-Q1YY/W3PXkW1lkaI/AAAAAAAAHHg/Bh9IsuLV01kbctIu6lcRJHKkY-abcDE6gCLcBGAs/w530-h353-p/_MG_2688-Edit.jpg
|
132
|
+
//lh3.googleusercontent.com/proxy/SEfB6tFuim6X0HdZfEBSxrXtumUdf4Q4y05rUW4wc_clWWVrowuWAGZghx71xwPUmf_abcDE6wnRivsM7PfD2gp3kA=w480-h360-n
|
133
|
+
https://lh3.googleusercontent.com/-u3FhiUTmLCY/Vk7dMQnxR2I/AAAAAAAAMc0/I76_abcDE6s/w530-h322-n/Harekosh_A%252520Concert_YkRqQg.jpg
|
134
|
+
https://lh3.googleusercontent.com/-t_ab__91ChA/VeLaObkUlgI/AAAAAAAAL4s/abcDE6_lkRw/w530-d-h351-n/30.08.15%2B-%2B1
|
135
|
+
//lh3.googleusercontent.com/-u2NzdIQfVyQ/Wy83AzoFT8I/AAAAAAAAh6M/fdpxOUkj5mUIfpvYol_abcDE6nF2nDIEACJoC/w530-h298-p/_DSC9134.jpg
|
136
|
+
}.each_with_index do |link, i| # July contenstants
|
137
|
+
it "another (July) Google Plus community post image ##{i + 1}" do
|
138
|
+
assert DirectLink.google link
|
139
|
+
end
|
140
|
+
end
|
141
|
+
%w{
|
142
|
+
https://lh3.googleusercontent.com/-f37xWyiyP8U/WvmxOxCd-0I/AAAAAAAACpw/3A2tRj02oY40MzJqZBJyWabcDE6r0lwMgCJoC/s0/140809%2B029.jpg
|
143
|
+
https://lh3.googleusercontent.com/-1s_eiQB4x2k/WvXQEx59z2I/AAAAAAAAcI0/DvKYzWw3g6UNelqAQdOwrabcDE6qKgkxwCJoC/s0/001
|
144
|
+
https://lh3.googleusercontent.com/-1Rcbffs4iRI/WvaSsRCrxJI/AAAAAAAAcJs/e-N9tmjaTCIxEBE_jXwFjabcDE6Fwh4owCJoC/s0/001
|
145
|
+
https://lh3.googleusercontent.com/-VXUjuSl-dZY/WvK340_E9uI/AAAAAAAAVlg/HqKf1LgUcPUJNrLxHebCMabcDE6q36_bQCJoC/s0/gplus248254159.jpg
|
146
|
+
https://lh3.googleusercontent.com/-NlZRwcX_Lj8/WvQTijeAfJI/AAAAAAABNyo/jgoDgbZdTvsnLOGmmYlXMabcDE6ieZV4QCJoC/s0/67u8iii.png
|
147
|
+
https://lh3.googleusercontent.com/-8baBz80pf8Y/Wu8KG5lyGhI/AAAAAAACSyU/s3hasZzObK0VlntA1EBj-abcDE6gzRnLQCJoC/s0/%25D0%2592%25D0%25B5%25D1%2581%25D0%25B5%25D0%25BD%25D0%25BD%25D0%25B8%25D0%25B5%2B%25D0%25BA%25D1%2580%25D0%25B0%25D1%2581%25D0%25B0%25D0%25B2%25D1%2586%25D1%258B.JPG
|
148
|
+
https://lh3.googleusercontent.com/-BBjhu17YIgg/W-gnZNaZeMI/AAAAAAABA-k/UMlSbNuE0DsSEPV8u3yf_abcDE69vFoBgCJoC/s0/gplus320347186.png
|
149
|
+
}.each_with_index do |link, i|
|
150
|
+
it "already high res image ##{i + 1}" do
|
151
|
+
assert DirectLink.google link
|
152
|
+
end
|
153
|
+
end
|
154
|
+
%w{
|
155
|
+
https://lh3.googleusercontent.com/-5USmSTZHWWI/WMi3q1GdgiI/AAAAAAAAQIA/lu9FTcUL6xMw4wdoW_I148Vm1abcDE6mwCJoC/w346-h195-n-k-no/Good%2BJob.gif
|
156
|
+
https://lh3.googleusercontent.com/-G8eSL3Xx2Kc/WxWt9M6LptI/AAAAAAAAB_c/KNF9RBxjL04Reb3fBtwYLI2AlabcDE67gCJoC/s0/20180602212016_IMG_0244.JPG
|
157
|
+
https://lh3.googleusercontent.com/-aUVoiLNsmAg/WzcsUU2xfNI/AAAAAAAAODw/DOBual6E1rkVLHh3SKZSzbpNQabcDE6OQCJoC/w530-h883-n-k-no/gplus-1797734754.mp4
|
158
|
+
//lh3.googleusercontent.com/proxy/hOIoIpMEmoVDSP40VRzM92Zw2AeLvEEhxfyKHCOxiNVPyiGvZik5rMvl3jYISLabcDE6mhZuk8pFEYJhX5BU2wy_dw=w530-h822-p
|
159
|
+
https://lh3.googleusercontent.com/-GP3BA3zGR5A/W0IwuVXlfmI/AAAAAAADROs/SH8rRlBDYTsHZiHpM45S3zpEiabcDE6PwCJoC/s0/%25D1%2582%25D0%25B0%25D0%25B4%25D0%25B6%25D0%25B8%25D0%25BA%25D1%2581%25D0%25BA%25D0%25BE%25D0%25B5%2B%25D1%2580%25D0%25B0%25D0%25B7%25D0%25BD%25D0%25BE%25D1%2582%25D1%2580%25D0%25B0%25D0%25B2%25D1%258C%25D0%25B5.png
|
160
|
+
https://lh3.googleusercontent.com/-DLODAbD9W7E/W27ob5XGCOI/AAAAAAADV8g/J_6RYR6UkKsc2RJOWRx6Q-NBVabcDE6xwCJoC/s0/1236080.jpg
|
161
|
+
https://lh3.googleusercontent.com/-cJajRreI87w/W4gW5uF4Q7I/AAAAAAADZKI/mw1YayYE-MY2-1OCCmjvgM3kbabcDE6ggCJoC/s0/2504855.jpg
|
162
|
+
https://lh3.googleusercontent.com/-rm-m1meCOMY/W92GhExMG-I/AAAAAAADsTw/bIAm5-1CIOYEpyPJLnxT8VmI_abcDE6dACJoC/s0/2659806_800n.jpg
|
163
|
+
https://lh3.googleusercontent.com/-z1nwsq4NOT4/XETT5qhXP-I/AAAAAAAAC0s/03kJ22drB1EdqZ97gUXCPHkLZabcDE6OACJoC/w530-h942-n/gplus1629127930.jpg
|
164
|
+
https://lh3.googleusercontent.com/-NiGph3ObOPg/XE3DgnavXlI/AAAAAAABvgE/pcPPCe88rsU1r941wwP76TVf_abcDE6kwCJoC/w530-h353-n/DSCF0753.JPG
|
165
|
+
https://lh3.googleusercontent.com/-QfChCi9Lj6A/XEciVlXmDhI/AAAAAAACuZw/iYzoMIxr7SsGzEFbk1LrqIdCdabcDE6HACJoC/w795-h1193-n-rw/z7765765765757575.jpg
|
166
|
+
}.each_with_index do |link, i|
|
167
|
+
it "gpluscomm_105636351696833883213_86400 ##{i + 1}" do
|
168
|
+
assert DirectLink.google link
|
169
|
+
end
|
170
|
+
end
|
171
|
+
%w{
|
172
|
+
https://4.bp.blogspot.com/--L451qLtGq8/W2MiFy8SVCI/AAAAAAAARgM/9qr4fr2PiV8IE4dabcDE6dEnlchx1V6vwCLcBGAs/w72-h72-p-k-no-nu/blood_moon_5k.jpg
|
173
|
+
https://3.bp.blogspot.com/-aZETNznngSo/W2xbe673_6I/AAAAAAAARhs/hkXvEk85ol4SqVeabcDE6uDGLyT4V45kACLcBGAs/w72-h72-p-k-no-nu/waterfall-1280x800-ireland-4k-19245.jpg
|
174
|
+
https://3.bp.blogspot.com/-ZmCuJkPliO8/W3WjIWvdjXI/AAAAAAAARi4/qO9I8kzJvCMRWsgabcDE6cOCQPCyu_xDQCLcBGAs/w72-h72-p-k-no-nu/ford_mustang_neon_lights_5k.jpg
|
175
|
+
https://2.bp.blogspot.com/-rb2PXLGZy0s/W2nQe3mXOSI/AAAAAAAARhQ/P8gV-bMtYbY2xxpabcDE6xu3XDTUaugxQCLcBGAs/w72-h72-p-k-no-nu/beach-bora-bora-clouds-753626.jpg
|
176
|
+
https://1.bp.blogspot.com/-FGnZn0040os/W3g7wnT2o-I/AAAAAAAARjE/xfgcR4fyvQgBgV5abcDE6YOVK4d4dTouwCLcBGAs/w72-h72-p-k-no-nu/axl_2018_movie_4k_8k-7680x4320.jpg
|
177
|
+
https://1.bp.blogspot.com/-h9kL603XSgY/XCe5rYiOczI/AAAAAAAARmY/qz_kMyR1q-scfs-abcDE6of_QocYK7RegCLcBGAs/w72-h72-p-k-no-nu/spider_man_into_the_spider_verse_hd_4k.jpg
|
178
|
+
https://2.bp.blogspot.com/-rb2PXLGZy0s/W2nQe3mXOSI/AAAAAAAARhQ/P8gV-bMtYbY2xxpabcDE6xu3XDTUaugxQCLcBGAs/s640/beach-bora-bora-clouds-753626.jpg
|
179
|
+
http://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/abcDE6b-v-g/w72-h72-p-k-no-nu/Top-24-Inspired-181.jpg
|
180
|
+
http://1.bp.blogspot.com/-iSU4orVuR9Y/VFYrwQZ5qYI/AAAAAAAAMnc/abcDE6aeplw/w72-h72-p-k-no-nu/Wolf%2Bphotography2.jpg
|
181
|
+
http://1.bp.blogspot.com/-vPQSh6RKijU/VEi7r3D-jJI/AAAAAAAAL2Q/abcDE6oDp5M/w72-h72-p-k-no-nu/Building%2BIn%2BLondon1-4__880.jpeg
|
182
|
+
http://1.bp.blogspot.com/-W4xKJSsVf3M/Uz73jPlctbI/AAAAAAAAGz4/abcDE6ILMeY/w72-h72-p-k-no-nu/Beautiful+Japanese+places4.jpg
|
183
|
+
https://1.bp.blogspot.com/-__qsdLxNtcQ/XhaOQle-ECI/AAAAAAAABQ4/S_7SGG_K8eQ7abcDE6yPvTj9OyBfr_1sQCLcBGAsYHQ/w1200-h630-p-k-no-nu/iceland_poppies_orange_flowers_field-wallpaper-3840x2160.jpg
|
184
|
+
https://lh3.googleusercontent.com/-tV86KJvppss/XE2Nb2Z2aAI/AAAAAAAAGu4/94E_abcDE6AaJ59n43wmmd9rFa--OUuSQCJoC/w530-h338-n/IMG_6845%252C.png
|
185
|
+
https://lh3.googleusercontent.com/-cr-2ZSQGMPg/XFWLfetwr7I/AAAAAAAAQQQ/TbwDabcDE6wb4IDDO0SwfArFSZyDG0i0wCJoC/w530-h360-n/DSC07294.JPG
|
186
|
+
https://lh3.googleusercontent.com/-7ey25Wg_cQ4/X-Xy8LJPjMI/AAAAAAAAALE/raXQabcDE6EzEDfAg3TcsOU_xc9z4szcwCLcBGAsYHQ/w1200-h630-p-k-no-nu/1608905381407960-0.png
|
187
|
+
https://lh3.googleusercontent.com/C84udoMpvJmi95AqshlF9acaR11TCsUgO9rGB9gG1w5Wp3WpB7U52ntft4jBHAyDg2guo6zqI4KZim-nGx_jf_XGqqiVANe_Jr8u2g=w1400-k
|
188
|
+
}.each_with_index do |link, i|
|
189
|
+
it "largeimages ##{i + 1}" do
|
190
|
+
assert DirectLink.google link
|
191
|
+
end
|
192
|
+
end
|
193
|
+
%w{
|
194
|
+
//lh3.googleusercontent.com/proxy/S-Z1P92Dd_u0DjYrz5Tb7j0mbZsGjPVffx9lHPQZCqqCFr6vAigCPOG0fEYKU6d-wIvwYr2WriAfh97KjBr9Bq1RKgyHzHq2fpAotTnJYOLd3x_abcDE6GBVuAewE7qp2QDtCYyomyn3dGjZ6cKUnYIC8w=s110-p-k
|
195
|
+
}.each_with_index do |link, i|
|
196
|
+
it "posted_website_preview_##{i + 1}" do
|
197
|
+
assert DirectLink.google link
|
198
|
+
end
|
199
|
+
end
|
200
|
+
%w{
|
201
|
+
0 https://lh3.googleusercontent.com/-okfIabcDE6g/AAAAAAAAAAI/AAAAAAAAZa0/FEv9H8woCBg/s30-p-rw-no/photo.jpg
|
202
|
+
7 https://lh3.googleusercontent.com/-okfIabcDE6g/AAAAAAAAAAI/AAAAAAAAZa0/FEv9H8woCBg/s75-p-rw-no/photo.jpg
|
203
|
+
_ https://lh3.googleusercontent.com/-bhgxabcDE6I/AAAAAAAAAAI/AAAAAAAA4MI/_KuKE-Goa7E/s35-p-k-rw-no/photo.jpg
|
204
|
+
- https://lh3.googleusercontent.com/-tl9-abcDE6Y/AAAAAAAAAAI/AAAAAAAA8uY/vVeZX8SbTXI/s35-p-k-rw-no/photo.jpg
|
205
|
+
4 https://lh3.googleusercontent.com/-Rb83abcDE64/AAAAAAAAAAI/AAAAAAAAEJc/DawCLQGnaSA/s45-p-k-rw-no/photo.jpg
|
206
|
+
}.each_slice 2 do |i, link|
|
207
|
+
it "Google Plus userpic #{i}" do
|
208
|
+
assert DirectLink.google link
|
209
|
+
end
|
210
|
+
end
|
211
|
+
%w{
|
212
|
+
- https://lh3.googleusercontent.com/-abcDE6oWuoU/AAAAAAAAAAI/AAAAAAAAl90/ed314-fNMGg/s20-c-k-no/photo.jpg
|
213
|
+
just https://lh5.googleusercontent.com/-abcDE6YpZzU/AAAAAAAAAAI/AAAAAAAAAO4/WISrqFs1vT8/s46-c-k-no/photo.jpg
|
214
|
+
no-no https://lh5.googleusercontent.com/-abcDE6MkCWA/AAAAAAAAAAI/AAAAAAAAAAA/4252rscbv5M/s64-c-k/photo.jpg
|
215
|
+
no-k-no https://lh3.googleusercontent.com/-abcDE66JAgg/AAAAAAAAAAI/AAAAAAAAAAA/AIcfdXD1lA9yGoSbsihWmGfnl6Z3Rn43WA/s64-c-mo/photo.jpg
|
216
|
+
_ https://lh6.googleusercontent.com/-abcDE6PRFk4/AAAAAAAAAAI/AAAAAAAAAAA/AIcfdXDBweE5VzGGy4zMraO_pqiLuFN3yQ/s46-c-k-no-mo/photo.jpg
|
217
|
+
}.each_slice 2 do |i, link|
|
218
|
+
it "Hangout userpic #{i}" do
|
219
|
+
assert DirectLink.google link
|
220
|
+
end
|
221
|
+
end
|
222
|
+
%w{
|
223
|
+
https://lh4.googleusercontent.com/abcDE6lyjNKXqSqszuiCgPMi7_oE5fVv1Sw373HXBYlguP8AnIPAqefTS6DbBuurVGYRSxGrtDyKei1hae9Djf6rjiwjJd0aauA5Bg-z=s615
|
224
|
+
https://lh5.googleusercontent.com/fRmAL_04p7oomNHCiV4tH4-agHSDBtLaWi_Tb6bgE5ZSHVu5OjQF3iRn06nNwP3ywZwdFP92zWM-abcDE6n6m0tDTBARuO6F9e0wYu_1=s685
|
225
|
+
https://lh5.googleusercontent.com/FcYUQBKLXWtFLEvbQduvu7FHUm2f7U_MVdMBVnNbpwfzKHIU-xABkudxw-abcDE60jFYRHedh7Is5Dg6qlgIQF1iSndlWjiKCTTsUo1w=s1080
|
226
|
+
https://lh5.googleusercontent.com/gcDb3dxbch9jUKPzKGawJiwtHcNS9wp6o2sc0aJj9wOWQA-u8kXmKIrZ-abcDE6ee6qLaT2p6OK2N7klTJ9CxU66OnpBhYJMg0q9QEdq5Q=s2160
|
227
|
+
}.each_with_index do |link, i|
|
228
|
+
it "google keep ##{i + 1}" do
|
229
|
+
assert DirectLink.google link
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "imgur" do
|
238
|
+
|
239
|
+
%w{
|
240
|
+
https://imgur.com/a/badlinkpattern
|
241
|
+
http://example.com/
|
242
|
+
https://imgur.com/gallery/abcD5.
|
243
|
+
}.each_with_index do |url, i|
|
244
|
+
it "ErrorBadLink_##{i + 1}" do
|
245
|
+
assert_raises DirectLink::ErrorBadLink do
|
246
|
+
DirectLink.imgur url
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
it "ErrorNotFound when album is empty" do
|
252
|
+
stub_request(:head, "https://api.imgur.com/3/album/abcDEF7/0.json")#.to_return(status: 200, body: "", headers: {})
|
253
|
+
stub_request(:get, "https://api.imgur.com/3/album/abcDEF7/0.json").to_return body: {data: {images: {}}}.to_json
|
254
|
+
e = assert_raises DirectLink::ErrorNotFound do
|
255
|
+
DirectLink.imgur "https://imgur.com/a/abcDEF7"
|
256
|
+
end
|
257
|
+
assert_nil e.cause if Exception.instance_methods.include? :cause # Ruby 2.1
|
258
|
+
end
|
259
|
+
|
260
|
+
valid_imgur_image_url_direct = "https://i.imgur.com/abcDEF7.jpg"
|
261
|
+
valid_imgur_image_url_album = "https://imgur.com/a/abcDEF7"
|
262
|
+
[404].each do |error_code|
|
263
|
+
it error_code do
|
264
|
+
e = assert_raises DirectLink::ErrorNotFound do
|
265
|
+
NetHTTPUtils.stub :request_data, ->*{ raise NetHTTPUtils::Error.new "", error_code } do
|
266
|
+
DirectLink.imgur valid_imgur_image_url_direct
|
267
|
+
end
|
268
|
+
end
|
269
|
+
assert_equal error_code, e.cause.code if Exception.instance_methods.include? :cause # Ruby 2.1
|
270
|
+
end
|
271
|
+
end
|
272
|
+
[599].each do |error_code|
|
273
|
+
it error_code do
|
274
|
+
e = assert_raises DirectLink::ErrorAssert do
|
275
|
+
NetHTTPUtils.stub :request_data, ->*{ raise NetHTTPUtils::Error.new "", error_code } do
|
276
|
+
DirectLink.imgur valid_imgur_image_url_direct
|
277
|
+
end
|
278
|
+
end
|
279
|
+
assert_equal error_code, e.cause.code if Exception.instance_methods.include? :cause # Ruby 2.1
|
280
|
+
end
|
281
|
+
end
|
282
|
+
[400, 500, 502, 503].each do |error_code|
|
283
|
+
[
|
284
|
+
[valid_imgur_image_url_direct, :direct],
|
285
|
+
[valid_imgur_image_url_album, :album],
|
286
|
+
].each do |url, kind|
|
287
|
+
it "retries a limited number of times on error #{error_code} (#{kind})" do
|
288
|
+
tries = 0
|
289
|
+
e = assert_raises DirectLink::ErrorAssert do
|
290
|
+
NetHTTPUtils.stub :request_data, ->*{ tries += 1; raise NetHTTPUtils::Error.new "", error_code } do
|
291
|
+
DirectLink.imgur url, 1.5
|
292
|
+
end
|
293
|
+
end
|
294
|
+
assert_equal error_code, e.cause.code if Exception.instance_methods.include? :cause # Ruby 2.1
|
295
|
+
assert_equal 2, tries
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
it "does not throw 400 after a successfull retry" do
|
300
|
+
stub_request(:head, "https://api.imgur.com/3/image/abcDEF7/0.json")
|
301
|
+
stub_request(:get, "https://api.imgur.com/3/image/abcDEF7/0.json").to_return body: {data: {width: 100, height: 200, type: "image/jpeg", link: "https://i.imgur.com/abcDEF7.jpg"}}.to_json
|
302
|
+
f = 0
|
303
|
+
m = NetHTTPUtils.method :request_data
|
304
|
+
NetHTTPUtils.stub :request_data, lambda{ |*args, **kwargs|
|
305
|
+
raise NetHTTPUtils::Error.new "", 400 if 1 == f += 1
|
306
|
+
m.call *args, **kwargs
|
307
|
+
} do
|
308
|
+
assert_equal [[valid_imgur_image_url_direct, 100, 200, "image/jpeg"]],
|
309
|
+
DirectLink.imgur(valid_imgur_image_url_direct, 1.5)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
[
|
314
|
+
["gifv" , "http://i.imgur.com/abcDEF7.gifv", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"http://i.imgur.com/abcDEF7h.gif", "width"=>100, "height"=>200, "type"=>"image/gif"}],
|
315
|
+
["gif" , "https://i.imgur.com/abcD5.mp4", "https://api.imgur.com/3/image/abcD5/0.json", {"link"=>"https://i.imgur.com/abcD5.gif", "width"=>100, "height"=>200, "type"=>"image/gif"}],
|
316
|
+
["mp4" , "https://i.imgur.com/abcDEF7.png", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"}],
|
317
|
+
["fb" , "https://i.imgur.com/abcDEF7.jpg?fb", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
318
|
+
["jpEg" , "https://i.imgur.com/abcDEF7.jpeg", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
319
|
+
[nil , "http://m.imgur.com/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
320
|
+
[nil , "https://imgur.com/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.mp4", "width"=>100, "height"=>200, "type"=>"video/mp4"}],
|
321
|
+
[nil , "http://imgur.com/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
322
|
+
["5 char photo" , "https://imgur.com/abcD5", "https://api.imgur.com/3/image/abcD5/0.json", {"link"=>"https://i.imgur.com/abcD5.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
323
|
+
["single photo album" , "https://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]}],
|
324
|
+
["5 char https album" , "https://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]*6}, 6],
|
325
|
+
["7 char https album" , "https://imgur.com/a/abcDEF7", "https://api.imgur.com/3/album/abcDEF7/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"]*2}, 2],
|
326
|
+
["album zoomable" , "http://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]*49}, 49],
|
327
|
+
["album not zoomable" , "http://imgur.com/a/abcD5", "https://api.imgur.com/3/album/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"]*20}, 20],
|
328
|
+
[nil , "http://imgur.com/gallery/abcDEF7/new", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
329
|
+
[nil , "http://imgur.com/gallery/abcD5", "https://api.imgur.com/3/gallery/abcD5/0.json", {"images"=>["link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"]*7}, 7],
|
330
|
+
["single image gallery?" , "http://imgur.com/gallery/abcDEF7", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.png", "width"=>100, "height"=>200, "type"=>"image/png"}],
|
331
|
+
[nil , "http://imgur.com/gallery/abcD5/new", "https://api.imgur.com/3/gallery/abcD5/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
332
|
+
["gallery mp4" , "https://imgur.com/gallery/abcDEF7", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.mp4", "width"=>100, "height"=>200, "type"=>"video/mp4"}],
|
333
|
+
["id belongs to an image", "http://imgur.com/gallery/abcDEF7", "https://api.imgur.com/3/gallery/abcDEF7/0.json", {status: [404, "Not Found"]}, DirectLink::ErrorNotFound],
|
334
|
+
["id belongs to an album", "http://imgur.com/gallery/abcD5", "https://api.imgur.com/3/gallery/abcD5/0.json", {status: [404, "Not Found"]}, DirectLink::ErrorNotFound],
|
335
|
+
[nil , "http://imgur.com/r/wallpaper/abcDEF7", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg?1", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
336
|
+
[nil , "https://imgur.com/abcDEF7?third_party=1#_=_", "https://api.imgur.com/3/image/abcDEF7/0.json", {"link"=>"https://i.imgur.com/abcDEF7.jpg", "width"=>100, "height"=>200, "type"=>"image/jpeg"}],
|
337
|
+
].each_with_index do |t, i|
|
338
|
+
desc, url, stub_head, stub, m = t
|
339
|
+
it "kinds of post ##{i + 1}#{" (#{desc})" if desc}" do
|
340
|
+
case m
|
341
|
+
when Class
|
342
|
+
stub_request(:head, stub_head).to_return(stub) if stub_head
|
343
|
+
assert_raises m do
|
344
|
+
DirectLink.imgur url
|
345
|
+
end
|
346
|
+
when NilClass
|
347
|
+
stub_request(:head, stub_head) if stub_head
|
348
|
+
stub_request(:get, stub_head).to_return body: {data: stub}.to_json if stub
|
349
|
+
real = DirectLink.imgur url
|
350
|
+
assert_equal 1, real.size
|
351
|
+
assert_equal((stub["images"] ? stub["images"][0].values : stub.values), real.first)
|
352
|
+
when Numeric
|
353
|
+
stub_request(:head, stub_head) if stub_head
|
354
|
+
stub_request(:get, stub_head).to_return body: {data: stub}.to_json if stub
|
355
|
+
real = DirectLink.imgur url
|
356
|
+
assert_equal m, real.size
|
357
|
+
assert_equal stub["images"][0].values, real.first
|
358
|
+
else
|
359
|
+
fail "bug in tests"
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe "_500px" do
|
366
|
+
[
|
367
|
+
["https://500px.com/photo/123456789/morning-by", [1200, 800, "https://drscdn.500px.org/photo/123456789/m%3D900/v2?sig=#{Array.new(64){rand(16).to_s(16)}.join}", "jpeg"]],
|
368
|
+
["https://500px.com/photo/1234567890/-flowers-by/", [1819, 2500, "https://drscdn.500px.org/photo/1234567890/m%3D900/v2?sig=#{Array.new(64){rand(16).to_s(16)}.join}", "jpeg"]],
|
369
|
+
["https://500px.com/photo/1234567890/is%E5-by-%E7ku-/", [2048, 2048, "https://drscdn.500px.org/photo/1234567890/m%3D2048/v2?sig=#{Array.new(64){rand(16).to_s(16)}.join}", "jpeg"]]
|
370
|
+
].each_with_index do |(input, (w, h, u, t)), i|
|
371
|
+
it "kinds of links" do
|
372
|
+
id = URI(input).path[/\d+/]
|
373
|
+
stub_request(:head, "https://api.500px.com/v1/photos?ids=#{id}")
|
374
|
+
stub_request(:get, "https://api.500px.com/v1/photos?ids=#{id}").to_return body: {"photos"=>{id=>{"width"=>w,"height"=>h}}}.to_json
|
375
|
+
stub_request(:head, "https://api.500px.com/v1/photos?ids=#{id}&image_size%5B%5D=#{w}")
|
376
|
+
stub_request(:get, "https://api.500px.com/v1/photos?ids=#{id}&image_size%5B%5D=#{w}").to_return body: {"photos"=>{id=>{"images"=>[{"format"=>t,"url"=>u}]}}}.to_json
|
377
|
+
result = DirectLink.method(:_500px).call input
|
378
|
+
assert_equal [w, h, u, t], result, "#{input} :: #{result.inspect} != #{[w, h, u, t].inspect}"
|
379
|
+
end
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
describe "flickr" do
|
384
|
+
[
|
385
|
+
["https://www.flickr.com/photos/tomas-/12345678901/", DirectLink::ErrorNotFound],
|
386
|
+
["https://www.flickr.com/photos/12345678@N07/12345678901", DirectLink::ErrorNotFound],
|
387
|
+
["https://www.flickr.com/photos/12345678@N00/12345678901/", [3000, 2000, "https://live.staticflickr.com/7757/12345678901_ed5178cc6a_o.jpg"]], # trailing slash
|
388
|
+
["https://www.flickr.com/photos/jacob_schmidt/12345678901/in/album-12345678901234567/", DirectLink::ErrorNotFound], # username in-album
|
389
|
+
["https://www.flickr.com/photos/tommygi/1234567890/in/dateposted-public/", [1600, 1062, "https://live.staticflickr.com/5249/1234567890_29fae96e38_h.jpg"]], # username in-public
|
390
|
+
["https://www.flickr.com/photos/123456789@N02/12345678901/in/album-12345678901234567/", DirectLink::ErrorNotFound],
|
391
|
+
["https://www.flickr.com/photos/123456789@N03/12345678901/in/dateposted-public/", [4621, 3081, "https://live.staticflickr.com/3796/12345678901_f751b35aeb_o.jpg"]], # userid in-public
|
392
|
+
["https://www.flickr.com/photos/frank3/1234567890/in/photolist#{"-6KVb92"*50}", [4096, 2723, "https://live.staticflickr.com/2499/1234567890_dfa75a41cc_4k.jpg"]],
|
393
|
+
["https://www.flickr.com/photos/patricksloan/12345678901/sizes/l", [2048, 491, "https://live.staticflickr.com/5572/12345678900_fec4783d79_k.jpg"]],
|
394
|
+
["https://flic.kr/p/abcDEF", [5120, 3413, "https://live.staticflickr.com/507/12345678901_1bd49c5ebd_5k.jpg"]],
|
395
|
+
].each_with_index do |(input, expectation), i|
|
396
|
+
it "kinds of links" do
|
397
|
+
stub_request(:head, /\Ahttps:\/\/api\.flickr\.com\/services\/rest\/\?api_key=#{ENV["FLICKR_API_KEY"]}&format=json&method=flickr\.photos\.getSizes&nojsoncallback=1&photo_id=[\da-zA-Z]+\z/)
|
398
|
+
if expectation.is_a? Class
|
399
|
+
stub_request(:get, /\Ahttps:\/\/api\.flickr\.com\/services\/rest\/\?api_key=#{ENV["FLICKR_API_KEY"]}&format=json&method=flickr\.photos\.getSizes&nojsoncallback=1&photo_id=[\da-zA-Z]+\z/).to_return body: {"stat"=>"fail", "code"=>1, "message"=>"Photo not found"}.to_json
|
400
|
+
assert_raises expectation, input do
|
401
|
+
DirectLink.method(:flickr).call input
|
402
|
+
end
|
403
|
+
else
|
404
|
+
w, h, u = expectation
|
405
|
+
stub_request(:get, /\Ahttps:\/\/api\.flickr\.com\/services\/rest\/\?api_key=#{ENV["FLICKR_API_KEY"]}&format=json&method=flickr\.photos\.getSizes&nojsoncallback=1&photo_id=[\da-zA-Z]+\z/).to_return body: {"stat"=>"ok", "sizes"=>{ "size"=>[
|
406
|
+
{"width"=>w/2, "height"=>h , "source"=>u*2},
|
407
|
+
{"width"=>w , "height"=>h , "source"=>u },
|
408
|
+
{"width"=>w , "height"=>h/2, "source"=>u*2},
|
409
|
+
] } }.to_json
|
410
|
+
result = DirectLink.method(:flickr).call input
|
411
|
+
assert_equal expectation, result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe "wiki" do
|
418
|
+
[
|
419
|
+
["https://en.wikipedia.org/wiki/Prostitution_by_country#/media/File:Prostitution_laws_of_the_world.PNG", "https://upload.wikimedia.org/wikipedia/commons/e/e8/Prostitution_laws_of_the_world.PNG"],
|
420
|
+
["https://en.wikipedia.org/wiki/Third_Party_System#/media/File:United_States_presidential_election_results,_1876-1892.svg", DirectLink::ErrorAssert],
|
421
|
+
["http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg", "https://upload.wikimedia.org/wikipedia/commons/0/0d/Eduard_Bohlen_anagoria.jpg"],
|
422
|
+
["https://en.wikipedia.org/wiki/Spanish_Civil_War#/media/File:Alfonso_XIIIdeEspa%C3%B1a.jpg", "https://upload.wikimedia.org/wikipedia/commons/f/fb/Alfonso_XIIIdeEspa%C3%B1a.jpg"], # escaped input URI
|
423
|
+
["https://en.wikipedia.org/wiki/File:Tyson_Lewis.jpg", "https://upload.wikimedia.org/wikipedia/en/c/cd/Tyson_Lewis.jpg"], # exists only in en.wiki, not in commons
|
424
|
+
].each_with_index do |(input, expectation), i|
|
425
|
+
it "kinds of links" do
|
426
|
+
url = URI(input).tap{ |_| _.fragment = nil }.to_s
|
427
|
+
stub_request(:head, url)
|
428
|
+
stub_request(:head, "https://#{URI(input).hostname}/w/api.php?action=query&format=json&iiprop=url&prop=imageinfo&titles=#{input[/(File:.+)/]}")
|
429
|
+
if expectation.is_a? Class
|
430
|
+
stub_request(:get, "https://en.wikipedia.org/w/api.php?action=query&format=json&iiprop=url&prop=imageinfo&titles=#{input[/(File:.+)/]}").to_return body: {
|
431
|
+
"query"=>{"pages"=>{"-1"=>{}}}
|
432
|
+
}.to_json
|
433
|
+
assert_raises expectation, input do
|
434
|
+
DirectLink.wiki input
|
435
|
+
end
|
436
|
+
else
|
437
|
+
stub_request(:get, "https://#{URI(input).hostname}/w/api.php?action=query&format=json&iiprop=url&prop=imageinfo&titles=#{input[/(File:.+)/]}").to_return body: {
|
438
|
+
"query"=>{"pages"=>{"-1"=>{"imageinfo"=>[{"url"=>expectation}]}}}
|
439
|
+
}.to_json
|
440
|
+
result = DirectLink.wiki input
|
441
|
+
assert_equal expectation, result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
describe "reddit" do
|
448
|
+
[
|
449
|
+
["https://i.redd.it/abcde6k7r5xz.jpg", [true, "https://i.redd.it/abcde6k7r5xz.jpg"]],
|
450
|
+
["https://www.reddit.com/r/cacography/comments/abcde6/c/", [true, "http://i.imgur.com/abcde6Z.jpg"], false, "abcde6"],
|
451
|
+
["http://redd.it/abcde6", [true, "http://i.imgur.com/abcde6Z.jpg"], false, "abcde6"], # TODO maybe check that it calls #imgur recursively
|
452
|
+
["http://redd.it/abcde6", [true, "https://i.redd.it/abcde66ehrg11.jpg"], false, "abcde6"],
|
453
|
+
["https://reddit.com/abcde6", [true, "https://i.ytimg.com/vi/abcde6RbIeU/hqdefault.jpg"],
|
454
|
+
false, "abcde6",
|
455
|
+
{"type"=>"youtube.com","oembed"=>{"thumbnail_url"=>"https://i.ytimg.com/vi/abcde6RbIeU/hqdefault.jpg"}},
|
456
|
+
nil,
|
457
|
+
"http://www.youtube.com/watch?v=abcde6RbIeU&feature=g-vrec",
|
458
|
+
],
|
459
|
+
["https://www.reddit.com/r/hangers/comments/abcde6/tara_radovic/", [true, "https://i.imgur.com/abcDE6u.jpg"],
|
460
|
+
false, "abcde6",
|
461
|
+
nil,
|
462
|
+
"t3_abcde7",
|
463
|
+
], # "crossport" from Imgur
|
464
|
+
["https://www.reddit.com/gallery/abcde6",
|
465
|
+
[true, [
|
466
|
+
["image/jpg", 1440, 1440, "https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b"],
|
467
|
+
["image/jpg", 2441, 2441, "https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a"],
|
468
|
+
] ],
|
469
|
+
false, "abcde6",
|
470
|
+
nil,
|
471
|
+
nil,
|
472
|
+
"https://www.reddit.com/gallery/abcde6",
|
473
|
+
{
|
474
|
+
"x31msdjabcde6"=>{
|
475
|
+
"status"=>"valid", "m"=>"image/jpg", "s"=>{
|
476
|
+
"y"=>1440,
|
477
|
+
"x"=>1440,
|
478
|
+
"u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b",
|
479
|
+
},
|
480
|
+
},
|
481
|
+
"mwkzq6jabcde6"=>{
|
482
|
+
"status"=>"valid", "m"=>"image/jpg", "s"=>{
|
483
|
+
"y"=>2441,
|
484
|
+
"x"=>2441,
|
485
|
+
"u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a",
|
486
|
+
},
|
487
|
+
},
|
488
|
+
},
|
489
|
+
],
|
490
|
+
["https://www.reddit.com/abcde6",
|
491
|
+
[true, [
|
492
|
+
["image/jpg", 1440, 1440, "https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b"],
|
493
|
+
["image/jpg", 2441, 2441, "https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a"],
|
494
|
+
] ],
|
495
|
+
false, "abcde6",
|
496
|
+
nil,
|
497
|
+
nil,
|
498
|
+
"https://www.reddit.com/gallery/abcde6",
|
499
|
+
{
|
500
|
+
"x31msdjabcde6"=>{
|
501
|
+
"status"=>"valid", "m"=>"image/jpg", "s"=>{
|
502
|
+
"y"=>1440,
|
503
|
+
"x"=>1440,
|
504
|
+
"u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=1440&format=pjpg&auto=webp&s=b79952f8364bb98692d978944347f19e28774d1b",
|
505
|
+
},
|
506
|
+
},
|
507
|
+
"mwkzq6jabcde6"=>{
|
508
|
+
"status"=>"valid", "m"=>"image/jpg", "s"=>{
|
509
|
+
"y"=>2441,
|
510
|
+
"x"=>2441,
|
511
|
+
"u"=>"https://preview.redd.it/abcde6j6vee51.jpg?width=2441&format=pjpg&auto=webp&s=455e669356550351e6b8768d8009de616c11142a",
|
512
|
+
},
|
513
|
+
},
|
514
|
+
},
|
515
|
+
],
|
516
|
+
["https://www.reddit.com/gallery/abcde6", [true, "https://www.reddit.com/gallery/abcde6"], false, "abcde6"], # deleted gallery
|
517
|
+
["https://www.reddit.com/abcde6", [true, "https://www.reddit.com/r/Firewatch/comments/abcde7/new_wallpaper/"],
|
518
|
+
false, "abcde6",
|
519
|
+
nil,
|
520
|
+
"t3_abcde7",
|
521
|
+
"/r/Firewatch/comments/abcde7/new_wallpaper/",
|
522
|
+
], # deleted gallery
|
523
|
+
["https://www.reddit.com/abcde6",
|
524
|
+
[true, [
|
525
|
+
["image/jpg", 500, 500, "https://preview.redd.it/abcde6eexo461.jpg?width=500&format=pjpg&auto=webp&s=df211fe0699e3970681ffe493ed1af79725857e8"],
|
526
|
+
["image/jpg", 720, 446, "https://preview.redd.it/abcde6hexo461.jpg?width=720&format=pjpg&auto=webp&s=5e34ab0e6d54c0acfdb47f1daaf283087c5ad6a6"],
|
527
|
+
["image/jpg", 713, 588, "https://preview.redd.it/abcde6lexo461.jpg?width=713&format=pjpg&auto=webp&s=969dfb52bedd6f0055249aa8b7454b23adaa946e"],
|
528
|
+
] ],
|
529
|
+
false, "abcde6",
|
530
|
+
nil,
|
531
|
+
nil,
|
532
|
+
"https://www.reddit.com/gallery/abcde6",
|
533
|
+
{
|
534
|
+
"71t8ljeabcde6"=>{
|
535
|
+
"status"=>"valid", "m"=>"image/jpg", "s"=>{
|
536
|
+
"y"=>500,
|
537
|
+
"x"=>500,
|
538
|
+
"u"=>"https://preview.redd.it/abcde6eexo461.jpg?width=500&format=pjpg&auto=webp&s=df211fe0699e3970681ffe493ed1af79725857e8",
|
539
|
+
},
|
540
|
+
},
|
541
|
+
"bfmjbtjabcde6"=>{"status"=>"failed"},
|
542
|
+
"c11nt7habcde6"=>{
|
543
|
+
"status"=>"valid", "m"=>"image/jpg", "s"=>{
|
544
|
+
"y"=>446,
|
545
|
+
"x"=>720,
|
546
|
+
"u"=>"https://preview.redd.it/abcde6hexo461.jpg?width=720&format=pjpg&auto=webp&s=5e34ab0e6d54c0acfdb47f1daaf283087c5ad6a6",
|
547
|
+
},
|
548
|
+
},
|
549
|
+
"67mqvllabcde6"=>{
|
550
|
+
"status"=>"valid", "m"=>"image/jpg", "s"=>{
|
551
|
+
"y"=>588,
|
552
|
+
"x"=>713,
|
553
|
+
"u"=>"https://preview.redd.it/abcde6lexo461.jpg?width=713&format=pjpg&auto=webp&s=969dfb52bedd6f0055249aa8b7454b23adaa946e"
|
554
|
+
},
|
555
|
+
},
|
556
|
+
},
|
557
|
+
], # failed media
|
558
|
+
["https://www.reddit.com/r/CatsStandingUp/duplicates/abcde6/cat/",
|
559
|
+
[true, "https://v.redd.it/abcde6fb6w721/DASH_2_4_M?source=fallback"],
|
560
|
+
false, "abcde6",
|
561
|
+
{"reddit_video"=>{"fallback_url"=>"https://v.redd.it/abcde6fb6w721/DASH_2_4_M?source=fallback"}},
|
562
|
+
nil,
|
563
|
+
"https://v.redd.it/abcde6fb6w721",
|
564
|
+
],
|
565
|
+
["https://www.reddit.com/r/MapPorn/comments/abd123/________aaaabdeeeeeefggghhhiilmmnnoorrrssttuvyyz/",
|
566
|
+
[true, [
|
567
|
+
["image/gif", 500, 375, "https://i.redd.it/00146fghhjkox.gif"],
|
568
|
+
["image/jpg", 1000, 600, "https://preview.redd.it/1369aacghkswy.jpg?width=1000&format=pjpg&auto=webp&s=0122334444557777778889aaabbbbcdddddeeeef"],
|
569
|
+
]],
|
570
|
+
false, "abd123",
|
571
|
+
nil,
|
572
|
+
nil,
|
573
|
+
"https://www.reddit.com/gallery/abd123",
|
574
|
+
{
|
575
|
+
"00146fghhjkox"=>{
|
576
|
+
"status"=>"valid",
|
577
|
+
"e"=>"AnimatedImage",
|
578
|
+
"m"=>"image/gif",
|
579
|
+
"p"=>[],
|
580
|
+
"s"=>{
|
581
|
+
"y"=>375,
|
582
|
+
"gif"=>"https://i.redd.it/00146fghhjkox.gif",
|
583
|
+
"mp4"=>"",
|
584
|
+
"x"=>500
|
585
|
+
},
|
586
|
+
"id"=>"00146fghhjkox"
|
587
|
+
},
|
588
|
+
"1369aacghkswy"=>{
|
589
|
+
"status"=>"valid",
|
590
|
+
"e"=>"Image",
|
591
|
+
"m"=>"image/jpg",
|
592
|
+
"p"=>[],
|
593
|
+
"s"=>{
|
594
|
+
"y"=>600,
|
595
|
+
"x"=>1000,
|
596
|
+
"u"=>"https://preview.redd.it/1369aacghkswy.jpg?width=1000&format=pjpg&auto=webp&s=0122334444557777778889aaabbbbcdddddeeeef"
|
597
|
+
},
|
598
|
+
"id"=>"1369aacghkswy"
|
599
|
+
}
|
600
|
+
},
|
601
|
+
]
|
602
|
+
].each_with_index do |(input, expectation, is_self, id, media, crosspost_parent, url, media_metadata), i|
|
603
|
+
it "kinds of links" do
|
604
|
+
unless is_self.nil?
|
605
|
+
fail "bug in test: no id" unless id
|
606
|
+
stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: {"access_token"=>"123456789012-abcDE6CFsglE63e5F1v8ThrVa9HThg"}.to_json
|
607
|
+
stub_request(:get, "https://oauth.reddit.com/by_id/t3_#{id}?api_type=json").to_return body: {
|
608
|
+
"data"=>{"children"=>[{"data"=>{
|
609
|
+
"is_self"=>is_self,
|
610
|
+
"media"=>media,
|
611
|
+
"crosspost_parent"=>crosspost_parent,
|
612
|
+
"url"=>(url||expectation[1]),
|
613
|
+
"media_metadata"=>media_metadata,
|
614
|
+
# "permalink"=>"/r/cacography/comments/32tq0i/c/",
|
615
|
+
# "selftext"=>"",
|
616
|
+
}}]}
|
617
|
+
}.to_json
|
618
|
+
end
|
619
|
+
result = DirectLink.reddit input
|
620
|
+
assert_equal expectation, result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
|
621
|
+
end
|
622
|
+
end
|
623
|
+
end
|
624
|
+
|
625
|
+
describe "vk" do
|
626
|
+
[
|
627
|
+
["https://vk.com/wall-123456091_7806", [960, 1280, "https://userapi.com/impf/c123456/v123456900/a72f1/7OZ8ux9Wcwo.jpg"], "wall", [
|
628
|
+
[97, 130, "https://sun9-3.userapi.com/impf/c123456/v123456900/a72f1/7OZ8ux9Wcwo.jpg?size=98x130&quality=96&sign=1f2bdc7b856b2a8f60297e3ac2c58689&c_uniq_tag=ggVFjBTdFDFuIz7Ee5o48mEP3fWLixCvjuPmehhyaTI&type=album"],
|
629
|
+
[960, 1280, "https://sun9-3.userapi.com/impf/c123456/v123456900/a72f1/7OZ8ux9Wcwo.jpg?size=960x1280&quality=96&proxy=1&sign=985328651fa11a0daef2c2a324f2de09&c_uniq_tag=vKCnEFEDol5QYM0qPrYAkbDwzYo6U_jo0SOR8iQO7HA&type=album"],
|
630
|
+
] ],
|
631
|
+
["https://vk.com/wall-123456611_454?z=photo-123456611_457239340%2Fwall-123456611_454", [1280, 960, "https://userapi.com/impf/c123456/v123456578/1a62f6/VB4SdR1O6Tg.jpg"], "photos", [
|
632
|
+
[130, 97, "https://sun9-59.userapi.com/impf/c123456/v123456578/1a62f6/VB4SdR1O6Tg.jpg?size=130x98&quality=96&sign=1e56a7310fd780cd48bed7304a369b1c&c_uniq_tag=xJlpXkJvi0P9WQhcM5acgLHqSUzXK3FGahuZHHncZQY&type=album"],
|
633
|
+
[1280, 960, "https://sun9-59.userapi.com/impf/c123456/v123456578/1a62f6/VB4SdR1O6Tg.jpg?size=1280x960&quality=96&proxy=1&sign=f5825d997937393a5c0a95c6775dce19&c_uniq_tag=2ulEOYXMOAN-KJm7HPNZYNcScyikyHdIsRmeqM8i16w&type=album"],
|
634
|
+
] ],
|
635
|
+
["https://vk.com/wall-123456091_7946?z=photo-123456091_457243312%2Falbum-123456091_00%2Frev", [1280, 875, "https://userapi.com/impf/c123456/v123456134/1b6b36/0IsDFb-Hda4.jpg"], "photos", [
|
636
|
+
[130, 89, "https://sun9-20.userapi.com/impf/c123456/v123456134/1b6b36/0IsDFb-Hda4.jpg?size=130x89&quality=96&sign=20f98d85da83704a93641c258dd9fb98&c_uniq_tag=PcNYWJFing2At2LiJVOYQOTUd_MbMLxiyPybwnyzaN4&type=album"],
|
637
|
+
[1280, 875, "https://sun9-20.userapi.com/impf/c123456/v123456134/1b6b36/0IsDFb-Hda4.jpg?size=1280x875&quality=96&proxy=1&sign=9b1e295c741c53b9485f4156da36ecde&c_uniq_tag=o7eFSi5F74SmkTirdrIS19nh8CEG32Od6yPvX9IPXds&type=album"],
|
638
|
+
] ],
|
639
|
+
["https://vk.com/id12345627?z=photo12345627_456241143%2Falbum12345627_0", [1920, 1440, "https://userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg"], "photos", [
|
640
|
+
[130, 97, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=130x98&quality=96&sign=5a7785886e75cde41f7ddc190775c941&c_uniq_tag=uJX7tU35qumnZFlAUe-EhyVVT1FDBoHmp_8Z-dFAH_I&type=album"],
|
641
|
+
[1920, 1440, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=1920x1440&quality=96&proxy=1&sign=56acc1844d38b491c1b2e4dbedd76ba4&c_uniq_tag=06VziJvbo7gkdo5t0AUEQRs6EX8UrmiT2XkfGRmfRz8&type=album"],
|
642
|
+
] ],
|
643
|
+
["https://vk.com/id12345627?z=photo12345627_456241143", [1920, 1440, "https://userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg"], "photos", [
|
644
|
+
[130, 97, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=130x98&quality=96&sign=5a7785886e75cde41f7ddc190775c941&c_uniq_tag=uJX7tU35qumnZFlAUe-EhyVVT1FDBoHmp_8Z-dFAH_I&type=album"],
|
645
|
+
[1920, 1440, "https://sun9-9.userapi.com/impf/c123456/v123456944/167836/bP9z41BybhI.jpg?size=1920x1440&quality=96&proxy=1&sign=56acc1844d38b491c1b2e4dbedd76ba4&c_uniq_tag=06VziJvbo7gkdo5t0AUEQRs6EX8UrmiT2XkfGRmfRz8&type=album"],
|
646
|
+
] ],
|
647
|
+
["https://vk.com/photo1_123187843?all=1", [2560, 1913, "https://userapi.com/impf/c123/v123001/6/53_VwoACy4I.jpg"], "photos", [
|
648
|
+
[130, 98, "https://sun1-23.userapi.com/impf/c123/v123001/6/53_VwoACy4I.jpg?size=130x97&quality=96&sign=f8f5b706de9bf4cba377c4192ca0faeb&c_uniq_tag=Hq3mDN7NbJvgRd82cKsQpJ45Tze8deKbUX4FZDwVZGQ&type=album"],
|
649
|
+
[2560, 1913, "https://sun1-23.userapi.com/impf/c123/v123001/6/53_VwoACy4I.jpg?size=2560x1913&quality=96&proxy=1&sign=c55f340348a35dd86542875a57ad8537&c_uniq_tag=yANq6f3QAVxu7M1xuy6fMu1JgkYOPqB1jBV4bQVjc0Y&type=album"],
|
650
|
+
] ],
|
651
|
+
["https://vk.com/photo123456340_456243948?rev=1", [1583, 1080, "https://userapi.com/impf/c123456/v123456479/321be/9rZaJ2QTdz4.jpg"], "photos", [
|
652
|
+
[130, 89, "https://sun9-21.userapi.com/impf/c123456/v123456479/321be/9rZaJ2QTdz4.jpg?size=130x89&quality=96&sign=4095eaa6d55dbb6af3a6d3baed593ecb&c_uniq_tag=9comrJGukZcMLlCDrmQMWhFtne217kVaZcafgoQmCVM&type=album"],
|
653
|
+
[1583, 1080, "https://sun9-21.userapi.com/impf/c123456/v123456479/321be/9rZaJ2QTdz4.jpg?size=1583x1080&quality=96&proxy=1&sign=27a9d92fcbd2cf748531a89278281cc3&c_uniq_tag=iwiLvdT52wwR8avHhjDUwPUozsvMpVyuFHHACavY2zA&type=album"],
|
654
|
+
] ],
|
655
|
+
["https://vk.com/photo-123456973_456242404", [1486, 1000, "https://userapi.com/impf/c123456/v123456877/8578e/m6AJWiskiKE.jpg"], "photos", [
|
656
|
+
[130, 87, "https://sun9-51.userapi.com/impf/c123456/v123456877/8578e/m6AJWiskiKE.jpg?size=130x87&quality=96&sign=c89c47cebc77fd0063dbe4891245aebe&c_uniq_tag=pSxKInGItqdMMW_83z9SXDzIi74Zl9UJ-P-snVmzHHY&type=album"],
|
657
|
+
[1486, 1000, "https://sun9-51.userapi.com/impf/c123456/v123456877/8578e/m6AJWiskiKE.jpg?size=1486x1000&quality=96&proxy=1&sign=f67bdef805a49775776ba9fe3ddddfdd&c_uniq_tag=2IwG6BAja36QQl3mDsUcWS6PC7ozt6TSExLsfRXRyzA&type=album"],
|
658
|
+
] ],
|
659
|
+
["https://vk.com/feed?section=likes&z=photo-123456754_456261460%2Fliked1234566", [1024, 1335, "https://userapi.com/impf/c123456/v123456353/895b6/izQJresLdf0.jpg"], "photos", [
|
660
|
+
[100, 130, "https://sun9-55.userapi.com/impf/c123456/v123456353/895b6/izQJresLdf0.jpg?size=100x130&quality=96&sign=56c2f6f2e772c5cac6e891d62c6c563e&c_uniq_tag=HHJ8PsYFgnwmuq9OfND51luLXJve81QbpWvudWXv5aw&type=album"],
|
661
|
+
[1024, 1335, "https://sun9-55.userapi.com/impf/c123456/v123456353/895b6/izQJresLdf0.jpg?size=1024x1335&quality=96&proxy=1&sign=b66a4c70eeb4083a05907e36d18cc481&c_uniq_tag=42fraqliOifFUG1CvgahG1lg1txVMF5hbSVlAUkLwf8&type=album"],
|
662
|
+
] ],
|
663
|
+
["https://vk.com/likizimy?z=photo-12345651_456239941%2Fwall-12345651_1908", [1179, 1731, "https://userapi.com/impf/c123456/v123456571/60f7b/ryCPJIMyMkI.jpg"], "photos", [
|
664
|
+
[89, 130, "https://sun9-37.userapi.com/impf/c123456/v123456571/60f7b/ryCPJIMyMkI.jpg?size=89x130&quality=96&sign=3ae95211e73168c7b66e12daa854f922&c_uniq_tag=uaDVTYCfixIN4JKSGzgNSTsjiuOUi0658_CgoIF-mqc&type=album"],
|
665
|
+
[1179, 1731, "https://sun9-37.userapi.com/impf/c123456/v123456571/60f7b/ryCPJIMyMkI.jpg?size=1179x1731&quality=96&proxy=1&sign=7930a6d1b4a88ce1fa4954fc6643d3e1&c_uniq_tag=rTxHctkqrP4SQsbcECYGDCVt03A43cLYRN8eTnOFtD0&type=album"],
|
666
|
+
] ],
|
667
|
+
["https://vk.com/e_rod?z=photo123456340_457247118%2Fphotos123456340", [1728, 2160, "https://userapi.com/impf/c123456/v123456596/c7714/oImGe4o1ZJI.jpg"], "photos", [
|
668
|
+
[104, 130, "https://sun9-53.userapi.com/impf/c123456/v123456596/c7714/oImGe4o1ZJI.jpg?size=104x130&quality=96&sign=6ad356e84dcd6bbf2069d9b869a7bdb1&c_uniq_tag=8KN44nSlDjD-FMDiRhHqk6udwiqZfn5n1qqPNFwu_nI&type=album"],
|
669
|
+
[1728, 2160, "https://sun9-53.userapi.com/impf/c123456/v123456596/c7714/oImGe4o1ZJI.jpg?size=1728x2160&quality=96&proxy=1&sign=c7961913ff3efd5064f2ed6c394288f2&c_uniq_tag=CA61KgCRsRXbHm4VJEYYskjpjpSiTHI7UPV4FsCPRmI&type=album"],
|
670
|
+
] ],
|
671
|
+
["https://vk.com/wasserman.anatoliy?w=wall-123457771_353", [864, 1080, "https://userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg"], "wall", [
|
672
|
+
[104, 130, "https://sun9-38.userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg?size=104x130&quality=96&sign=a6012bb508e208c7b2b22c42872215e4&c_uniq_tag=qX06fI2p7bmyvnta_Pt2omQ-l5RBLcrG1DBsLWx1jJA&type=album"],
|
673
|
+
[864, 1080, "https://sun9-38.userapi.com/impg/13456AABBCDDKKOQSTUWXZbcfghhhjlpqquwyz/z0UtQg2M1s4.jpg?size=864x1080&quality=96&sign=8f02c4c6794efd653ed79609bf0850c8&c_uniq_tag=6WP6TY0RTDiG_8NK1lkYUOge22jtjkzGLLwc6IDxjjg&type=album"],
|
674
|
+
] ],
|
675
|
+
].each_with_index do |(input, expectation, mtd, stub), i|
|
676
|
+
it "kinds of links" do
|
677
|
+
stub = {sizes: stub.map{ |w,h,u| {width: w, height: h, url: u} }}
|
678
|
+
stub_request(:post, "https://api.vk.com/method/#{mtd}.getById").to_return body: {response: [
|
679
|
+
mtd == "photos" ? stub : {attachments: [{type: :photo, photo: stub}]}
|
680
|
+
] }.to_json
|
681
|
+
result = DirectLink.method(:vk).call input
|
682
|
+
assert_equal 1, result.size
|
683
|
+
result[0][-1].tap do |url|
|
684
|
+
url.replace( URI.parse(url).tap do |_|
|
685
|
+
_.host = _.host.split(?.).drop(1).join(?.)
|
686
|
+
_.query = nil
|
687
|
+
end.to_s )
|
688
|
+
end
|
689
|
+
assert_equal [expectation], result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
|
690
|
+
end
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
describe "google" do
|
695
|
+
method = :google
|
696
|
+
[
|
697
|
+
"https://lh3.googleusercontent.com/-NVJgqmI_2Is/WqMM2OMYg-I/AAAAAAAALrk/5-p3JL3iZt0Ho9dOf_abcDE6zqwr3Wp0ACJoC/w424-h318-n/001",
|
698
|
+
"//lh3.googleusercontent.com/proxy/DZtTi5KL7PqiBwJc8weNGLk_Wi2UTaQH0AC_abcDE6iu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n",
|
699
|
+
"//1.bp.blogspot.com/-rYk_u-qROQc/WngolJ8M0LI/AAAAAAAAD-w/woivnaIVzasBPG5C2T1t-VrWKRd_abcDE6LcBGAs/w530-h278-p/i-469.jpg",
|
700
|
+
"https://2.bp.blogspot.com/-rb2PXLGZy0s/W2nQe3mXOSI/AAAAAAAARhQ/P8gV-abcDE62xxpTJNcYVxu3XDTUaugxQCLcBGAs/s640/beach-bora-bora-clouds-753626.jpg",
|
701
|
+
"http://4.bp.blogspot.com/-poH-QXn7YGg/U-3ZTDkeF_I/AAAAAAAAISE/mabcDE6-v-g/w72-h72-p-k-no-nu/Top-24-Inspired-181.jpg",
|
702
|
+
"https://lh5.googleusercontent.com/FcYUQBKLXWtFLEvbQduvu7FHUm2f7U_MVdMBVnNbpwfzKHIU-xABkudxw-abcDE60jFYRHedh7Is5Dg6qlgIQF1iSndlWjiKCTTsUo1w=s1080",
|
703
|
+
].each do |input|
|
704
|
+
it "DirectLink() choses a method '#{method}' according to a domain" do
|
705
|
+
DirectLink.stub method, ->(link, timeout = nil){
|
706
|
+
assert_equal input, link
|
707
|
+
throw :_
|
708
|
+
} do
|
709
|
+
catch :_ do
|
710
|
+
DirectLink input
|
711
|
+
fail "DirectLink.#{method} was not called"
|
712
|
+
end
|
713
|
+
end
|
714
|
+
end
|
715
|
+
end
|
716
|
+
end
|
717
|
+
|
718
|
+
{
|
719
|
+
imgur: [
|
720
|
+
[%w{ https://imgur.com/abcD5 https://imgur.com/abcD5 }, [
|
721
|
+
%w{ https://imgur.com/abcD5 },
|
722
|
+
] ],
|
723
|
+
[%w{ https://i.imgur.com/abcD5 https://imgur.com/abcD5 }, [
|
724
|
+
[*%w{ https://i.imgur.com/abcD5 https://imgur.com/abcD5 }, [302, "Moved Temporarily"]],
|
725
|
+
%w{ https://imgur.com/abcD5 },
|
726
|
+
] ],
|
727
|
+
[%w{ https://m.imgur.com/abcD5 https://imgur.com/abcD5 }, [
|
728
|
+
%w{ https://m.imgur.com/abcD5 https://imgur.com/abcD5 },
|
729
|
+
%w{ https://imgur.com/abcD5 },
|
730
|
+
] ],
|
731
|
+
[%w{ https://www.imgur.com/abcD5 https://imgur.com/abcD5 }, [
|
732
|
+
[*%w{ https://www.imgur.com/abcD5 https://imgur.com/abcD5 }, [301, "Moved Permanently"]],
|
733
|
+
%w{ https://imgur.com/abcD5 },
|
734
|
+
] ],
|
735
|
+
[%w{ https://goo.gl/abcDE6 https://i.imgur.com/abcDEFY.png }, [
|
736
|
+
%w{ https://goo.gl/abcDE6 https://i.imgur.com/abcDEFY.png },
|
737
|
+
%w{ https://i.imgur.com/abcDEFY.png },
|
738
|
+
] ],
|
739
|
+
],
|
740
|
+
_500px: [
|
741
|
+
[%w{ https://500px.com/photo/123456789/milky-way https://500px.com/photo/123456789/milky-way }, [
|
742
|
+
%w{ https://500px.com/photo/123456789/milky-way },
|
743
|
+
] ],
|
744
|
+
],
|
745
|
+
flickr: [
|
746
|
+
["https://www.flickr.com/photos/12345678@N07/12345678901/in/dateposted-public/", [
|
747
|
+
["https://www.flickr.com/photos/12345678@N07/12345678901/in/dateposted-public/"],
|
748
|
+
] ],
|
749
|
+
[["https://flic.kr/p/abcDEF", "https://www.flickr.com/photos/lopez/12345678901/"], [
|
750
|
+
["https://flic.kr/p/abcDEF", "https://www.flickr.com/photo.gne?short=abcDEF"],
|
751
|
+
["https://www.flickr.com/photo.gne?short=abcDEF", "/photo.gne?rb=1&short=abcDEF"],
|
752
|
+
["https://www.flickr.com/photo.gne?rb=1&short=abcDEF", "/photos/lopez/12345678901/"],
|
753
|
+
["https://www.flickr.com/photos/lopez/12345678901/"],
|
754
|
+
] ],
|
755
|
+
],
|
756
|
+
wiki: [
|
757
|
+
["https://en.wikipedia.org/wiki/Third_Party_System#/media/File:United_States_presidential_election_results,_1876-1892.svg", [
|
758
|
+
%w{ https://en.wikipedia.org/wiki/Third_Party_System },
|
759
|
+
] ],
|
760
|
+
[%w{ http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg https://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg }, [
|
761
|
+
%w{ http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg https://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg },
|
762
|
+
%w{ https://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg }
|
763
|
+
] ],
|
764
|
+
],
|
765
|
+
reddit: [
|
766
|
+
[%w{ https://www.reddit.com/r/abcdef/comments/abcde6/c/ }, [
|
767
|
+
%w{ https://www.reddit.com/r/abcdef/comments/abcde6/c/ },
|
768
|
+
] ],
|
769
|
+
[%w{ http://redd.it/abcde6 https://www.reddit.com/comments/abcde6 }, [
|
770
|
+
[*%w{ http://redd.it/abcde6 https://redd.it/abcde6 }, [301, "Moved Permanently"]],
|
771
|
+
[*%w{ https://redd.it/abcde6 https://www.reddit.com/comments/abcde6 }, [302, "Temporarily Moved"]],
|
772
|
+
%w{ https://www.reddit.com/comments/abcde6 },
|
773
|
+
] ],
|
774
|
+
[%w{ https://reddit.com/123456 https://www.reddit.com/r/funny/comments/123456/im_thinking/ }, [
|
775
|
+
[*%w{ https://reddit.com/123456 https://www.reddit.com/123456 }, [301, "Moved Permanently"]],
|
776
|
+
[*%w{ https://www.reddit.com/123456 https://www.reddit.com/r/funny/comments/123456/im_thinking/ }, [301, "Moved Permanently"]],
|
777
|
+
%w{ https://www.reddit.com/r/funny/comments/123456/im_thinking/ },
|
778
|
+
] ],
|
779
|
+
[%w{ https://www.reddit.com/r/abcDEF/comments/abcde6/beard_trimmer/ }, [
|
780
|
+
%w{ https://www.reddit.com/r/abcDEF/comments/abcde6/beard_trimmer/ }
|
781
|
+
] ], # NSFW causes redirect to /over_18? if the special cookie not provided # TODO: improve this test
|
782
|
+
],
|
783
|
+
vk: [
|
784
|
+
["https://vk.com/id12345678?z=photo12345678_456241143", [
|
785
|
+
["https://vk.com/id12345678?z=photo12345678_456241143", nil, [418, ""]],
|
786
|
+
] ],
|
787
|
+
],
|
788
|
+
}.each do |method, tests|
|
789
|
+
describe "DirectLink() choses a method '#{method}' according to a domain" do
|
790
|
+
tests.each_with_index do |((input, expected), stub), i|
|
791
|
+
it "##{i + 1}" do
|
792
|
+
DirectLink.stub method, ->(link, timeout = nil, **__){
|
793
|
+
assert_equal (expected || input), link
|
794
|
+
throw :_
|
795
|
+
} do
|
796
|
+
(stub || []).each do |u, o, code|
|
797
|
+
if o
|
798
|
+
stub_request(:head, u).to_return status: (code || [302, "Found"]), headers: {location: o}
|
799
|
+
else
|
800
|
+
if code
|
801
|
+
stub_request(:head, u).to_return status: code
|
802
|
+
else
|
803
|
+
stub_request(:head, u)
|
804
|
+
end
|
805
|
+
end
|
806
|
+
end
|
807
|
+
catch :_ do
|
808
|
+
DirectLink input
|
809
|
+
fail "DirectLink.#{method} was not called"
|
810
|
+
end
|
811
|
+
end
|
812
|
+
end
|
813
|
+
end
|
814
|
+
end
|
815
|
+
end
|
816
|
+
|
817
|
+
# TODO: make a Reddit describe
|
818
|
+
it "retries limited amount of times on error JSON::ParserError" do
|
819
|
+
# TODO: the same but with the error expected to be gone after tries
|
820
|
+
stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: '{"access_token": "123456789000-17BDFFGGJJKNPVXZlt-2ACKQZfoswz", "token_type": "bearer", "expires_in": 3600, "scope": "*"}'
|
821
|
+
stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde6?api_type=json").to_return body: "invalid JSON"
|
822
|
+
tries = 0
|
823
|
+
m = JSON.method :load
|
824
|
+
e = assert_raises DirectLink::ErrorBadLink do
|
825
|
+
JSON.stub :load, ->*_,**__{ tries += 1; m.call *_,**__ } do
|
826
|
+
DirectLink.reddit "https://www.reddit.com/r/gifs/comments/abcde6/", 2.5
|
827
|
+
end
|
828
|
+
end
|
829
|
+
assert_instance_of JSON::ParserError, e.cause if Exception.instance_methods.include? :cause # Ruby 2.1
|
830
|
+
assert (3 <= tries)
|
831
|
+
assert (tries <= 4)
|
832
|
+
end
|
833
|
+
|
834
|
+
it "Reddit correctly parses out id when no token provided" do
|
835
|
+
stub_request(:head, "https://www.reddit.com/r/gifs/comments/9ftc8f/")
|
836
|
+
m = NetHTTPUtils.method :request_data
|
837
|
+
NetHTTPUtils.stub :request_data, lambda{ |u, *args, **kwargs|
|
838
|
+
throw :_ if u == "https://www.reddit.com/9ftc8f.json"
|
839
|
+
m.call u, *args, **kwargs
|
840
|
+
} do
|
841
|
+
t = ENV.delete "REDDIT_SECRETS"
|
842
|
+
begin
|
843
|
+
catch :_ do
|
844
|
+
DirectLink "https://www.reddit.com/r/gifs/comments/9ftc8f/"
|
845
|
+
fail
|
846
|
+
end
|
847
|
+
ensure
|
848
|
+
ENV["REDDIT_SECRETS"] = t
|
849
|
+
end
|
850
|
+
end
|
851
|
+
end
|
852
|
+
|
853
|
+
describe "throws ErrorBadLink if method does not match the link" do
|
854
|
+
%i{ google imgur flickr _500px wiki reddit vk }.each do |method|
|
855
|
+
["", "test", "http://example.com/"].each_with_index do |url, i|
|
856
|
+
it "#{method} ##{i + 1}" do
|
857
|
+
assert_raises DirectLink::ErrorBadLink do
|
858
|
+
DirectLink.method(method).call url
|
859
|
+
end
|
860
|
+
end
|
861
|
+
end
|
862
|
+
end
|
863
|
+
end
|
864
|
+
|
865
|
+
end
|
866
|
+
|
867
|
+
describe "DirectLink()" do
|
868
|
+
|
869
|
+
# thanks to gem addressable
|
870
|
+
it "does not throw URI::InvalidURIError if there are brackets" do
|
871
|
+
stub_request(:head, "https://www.flickr.com/photos/nakilon/12345678900/%2520%5B2048x1152%5D").to_return status: [404, "Not Found"]
|
872
|
+
assert_equal 404, (
|
873
|
+
assert_raises NetHTTPUtils::Error do
|
874
|
+
DirectLink "https://www.flickr.com/photos/nakilon/12345678900/%20[2048x1152]"
|
875
|
+
end.code
|
876
|
+
)
|
877
|
+
end
|
878
|
+
|
879
|
+
it "throws ErrorNotFound when Reddit gallery is removed" do
|
880
|
+
stub_request(:head, "https://www.reddit.com/gallery/abcde6")
|
881
|
+
stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: {"access_token"=>"123456789012-abcde6cOO5V20ZD6J8WC6l36gMYRXQ"}.to_json
|
882
|
+
stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde6?api_type=json").to_return body: {
|
883
|
+
"data"=>{
|
884
|
+
"children"=>[{
|
885
|
+
"data"=>{
|
886
|
+
"selftext"=>"[удалено]",
|
887
|
+
"media_metadata"=>nil,
|
888
|
+
"is_self"=>false,
|
889
|
+
"permalink"=>"/r/woahdude/comments/abcde6/crystal_light/",
|
890
|
+
"url"=>"https://www.reddit.com/gallery/abcde6",
|
891
|
+
"media"=>nil
|
892
|
+
}
|
893
|
+
}]
|
894
|
+
}
|
895
|
+
}.to_json
|
896
|
+
assert_raises DirectLink::ErrorNotFound do
|
897
|
+
DirectLink "https://www.reddit.com/gallery/abcde6"
|
898
|
+
end
|
899
|
+
end
|
900
|
+
|
901
|
+
it "follows Reddit crosspost" do
|
902
|
+
stub_request(:head, "https://www.reddit.com/abcde6").to_return status: [301, "Moved Permanently"], headers: {location: "https://www.reddit.com/r/wallpapers/comments/abcde6/new_wallpaper/"}
|
903
|
+
stub_request(:head, "https://www.reddit.com/r/wallpapers/comments/abcde6/new_wallpaper/")
|
904
|
+
stub_request(:post, "https://www.reddit.com/api/v1/access_token").to_return body: {"access_token"=>"123456789012-abcde6WGKuIupoi5M3NtPVdI7bk1jg"}.to_json
|
905
|
+
stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde6?api_type=json").to_return body: {
|
906
|
+
"data"=>{
|
907
|
+
"children"=>[{
|
908
|
+
"data"=>{
|
909
|
+
"selftext"=>"",
|
910
|
+
"is_self"=>false,
|
911
|
+
"crosspost_parent"=>"t3_abcde7",
|
912
|
+
"permalink"=>"/r/wallpapers/comments/abcde6/new_wallpaper/",
|
913
|
+
"url"=>"/r/Firewatch/comments/abcde7/new_wallpaper/",
|
914
|
+
"media"=>nil,
|
915
|
+
}
|
916
|
+
}]
|
917
|
+
}
|
918
|
+
}.to_json
|
919
|
+
stub_request(:head, "https://www.reddit.com/r/Firewatch/comments/abcde7/new_wallpaper/")
|
920
|
+
stub_request(:get, "https://oauth.reddit.com/by_id/t3_abcde7?api_type=json").to_return body: {
|
921
|
+
"data"=>{
|
922
|
+
"children"=>[{
|
923
|
+
"data"=>{
|
924
|
+
"selftext"=>"I",
|
925
|
+
"media_metadata"=>{
|
926
|
+
"abcde62zhek51"=>{
|
927
|
+
"status"=>"valid",
|
928
|
+
"m"=>"image/png",
|
929
|
+
"s"=>{"y"=>1920, "x"=>4920, "u"=>"asd"},
|
930
|
+
},
|
931
|
+
"abcde72zhek51"=>{
|
932
|
+
"status"=>"valid",
|
933
|
+
"m"=>"image/png",
|
934
|
+
"s"=>{"y"=>1920, "x"=>4920, "u"=>"asd"},
|
935
|
+
}
|
936
|
+
},
|
937
|
+
"is_self"=>true,
|
938
|
+
"media"=>nil,
|
939
|
+
"permalink"=>"/r/Firewatch/comments/abcde7/new_wallpaper/",
|
940
|
+
"url"=>"https://www.reddit.com/r/Firewatch/comments/abcde7/new_wallpaper/",
|
941
|
+
}
|
942
|
+
}],
|
943
|
+
}
|
944
|
+
}.to_json
|
945
|
+
assert_equal %w{ image/png image/png }, DirectLink("https://www.reddit.com/abcde6").map(&:type)
|
946
|
+
end
|
947
|
+
|
948
|
+
it "throws ErrorBadLink if link is invalid" do
|
949
|
+
assert_equal "test".inspect, (
|
950
|
+
assert_raises DirectLink::ErrorBadLink do
|
951
|
+
DirectLink "test"
|
952
|
+
end
|
953
|
+
).message
|
954
|
+
end
|
955
|
+
|
956
|
+
describe "does not shadow the internal exception" do
|
957
|
+
[
|
958
|
+
SocketError,
|
959
|
+
Errno::ECONNRESET,
|
960
|
+
].each do |exception|
|
961
|
+
it "raises #{exception} from the redirect resolving stage" do
|
962
|
+
assert_raises exception do
|
963
|
+
NetHTTPUtils.stub :request_data, ->*{ raise exception.new } do
|
964
|
+
DirectLink "http://example.com/404"
|
965
|
+
end
|
966
|
+
end
|
967
|
+
end
|
968
|
+
end
|
969
|
+
it "raises Net::OpenTimeout -- server side issues can happen (not related to User Agent)" do
|
970
|
+
assert_raises Net::OpenTimeout do
|
971
|
+
NetHTTPUtils.stub :request_data, ->*{ raise Net::OpenTimeout.new } do
|
972
|
+
DirectLink "http://example.com/404"
|
973
|
+
end
|
974
|
+
end
|
975
|
+
end
|
976
|
+
it "HEAD Errno::ETIMEDOUT and GET FastImage::ImageFetchFailure are handled by DirectLink::NORMAL_EXCEPTIONS" do
|
977
|
+
assert_includes DirectLink::NORMAL_EXCEPTIONS, FastImage::ImageFetchFailure
|
978
|
+
assert_raises FastImage::ImageFetchFailure do
|
979
|
+
NetHTTPUtils.stub :request_data, ->_,mtd,*{ fail unless mtd == :HEAD; raise Errno::ETIMEDOUT } do
|
980
|
+
FastImage.stub :new, ->*{ raise FastImage::ImageFetchFailure } do
|
981
|
+
DirectLink "http://www.mesacc.edu/~hello12345/hello/images/photos/aerial/a1234.jpg"
|
982
|
+
end
|
983
|
+
end
|
984
|
+
end
|
985
|
+
end
|
986
|
+
[ # TODO this URLs may be reused from tests that check that this method calls internal method
|
987
|
+
[:google, "//lh3.googleusercontent.com/proxy/578BDGJKLLNPTZceiikqtww_Wi2UTaQH0AC_h2kuURiu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n"],
|
988
|
+
[:imgur, "http://imgur.com/ABCDEFG"],
|
989
|
+
[:flickr, "https://www.flickr.com/photos/12345678@N00/00013355778/"],
|
990
|
+
[:_500px, "https://500px.com/photo/123456789/milky-way"],
|
991
|
+
[:wiki, "http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg"],
|
992
|
+
[:reddit, "https://www.reddit.com/123456"],
|
993
|
+
[:vk, "https://vk.com/"],
|
994
|
+
].each do |method, link|
|
995
|
+
it "can otherwise raise DirectLink::ErrorBadLink #{method}" do
|
996
|
+
stub_request(:head, link)
|
997
|
+
e = assert_raises(DirectLink::ErrorBadLink, link) do
|
998
|
+
DirectLink.stub method, ->*{ raise DirectLink::ErrorBadLink.new "test" } do
|
999
|
+
DirectLink link
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
assert_equal "\"test\" -- if you think this link is valid, please report the issue", e.message
|
1003
|
+
end
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
describe "other domains tests" do
|
1008
|
+
[
|
1009
|
+
["http://www.cute.org/wp-content/uploads/2010/10/Niagara.jpg", SocketError, /nodename nor servname provided, or not known|Name or service not known|getaddrinfo: Name does not resolve/, 0],
|
1010
|
+
].each_with_index do |(input, expectation, message_string_or_regex, max_redirect_resolving_retry_delay), i|
|
1011
|
+
it "##{i + 1}" do
|
1012
|
+
if expectation.is_a? Class
|
1013
|
+
# TODO: move the stub to the array above
|
1014
|
+
stub_request(:head, input).to_raise expectation.new("Failed to open TCP connection to www.cute.org:80 (getaddrinfo: nodename nor servname provided, or not known)")
|
1015
|
+
e = assert_raises expectation, "for #{input}" do
|
1016
|
+
DirectLink input, max_redirect_resolving_retry_delay
|
1017
|
+
end
|
1018
|
+
if message_string_or_regex.is_a? String
|
1019
|
+
assert_equal message_string_or_regex, e.message, "for #{input}"
|
1020
|
+
else
|
1021
|
+
assert_match message_string_or_regex, e.message, "for #{input}"
|
1022
|
+
end
|
1023
|
+
else
|
1024
|
+
u, w, h, t = expectation
|
1025
|
+
result = DirectLink input, max_redirect_resolving_retry_delay
|
1026
|
+
assert_equal DirectLink.class_variable_get(:@@directlink).new(u, w, h, t), result, "for #{input}"
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
end
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
describe "giving up" do
|
1033
|
+
[
|
1034
|
+
[
|
1035
|
+
["http://example.com", FastImage::UnknownImageType],
|
1036
|
+
[
|
1037
|
+
[:get, "http://example.com", {body: "<!doctype html><html><head><title>Example Domain</title><meta charset='utf-8'/></head><body><div><h1>Example Domain</h1><p>Lorem ipsum.</p></div></body></html>"}],
|
1038
|
+
],
|
1039
|
+
],
|
1040
|
+
[
|
1041
|
+
["http://imgur.com/QWERTYU", FastImage::UnknownImageType, true],
|
1042
|
+
[
|
1043
|
+
[:get, "http://imgur.com/QWERTYU", {status: [301, "Moved Permanently"], headers: {location: "https://imgur.com/QWERTYU"}}],
|
1044
|
+
[:get, "https://imgur.com/QWERTYU", {body: "<html><body></body></html>"}],
|
1045
|
+
],
|
1046
|
+
],
|
1047
|
+
[
|
1048
|
+
["http://imgur.com/QWERTYU", "https://i.imgur.com/QWERTYU.jpeg?fb"], # .at_css("meta[@property='og:image']")
|
1049
|
+
[
|
1050
|
+
[:head, "http://imgur.com/QWERTYU", {status: [301, "Moved Permanently"], headers: {Location: "https://imgur.com/QWERTYU"}}],
|
1051
|
+
[:get, "http://imgur.com/QWERTYU", {status: [301, "Moved Permanently"], headers: {Location: "https://imgur.com/QWERTYU"}}],
|
1052
|
+
[:head, "https://imgur.com/QWERTYU", {headers: {"Content-Type"=>"text/html"}}],
|
1053
|
+
[:get, "https://imgur.com/QWERTYU", {body: <<~HEREDOC
|
1054
|
+
<html>
|
1055
|
+
<head>
|
1056
|
+
<meta property="og:url" data-react-helmet="true" content="https://imgur.com/QWERTYU">
|
1057
|
+
<meta name="twitter:image" data-react-helmet="true" content="https://i.imgur.com/QWERTYUh.jpg">
|
1058
|
+
<meta property="og:image:width" data-react-helmet="true" content="1">
|
1059
|
+
<meta property="og:image:height" data-react-helmet="true" content="2">
|
1060
|
+
<meta property="og:image" data-react-helmet="true" content="https://i.imgur.com/QWERTYU.jpeg?fb">
|
1061
|
+
<meta property="og:type" data-react-helmet="true" content="article">
|
1062
|
+
</head>
|
1063
|
+
<body></body>
|
1064
|
+
</html>
|
1065
|
+
HEREDOC
|
1066
|
+
} ],
|
1067
|
+
[:head, "https://i.imgur.com/QWERTYU.jpeg?fb"],
|
1068
|
+
[:get, "https://i.imgur.com/QWERTYU.jpeg?fb", {body: "\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xFF\xDB\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\b\x06\x06\x05\x06\t\b\n\n\t\b\t\t\n\f\x0F\f\n\v\x0E\v\t\t\r\x11\r\x0E\x0F\x10\x10\x11\x10\n\f\x12\x13\x12\x10\x13\x0F\x10\x10\x10\xFF\xC9\x00\v\b\x00\x01\x00\x01\x01\x01\x11\x00\xFF\xCC\x00\x06\x00\x10\x10\x05\xFF\xDA\x00\b\x01\x01\x00\x00?\x00\xD2\xCF \xFF\xD9"}],
|
1069
|
+
],
|
1070
|
+
],
|
1071
|
+
[
|
1072
|
+
["https://www.deviantart.com/nakilon/art/Nakilon-123456789", FastImage::UnknownImageType, true],
|
1073
|
+
[
|
1074
|
+
[:get, "https://www.deviantart.com/nakilon/art/Nakilon-123456789", {body: <<~HEREDOC
|
1075
|
+
<html>
|
1076
|
+
<head>
|
1077
|
+
<meta data-rh="true" property="og:image" content="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/>
|
1078
|
+
</head>
|
1079
|
+
<body class="theme-dark">
|
1080
|
+
<div id="root">
|
1081
|
+
<main role="main" class="_1TdPo">
|
1082
|
+
<div class="_3tEjH">
|
1083
|
+
<div><img alt="Nakilon" aria-hidden="true" class="_1izoQ" src="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/></div>
|
1084
|
+
</div>
|
1085
|
+
</main>
|
1086
|
+
</div>
|
1087
|
+
</body>
|
1088
|
+
</html>
|
1089
|
+
HEREDOC
|
1090
|
+
} ],
|
1091
|
+
],
|
1092
|
+
],
|
1093
|
+
[
|
1094
|
+
["https://www.deviantart.com/nakilon/art/Nakilon-123456789", "https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"],
|
1095
|
+
[
|
1096
|
+
[:head, "https://www.deviantart.com/nakilon/art/Nakilon-123456789", {headers: {"Content-Type"=>"text/html; charset=utf-8"}}],
|
1097
|
+
[:get, "https://www.deviantart.com/nakilon/art/Nakilon-123456789", {body: <<~HEREDOC
|
1098
|
+
<html>
|
1099
|
+
<head>
|
1100
|
+
<meta data-rh="true" property="og:image" content="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/>
|
1101
|
+
</head>
|
1102
|
+
<body class="theme-dark">
|
1103
|
+
<div id="root">
|
1104
|
+
<main role="main" class="_1TdPo">
|
1105
|
+
<div class="_3tEjH">
|
1106
|
+
<div><img alt="Nakilon" aria-hidden="true" class="_1izoQ" src="https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"/></div>
|
1107
|
+
</div>
|
1108
|
+
</main>
|
1109
|
+
</div>
|
1110
|
+
</body>
|
1111
|
+
</html>
|
1112
|
+
HEREDOC
|
1113
|
+
} ],
|
1114
|
+
[:head, "https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01"],
|
1115
|
+
[:get, "https://images-wixmp-abc456.wixmp.com/f/abc456-abc456/abc456-abc456.jpg/v1/fill/w_1024,h_732,q_75,strp/nakilon.jpg?token=abCD01.abCD01.abCD01_abCD01_abCD01", {body: "\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xFF\xDB\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\b\x06\x06\x05\x06\t\b\n\n\t\b\t\t\n\f\x0F\f\n\v\x0E\v\t\t\r\x11\r\x0E\x0F\x10\x10\x11\x10\n\f\x12\x13\x12\x10\x13\x0F\x10\x10\x10\xFF\xC9\x00\v\b\x00\x01\x00\x01\x01\x01\x11\x00\xFF\xCC\x00\x06\x00\x10\x10\x05\xFF\xDA\x00\b\x01\x01\x00\x00?\x00\xD2\xCF \xFF\xD9"}],
|
1116
|
+
],
|
1117
|
+
],
|
1118
|
+
# TODO: og:image without scheme
|
1119
|
+
[
|
1120
|
+
["https://www.reddit.com/r/darksouls3/comments/qwe123/hand/", DirectLink::ErrorBadLink, true],
|
1121
|
+
[
|
1122
|
+
[:head, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {location: "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
|
1123
|
+
[:head, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"],
|
1124
|
+
[:get, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {"Location"=>"https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
|
1125
|
+
[:get, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json", {body: <<~HEREDOC
|
1126
|
+
[
|
1127
|
+
{
|
1128
|
+
"data" : {
|
1129
|
+
"before" : null,
|
1130
|
+
"children" : [
|
1131
|
+
{
|
1132
|
+
"data" : {
|
1133
|
+
"selftext" : "[A](https://imgur.com/a/abcDEF1). I \\n [Here](https://imgur.com/a/abcDEF2)\\n\\nMobile: https://imgur.com/a/abcDEF3",
|
1134
|
+
"id" : "qwe123",
|
1135
|
+
"name" : "t3_qwe123",
|
1136
|
+
"is_self" : true,
|
1137
|
+
"media" : null,
|
1138
|
+
"permalink" : "/r/darksouls3/comments/qwe123/hand/",
|
1139
|
+
"over_18" : false,
|
1140
|
+
"url" : "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/"
|
1141
|
+
},
|
1142
|
+
"kind" : "t3"
|
1143
|
+
}
|
1144
|
+
]
|
1145
|
+
}
|
1146
|
+
}, {}
|
1147
|
+
]
|
1148
|
+
HEREDOC
|
1149
|
+
} ],
|
1150
|
+
],
|
1151
|
+
],
|
1152
|
+
[
|
1153
|
+
["https://www.reddit.com/r/darksouls3/comments/qwe123/hand/", 6], # TODO: should see the 3rd album too
|
1154
|
+
[
|
1155
|
+
[:head, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {location: "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
|
1156
|
+
[:head, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"],
|
1157
|
+
[:get, "https://www.reddit.com/qwe123.json", {status: [301, "Moved Permanently"], headers: {Location: "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json"}}],
|
1158
|
+
[:get, "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/.json", {body: <<~HEREDOC
|
1159
|
+
[
|
1160
|
+
{
|
1161
|
+
"data" : {
|
1162
|
+
"before" : null,
|
1163
|
+
"children" : [
|
1164
|
+
{
|
1165
|
+
"data" : {
|
1166
|
+
"selftext" : "[A](https://imgur.com/a/abcDEF1). I \\n [Here](https://imgur.com/a/abcDEF2)\\n\\nMobile: https://imgur.com/a/abcDEF3",
|
1167
|
+
"id" : "qwe123",
|
1168
|
+
"name" : "t3_qwe123",
|
1169
|
+
"is_self" : true,
|
1170
|
+
"media" : null,
|
1171
|
+
"permalink" : "/r/darksouls3/comments/qwe123/hand/",
|
1172
|
+
"over_18" : false,
|
1173
|
+
"url" : "https://www.reddit.com/r/darksouls3/comments/qwe123/hand/"
|
1174
|
+
},
|
1175
|
+
"kind" : "t3"
|
1176
|
+
}
|
1177
|
+
]
|
1178
|
+
}
|
1179
|
+
}, {}
|
1180
|
+
]
|
1181
|
+
HEREDOC
|
1182
|
+
} ],
|
1183
|
+
[:head, "https://imgur.com/a/abcDEF1"],
|
1184
|
+
[:head, "https://api.imgur.com/3/album/abcDEF1/0.json"],
|
1185
|
+
[:get, "https://api.imgur.com/3/album/abcDEF1/0.json", {body: <<~HEREDOC
|
1186
|
+
{
|
1187
|
+
"status" : 200,
|
1188
|
+
"success" : true,
|
1189
|
+
"data" : {
|
1190
|
+
"id" : "abcDEF1",
|
1191
|
+
"link" : "https://imgur.com/a/abcDEF1",
|
1192
|
+
"images" : [
|
1193
|
+
{
|
1194
|
+
"link" : "https://i.imgur.com/abcDEF4.png",
|
1195
|
+
"type" : "image/png",
|
1196
|
+
"height" : 1080,
|
1197
|
+
"width" : 1920
|
1198
|
+
},
|
1199
|
+
{
|
1200
|
+
"link" : "https://i.imgur.com/abcDEF5.png",
|
1201
|
+
"type" : "image/png",
|
1202
|
+
"height" : 1080,
|
1203
|
+
"width" : 1920
|
1204
|
+
}
|
1205
|
+
]
|
1206
|
+
}
|
1207
|
+
}
|
1208
|
+
HEREDOC
|
1209
|
+
} ],
|
1210
|
+
[:head, "https://imgur.com/a/abcDEF2"],
|
1211
|
+
[:head, "https://api.imgur.com/3/album/abcDEF2/0.json"],
|
1212
|
+
[:get, "https://api.imgur.com/3/album/abcDEF2/0.json", {body: <<~HEREDOC
|
1213
|
+
{
|
1214
|
+
"status" : 200,
|
1215
|
+
"success" : true,
|
1216
|
+
"data" : {
|
1217
|
+
"id" : "abcDEF2",
|
1218
|
+
"link" : "https://imgur.com/a/abcDEF2",
|
1219
|
+
"images" : [
|
1220
|
+
{
|
1221
|
+
"link" : "https://i.imgur.com/abcDEF6.png",
|
1222
|
+
"type" : "image/png",
|
1223
|
+
"height" : 1080,
|
1224
|
+
"width" : 1920
|
1225
|
+
},
|
1226
|
+
{
|
1227
|
+
"link" : "https://i.imgur.com/abcDEF7.jpg",
|
1228
|
+
"type" : "image/jpeg",
|
1229
|
+
"height" : 1080,
|
1230
|
+
"width" : 1920
|
1231
|
+
},
|
1232
|
+
{
|
1233
|
+
"link" : "https://i.imgur.com/abcDEF8.jpg",
|
1234
|
+
"type" : "image/jpeg",
|
1235
|
+
"height" : 1080,
|
1236
|
+
"width" : 1920
|
1237
|
+
},
|
1238
|
+
{
|
1239
|
+
"link" : "https://i.imgur.com/abcDEF9.jpg",
|
1240
|
+
"type" : "image/jpeg",
|
1241
|
+
"height" : 1080,
|
1242
|
+
"width" : 1920
|
1243
|
+
}
|
1244
|
+
]
|
1245
|
+
}
|
1246
|
+
}
|
1247
|
+
HEREDOC
|
1248
|
+
} ],
|
1249
|
+
],
|
1250
|
+
],
|
1251
|
+
].each do |(input, expectation, giveup), stubs|
|
1252
|
+
it "#{URI(input).host} giveup=#{!!giveup}" do
|
1253
|
+
stub_request(:head, input)
|
1254
|
+
stubs.each do |mtd, link, response|
|
1255
|
+
if response
|
1256
|
+
stub_request(mtd, link).to_return **response
|
1257
|
+
else
|
1258
|
+
stub_request(mtd, link)
|
1259
|
+
end
|
1260
|
+
end
|
1261
|
+
ti = ENV.delete "IMGUR_CLIENT_ID" if %w{ imgur com } == URI(input).host.split(?.).last(2)
|
1262
|
+
tr = ENV.delete "REDDIT_SECRETS" if %w{ reddit com } == URI(input).host.split(?.).last(2)
|
1263
|
+
begin
|
1264
|
+
case expectation
|
1265
|
+
when Class
|
1266
|
+
e = assert_raises expectation, "for #{input} (giveup = #{giveup})" do
|
1267
|
+
DirectLink input, 5, giveup: giveup
|
1268
|
+
end
|
1269
|
+
assert_equal expectation.to_s, e.class.to_s, "for #{input} (giveup = #{giveup})"
|
1270
|
+
when String
|
1271
|
+
result = DirectLink input, 5, giveup: giveup
|
1272
|
+
assert_equal expectation, result.url, "for #{input} (giveup = #{giveup})"
|
1273
|
+
else
|
1274
|
+
result = DirectLink input, 5, giveup: giveup
|
1275
|
+
result = [result] unless result.is_a? Array # we can't do `Array(<Struct>)` because it splats by elements
|
1276
|
+
assert_equal expectation, result.size, ->{
|
1277
|
+
"for #{input} (giveup = #{giveup}): #{result.map &:url}"
|
1278
|
+
}
|
1279
|
+
end
|
1280
|
+
ensure
|
1281
|
+
ENV["IMGUR_CLIENT_ID"] = ti if ti
|
1282
|
+
ENV["REDDIT_SECRETS"] = tr if tr
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
end
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
end
|
1289
|
+
|
1290
|
+
describe "./bin" do
|
1291
|
+
require "open3"
|
1292
|
+
|
1293
|
+
describe "shows usage help if misused" do
|
1294
|
+
[
|
1295
|
+
[/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, nil],
|
1296
|
+
[/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "-h"],
|
1297
|
+
[/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "--help"],
|
1298
|
+
[/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "-v"],
|
1299
|
+
[/\Ausage: directlink \[--debug\] \[--json\] \[--github\] \[--ignore-meta\] <link1> <link2> <link3> \.\.\.\ndirectlink version \d\.\d\.\d\d?\.\d\d? \(https:\/\/github\.com\/nakilon\/directlink\)\n\z/, "--version"],
|
1300
|
+
["DirectLink::ErrorBadLink: \"--\"\n", "--"],
|
1301
|
+
["DirectLink::ErrorBadLink: \"-\"\n", "-"],
|
1302
|
+
["DirectLink::ErrorBadLink: \"-\"\n", "- -"],
|
1303
|
+
["DirectLink::ErrorBadLink: \"asd\"\n", "asd"],
|
1304
|
+
].each_with_index do |(expectation, param), i|
|
1305
|
+
it "##{i + 1}" do
|
1306
|
+
string, status = Open3.capture2e "RUBYOPT='-rbundler/setup' ./bin/directlink #{param}"
|
1307
|
+
if expectation.is_a? String
|
1308
|
+
assert_equal expectation, string
|
1309
|
+
else
|
1310
|
+
assert_match expectation, string
|
1311
|
+
end
|
1312
|
+
assert_equal 1, status.exitstatus
|
1313
|
+
end
|
1314
|
+
end
|
1315
|
+
end
|
1316
|
+
|
1317
|
+
# that hack around `export` is for crossplatform Travis test, since Ubuntu uses `sh` that can't `source`
|
1318
|
+
# TODO: but maybe I could make Open3 use the shell I need, since `source` works fine for `.travis.yaml`'s `:script`
|
1319
|
+
|
1320
|
+
popen = lambda do |input, stubs, export = nil, param = nil|
|
1321
|
+
file = Tempfile.new %w{ directlink_webmock .rb }
|
1322
|
+
file.write <<~HEREDOC
|
1323
|
+
require "webmock"
|
1324
|
+
include WebMock::API
|
1325
|
+
WebMock.enable!
|
1326
|
+
require "#{__dir__}/webmock_patch"
|
1327
|
+
#{stubs.inspect}.each do |mtd, input, response|
|
1328
|
+
if response
|
1329
|
+
stub_request(mtd, input).to_return **response
|
1330
|
+
else
|
1331
|
+
stub_request(mtd, input)
|
1332
|
+
end
|
1333
|
+
end
|
1334
|
+
HEREDOC
|
1335
|
+
file.flush
|
1336
|
+
begin
|
1337
|
+
Open3.capture2e "#{"export #{File.read("api_tokens.sh").scan(/(?<=^export )\S+=\S+/).join(" ")} && " if export}RUBYOPT='-r bundler/setup #{$-I.map{ |i| "-I #{i}" }.join " "} -r #{file.path}' ./bin/directlink#{" --#{param}" if param} #{input}"
|
1338
|
+
ensure
|
1339
|
+
file.close
|
1340
|
+
file.unlink
|
1341
|
+
end
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
[
|
1345
|
+
[1, "http://example.com/", /\AFastImage::UnknownImageType\n\z/, [
|
1346
|
+
[:head, "http://example.com/"],
|
1347
|
+
[:get, "http://example.com/", {body: "<html></html>"}],
|
1348
|
+
] ],
|
1349
|
+
[1, "http://example.com/404", /\ANetHTTPUtils::Error: HTTP error #404 \n\z/, [
|
1350
|
+
[:head, "http://example.com/404", {status: [404, "Not Found"]}],
|
1351
|
+
] ],
|
1352
|
+
|
1353
|
+
# TODO: a test when the giveup=false fails and reraises the DirectLink::ErrorMissingEnvVar
|
1354
|
+
# maybe put it to ./lib tests
|
1355
|
+
|
1356
|
+
# by design it should be impossible to write a test for DirectLink::ErrorAssert
|
1357
|
+
[1, "https://flic.kr/p/DirectLinkErrorNotFound", /\ANetHTTPUtils::Error: HTTP error #404 \n\z/, [
|
1358
|
+
[:head, "https://flic.kr/p/DirectLinkErrorNotFound", {status: [302, "Found"], headers: {"Location"=>"https://www.flickr.com/photo.gne?short=DirectLinkErrorNotFound"}}],
|
1359
|
+
[:head, "https://www.flickr.com/photo.gne?short=DirectLinkErrorNotFound", {status: [302, "Found"], headers: {"Location"=>"/photo.gne?rb=1&short=DirectLinkErrorNotFound"}}],
|
1360
|
+
[:head, "https://www.flickr.com/photo.gne?rb=1&short=DirectLinkErrorNotFound", {status: [404, "Not Found"]}],
|
1361
|
+
] ],
|
1362
|
+
|
1363
|
+
[1, "https://imgur.com/a/badlinkpattern", /\ANetHTTPUtils::Error: HTTP error #404 \n\z/, [
|
1364
|
+
[:head, "https://imgur.com/a/badlinkpattern", {status: [404, "Not Found"]}],
|
1365
|
+
] ],
|
1366
|
+
# TODO: a test that it appends the `exception.cause`
|
1367
|
+
].each do |expected_exit_code, input, expected_output, stubs|
|
1368
|
+
it "fails" do
|
1369
|
+
string, status = popen.call(input, stubs, true)
|
1370
|
+
assert_equal expected_exit_code, status.exitstatus, "for #{input}"
|
1371
|
+
assert string[expected_output], "for #{input}: string=#{string.inspect}"
|
1372
|
+
end
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
valid_imgur_image_url1 = "https://goo.gl/ySqUb5"
|
1376
|
+
valid_imgur_image_url2 = "https://imgur.com/a/oacI3gl"
|
1377
|
+
stubs = [
|
1378
|
+
[:head, "https://goo.gl/ySqUb5", {status: [302, "Found"], headers: {"Location"=>"https://i.imgur.com/QpOBvRY.png"}}],
|
1379
|
+
[:head, "https://i.imgur.com/QpOBvRY.png"],
|
1380
|
+
[:head, "https://api.imgur.com/3/image/QpOBvRY/0.json"],
|
1381
|
+
[:get, "https://api.imgur.com/3/image/QpOBvRY/0.json", {body: <<~HEREDOC
|
1382
|
+
{
|
1383
|
+
"status" : 200,
|
1384
|
+
"success" : true,
|
1385
|
+
"data" : {
|
1386
|
+
"height" : 460,
|
1387
|
+
"link" : "https://i.imgur.com/QpOBvRY.png",
|
1388
|
+
"type" : "image/png",
|
1389
|
+
"width" : 460
|
1390
|
+
}
|
1391
|
+
}
|
1392
|
+
HEREDOC
|
1393
|
+
} ],
|
1394
|
+
[:head, "https://imgur.com/a/oacI3gl"],
|
1395
|
+
[:head, "https://api.imgur.com/3/album/oacI3gl/0.json"],
|
1396
|
+
[:get, "https://api.imgur.com/3/album/oacI3gl/0.json", {body: <<~HEREDOC
|
1397
|
+
{
|
1398
|
+
"status" : 200,
|
1399
|
+
"success" : true,
|
1400
|
+
"data" : {
|
1401
|
+
"id" : "oacI3gl",
|
1402
|
+
"link" : "https://imgur.com/a/oacI3gl",
|
1403
|
+
"images" : [
|
1404
|
+
{
|
1405
|
+
"height" : 100,
|
1406
|
+
"link" : "https://i.imgur.com/9j4KdkJ.png",
|
1407
|
+
"type" : "image/png",
|
1408
|
+
"width" : 100
|
1409
|
+
},
|
1410
|
+
{
|
1411
|
+
"height" : 460,
|
1412
|
+
"link" : "https://i.imgur.com/QpOBvRY.png",
|
1413
|
+
"type" : "image/png",
|
1414
|
+
"width" : 460
|
1415
|
+
}
|
1416
|
+
]
|
1417
|
+
}
|
1418
|
+
}
|
1419
|
+
HEREDOC
|
1420
|
+
} ]
|
1421
|
+
]
|
1422
|
+
[
|
1423
|
+
[stubs, <<~HEREDOC],
|
1424
|
+
<= #{valid_imgur_image_url1}
|
1425
|
+
=> https://i.imgur.com/QpOBvRY.png
|
1426
|
+
image/png 460x460
|
1427
|
+
<= #{valid_imgur_image_url2}
|
1428
|
+
=> https://i.imgur.com/QpOBvRY.png
|
1429
|
+
image/png 460x460
|
1430
|
+
=> https://i.imgur.com/9j4KdkJ.png
|
1431
|
+
image/png 100x100
|
1432
|
+
HEREDOC
|
1433
|
+
[stubs, <<~HEREDOC, "json"]
|
1434
|
+
[
|
1435
|
+
{
|
1436
|
+
"url": "https://i.imgur.com/QpOBvRY.png",
|
1437
|
+
"width": 460,
|
1438
|
+
"height": 460,
|
1439
|
+
"type": "image/png"
|
1440
|
+
},
|
1441
|
+
[
|
1442
|
+
{
|
1443
|
+
"url": "https://i.imgur.com/QpOBvRY.png",
|
1444
|
+
"width": 460,
|
1445
|
+
"height": 460,
|
1446
|
+
"type": "image/png"
|
1447
|
+
},
|
1448
|
+
{
|
1449
|
+
"url": "https://i.imgur.com/9j4KdkJ.png",
|
1450
|
+
"width": 100,
|
1451
|
+
"height": 100,
|
1452
|
+
"type": "image/png"
|
1453
|
+
}
|
1454
|
+
]
|
1455
|
+
]
|
1456
|
+
HEREDOC
|
1457
|
+
].each do |stubs, expected_output, param|
|
1458
|
+
it "#{param || "default"} output format" do
|
1459
|
+
string, status = popen.call("#{valid_imgur_image_url1} #{valid_imgur_image_url2}", stubs, true, param)
|
1460
|
+
assert_equal [0, expected_output], [status.exitstatus, string]
|
1461
|
+
end
|
1462
|
+
end
|
1463
|
+
|
1464
|
+
it "reddit_bot gem logger does not flood STDOUT" do
|
1465
|
+
string, status = popen.call("http://redd.it/123abc", [
|
1466
|
+
[:head, "http://redd.it/123abc", {status: [301, "Moved Permanently"], headers: {"Location"=>"https://redd.it/123abc"}}],
|
1467
|
+
[:head, "https://redd.it/123abc", {status: [302, "Temporarily Moved"], headers: {"Location"=>"https://www.reddit.com/comments/123abc"}}],
|
1468
|
+
[:head, "https://www.reddit.com/comments/123abc"],
|
1469
|
+
[:post, "https://www.reddit.com/api/v1/access_token", {body: {"access_token": "123456789268-NxVk35tst8DttE5uCSD8pPY00XeAXQ"}.to_json}],
|
1470
|
+
[:get, "https://oauth.reddit.com/by_id/t3_123abc?api_type=json", {body: <<~HEREDOC
|
1471
|
+
{
|
1472
|
+
"data" : {
|
1473
|
+
"children" : [
|
1474
|
+
{
|
1475
|
+
"data" : {
|
1476
|
+
"id" : "123abc",
|
1477
|
+
"is_self" : true,
|
1478
|
+
"media" : null,
|
1479
|
+
"name" : "t3_123abc",
|
1480
|
+
"permalink" : "/r/test___________/comments/123abc/for_the_httpsgithubcomnakilondirectlink_unit_tests/",
|
1481
|
+
"selftext" : "https://i.imgur.com/ABCabcd.jpg [test](https://goo.gl/ySqUb5)",
|
1482
|
+
"url" : "https://www.reddit.com/r/test___________/comments/123abc/for_the_httpsgithubcomnakilondirectlink_unit_tests/"
|
1483
|
+
}
|
1484
|
+
}
|
1485
|
+
]
|
1486
|
+
}
|
1487
|
+
}
|
1488
|
+
HEREDOC
|
1489
|
+
} ],
|
1490
|
+
[:head, "https://goo.gl/ySqUb5", {status: [302, "Found"], headers: {"Location"=>"https://i.imgur.com/QpOBvRY.png"}}],
|
1491
|
+
[:head, "https://i.imgur.com/QpOBvRY.png"],
|
1492
|
+
[:head, "https://api.imgur.com/3/image/QpOBvRY/0.json"],
|
1493
|
+
[:get, "https://api.imgur.com/3/image/QpOBvRY/0.json", {body: <<~HEREDOC
|
1494
|
+
{
|
1495
|
+
"status" : 200,
|
1496
|
+
"success" : true,
|
1497
|
+
"data" : {
|
1498
|
+
"height" : 460,
|
1499
|
+
"width" : 460,
|
1500
|
+
"link" : "https://i.imgur.com/QpOBvRY.png",
|
1501
|
+
"type" : "image/png"
|
1502
|
+
}
|
1503
|
+
}
|
1504
|
+
HEREDOC
|
1505
|
+
} ],
|
1506
|
+
] )
|
1507
|
+
assert_equal "<= http://redd.it/123abc\n=> https://i.imgur.com/QpOBvRY.png\n image/png 460x460\n", string
|
1508
|
+
end
|
1509
|
+
|
1510
|
+
# TODO: test about --json
|
1511
|
+
it "does not give up" do
|
1512
|
+
string, status = popen.call("https://www.kp.ru/daily/123/", [
|
1513
|
+
[:head, "https://www.kp.ru/daily/123/", {headers: {"Content-Type"=>"text/html"}}],
|
1514
|
+
[:get, "https://www.kp.ru/daily/123/", {body: <<~HEREDOC
|
1515
|
+
<!DOCTYPE html>
|
1516
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
1517
|
+
<head>
|
1518
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
1519
|
+
<link rel="icon" type="image/png" href="/favicon-16.png" sizes="16x16" />
|
1520
|
+
<link rel="icon" type="image/png" href="/favicon-32.png" sizes="32x32" />
|
1521
|
+
<link rel="icon" type="image/png" href="/favicon-96.png" sizes="96x96" />
|
1522
|
+
<link rel="icon" type="image/png" href="/favicon-128.png" sizes="128x128" />
|
1523
|
+
<meta data-react-helmet="true" property="og:image" content="https://s11.stc.all.kpcdn.net/share/20.jpg" />
|
1524
|
+
<meta data-react-helmet="true" name="twitter:image:src" content="https://s11.stc.all.kpcdn.net/share/20.jpg" />
|
1525
|
+
<link data-react-helmet="true" rel="image_src" href="https://s11.stc.all.kpcdn.net/share/20.jpg" />
|
1526
|
+
</head>
|
1527
|
+
<body>
|
1528
|
+
<div id="app">
|
1529
|
+
<div>
|
1530
|
+
<a href="/daily/author/1234">
|
1531
|
+
<img alt="Александра" src="https://s14.stc.all.kpcdn.net/share/i/3/1234567/avatar.jpg" data-show-on-desktop="false" data-show-on-mobile="false" />
|
1532
|
+
Ы
|
1533
|
+
</a>
|
1534
|
+
</div>
|
1535
|
+
</div>
|
1536
|
+
</body>
|
1537
|
+
</html>
|
1538
|
+
HEREDOC
|
1539
|
+
} ],
|
1540
|
+
[:head, "https://s11.stc.all.kpcdn.net/share/20.jpg"],
|
1541
|
+
[:get, "https://s11.stc.all.kpcdn.net/share/20.jpg", {body: "\xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xFF\xDB\x00C\x00\x03\x02\x02\x02\x02\x02\x03\x02\x02\x02\x03\x03\x03\x03\x04\x06\x04\x04\x04\x04\x04\b\x06\x06\x05\x06\t\b\n\n\t\b\t\t\n\f\x0F\f\n\v\x0E\v\t\t\r\x11\r\x0E\x0F\x10\x10\x11\x10\n\f\x12\x13\x12\x10\x13\x0F\x10\x10\x10\xFF\xC9\x00\v\b\x00\x01\x00\x01\x01\x01\x11\x00\xFF\xCC\x00\x06\x00\x10\x10\x05\xFF\xDA\x00\b\x01\x01\x00\x00?\x00\xD2\xCF \xFF\xD9"}],
|
1542
|
+
], false, "json")
|
1543
|
+
assert_equal [0, "https://s11.stc.all.kpcdn.net/share/20.jpg"], [status.exitstatus, JSON.load(string).fetch("url")]
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
end
|
1547
|
+
|
1548
|
+
end
|