FlickrCollage 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/FlickrCollage.gemspec +33 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +68 -0
- data/LICENSE.txt +8 -0
- data/README.md +102 -0
- data/Rakefile +56 -0
- data/bin/FlickrCollage +61 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/doc/FlickrCollage.html +187 -0
- data/doc/FlickrCollage/Dictionary.html +408 -0
- data/doc/FlickrCollage/Flickr.html +880 -0
- data/doc/FlickrCollage/Image.html +1611 -0
- data/doc/_index.html +146 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +481 -0
- data/doc/file.README.html +171 -0
- data/doc/file_list.html +56 -0
- data/doc/flickrCollage.jpg +0 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +171 -0
- data/doc/js/app.js +243 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +203 -0
- data/doc/top-level-namespace.html +112 -0
- data/lib/FlickrCollage.rb +399 -0
- data/lib/FlickrCollage/version.rb +3 -0
- data/tmp/Giant Robots Smashing into Other Giant Robots.jpg +0 -0
- data/tmp/cat.jpg +0 -0
- metadata +215 -0
@@ -0,0 +1,399 @@
|
|
1
|
+
require "FlickrCollage/version"
|
2
|
+
require "methadone"
|
3
|
+
require "flickraw"
|
4
|
+
require "mini_magick"
|
5
|
+
require "open-uri"
|
6
|
+
require "fileutils"
|
7
|
+
|
8
|
+
# Creating collage from top-rated Flickr images for your keywords
|
9
|
+
# @author Chromium
|
10
|
+
module FlickrCollage
|
11
|
+
# Class for Dictionary. Provides random words
|
12
|
+
IMG_COUNT = 10
|
13
|
+
IMG_PATH = "./"
|
14
|
+
COLLAGE_FILE = "flickrCollage"
|
15
|
+
RAISE_ERROR = true
|
16
|
+
|
17
|
+
class Dictionary
|
18
|
+
DICT_FILE = "/usr/share/dict/words"
|
19
|
+
# @return [Array] All words at dictionary file
|
20
|
+
attr_accessor :words
|
21
|
+
|
22
|
+
def initialize(opts = {})
|
23
|
+
opts[:file] ||= DICT_FILE
|
24
|
+
@words = File.read(opts[:file]).lines.select do |line|
|
25
|
+
(4..9).cover?(line.strip.size)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get random word from Dictionary file
|
30
|
+
#
|
31
|
+
# @return [String] random word
|
32
|
+
def get_word
|
33
|
+
@words.sample.strip
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Class for Flickr. Get and download top-rated images for keywords
|
38
|
+
class Flickr
|
39
|
+
include Methadone::CLILogging
|
40
|
+
|
41
|
+
API_KEY = "27ad23a09746546c02c79f39879ee408"
|
42
|
+
SHARED_SECRET = "707eaf92eece0744"
|
43
|
+
SEARCH_KEYWORD = "Giant Robots Smashing into Other Giant Robots"
|
44
|
+
SEARCH_COUNT = 1
|
45
|
+
# @return [String] Path for saving images
|
46
|
+
attr_accessor :img_path
|
47
|
+
|
48
|
+
def initialize(opts = {})
|
49
|
+
opts[:api_key] ||= API_KEY
|
50
|
+
opts[:shared_secret] ||= SHARED_SECRET
|
51
|
+
opts[:img_path] ||= IMG_PATH
|
52
|
+
|
53
|
+
FlickRaw.api_key = opts[:api_key]
|
54
|
+
FlickRaw.shared_secret = opts[:shared_secret]
|
55
|
+
@img_path = opts[:img_path]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Search top-rated images for keyword
|
59
|
+
#
|
60
|
+
# @param [Hash] opts
|
61
|
+
# @option opts [String] :keyword ('Giant Robots Smashing into Other Giant Robots') keyword for search
|
62
|
+
# @option opts [Number] :count (1) how many images you need
|
63
|
+
#
|
64
|
+
# @return [Array<String>] urls with top-rated images for keyword
|
65
|
+
# @return [String] url with top-rated image for keyword
|
66
|
+
def search(opts = {})
|
67
|
+
opts[:keyword] ||= SEARCH_KEYWORD
|
68
|
+
opts[:count] ||= SEARCH_COUNT
|
69
|
+
photos = []
|
70
|
+
begin
|
71
|
+
list = flickr.photos.search(text: opts[:keyword], sort: "interestingness-desc", per_page: opts[:count])
|
72
|
+
debug "flickr.search: #{opts[:keyword]} (img: #{list.size})"
|
73
|
+
|
74
|
+
list.each do |photo|
|
75
|
+
info = flickr.photos.getInfo(photo_id: photo.id)
|
76
|
+
debug "flickr.search: get image url for #{photo.id}"
|
77
|
+
# debug "flickr.search: #{FlickRaw.url_photopage(info)}"
|
78
|
+
photos << FlickRaw.url_c(info)
|
79
|
+
end
|
80
|
+
rescue StandardError => e
|
81
|
+
warn "flickr.search: caught exception #{e}"
|
82
|
+
raise e if RAISE_ERROR
|
83
|
+
end
|
84
|
+
photos.size > 1 ? photos : photos.first
|
85
|
+
end
|
86
|
+
|
87
|
+
# Download images from urls
|
88
|
+
#
|
89
|
+
# @param [Array<Hash>] opts
|
90
|
+
# @option opts [String] :keyword keyword for file name
|
91
|
+
# @option opts [String] :url image url
|
92
|
+
#
|
93
|
+
# @return [Array<String>] files paths for downloaded images
|
94
|
+
# @return [String] file path for downloaded image
|
95
|
+
def download(opts = {})
|
96
|
+
opts ||= []
|
97
|
+
photos = []
|
98
|
+
return photos unless opts.any?
|
99
|
+
opts = [keyword: opts[:keyword], url: opts[:url]] unless opts.is_a?(Array)
|
100
|
+
FileUtils.mkdir_p("#{@img_path}tmp")
|
101
|
+
|
102
|
+
begin
|
103
|
+
opts.each do |img|
|
104
|
+
debug "flickr.download: #{img[:keyword]} #{img[:url]}"
|
105
|
+
next unless defined?(img[:url]) && !img[:url].nil?
|
106
|
+
open(img[:url]) do |url|
|
107
|
+
File.open("#{@img_path}tmp/#{img[:keyword]}.jpg", "wb") do |file|
|
108
|
+
file.puts url.read
|
109
|
+
end
|
110
|
+
file = "#{@img_path}tmp/#{img[:keyword]}.jpg"
|
111
|
+
debug "flickr.download: file #{file}"
|
112
|
+
photos << file if Image.valid?(file)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
rescue StandardError => e
|
116
|
+
warn "flickr.download: caught exception: #{e.inspect}"
|
117
|
+
raise e if RAISE_ERROR
|
118
|
+
end
|
119
|
+
photos.size > 1 ? photos : photos.first
|
120
|
+
end
|
121
|
+
|
122
|
+
# Scrape top-rated images for keyword
|
123
|
+
#
|
124
|
+
# @param [Hash] opts
|
125
|
+
# @option opts [String] :keyword ('Giant Robots Smashing into Other Giant Robots') keyword for scrape
|
126
|
+
#
|
127
|
+
# @return [String] file path for downloaded image
|
128
|
+
def scrape(opts = {})
|
129
|
+
opts[:keyword] ||= SEARCH_KEYWORD
|
130
|
+
|
131
|
+
url = search(keyword: opts[:keyword])
|
132
|
+
debug "flickr.scrape: #{opts[:keyword]} #{url}"
|
133
|
+
download(keyword: opts[:keyword], url: url)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Class for Image. Create collage and crop images
|
138
|
+
# @attr_reader [String] img_path Path for saving images
|
139
|
+
# @attr_reader [Number] img_width Width for images crop
|
140
|
+
# @attr_reader [Number] img_height Height for images crop
|
141
|
+
# @attr_reader [String] collage_file Collage file name
|
142
|
+
# @attr_reader [Boolean] clear_tmp Delete all downloaded images
|
143
|
+
class Image
|
144
|
+
include Methadone::CLILogging
|
145
|
+
|
146
|
+
IMG_WIDTH = 800
|
147
|
+
IMG_HEIGHT = 600
|
148
|
+
|
149
|
+
attr_accessor :img_path, :img_width, :img_height, :collage_file, :clear_tmp
|
150
|
+
|
151
|
+
def initialize(opts = {})
|
152
|
+
opts[:img_path] ||= IMG_PATH
|
153
|
+
opts[:img_width] ||= IMG_WIDTH
|
154
|
+
opts[:img_height] ||= IMG_HEIGHT
|
155
|
+
opts[:collage_file] ||= COLLAGE_FILE
|
156
|
+
|
157
|
+
@img_path = opts[:img_path]
|
158
|
+
@img_width = opts[:img_width]
|
159
|
+
@img_height = opts[:img_height]
|
160
|
+
@collage_file = opts[:collage_file]
|
161
|
+
@clear_tmp = opts[:clear_tmp]
|
162
|
+
end
|
163
|
+
|
164
|
+
# Validates downloaded image
|
165
|
+
#
|
166
|
+
# @param [String] file file path for downloaded image
|
167
|
+
#
|
168
|
+
# @return [true] image is valid
|
169
|
+
# @return [false] image is not valid
|
170
|
+
def self.valid?(file)
|
171
|
+
return false if file.nil?
|
172
|
+
begin
|
173
|
+
image = MiniMagick::Image.open(file)
|
174
|
+
rescue StandardError => e
|
175
|
+
warn "Image.valid: caught exception #{e}"
|
176
|
+
raise e if RAISE_ERROR
|
177
|
+
end
|
178
|
+
image.valid?
|
179
|
+
end
|
180
|
+
|
181
|
+
# Resize image
|
182
|
+
#
|
183
|
+
# @param [Hash] opts
|
184
|
+
# @option opts [String] :file file path for image
|
185
|
+
# @option opts [Number] :width (@img_width) image new width
|
186
|
+
# @option opts [Number] :height (@img_height) image new height
|
187
|
+
#
|
188
|
+
# @return [String] file path for resized image
|
189
|
+
def resize(opts = {})
|
190
|
+
return false if opts[:file].nil?
|
191
|
+
|
192
|
+
opts[:width] ||= @img_width
|
193
|
+
opts[:height] ||= @img_height
|
194
|
+
begin
|
195
|
+
image = MiniMagick::Image.open(opts[:file])
|
196
|
+
resize_to_fill(opts[:width], opts[:height], image)
|
197
|
+
file_resize = "#{@img_path}tmp/#{File.basename(opts[:file], ".jpg")}_resize.jpg"
|
198
|
+
image.write file_resize
|
199
|
+
debug "Resize #{opts[:file]} to #{opts[:width]}x#{opts[:height]}"
|
200
|
+
rescue StandardError => e
|
201
|
+
warn "Image.resize: caught exception #{e}"
|
202
|
+
raise e if RAISE_ERROR
|
203
|
+
end
|
204
|
+
file_resize
|
205
|
+
end
|
206
|
+
|
207
|
+
# Creates collage from 10 images
|
208
|
+
#
|
209
|
+
# @param [Hash] opts
|
210
|
+
# @option opts [Array<String>] :files file paths for collage images
|
211
|
+
#
|
212
|
+
# @return [true] collage created successfully
|
213
|
+
# @return [false] something went wrong
|
214
|
+
def collage(opts = {})
|
215
|
+
unless opts[:files].size == IMG_COUNT
|
216
|
+
info "Not enough images for collage"
|
217
|
+
return false
|
218
|
+
end
|
219
|
+
|
220
|
+
begin
|
221
|
+
(1..4).each do |row|
|
222
|
+
montage = MiniMagick::Tool::Montage.new
|
223
|
+
files = montage_resize(files: opts[:files], row: row)
|
224
|
+
files.each do |file|
|
225
|
+
montage << file
|
226
|
+
end
|
227
|
+
montage << "-mode"
|
228
|
+
montage << "Concatenate"
|
229
|
+
montage << "-background"
|
230
|
+
montage << "none"
|
231
|
+
montage << "-geometry"
|
232
|
+
montage << montage_geometry(row: row)
|
233
|
+
montage << "-tile"
|
234
|
+
montage << montage_tile(row: row)
|
235
|
+
montage << montage_img_path(row: row)
|
236
|
+
montage.call
|
237
|
+
end
|
238
|
+
rescue StandardError => e
|
239
|
+
warn "Image.collage: caught exception #{e}"
|
240
|
+
raise e if RAISE_ERROR
|
241
|
+
end
|
242
|
+
FileUtils.rm_rf("#{@img_path}tmp") if @clear_tmp
|
243
|
+
true
|
244
|
+
end
|
245
|
+
|
246
|
+
# Smart image crop
|
247
|
+
#
|
248
|
+
# @param [Number] width image new width
|
249
|
+
# @param [Number] height image new height
|
250
|
+
# @param [MiniMagick::Image] img image
|
251
|
+
# @param [String] gravity crop around
|
252
|
+
#
|
253
|
+
# @return [MiniMagick::Image] cropped image
|
254
|
+
def resize_to_fill(width, height, img, gravity = "Center")
|
255
|
+
cols, rows = img[:dimensions]
|
256
|
+
img.combine_options do |cmd|
|
257
|
+
if width != cols || height != rows
|
258
|
+
scale_x = width / cols.to_f
|
259
|
+
scale_y = height / rows.to_f
|
260
|
+
if scale_x >= scale_y
|
261
|
+
cols = (scale_x * (cols + 0.5)).round
|
262
|
+
rows = (scale_x * (rows + 0.5)).round
|
263
|
+
cmd.resize cols.to_s
|
264
|
+
else
|
265
|
+
cols = (scale_y * (cols + 0.5)).round
|
266
|
+
rows = (scale_y * (rows + 0.5)).round
|
267
|
+
cmd.resize "x#{rows}"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
cmd.gravity gravity
|
272
|
+
cmd.background "rgba(255,255,255,0.0)"
|
273
|
+
cmd.extent "#{width}x#{height}" if cols != width || rows != height
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
# Creates simple collage 5x2 from 10 images
|
278
|
+
#
|
279
|
+
# @param [Hash] opts
|
280
|
+
# @option opts [Array<String>] :files file paths for collage images
|
281
|
+
#
|
282
|
+
# @return [true] collage created successfully
|
283
|
+
# @return [false] something went wrong
|
284
|
+
# @deprecated First collage implementation
|
285
|
+
def collage_simple(opts = {})
|
286
|
+
unless opts[:files].size == IMG_COUNT
|
287
|
+
info "No images for collage"
|
288
|
+
return false
|
289
|
+
end
|
290
|
+
|
291
|
+
begin
|
292
|
+
montage = MiniMagick::Tool::Montage.new
|
293
|
+
opts[:files].each do |file|
|
294
|
+
montage << resize(file: file)
|
295
|
+
end
|
296
|
+
montage << "-mode"
|
297
|
+
montage << "Concatenate"
|
298
|
+
montage << "-background"
|
299
|
+
montage << "none"
|
300
|
+
montage << "-geometry"
|
301
|
+
montage << "#{@img_width}x#{@img_height}+0+0"
|
302
|
+
montage << "-tile"
|
303
|
+
montage << "5x2"
|
304
|
+
montage << "#{@img_path}#{@collage_file}.jpg"
|
305
|
+
puts montage.inspect.to_s
|
306
|
+
montage.call
|
307
|
+
rescue StandardError => e
|
308
|
+
warn "Image.collage: caught exception #{e}"
|
309
|
+
raise e if RAISE_ERROR
|
310
|
+
end
|
311
|
+
true
|
312
|
+
end
|
313
|
+
|
314
|
+
private
|
315
|
+
|
316
|
+
# Montage Collage - resizing images for rows
|
317
|
+
# 1 row - 3 images
|
318
|
+
# 2 row - 4 images
|
319
|
+
# 3 row - 3 images
|
320
|
+
#
|
321
|
+
# @param [Hash] opts
|
322
|
+
# @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
|
323
|
+
#
|
324
|
+
# @return [Array<String>] Array of file paths for resized images
|
325
|
+
def montage_resize(opts = {})
|
326
|
+
files = []
|
327
|
+
case opts[:row]
|
328
|
+
when 1
|
329
|
+
(0..2).each do |i|
|
330
|
+
files << resize(file: opts[:files][i])
|
331
|
+
end
|
332
|
+
when 2
|
333
|
+
(3..6).each do |i|
|
334
|
+
files << resize(file: opts[:files][i], width: @img_width * 0.75)
|
335
|
+
end
|
336
|
+
when 3
|
337
|
+
(7..9).each do |i|
|
338
|
+
files << resize(file: opts[:files][i])
|
339
|
+
end
|
340
|
+
when 4
|
341
|
+
(1..3).each do |i|
|
342
|
+
files << "#{@img_path}tmp/#{@collage_file}-#{i}.jpg"
|
343
|
+
end
|
344
|
+
end
|
345
|
+
files
|
346
|
+
end
|
347
|
+
|
348
|
+
# Montage Collage - setting images geometry for rows
|
349
|
+
# 1 row - 3 images
|
350
|
+
# 2 row - 4 images
|
351
|
+
# 3 row - 3 images
|
352
|
+
#
|
353
|
+
# @param [Hash] opts
|
354
|
+
# @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
|
355
|
+
#
|
356
|
+
# @return [String] images geometry
|
357
|
+
def montage_geometry(opts = {})
|
358
|
+
case opts[:row]
|
359
|
+
when 1, 3 then "#{@img_width}x#{@img_height}+0+0"
|
360
|
+
when 2 then "#{@img_width * 0.75}x#{@img_height}+0+0"
|
361
|
+
when 4 then "#{@img_width * 3}x#{@img_height}+0+0"
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
# Montage Collage - setting images tile for rows
|
366
|
+
# 1 row - 3 images
|
367
|
+
# 2 row - 4 images
|
368
|
+
# 3 row - 3 images
|
369
|
+
#
|
370
|
+
# @param [Hash] opts
|
371
|
+
# @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
|
372
|
+
#
|
373
|
+
# @return [String] images tile
|
374
|
+
def montage_tile(opts = {})
|
375
|
+
case opts[:row]
|
376
|
+
when 1, 3 then "3x1"
|
377
|
+
when 2 then "4x1"
|
378
|
+
when 4 then "1x3"
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
# Montage Collage - setting images paths for rows
|
383
|
+
# 1 row - 3 images
|
384
|
+
# 2 row - 4 images
|
385
|
+
# 3 row - 3 images
|
386
|
+
#
|
387
|
+
# @param [Hash] opts
|
388
|
+
# @option opts [Number] :row collage row 1..4 (4 row - final collage from first 3 rows)
|
389
|
+
#
|
390
|
+
# @return [String] images path
|
391
|
+
def montage_img_path(opts = {})
|
392
|
+
case opts[:row]
|
393
|
+
when 1..3 then "#{@img_path}tmp/#{@collage_file}-#{opts[:row]}.jpg"
|
394
|
+
when 4 then "#{@img_path}#{@collage_file}.jpg"
|
395
|
+
else ""
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
Binary file
|
data/tmp/cat.jpg
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: FlickrCollage
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chromium
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rdoc
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.2.2
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 4.2.2
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - "~>"
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: 4.2.2
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 4.2.2
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: aruba
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.14.2
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.14.2
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: methadone
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 1.9.2
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 1.9.2
|
85
|
+
type: :runtime
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - "~>"
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: 1.9.2
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 1.9.2
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: test-unit
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - "~>"
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 3.2.1
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 3.2.1
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 3.2.1
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: 3.2.1
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: flickraw
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: 0.9.9
|
122
|
+
type: :runtime
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - "~>"
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: 0.9.9
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: mini_magick
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: 4.5.1
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 4.5.1
|
139
|
+
type: :runtime
|
140
|
+
prerelease: false
|
141
|
+
version_requirements: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 4.5.1
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
version: 4.5.1
|
149
|
+
description: |-
|
150
|
+
This gem creates collage from 10 top-rated Flickr images for your keywords.
|
151
|
+
It's a part of coding challenge and it's fun.
|
152
|
+
email:
|
153
|
+
- crcs2o4@gmail.com
|
154
|
+
executables: []
|
155
|
+
extensions: []
|
156
|
+
extra_rdoc_files: []
|
157
|
+
files:
|
158
|
+
- ".gitignore"
|
159
|
+
- FlickrCollage.gemspec
|
160
|
+
- Gemfile
|
161
|
+
- Gemfile.lock
|
162
|
+
- LICENSE.txt
|
163
|
+
- README.md
|
164
|
+
- Rakefile
|
165
|
+
- bin/FlickrCollage
|
166
|
+
- bin/console
|
167
|
+
- bin/setup
|
168
|
+
- doc/FlickrCollage.html
|
169
|
+
- doc/FlickrCollage/Dictionary.html
|
170
|
+
- doc/FlickrCollage/Flickr.html
|
171
|
+
- doc/FlickrCollage/Image.html
|
172
|
+
- doc/_index.html
|
173
|
+
- doc/class_list.html
|
174
|
+
- doc/css/common.css
|
175
|
+
- doc/css/full_list.css
|
176
|
+
- doc/css/style.css
|
177
|
+
- doc/file.README.html
|
178
|
+
- doc/file_list.html
|
179
|
+
- doc/flickrCollage.jpg
|
180
|
+
- doc/frames.html
|
181
|
+
- doc/index.html
|
182
|
+
- doc/js/app.js
|
183
|
+
- doc/js/full_list.js
|
184
|
+
- doc/js/jquery.js
|
185
|
+
- doc/method_list.html
|
186
|
+
- doc/top-level-namespace.html
|
187
|
+
- lib/FlickrCollage.rb
|
188
|
+
- lib/FlickrCollage/version.rb
|
189
|
+
- tmp/Giant Robots Smashing into Other Giant Robots.jpg
|
190
|
+
- tmp/cat.jpg
|
191
|
+
homepage: https://github.com/CrCs2O4/FlickrCollage.git
|
192
|
+
licenses:
|
193
|
+
- MIT
|
194
|
+
metadata: {}
|
195
|
+
post_install_message:
|
196
|
+
rdoc_options: []
|
197
|
+
require_paths:
|
198
|
+
- lib
|
199
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - ">="
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '0'
|
204
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - ">="
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '0'
|
209
|
+
requirements: []
|
210
|
+
rubyforge_project:
|
211
|
+
rubygems_version: 2.5.1
|
212
|
+
signing_key:
|
213
|
+
specification_version: 4
|
214
|
+
summary: Create collage from 10 top-rated Flickr images for your keywords
|
215
|
+
test_files: []
|