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