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