directlink 0.0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +26 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +71 -0
- data/Rakefile +1 -0
- data/api_tokens_for_travis.sh +3 -0
- data/bin/directlink +53 -0
- data/directlink.gemspec +23 -0
- data/gplus.txt +1454 -0
- data/lib/directlink.rb +219 -0
- data/test.rb +374 -0
- metadata +100 -0
data/lib/directlink.rb
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
module DirectLink
|
2
|
+
|
3
|
+
class << self
|
4
|
+
attr_accessor :silent
|
5
|
+
end
|
6
|
+
self.silent = false
|
7
|
+
class << self
|
8
|
+
attr_accessor :logger
|
9
|
+
end
|
10
|
+
self.logger = Object.new
|
11
|
+
self.logger.define_singleton_method :error do |str|
|
12
|
+
puts str unless Module.nesting.first.silent
|
13
|
+
end
|
14
|
+
|
15
|
+
class ErrorMissingEnvVar < RuntimeError ; end
|
16
|
+
class ErrorAssert < RuntimeError
|
17
|
+
def initialize msg
|
18
|
+
super "#{msg} -- consider reporting this issue to GitHub"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
@@LoggingError = Class.new RuntimeError do
|
22
|
+
def initialize msg
|
23
|
+
Module.nesting.first.logger.error msg
|
24
|
+
super msg
|
25
|
+
end
|
26
|
+
end
|
27
|
+
class ErrorNotFound < @@LoggingError ; end
|
28
|
+
class ErrorBadLink < @@LoggingError
|
29
|
+
def initialize link, sure = false
|
30
|
+
super "#{link.inspect}#{" -- if you think this link is valid, please report the issue" unless sure}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
def self.google src, width = 0
|
36
|
+
case src
|
37
|
+
when /\A(https:\/\/lh3\.googleusercontent\.com\/-[a-zA-Z0-9_-]{11}\/W[n-r][a-zA-Z0-9_-]{8}I\/AAAAAAAA[bA-V][a-zA-Z0-9]{2}\/[a-zA-Z0-9_-]{32}[gwAQ]CJoC\/)w[1-4]\d\d-h(318|353|727)-n(\/[^\/]+)\z/,
|
38
|
+
/\A(https:\/\/lh3\.googleusercontent\.com\/-[a-zA-Z0-9_-]{11}\/W[a-zA-Z0-9_-]{9}I\/AAAAAAA[a-zA-Z0-9_-]{4}\/[a-zA-Z0-9_-]{33}(?:CJoC|CL0B(?:GAs)?)\/)w530(?:-d)?-h[2-9]\d\d-n(\/[^\/]+)\z/
|
39
|
+
"#{$1}s#{width}#{$2}"
|
40
|
+
when /\A(\/\/lh3\.googleusercontent\.com\/proxy\/[a-zA-Z0-9_-]{66,523}=)(?:w(?:464|504|530)-h[2-7]\d\d-[np]|s530-p)\z/
|
41
|
+
"https:#{$1}s#{width}"
|
42
|
+
when /\A(\/\/lh3\.googleusercontent\.com\/-[a-zA-Z0-9-]{11}\/W[a-zA-Z0-9_-]{9}I\/AAAAAAA[AC][a-zA-Z0-9]{3}\/[a-zA-Z0-9_-]{32}[gw]CJoC\/)w530-h3\d\d-p(\/[^\/]+)\z/,
|
43
|
+
/\A(\/\/[14]\.bp\.blogspot\.com\/-[a-zA-Z0-9_-]{11}\/W[np][a-zA-Z0-9_-]{8}I\/AAAAAAAA[DE][a-zA-Z0-9_-]{2}\/[a-zA-Z0-9_-]{33}C(?:Lc|Kg)BGAs\/)w530-h278-p(\/[^\/]+)\z/
|
44
|
+
"https:#{$1}s#{width}#{$2}"
|
45
|
+
else
|
46
|
+
raise ErrorBadLink.new src
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
require "json"
|
51
|
+
require "nethttputils"
|
52
|
+
|
53
|
+
def self.imgur link
|
54
|
+
raise ErrorMissingEnvVar.new "define IMGUR_CLIENT_ID env var" unless ENV["IMGUR_CLIENT_ID"]
|
55
|
+
|
56
|
+
case link
|
57
|
+
when /\Ahttps?:\/\/(?:(?:i|m|www)\.)?imgur\.com\/(a|gallery)\/([a-zA-Z0-9]{5}(?:[a-zA-Z0-9]{2})?)\z/,
|
58
|
+
/\Ahttps?:\/\/imgur\.com\/(gallery)\/([a-zA-Z0-9]{5}(?:[a-zA-Z0-9]{2})?)\/new\z/
|
59
|
+
timeout = 1
|
60
|
+
json = begin
|
61
|
+
NetHTTPUtils.request_data "https://api.imgur.com/3/#{
|
62
|
+
$1 == "gallery" ? "gallery" : "album"
|
63
|
+
}/#{$2}/0.json", header: { Authorization: "Client-ID #{ENV["IMGUR_CLIENT_ID"]}" }
|
64
|
+
rescue NetHTTPUtils::Error => e
|
65
|
+
case e.code
|
66
|
+
when 500
|
67
|
+
logger.error "retrying in #{timeout} seconds because of Imgur HTTP ERROR 500"
|
68
|
+
sleep timeout
|
69
|
+
timeout *= 2
|
70
|
+
retry
|
71
|
+
when 404 ; raise ErrorNotFound.new link.inspect
|
72
|
+
else ; raise ErrorAssert.new "unexpected http error for #{link}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
data = JSON.load(json)["data"]
|
76
|
+
if data["error"]
|
77
|
+
raise ErrorAssert.new "unexpected error #{data.inspect} for #{link}"
|
78
|
+
elsif data["images"]
|
79
|
+
data["images"]
|
80
|
+
elsif data["type"] && data["type"].start_with?("image/")
|
81
|
+
[ data ]
|
82
|
+
# elsif data["comment"]
|
83
|
+
# fi["https://imgur.com/" + data["image_id"]]
|
84
|
+
else
|
85
|
+
# one day single-video item should hit this but somehow it didn't yet
|
86
|
+
raise ErrorAssert.new "unknown data format #{data.inspect} for #{link}"
|
87
|
+
end
|
88
|
+
when /\Ahttps?:\/\/(?:(?:i|m|www)\.)?imgur\.com\/([a-zA-Z0-9]{7})(?:\.(?:gifv|jpg))?\z/,
|
89
|
+
/\Ahttps?:\/\/(?:(?:i|m|www)\.)?imgur\.com\/([a-zA-Z0-9]{5})\.mp4\z/,
|
90
|
+
/\Ahttps?:\/\/imgur\.com\/([a-zA-Z0-9]{5}(?:[a-zA-Z0-9]{2})?)\z/,
|
91
|
+
/\Ahttps?:\/\/imgur\.com\/([a-zA-Z0-9]{7})(?:\?\S+)?\z/,
|
92
|
+
/\Ahttps?:\/\/imgur\.com\/r\/[0-9_a-z]+\/([a-zA-Z0-9]{7})\z/
|
93
|
+
json = begin
|
94
|
+
NetHTTPUtils.request_data "https://api.imgur.com/3/image/#{$1}/0.json", header: { Authorization: "Client-ID #{ENV["IMGUR_CLIENT_ID"]}" }
|
95
|
+
rescue NetHTTPUtils::Error => e
|
96
|
+
raise ErrorNotFound.new link.inspect if e.code == 404
|
97
|
+
raise ErrorAssert.new "unexpected http error for #{link}"
|
98
|
+
end
|
99
|
+
[ JSON.load(json)["data"] ]
|
100
|
+
else
|
101
|
+
raise ErrorBadLink.new link
|
102
|
+
end.map do |image|
|
103
|
+
case image["type"]
|
104
|
+
when "image/jpeg", "image/png", "image/gif", "video/mp4"
|
105
|
+
image.values_at "link", "width", "height", "type"
|
106
|
+
else
|
107
|
+
raise ErrorAssert.new "unknown type of #{link}: #{image}"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def self._500px link
|
113
|
+
raise ErrorBadLink.new link unless %r{\Ahttps://500px\.com/photo/(?<id>[^/]+)/[^/]+\z} =~ link
|
114
|
+
raise ErrorMissingEnvVar.new "define _500PX_CONSUMER_KEY env var !!! WARNING: the 500px.com deprecates their API in summer of 2018 !!!" unless ENV["_500PX_CONSUMER_KEY"]
|
115
|
+
JSON.load( NetHTTPUtils.request_data "https://api.500px.com/v1/photos/#{id}", form: {
|
116
|
+
image_size: 2048,
|
117
|
+
consumer_key: ENV["_500PX_CONSUMER_KEY"],
|
118
|
+
} )["photo"].values_at "width", "height", "image_url", "image_format" # could also get "camera" and "taken_at"
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.flickr link
|
122
|
+
raise ErrorBadLink.new link unless %r{\Ahttps://www\.flickr\.com/photos/[^/]+/(?<id>[^/]+)} =~ link ||
|
123
|
+
%r{\Ahttps://flic\.kr/p/(?<id>[^/]+)\z} =~ link
|
124
|
+
raise ErrorMissingEnvVar.new "define FLICKR_API_KEY env var" unless ENV["FLICKR_API_KEY"]
|
125
|
+
|
126
|
+
flickr = lambda do |id, method|
|
127
|
+
JSON.load NetHTTPUtils.request_data "https://api.flickr.com/services/rest/", form: {
|
128
|
+
api_key: ENV["FLICKR_API_KEY"],
|
129
|
+
format: "json",
|
130
|
+
nojsoncallback: 1,
|
131
|
+
photo_id: id,
|
132
|
+
method: "flickr.photos.#{method}",
|
133
|
+
}
|
134
|
+
end
|
135
|
+
json = flickr.call id, "getSizes"
|
136
|
+
raise ErrorNotFound.new link.inspect if json == {"stat"=>"fail", "code"=>1, "message"=>"Photo not found"}
|
137
|
+
raise ErrorAssert.new "unhandled API response stat for #{link}: #{json}" unless json["stat"] == "ok"
|
138
|
+
json["sizes"]["size"].map do |_|
|
139
|
+
w, h, u = _.values_at("width", "height", "source")
|
140
|
+
[w.to_i, h.to_i, u]
|
141
|
+
end.max_by{ |w, h, u| w * h }
|
142
|
+
end
|
143
|
+
|
144
|
+
def self.wiki link
|
145
|
+
raise ErrorBadLink.new link unless %r{\Ahttps?://([a-z]{2}\.wikipedia|commons.wikimedia)\.org/wiki(/[^/]+)*/(?<id>File:.+)} =~ link
|
146
|
+
t = JSON.load json = NetHTTPUtils.request_data( "https://commons.wikimedia.org/w/api.php", form: {
|
147
|
+
format: "json",
|
148
|
+
action: "query",
|
149
|
+
prop: "imageinfo",
|
150
|
+
iiprop: "url",
|
151
|
+
titles: id,
|
152
|
+
} )
|
153
|
+
imageinfo = t["query"]["pages"].values.first["imageinfo"]
|
154
|
+
raise ErrorAssert.new "unexpected format of API response about #{link}: #{json}" unless imageinfo
|
155
|
+
imageinfo.first["url"]
|
156
|
+
end
|
157
|
+
|
158
|
+
|
159
|
+
class_variable_set :@@directlink, Struct.new(:url, :width, :height, :type)
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
require "fastimage"
|
164
|
+
|
165
|
+
def DirectLink link
|
166
|
+
begin
|
167
|
+
URI link
|
168
|
+
rescue URI::InvalidURIError
|
169
|
+
link = URI.escape link
|
170
|
+
end
|
171
|
+
raise DirectLink::ErrorBadLink.new link, true unless URI(link).host
|
172
|
+
|
173
|
+
struct = Module.const_get(__callee__).class_variable_get :@@directlink
|
174
|
+
|
175
|
+
|
176
|
+
if %w{ lh3 googleusercontent com } == URI(link).host.split(?.).last(3) ||
|
177
|
+
%w{ bp blogspot com } == URI(link).host.split(?.).last(3)
|
178
|
+
u = DirectLink.google link
|
179
|
+
f = FastImage.new(u, raise_on_failure: true, http_header: {"User-Agent" => "Mozilla"})
|
180
|
+
w, h = f.size
|
181
|
+
return struct.new u, w, h, f.type
|
182
|
+
end
|
183
|
+
|
184
|
+
if %w{ imgur com } == URI(link).host.split(?.).last(2) ||
|
185
|
+
%w{ i imgur com } == URI(link).host.split(?.).last(3) ||
|
186
|
+
%w{ m imgur com } == URI(link).host.split(?.).last(3) ||
|
187
|
+
%w{ www imgur com } == URI(link).host.split(?.).last(3)
|
188
|
+
imgur = DirectLink.imgur(link).sort_by{ |u, w, h, t| - w * h }.map do |u, w, h, t|
|
189
|
+
struct.new u, w, h, t
|
190
|
+
end
|
191
|
+
# `DirectLink.imgur` return value is always an Array
|
192
|
+
return imgur.size == 1 ? imgur.first : imgur
|
193
|
+
end
|
194
|
+
|
195
|
+
if %w{ 500px com } == URI(link).host.split(?.).last(2)
|
196
|
+
w, h, u, t = DirectLink._500px(link)
|
197
|
+
return struct.new u, w, h, t
|
198
|
+
end
|
199
|
+
|
200
|
+
if %w{ www flickr com } == URI(link).host.split(?.).last(3) ||
|
201
|
+
%w{ flic kr } == URI(link).host.split(?.).last(2)
|
202
|
+
w, h, u = DirectLink.flickr(link)
|
203
|
+
f = FastImage.new(u, raise_on_failure: true, http_header: {"User-Agent" => "Mozilla"})
|
204
|
+
return struct.new u, w, h, f.type
|
205
|
+
end
|
206
|
+
|
207
|
+
if %w{ wikipedia org } == URI(link).host.split(?.).last(2) ||
|
208
|
+
%w{ commons wikimedia org } == URI(link).host.split(?.).last(3)
|
209
|
+
u = DirectLink.wiki link
|
210
|
+
f = FastImage.new(u, raise_on_failure: true, http_header: {"User-Agent" => "Mozilla"})
|
211
|
+
w, h = f.size
|
212
|
+
return struct.new u, w, h, f.type
|
213
|
+
end
|
214
|
+
|
215
|
+
f = FastImage.new(link, raise_on_failure: true, http_header: {"User-Agent" => "Mozilla"})
|
216
|
+
w, h = f.size
|
217
|
+
struct.new link, w, h, f.type
|
218
|
+
|
219
|
+
end
|
data/test.rb
ADDED
@@ -0,0 +1,374 @@
|
|
1
|
+
STDOUT.sync = true
|
2
|
+
|
3
|
+
require "minitest/autorun"
|
4
|
+
require "minitest/mock"
|
5
|
+
|
6
|
+
require_relative "lib/directlink"
|
7
|
+
DirectLink.silent = true
|
8
|
+
describe DirectLink do
|
9
|
+
|
10
|
+
describe "methods" do
|
11
|
+
|
12
|
+
describe "google" do
|
13
|
+
"
|
14
|
+
1 //1.bp.blogspot.com/-rYk_u-qROQc/WngolJ8M0LI/AAAAAAAAD-w/woivnaIVzasBPG5C2T1t-VrWKRd_U6lMgCLcBGAs/w530-h278-p/i-469.jpg
|
15
|
+
2 //4.bp.blogspot.com/-1RlHbRShONs/Wngp9WfxbfI/AAAAAAAAD-8/vnBBXpSZdvUMz4VjJPBpprLBrJ5QpBaqACLcBGAs/w530-h278-p/i-468.jpg
|
16
|
+
3 //4.bp.blogspot.com/-5kP8ndL0kuM/Wpt82UCqvmI/AAAAAAAAEjI/ZbbZWs0-kgwRXEJ9JEGioR0bm6U8MOkvQCKgBGAs/w530-h278-p/IMG_20171223_093922.jpg
|
17
|
+
4 //4.bp.blogspot.com/-bS1SZxFkvek/Wnjz3D5Il4I/AAAAAAAAD_I/bKYvRLGB7r4NGJ0aR1F-ugsbVm4HUjf5ACLcBGAs/w530-h278-p/i-466.jpg
|
18
|
+
5 //lh3.googleusercontent.com/-1CF2jge1MYI/Wmr_kfCQQUI/AAAAAAAClKs/N1F2tz4v0q0i5N7rgso6G8SrhJNzsHEagCJoC/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
|
19
|
+
6 //lh3.googleusercontent.com/-h1siEcRFqJ8/Wiv1iDQhNVI/AAAAAAAAQV4/9gGepSmYkDMLyVTG_1EBCMmj-UhmclXWwCJoC/w530-h353-p/001
|
20
|
+
7 //lh3.googleusercontent.com/-qnZygRb-Tn8/Wlyj4UuKbaI/AAAAAAAATqE/iKWSto-XBZwsh843xJ3cSd0JPt1LedU9gCJoC/w530-h330-p/001
|
21
|
+
8 //lh3.googleusercontent.com/-rXO9PzbjNmk/WlNfjJkJBmI/AAAAAAAATNY/4dHLtYtWBzUKWufNXWkK82etw3RKA6jVgCJoC/w530-h361-p/001
|
22
|
+
|
23
|
+
13 //lh3.googleusercontent.com/proxy/2fsWfEOeeCMNEP8MGvHiJPkBlg47Ifaf8DwpgDPJSPSYsh9iomTrfOA9OuwB60laZimtNr4-1GKA5J2csuVB6-1DLNO30K-fngB8p56ivICWRFAUuOwzizaztBx5gQ=w530-h707-p
|
24
|
+
14 //lh3.googleusercontent.com/proxy/2qy3gOwhBT77Ie_qa9VgGz6kgN14tnOh1AMmV9FB65oiXOSAIll1_qmOZdupL3QCcJQL4701YskEgeDUnxJTnFGq4mFEzNFvjpNC-QMX9Jg7mdar3e89u_siA4AD-j1SJ6mrkl2MwSJSu1s2guYn0NR5ND1985lK34_iGiwzjoGHG2a65IbxKDSEzgSGbPQ_CQiQ6rBIvfcgvAxtS6E=s530-p
|
25
|
+
28 //lh3.googleusercontent.com/proxy/7N0QCidzIFysO6OhmrG8twRJ74-sboNenI3Nhy3mIWP8C0SSa8J6xFQU3iyBTw4k3QeleiAgXOME3abYutPvBrHGx-0TBUcI-_LsgFa59Zaw6PAGdLndkxp5ReRJnsg=w530-h298-p
|
26
|
+
31 //lh3.googleusercontent.com/proxy/7pN3aTE159nEXXQb_KajU1vcnDDzJVpGOv9vlWWPd3CbVuCKu-v4ndr423Mmhx-Zn5vqkVf6-TfZgPA5NyHECsr4w7kaw1jTmQDJbWO-9jU-Cs7ywrzcIRhyYTTZT-hPGiazwI1oEdbooIk=w464-h640-p
|
27
|
+
48 //lh3.googleusercontent.com/proxy/DZtTi5KL7PqiBwJc8weNGLk_Wi2UTaQH0AC_h2kuURiu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n
|
28
|
+
74 //lh3.googleusercontent.com/proxy/P4FQdTYwWN8cU_PWmFja1cm3oYu57L_flea7LmKvFjx0Ibdxl3glxcp-KFWsdRxMFTQ3gQkWsWzlrkyCm9QrSjCUcGIgnbsYBCXewnhEwSn0ZgT4XDg485GdXMoGWpNETrLYa8IGvG20_iw=w504-h597-p
|
29
|
+
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-4H12RdH7MyiHBQt04uRnb58GA4vl5VBQ=w530-h398-p
|
30
|
+
|
31
|
+
245 https://lh3.googleusercontent.com/-2JzV0ErXvv8/Wsdr-m5Q_aI/AAAAAAAA_-I/Lw_e6qEMPUck4yW9yWhkC-nBNd5em8c3QCJoC/w530-h795-n/888052_800n.jpg
|
32
|
+
346 https://lh3.googleusercontent.com/-8YmBt-SUaJo/War0Un_7YTI/AAAAAAAB9xs/kgXp9QrHZX8mpDfyLwuS9cvUSsXIoH6NgCL0BGAs/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
|
33
|
+
1317 https://lh3.googleusercontent.com/-tGAyJv4S6gM/WSLy4A7AFaI/AAAAAAABxk4/eq0Aprp2koM6GEti9xEIn-0PLh87bRRdQCL0B/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
|
34
|
+
|
35
|
+
178 https://lh3.googleusercontent.com/--Ggbfs9HJZM/Wog1DA2WcFI/AAAAAAAAbdQ/SZKPcnXFIr8MFfl9pddfiLPQnOiJ37muQCJoC/w409-h727-n/11a1c54f37c07d3c04588b40d108b4c2.jpg
|
36
|
+
260 https://lh3.googleusercontent.com/-3Fe6CL9RH4o/WnipWY4889I/AAAAAAAAI4I/CPqdKpjqdlwkaBlCqGQ3RdZ9bLJ4nzBwwCJoC/w239-h318-n/gplus1855963830.jpg
|
37
|
+
303 https://lh3.googleusercontent.com/-5vPhLnUILsA/WqFhJhu7VlI/AAAAAAAAAhQ/wWSrC8dqZTA7OuzeU3UoXJkNG19tqtAGwCJoC/w265-h353-n/DSC08260.JPG
|
38
|
+
668 https://lh3.googleusercontent.com/-NLW68hNxEzU/WrSNfBxFX2I/AAAAAAAAAT8/7cvRM-DUZLoIdlb6CS8pL5-eJ3wbwohlQCJoC/w179-h318-n/23.03.2018%2B-%2B3
|
39
|
+
669 https://lh3.googleusercontent.com/-NVJgqmI_2Is/WqMM2OMYg-I/AAAAAAAALrk/5-p3JL3iZt0Ho9dOf_p3gpddzqwr3Wp0ACJoC/w424-h318-n/001
|
40
|
+
783 https://lh3.googleusercontent.com/-SqAvt_F__bg/Wq0huHcX2NI/AAAAAAAAVj0/XfnwCU7JwhUh0Knw8rcXA-bhpKYkI4hdwCJoC/w358-h318-n/IMG_20180317_120218-01-01.jpeg
|
41
|
+
830 https://lh3.googleusercontent.com/-VB3YlLVL_tQ/Wo21yTbKl_I/AAAAAAAAApU/3DURmsYBklcv0kif2ZRjhoLG4mTHYf8OwCJoC/w254-h318-n/180218_00001.jpg
|
42
|
+
1002 https://lh3.googleusercontent.com/-d8FkfLWq-_4/WpQXzEfFgBI/AAAAAAAADww/J32xKSAYUkgIc3pyrZnNmRec6kjdnJBHgCJoC/w239-h318-n/gplus-485739203.jpg
|
43
|
+
".scan(/(\S+) (\S+)/).each do |i, url|
|
44
|
+
it "##{i}" do
|
45
|
+
assert_kind_of String, DirectLink.google(url)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "imgur" do
|
51
|
+
%w{
|
52
|
+
https://imgur.com/a/badlinkpattern
|
53
|
+
http://example.com/
|
54
|
+
https://imgur.com/gallery/YO49F.
|
55
|
+
}.each_with_index do |url, i|
|
56
|
+
it "ErrorBadLink_##{i + 1}" do
|
57
|
+
assert_raises DirectLink::ErrorBadLink do
|
58
|
+
DirectLink.imgur url
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
valid_imgur_image_url = "https://i.imgur.com/BLCesav.jpg"
|
64
|
+
it 200 do
|
65
|
+
assert_equal [["https://i.imgur.com/BLCesav.jpg", 1000, 1500, "image/jpeg"]],
|
66
|
+
DirectLink.imgur(valid_imgur_image_url)
|
67
|
+
end
|
68
|
+
it 404 do
|
69
|
+
assert_raises DirectLink::ErrorNotFound do
|
70
|
+
NetHTTPUtils.stub :request_data, ->*{ raise NetHTTPUtils::Error.new "", 404 } do
|
71
|
+
DirectLink.imgur valid_imgur_image_url
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
it 400 do
|
76
|
+
e = assert_raises DirectLink::ErrorAssert do
|
77
|
+
NetHTTPUtils.stub :request_data, ->*{ raise NetHTTPUtils::Error.new "", 400 } do
|
78
|
+
DirectLink.imgur valid_imgur_image_url
|
79
|
+
end
|
80
|
+
end
|
81
|
+
assert_equal 400, e.cause.code if Exception.instance_methods.include? :cause # Ruby 2.1
|
82
|
+
end
|
83
|
+
|
84
|
+
[ # TODO: move these end line comments to test names; and do the same in other tests
|
85
|
+
["https://imgur.com/a/Aoh6l", "https://i.imgur.com/BLCesav.jpg", 1000, 1500, "image/jpeg"],
|
86
|
+
["http://i.imgur.com/7xcxxkR.gifv", "http://i.imgur.com/7xcxxkRh.gif", 718, 404, "image/gif"],
|
87
|
+
["https://imgur.com/9yaMdJq", "https://i.imgur.com/9yaMdJq.mp4", 720, 404, "video/mp4"],
|
88
|
+
["http://imgur.com/gallery/dCQprEq/new", "https://i.imgur.com/dCQprEq.jpg"],
|
89
|
+
["http://imgur.com/HQHBBBD", "https://i.imgur.com/HQHBBBD.jpg"], # http
|
90
|
+
["https://imgur.com/BGDh6eu", "https://i.imgur.com/BGDh6eu.jpg"], # https
|
91
|
+
["https://imgur.com/a/qNCOo", 6, "https://i.imgur.com/vwqfi3s.jpg", "https://i.imgur.com/CnSMWvo.jpg"], # https album
|
92
|
+
["http://imgur.com/a/0MiUo", 49, "https://i.imgur.com/kJ1jrjO.jpg", "https://i.imgur.com/TMQJARX.jpg"], # album, zoomable
|
93
|
+
["http://imgur.com/a/WswMg", 20, "https://i.imgur.com/Bt3RWV7.png", "https://i.imgur.com/sRc2lqN.png"], # album image, not zoomable
|
94
|
+
["http://imgur.com/a/AdJUK", 3, "https://i.imgur.com/Yunpxnx.jpg", "https://i.imgur.com/2epn2nT.jpg"], # needs https because of authorship # WAT?
|
95
|
+
["http://imgur.com/gallery/vR4Am", 7, "https://i.imgur.com/yuUQI25.jpg", "https://i.imgur.com/RdxyAMQ.jpg"],
|
96
|
+
["http://imgur.com/gallery/qP2RQtL", "https://i.imgur.com/qP2RQtL.png"], # single image gallery?
|
97
|
+
["http://imgur.com/gallery/nKAwE/new", 28, "https://i.imgur.com/VQhR8hB.jpg", "https://i.imgur.com/axlzNRL.jpg"],
|
98
|
+
["http://m.imgur.com/rarOohr", "https://i.imgur.com/rarOohr.jpg"],
|
99
|
+
["http://imgur.com/r/wallpaper/j39dKMi", "https://i.imgur.com/j39dKMi.jpg"],
|
100
|
+
["http://imgur.com/gallery/jm0OKQM", DirectLink::ErrorNotFound], # this id does not belong to gallery but to an image, that is probably irrelevant
|
101
|
+
["http://imgur.com/gallery/oZXfZ", DirectLink::ErrorNotFound], # this id does not belong to gallery but to an album, that is probably irrelevant
|
102
|
+
["http://imgur.com/gallery/dCQprEq/new", "https://i.imgur.com/dCQprEq.jpg", 5760, 3840, "image/jpeg"],
|
103
|
+
["https://imgur.com/S5u2xRB?third_party=1#_=_", "https://i.imgur.com/S5u2xRB.jpg", 2448, 2448, "image/jpeg"],
|
104
|
+
["https://imgur.com/3eThW", "https://i.imgur.com/3eThW.jpg", 2560, 1600, "image/jpeg"],
|
105
|
+
["https://i.imgur.com/RGO6i.mp4", "https://i.imgur.com/RGO6i.gif", 339, 397, "image/gif"],
|
106
|
+
["https://imgur.com/a/oacI3gl", 2, "https://i.imgur.com/9j4KdkJ.png", "https://i.imgur.com/QpOBvRY.png"],
|
107
|
+
# some other tests not sure we need them
|
108
|
+
["http://i.imgur.com/7xcxxkR.gifv", "http://i.imgur.com/7xcxxkRh.gif"],
|
109
|
+
["http://imgur.com/HQHBBBD", "https://i.imgur.com/HQHBBBD.jpg", 1024, 768, "image/jpeg"],
|
110
|
+
["http://imgur.com/a/AdJUK", 3, "https://i.imgur.com/Yunpxnx.jpg", "https://i.imgur.com/2epn2nT.jpg", "https://i.imgur.com/3afw2aF.jpg"],
|
111
|
+
["https://imgur.com/9yaMdJq", "https://i.imgur.com/9yaMdJq.mp4", 720, 404, "video/mp4"],
|
112
|
+
["http://imgur.com/gallery/dCQprEq/new", "https://i.imgur.com/dCQprEq.jpg", 5760, 3840, "image/jpeg"],
|
113
|
+
].each_with_index do |t, i|
|
114
|
+
url, n, first, last, type = t
|
115
|
+
it "##{i + 1}" do
|
116
|
+
case last
|
117
|
+
when NilClass
|
118
|
+
if n.is_a? Class
|
119
|
+
assert_raises n do
|
120
|
+
DirectLink.imgur url
|
121
|
+
end
|
122
|
+
else
|
123
|
+
real = DirectLink.imgur url
|
124
|
+
assert_equal 1, real.size
|
125
|
+
assert_equal n, real.first.first
|
126
|
+
end
|
127
|
+
when Numeric
|
128
|
+
real = DirectLink.imgur url
|
129
|
+
assert_equal 1, real.size
|
130
|
+
assert_equal [n, first, last, type], real.first
|
131
|
+
when String
|
132
|
+
real = DirectLink.imgur url
|
133
|
+
assert_equal n, real.size
|
134
|
+
assert_equal first, real.first.first
|
135
|
+
assert_equal last, real.last.first
|
136
|
+
else
|
137
|
+
fail "bug in tests"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
[
|
144
|
+
[ :_500px, [
|
145
|
+
["https://500px.com/photo/112134597/milky-way-by-tom-hall", [4928, 2888, "https://drscdn.500px.org/photo/112134597/m%3D2048_k%3D1_a%3D1/v2?client_application_id=48351&webp=true&sig=6b9f6ac5aed6d051aa66911555657ef57262e7d998f406e40f50e6f61515808f", "jpeg"]],
|
146
|
+
] ],
|
147
|
+
[ :flickr, [
|
148
|
+
["https://www.flickr.com/photos/tomas-/17220613278/", DirectLink::ErrorNotFound],
|
149
|
+
["https://www.flickr.com/photos/16936123@N07/18835195572", DirectLink::ErrorNotFound],
|
150
|
+
["https://www.flickr.com/photos/44133687@N00/17380073505/", [3000, 2000, "https://farm8.staticflickr.com/7757/17380073505_ed5178cc6a_o.jpg"]], # trailing slash
|
151
|
+
["https://www.flickr.com/photos/jacob_schmidt/18414267018/in/album-72157654235845651/", DirectLink::ErrorNotFound], # username in-album
|
152
|
+
["https://www.flickr.com/photos/tommygi/5291099420/in/dateposted-public/", [1600, 1062, "https://farm6.staticflickr.com/5249/5291099420_3bf8f43326_o.jpg"]], # username in-public
|
153
|
+
["https://www.flickr.com/photos/132249412@N02/18593786659/in/album-72157654521569061/", DirectLink::ErrorNotFound],
|
154
|
+
["https://www.flickr.com/photos/130019700@N03/18848891351/in/dateposted-public/", [4621, 3081, "https://farm4.staticflickr.com/3796/18848891351_f751b35aeb_o.jpg"]], # userid in-public
|
155
|
+
["https://www.flickr.com/photos/frank3/3778768209/in/photolist-6KVb92-eCDTCr-ur8K-7qbL5z-c71afh-c6YvXW-7mHG2L-c71ak9-c71aTq-c71azf-c71aq5-ur8Q-6F6YkR-eCDZsD-eCEakg-eCE6DK-4ymYku-7ubEt-51rUuc-buujQE-ur8x-9fuNu7-6uVeiK-qrmcC6-ur8D-eCEbei-eCDY9P-eCEhCk-eCE5a2-eCH457-eCHrcq-eCEdZ4-eCH6Sd-c71b5o-c71auE-eCHa8m-eCDSbz-eCH1dC-eCEg3v-7JZ4rh-9KwxYL-6KV9yR-9tUSbU-p4UKp7-eCHfwS-6KVbAH-5FrdbP-eeQ39v-eeQ1UR-4jHAGN", [1024, 681, "https://farm3.staticflickr.com/2499/3778768209_280f82abab_b.jpg"]],
|
156
|
+
["https://www.flickr.com/photos/patricksloan/18230541413/sizes/l", [2048, 491, "https://farm6.staticflickr.com/5572/18230541413_fec4783d79_k.jpg"]],
|
157
|
+
["https://flic.kr/p/vPvCWJ", [2048, 1365, "https://farm1.staticflickr.com/507/19572004110_d44d1b4ead_k.jpg"]],
|
158
|
+
] ],
|
159
|
+
[ :wiki, [
|
160
|
+
["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"],
|
161
|
+
["https://en.wikipedia.org/wiki/Third_Party_System#/media/File:United_States_presidential_election_results,_1876-1892.svg", DirectLink::ErrorAssert],
|
162
|
+
["http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg", "https://upload.wikimedia.org/wikipedia/commons/0/0d/Eduard_Bohlen_anagoria.jpg"],
|
163
|
+
] ],
|
164
|
+
].each do |method, tests|
|
165
|
+
describe method do
|
166
|
+
tests.each_with_index do |(input, expectation), i|
|
167
|
+
it "##{i + 1}" do
|
168
|
+
if expectation.is_a? Class
|
169
|
+
assert_raises expectation do
|
170
|
+
DirectLink.method(method).call input
|
171
|
+
end
|
172
|
+
else
|
173
|
+
result = DirectLink.method(method).call input
|
174
|
+
assert_equal expectation, result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
{
|
182
|
+
google: %w{
|
183
|
+
https://lh3.googleusercontent.com/-NVJgqmI_2Is/WqMM2OMYg-I/AAAAAAAALrk/5-p3JL3iZt0Ho9dOf_p3gpddzqwr3Wp0ACJoC/w424-h318-n/001
|
184
|
+
https://lh3.googleusercontent.com/-2JzV0ErXvv8/Wsdr-m5Q_aI/AAAAAAAA_-I/Lw_e6qEMPUck4yW9yWhkC-nBNd5em8c3QCJoC/w530-h795-n/888052_800n.jpg
|
185
|
+
//lh3.googleusercontent.com/proxy/DZtTi5KL7PqiBwJc8weNGLk_Wi2UTaQH0AC_h2kuURiu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n
|
186
|
+
//lh3.googleusercontent.com/-h1siEcRFqJ8/Wiv1iDQhNVI/AAAAAAAAQV4/9gGepSmYkDMLyVTG_1EBCMmj-UhmclXWwCJoC/w530-h353-p/001
|
187
|
+
//1.bp.blogspot.com/-rYk_u-qROQc/WngolJ8M0LI/AAAAAAAAD-w/woivnaIVzasBPG5C2T1t-VrWKRd_U6lMgCLcBGAs/w530-h278-p/i-469.jpg
|
188
|
+
},
|
189
|
+
imgur: %w{
|
190
|
+
https://imgur.com/3eThW
|
191
|
+
https://i.imgur.com/3eThW
|
192
|
+
https://m.imgur.com/3eThW
|
193
|
+
https://www.imgur.com/3eThW
|
194
|
+
},
|
195
|
+
_500px: %w{
|
196
|
+
https://500px.com/photo/112134597/milky-way-by-tom-hall
|
197
|
+
},
|
198
|
+
flickr: %w{
|
199
|
+
https://www.flickr.com/photos/tomas-/17220613278/
|
200
|
+
https://flic.kr/p/vPvCWJ
|
201
|
+
},
|
202
|
+
wiki: %w{
|
203
|
+
https://en.wikipedia.org/wiki/Third_Party_System#/media/File:United_States_presidential_election_results,_1876-1892.svg
|
204
|
+
http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg
|
205
|
+
},
|
206
|
+
}.each do |method, tests|
|
207
|
+
describe "DirectLink() calls #{method}" do
|
208
|
+
tests.each_with_index do |input, i|
|
209
|
+
it "##{i + 1}" do
|
210
|
+
called = false
|
211
|
+
m = DirectLink.method method
|
212
|
+
DirectLink.stub method, ->link{ called = true } do
|
213
|
+
DirectLink.method(method).call input
|
214
|
+
assert called, "DirectLink.#{method} was not called"
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe "throws ErrorBadLink if method does not match the link" do
|
222
|
+
%i{ google imgur flickr _500px wiki }.each do |method|
|
223
|
+
it method do
|
224
|
+
assert_raises DirectLink::ErrorBadLink do
|
225
|
+
DirectLink.method(method).call ""
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
end
|
232
|
+
|
233
|
+
describe "DirectLink()" do
|
234
|
+
|
235
|
+
it "throws ErrorBadLink if link is invalid" do
|
236
|
+
e = assert_raises DirectLink::ErrorBadLink do
|
237
|
+
DirectLink "test"
|
238
|
+
end
|
239
|
+
assert_equal "test".inspect, e.message
|
240
|
+
end
|
241
|
+
|
242
|
+
describe "does not shadow the internal exception" do
|
243
|
+
[
|
244
|
+
[:google, "//lh3.googleusercontent.com/proxy/DZtTi5KL7PqiBwJc8weNGLk_Wi2UTaQH0AC_h2kuURiu0AbwyI2ywOk2XgdAjL7ceg=w530-h354-n"],
|
245
|
+
[:imgur, "http://imgur.com/HQHBBBD"],
|
246
|
+
[:flickr, "https://www.flickr.com/photos/tomas-/17220613278/"],
|
247
|
+
[:_500px, "https://500px.com/photo/112134597/milky-way-by-tom-hall"],
|
248
|
+
[:wiki, "http://commons.wikimedia.org/wiki/File:Eduard_Bohlen_anagoria.jpg"],
|
249
|
+
].each do |method, link|
|
250
|
+
it method do
|
251
|
+
e = assert_raises DirectLink::ErrorBadLink do
|
252
|
+
DirectLink.stub method, ->*{ raise DirectLink::ErrorBadLink.new "test" } do
|
253
|
+
DirectLink link
|
254
|
+
end
|
255
|
+
end
|
256
|
+
assert_equal "\"test\" -- if you think this link is valid, please report the issue", e.message
|
257
|
+
end
|
258
|
+
end
|
259
|
+
it "raises FastImage::ImageFetchFailure on Net::HTTP failure" do
|
260
|
+
assert_raises FastImage::ImageFetchFailure do
|
261
|
+
NetHTTPUtils.stub :get_response, ->*{ raise SocketError.new } do
|
262
|
+
DirectLink "http://example.com/404"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "some other tests" do
|
269
|
+
[
|
270
|
+
["http://www.aeronautica.difesa.it/organizzazione/REPARTI/divolo/PublishingImages/6%C2%B0%20Stormo/2013-decollo%20al%20tramonto%20REX%201280.jpg", ["http://www.aeronautica.difesa.it/organizzazione/REPARTI/divolo/PublishingImages/6%C2%B0%20Stormo/2013-decollo%20al%20tramonto%20REX%201280.jpg", 1280, 853, :jpeg]],
|
271
|
+
["http://example.com", FastImage::UnknownImageType], # was URL2Dimensions::ErrorUnknown
|
272
|
+
["http://minus.com/lkP3hgRJd9npi", FastImage::ImageFetchFailure], # was URL2Dimensions::Error404
|
273
|
+
["https://i.redd.it/si758zk7r5xz.jpg", FastImage::ImageFetchFailure], # was URL2Dimensions::Error404
|
274
|
+
["http://www.cutehalloweencostumeideas.org/wp-content/uploads/2017/10/Niagara-Falls_04.jpg", FastImage::ImageFetchFailure], # was URL2Dimensions::Error404
|
275
|
+
].each_with_index do |(input, expectation), i|
|
276
|
+
it "##{i + 1}" do
|
277
|
+
if expectation.is_a? Class
|
278
|
+
assert_raises expectation do
|
279
|
+
DirectLink input
|
280
|
+
end
|
281
|
+
else
|
282
|
+
u, w, h, t = expectation
|
283
|
+
result = DirectLink input
|
284
|
+
assert_equal DirectLink.class_variable_get(:@@directlink).new(u, w, h, t),
|
285
|
+
result, "#{input} :: #{result.inspect} != #{expectation.inspect}"
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "./bin" do
|
294
|
+
require "open3"
|
295
|
+
|
296
|
+
describe "shows usage help if misused" do
|
297
|
+
[
|
298
|
+
["usage: directlink [--debug] [--json] <link1> <link2> <link3> ...\n", nil],
|
299
|
+
["usage: directlink [--debug] [--json] <link1> <link2> <link3> ...\n", "--help"],
|
300
|
+
["usage: directlink [--debug] [--json] <link1> <link2> <link3> ...\n", "-h"],
|
301
|
+
["DirectLink::ErrorBadLink: \"--\"\n", "--"],
|
302
|
+
["DirectLink::ErrorBadLink: \"-\"\n", "-"],
|
303
|
+
["DirectLink::ErrorBadLink: \"-\"\n", "- -"],
|
304
|
+
["DirectLink::ErrorBadLink: \"asd\"\n", "asd"],
|
305
|
+
].each_with_index do |(expected_output, param), i|
|
306
|
+
it "##{i + 1}" do
|
307
|
+
string, status = Open3.capture2e "ruby -Ilib bin/directlink #{param}"
|
308
|
+
assert_equal [1, expected_output], [status.exitstatus, string]
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# that hack around `export` is for crossplatform Travis test, since Ubuntu uses `sh` that can't `source`
|
314
|
+
# TODO: but maybe I could make Open3 use the shell I need, since `source` works fine for `.travis.yaml`'s `:script`
|
315
|
+
|
316
|
+
describe "fails" do
|
317
|
+
[
|
318
|
+
[1, "http://example.com/", "FastImage::UnknownImageType"], # TODO: is it possible to obtain it from `.cause`?
|
319
|
+
[1, "http://example.com/404", "FastImage::ImageFetchFailure"],
|
320
|
+
[1, "http://imgur.com/HQHBBBD", "DirectLink::ErrorMissingEnvVar: define IMGUR_CLIENT_ID env var", " && unset IMGUR_CLIENT_ID"], # TODO: make similar test for ./lib
|
321
|
+
# by design it should be impossible to write a test for DirectLink::ErrorAssert
|
322
|
+
[1, "https://flic.kr/p/DirectLinkErrorNotFound", "DirectLink::ErrorNotFound: \"https://flic.kr/p/DirectLinkErrorNotFound\""],
|
323
|
+
[1, "https://imgur.com/a/badlinkpattern", "DirectLink::ErrorBadLink: \"https://imgur.com/a/badlinkpattern\" -- if you think this link is valid, please report the issue"],
|
324
|
+
].each_with_index do |(expected_exit_code, link, expected_output, unset), i|
|
325
|
+
it "##{i + 1}" do
|
326
|
+
string, status = Open3.capture2e "export #{File.read("api_tokens_for_travis.sh").gsub(/\n?export/, ?\s).strip}#{unset} && ruby -Ilib bin/directlink #{link}"
|
327
|
+
assert_equal [expected_exit_code, "#{expected_output}\n"], [status.exitstatus, string]
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
valid_imgur_image_urls = "https://avatars1.githubusercontent.com/u/2870363?100 https://imgur.com/a/oacI3gl"
|
333
|
+
[
|
334
|
+
['https://avatars1.githubusercontent.com/u/2870363?100
|
335
|
+
jpeg 460x460
|
336
|
+
|
337
|
+
https://i.imgur.com/QpOBvRY.png
|
338
|
+
image/png 460x460
|
339
|
+
https://i.imgur.com/9j4KdkJ.png
|
340
|
+
image/png 100x100
|
341
|
+
'.gsub(/^ {8}/, "")],
|
342
|
+
['[
|
343
|
+
{
|
344
|
+
"url": "https://avatars1.githubusercontent.com/u/2870363?100",
|
345
|
+
"width": 460,
|
346
|
+
"height": 460,
|
347
|
+
"type": "jpeg"
|
348
|
+
},
|
349
|
+
[
|
350
|
+
{
|
351
|
+
"url": "https://i.imgur.com/QpOBvRY.png",
|
352
|
+
"width": 460,
|
353
|
+
"height": 460,
|
354
|
+
"type": "image/png"
|
355
|
+
},
|
356
|
+
{
|
357
|
+
"url": "https://i.imgur.com/9j4KdkJ.png",
|
358
|
+
"width": 100,
|
359
|
+
"height": 100,
|
360
|
+
"type": "image/png"
|
361
|
+
}
|
362
|
+
]
|
363
|
+
]
|
364
|
+
'.gsub(/^ {8}/, ""), "json"],
|
365
|
+
].each do |expected_output, param|
|
366
|
+
it "#{param || "default"} succeeds" do
|
367
|
+
string, status = Open3.capture2e "export #{File.read("api_tokens_for_travis.sh").gsub(/\n?export/, ?\s).strip} && ruby -Ilib bin/directlink#{" --#{param}" if param} #{valid_imgur_image_urls}"
|
368
|
+
assert_equal [0, expected_output], [status.exitstatus, string]
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
end
|
373
|
+
|
374
|
+
end
|