wallzilla 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 82be8d70f275ad3b47b168a1fe9cb279c541d1c2
4
+ data.tar.gz: f3e379fd5291352e95d6dd86e791d823583dd293
5
+ SHA512:
6
+ metadata.gz: e2321f9bb4be9373dbff9207386855f3da863ae9c872fbdc53120999cefe116089ace10624deff2c7698ff0c8c519ecb7e3f6ee1e165e2ca275c9483030780f5
7
+ data.tar.gz: 4ea4016317fd6d494210f389fc87354dbc730c74a87733e18c52bca1ed9e7874ee078e076b9fbdba3d3ea081810ee530ba2a3092eba82ca73a52d5de73957fb5
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # rspec failure tracking
12
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.1
5
+ before_install: gem install bundler -v 1.15.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in wallzilla.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Yury Batenko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,112 @@
1
+ # Wallzilla
2
+
3
+ **Wallzilla** very simple ruby gem with CLI for generating mosaic images from Flickr.
4
+
5
+ It provides:
6
+
7
+ * accepts a list of search keywords as arguments
8
+ * queries the Flickr API for the top-rated (term: interestingness) image for each keyword
9
+ * downloads the results
10
+ * assembles a collage grid from ten images and
11
+ * writes the result to a user-supplied filenameds
12
+
13
+ If given less than ten keywords, or if any keyword fails to
14
+ result in a match, gem retrieve random words from a dictionary
15
+ source such as `/usr/share/dict/words` or provided one.
16
+
17
+ I like the idea to keep library as small as I can, so it has no external dependancies (except `imagemagick`)
18
+
19
+ ## Example
20
+
21
+ $ wz --key YOUR_FLICKR_KEY winter boy rocket racoon fear mars
22
+
23
+ <img src="https://raw.github.com/svenyurgensson/wallzilla/master/images/output.jpg" alt="Example resulting mosaic"/>
24
+
25
+ ## Installation
26
+
27
+ ### Prerequisites:
28
+
29
+ This gem assumes that you have `imagemagick` installed in your system.
30
+
31
+ You can install it from [official site](http://www.imagemagick.org/script/download.php)
32
+
33
+ ### CLI installation:
34
+
35
+ $ gem install wallzilla
36
+
37
+ ### Programm interface
38
+
39
+ Add this line to your application's Gemfile:
40
+
41
+ ```ruby
42
+ gem 'wallzilla'
43
+ ```
44
+ And then execute:
45
+
46
+ $ bundle
47
+
48
+ ## CLI Usage
49
+
50
+ ```shell
51
+ USAGE: wz [options] kw1 kw2 kw3 ... kw10
52
+ -o, --output FILE Write result to dir/to/filename.extname
53
+ -k, --key key_string Flickr API key string
54
+ -w, --words [FILE] Read words from dir/to/words file
55
+ -t, --tile [5x2 | 4x3] Images positioning columns x rows (4x3)
56
+ -b, --background color Fill background color (black)
57
+ -v, --version Show version
58
+ ```
59
+ ### Options:
60
+
61
+ `-o, --output FILE`
62
+ Save resulting mosaic to file. Default is `output.jpg` in current directory.
63
+
64
+ `-k, --key key_string`
65
+ Flickr API key, you could get one [here](https://www.flickr.com/services/apps/create/apply)
66
+ You also could set environment variable `export FLICKR_KEY=YOUR_KEY` somewhere in your profile scripts or in command line:
67
+
68
+ `$ FLICKR_KEY=YOUR_KEY wz winter boy rocket racoon fear mars`
69
+
70
+ `-b, --background color`
71
+ You could find color names [here](http://www.imagemagick.org/script/color.php), default is `black`
72
+
73
+ `-w, --words [FILE]`
74
+ Just plain text file filled with words you like, line by line. Default words sources: `/usr/share/dict/words`, `/usr/share/words`.
75
+
76
+ `-t, --tile [5x2 | 4x3]`
77
+ You could choose how images will be placed in resulting mosaic `columns X rows`, default is `4x3`
78
+
79
+ ## Library usage
80
+
81
+ ```ruby
82
+ Wallzilla::Runner.build(kw: %w(winter boy rocket racoon fear mars),
83
+ result: "output.jpg",
84
+ key: YOUR_FLICKR_KEY,
85
+ words: nil, # optional
86
+ tiles: "4x3", # optional
87
+ bg: "black") # optional
88
+ ```
89
+ As result you have file `output.jpg` in working directory.
90
+
91
+ ## Development
92
+
93
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
94
+
95
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
96
+
97
+ ## Contributing
98
+
99
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Svenyurgensson/wallzilla.
100
+
101
+ ## License
102
+
103
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
104
+
105
+ ## Progressbar
106
+
107
+ Progressbar code borrowed from:
108
+
109
+ # Ruby/ProgressBar - a text progress bar library
110
+ #
111
+ # Copyright (C) 2001-2005 Satoru Takabayashi <satoru@namazu.org>
112
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "wallzilla"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+
11
+ begin
12
+ require "pry"
13
+ Pry.start
14
+ rescue LoadError
15
+ require "irb"
16
+ IRB.start(__FILE__)
17
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/exe/wz ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $: << File.expand_path("../../lib/", __FILE__)
5
+
6
+ require "wallzilla"
7
+ require "optparse"
8
+
9
+ `#{Wallzilla::Montage.montage} --version`
10
+ if $? != 0
11
+ puts "You should have imagemagick installed!"
12
+ exit 1
13
+ end
14
+
15
+ help_usage = "USAGE: #{$PROGRAM_NAME} [options] kw1 kw2 kw3 ... kw10"
16
+
17
+ OptionParser.new do |o|
18
+ o.banner = help_usage
19
+
20
+ o.on_tail("-v", "--version", "Show version") { puts "Wallzilla version: #{Wallzilla::VERSION}"; exit 0 }
21
+
22
+ o.on("-o", "--output FILE", "Write result to dir/to/filename.extname") do |f|
23
+ ENV["result_file"] = f
24
+ end
25
+
26
+ o.on("-w", "--words [FILE]", "Read words from dir/to/words file") do |f|
27
+ ENV["words_file"] = f
28
+ end
29
+
30
+ o.on("-t", "--tile [5x2 | 4x3]", "Images positioning columns x rows (4x3)") do |f|
31
+ ENV["tiles"] = "4x3"
32
+ end
33
+
34
+ o.on("-b", "--background color", "Fill background color (black)") do |f|
35
+ ENV["background_color"] = f || "black"
36
+ end
37
+
38
+ o.on("-k", "--key key_string", "Flickr API key string") do |f|
39
+ ENV["FLICKR_KEY"] ||= f
40
+ end
41
+
42
+ end.parse!
43
+
44
+ require "wallzilla/progressbar"
45
+ # Progress function.
46
+ # Expects :started with file, :progress with current line and :finished or :interrupted when done.
47
+ # <tt>message</tt> Current state (:started, :finished, :interupted or :progress).
48
+ # <tt>value</tt> File or current line.
49
+ def handle_progress(message, value = nil)
50
+ case message
51
+ when :started
52
+ @progress_bar =
53
+ Wallzilla::ProgressBar.new("Wallzilla", Wallzilla::Runner::KEYWORDS_SIZE, STDERR)
54
+ when :finished
55
+ @progress_bar.finish
56
+ @progress_bar = nil
57
+ when :interrupted
58
+ if @progress_bar
59
+ @progress_bar.halt
60
+ @progress_bar = nil
61
+ end
62
+ when :progress
63
+ @progress_bar.set(value)
64
+ end
65
+ end
66
+
67
+ begin
68
+ Wallzilla::Runner.run!(ARGV, progressbar: method(:handle_progress))
69
+
70
+ puts
71
+ puts "Search Flickr for best photos (#{Wallzilla::Runner::KEYWORDS_SIZE}) with text keywords: #{Wallzilla::Runner.keywords}"
72
+ puts "Result mozaic image saved to: #{Wallzilla::Runner.output_file}"
73
+ puts Wallzilla::Runner::COPYRIGHT
74
+ puts
75
+ rescue => e
76
+ puts
77
+ puts e.message
78
+ puts
79
+ exit 1
80
+ end
Binary file
@@ -0,0 +1,8 @@
1
+ require "wallzilla/version"
2
+ require "wallzilla/words"
3
+ require "wallzilla/fetcher"
4
+ require "wallzilla/montage"
5
+ require "wallzilla/runner"
6
+
7
+ module Wallzilla
8
+ end
@@ -0,0 +1,75 @@
1
+ require "net/http"
2
+ require "tempfile"
3
+ require "uri"
4
+ require "json"
5
+
6
+ module Wallzilla
7
+ module Fetcher
8
+ extend Fetcher
9
+ WRONG_API_KEY = "Your Flicker API key "
10
+
11
+ # Downoads image to tempfile for the given keyword
12
+ # returns:
13
+ # file handler if image found and downloaded
14
+ # nil if no image found
15
+ def fetch(keyword)
16
+ if image = search_image(keyword)
17
+ download_photo(image)
18
+ else
19
+ nil
20
+ end
21
+ end
22
+
23
+ def search_image(keyword)
24
+ url = flickr_search_url(keyword)
25
+ uri = URI.parse(url)
26
+ response = Net::HTTP.get_response(uri)
27
+
28
+ result = JSON.parse(response.body)
29
+
30
+ if (100...117).cover?(result["code"])
31
+ fail(result["message"])
32
+ end
33
+
34
+ photos = result["photos"]["photo"]
35
+ return nil if photos.empty?
36
+
37
+ photos.first[photo_size_code]
38
+ end
39
+
40
+ def download_photo(url)
41
+ uri = URI.parse(url)
42
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == "https") do |http|
43
+ resp = http.get(uri.path)
44
+ file = Tempfile.new(["flickr", ".jpg"], encoding: "binary")
45
+ file.binmode
46
+ file.write(resp.body)
47
+ file.flush
48
+ file
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def flickr_search_url(keyword, key = flickr_api_key)
55
+ "https://api.flickr.com/services/rest/?method=flickr.photos.search" +
56
+ "&api_key=#{key}" +
57
+ "&text=#{keyword}" +
58
+ "&content_type=1" + # Only photos
59
+ "&sort=interestingness-desc" +
60
+ "&extras=#{photo_size_code}" +
61
+ "&media=photos" +
62
+ "&per_page=1" +
63
+ "&format=json" +
64
+ "&nojsoncallback=1"
65
+ end
66
+
67
+ def photo_size_code
68
+ "url_c"
69
+ end
70
+
71
+ def flickr_api_key
72
+ Wallzilla::Runner.flickr_api_key
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,15 @@
1
+ module Wallzilla
2
+ module Montage
3
+ extend Montage
4
+
5
+ def process!(file_handlers, output, fill)
6
+ files = file_handlers.map(&:path).join(" ")
7
+ cmd = "#{montage} -mode concatenate -background #{fill} -tile 5x2 #{files} #{output}"
8
+ system(cmd)
9
+ end
10
+
11
+ def montage
12
+ Gem.win_platform? ? "montage.exe" : "montage"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,237 @@
1
+ #
2
+ # Ruby/ProgressBar - a text progress bar library
3
+ #
4
+ # Copyright (C) 2001-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms
9
+ # of Ruby's license.
10
+
11
+ module Wallzilla
12
+ class ProgressBar
13
+ VERSION = '0.9'
14
+
15
+ def initialize(title, total, out = STDERR)
16
+ @title = title
17
+ @total = total
18
+ @out = out
19
+ @terminal_width = 80
20
+ @bar_mark = '='
21
+ @current = 0
22
+ @previous = 0
23
+ @finished_p = false
24
+ @start_time = Time.now
25
+ @previous_time = @start_time
26
+ @title_width = 24
27
+ @format = "%-#{@title_width}s %3d%% %s %s"
28
+ @format_arguments = [:title, :percentage, :bar, :stat]
29
+ clear
30
+ show
31
+ end
32
+
33
+ attr_reader :title
34
+ attr_reader :current
35
+ attr_reader :total
36
+ attr_accessor :start_time
37
+
38
+ private
39
+
40
+ def fmt_bar
41
+ bar_width = do_percentage * @terminal_width / 100
42
+ sprintf('[%s%s]',
43
+ @bar_mark * bar_width,
44
+ ' ' * (@terminal_width - bar_width))
45
+ end
46
+
47
+ def fmt_percentage
48
+ do_percentage
49
+ end
50
+
51
+ def fmt_stat
52
+ if @finished_p then elapsed else eta end
53
+ end
54
+
55
+ def fmt_stat_for_file_transfer
56
+ if @finished_p then
57
+ sprintf('%s %s %s', bytes, transfer_rate, elapsed)
58
+ else
59
+ sprintf('%s %s %s', bytes, transfer_rate, eta)
60
+ end
61
+ end
62
+
63
+ def fmt_title
64
+ @title[0, (@title_width - 1)] + ':'
65
+ end
66
+
67
+ def convert_bytes(bytes)
68
+ if bytes < 1024
69
+ sprintf('%6dB', bytes)
70
+ elsif bytes < 1024 * 1000 # 1000kb
71
+ sprintf('%5.1fKB', bytes.to_f / 1024)
72
+ elsif bytes < 1024 * 1024 * 1000 # 1000mb
73
+ sprintf('%5.1fMB', bytes.to_f / 1024 / 1024)
74
+ else
75
+ sprintf('%5.1fGB', bytes.to_f / 1024 / 1024 / 1024)
76
+ end
77
+ end
78
+
79
+ def transfer_rate
80
+ bytes_per_second = @current.to_f / (Time.now - @start_time)
81
+ sprintf('%s/s', convert_bytes(bytes_per_second))
82
+ end
83
+
84
+ def bytes
85
+ convert_bytes(@current)
86
+ end
87
+
88
+ def format_time(t)
89
+ t = t.to_i
90
+ sec = t % 60
91
+ min = (t / 60) % 60
92
+ hour = t / 3600
93
+ sprintf('%02d:%02d:%02d', hour, min, sec)
94
+ end
95
+
96
+ # ETA stands for Estimated Time of Arrival.
97
+ def eta
98
+ if @current == 0
99
+ 'ETA: --:--:--'
100
+ else
101
+ elapsed = Time.now - @start_time
102
+ eta = elapsed * @total / @current - elapsed
103
+ sprintf('ETA: %s', format_time(eta))
104
+ end
105
+ end
106
+
107
+ def elapsed
108
+ elapsed = Time.now - @start_time
109
+ sprintf('Time: %s', format_time(elapsed))
110
+ end
111
+
112
+ def eol
113
+ if @finished_p then "\n" else "\r" end
114
+ end
115
+
116
+ def do_percentage
117
+ if @total.zero?
118
+ 100
119
+ else
120
+ @current * 100 / @total
121
+ end
122
+ end
123
+
124
+ def show
125
+ arguments = @format_arguments.map do |method|
126
+ method = sprintf('fmt_%s', method)
127
+ send(method)
128
+ end
129
+ line = sprintf(@format, *arguments)
130
+
131
+ width = terminal_width(80, @out)
132
+ if line.length == width - 1
133
+ @out.print(line + eol)
134
+ @out.flush
135
+ elsif line.length >= width
136
+ @terminal_width = [@terminal_width - (line.length - width + 1), 0].max
137
+ if @terminal_width == 0 then @out.print(line + eol) else show end
138
+ else # line.length < width - 1
139
+ @terminal_width += width - line.length + 1
140
+ show
141
+ end
142
+ @previous_time = Time.now
143
+ end
144
+
145
+ def show_if_needed
146
+ if @total.zero?
147
+ cur_percentage = 100
148
+ prev_percentage = 0
149
+ else
150
+ cur_percentage = (@current * 100 / @total).to_i
151
+ prev_percentage = (@previous * 100 / @total).to_i
152
+ end
153
+
154
+ # Use "!=" instead of ">" to support negative changes
155
+ if cur_percentage != prev_percentage ||
156
+ Time.now - @previous_time >= 1 || @finished_p
157
+ show
158
+ end
159
+ end
160
+
161
+ public
162
+
163
+ def clear
164
+ @out.print "\r"
165
+ @out.print(' ' * (terminal_width(80) - 1))
166
+ @out.print "\r"
167
+ end
168
+
169
+ def finish
170
+ @current = @total
171
+ @finished_p = true
172
+ show
173
+ end
174
+
175
+ def finished?
176
+ @finished_p
177
+ end
178
+
179
+ def file_transfer_mode
180
+ @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
181
+ end
182
+
183
+ attr_writer :format
184
+
185
+ attr_writer :format_arguments
186
+
187
+ def halt
188
+ @finished_p = true
189
+ show
190
+ end
191
+
192
+ def inc(step = 1)
193
+ @current += step
194
+ @current = @total if @current > @total
195
+ show_if_needed
196
+ @previous = @current
197
+ end
198
+
199
+ def set(count)
200
+ count = 0 if count < 0
201
+ count = @total if count > @total
202
+
203
+ @current = count
204
+ show_if_needed
205
+ @previous = @current
206
+ end
207
+
208
+ def inspect
209
+ "#<ProgressBar:#{@current}/#{@total}>"
210
+ end
211
+
212
+ # Try to determine the terminal with.
213
+ # If it is not possible to to so, it returns the default_width.
214
+ # <tt>default_width</tt> Defaults to 81
215
+ def terminal_width(default_width = 81, out = STDOUT)
216
+ tiocgwinsz = 0x5413
217
+ data = [0, 0, 0, 0].pack('SSSS')
218
+ if !RUBY_PLATFORM.include?('java') && out.ioctl(tiocgwinsz, data) >= 0 # JRuby crashes on ioctl
219
+ _, cols, _, _ = data.unpack('SSSS')
220
+ fail unless cols > 0
221
+ cols
222
+ else
223
+ fail
224
+ end
225
+ rescue
226
+ begin
227
+ IO.popen('stty -a 2>&1') do |pipe|
228
+ column_line = pipe.find { |line| /(\d+) columns/ =~ line }
229
+ fail unless column_line
230
+ Regexp.last_match[1].to_i
231
+ end
232
+ rescue
233
+ default_width
234
+ end
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,117 @@
1
+ module Wallzilla
2
+ module Runner
3
+ extend Runner
4
+
5
+ KEYWORDS_SIZE = 10
6
+ KW_LEN_RANGE = 4...10
7
+ DEFAULT_FILENAME = "output.jpg"
8
+ NO_WORDS_FILE_FOUND = "Sorry, but no one words list file found!"
9
+ COPYRIGHT = "© 2017 Yury Batenko. Done with fun"
10
+
11
+ # Entry point for external calling Wallzilla image generation
12
+ #
13
+ def build(kw:, result:, key:, words: nil, tiles: "4x3", bg: "black")
14
+ @_output_file = result
15
+ @_key = key
16
+ @wordlist = words
17
+ @tiles = tiles
18
+ @_fill = bg
19
+
20
+ run!(kw)
21
+ end
22
+
23
+ def run!(kw, progressbar: nil)
24
+ @progressbar = progressbar
25
+ maybe_show_progress(:started)
26
+
27
+ @keywords = normalize(kw)
28
+
29
+ photos = process_photos(keywords)
30
+
31
+ Wallzilla::Montage.process!(photos, output_file, fill)
32
+
33
+ maybe_show_progress(:finished)
34
+ rescue => e
35
+ maybe_show_progress(:interrupted)
36
+ raise e
37
+ ensure
38
+ clean(photos) if photos
39
+ end
40
+
41
+ def process_photos(kw)
42
+ kw.map.with_index(1) do |word, idx|
43
+ fetched_photo = loop do
44
+ url = fetch(word)
45
+ break url if url
46
+ word = random_word
47
+ end
48
+ maybe_show_progress(:progress, idx)
49
+ fetched_photo
50
+ end
51
+ end
52
+
53
+ def clean(photos)
54
+ photos.map { |x| x.close; x.unlink }
55
+ end
56
+
57
+ def fetch(kw)
58
+ Wallzilla::Fetcher.fetch(kw)
59
+ end
60
+
61
+ def keywords
62
+ @keywords
63
+ end
64
+
65
+ def fill
66
+ return @_fill if defined?(@_fill)
67
+
68
+ @_fill =
69
+ ENV["background_color"] || "black"
70
+ end
71
+
72
+ def output_file
73
+ return @_output_file if defined?(@_output_file)
74
+
75
+ @_output_file =
76
+ ENV["result_file"] || File.join(Dir.pwd, DEFAULT_FILENAME)
77
+ end
78
+
79
+ def flickr_api_key
80
+ return @_key if defined?(@_key)
81
+
82
+ @_key = ENV.fetch("FLICKR_KEY") do |e|
83
+ fail("You should provide Flickr API application key! (--key key_string)")
84
+ end
85
+ end
86
+
87
+ def dict_file
88
+ return @_dict if defined?(@_dict)
89
+
90
+ @_dict = maybe_dictionaries.
91
+ uniq.
92
+ compact.
93
+ select { |f| FileTest.readable?(f) }.first || fail(NO_WORDS_FILE_FOUND)
94
+ end
95
+
96
+ def maybe_dictionaries
97
+ Array(@wordlist) +
98
+ Array(ENV["words_file"]) +
99
+ ["/usr/share/dict/words", "/usr/share/words"]
100
+ end
101
+
102
+ def normalize(kw)
103
+ Array.new(KEYWORDS_SIZE) do |i|
104
+ kw[i] || random_word
105
+ end
106
+ end
107
+
108
+ def random_word
109
+ Wallzilla::Words.random_word(KW_LEN_RANGE)
110
+ end
111
+
112
+ def maybe_show_progress(msg, value = nil)
113
+ return unless @progressbar
114
+ @progressbar.call(msg, value)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,3 @@
1
+ module Wallzilla
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ module Wallzilla
2
+ module Words
3
+ extend Words
4
+
5
+ # @params [size_range] # Example: 3...9
6
+ #
7
+ # returns:
8
+ # random word from dictionary word list file
9
+ def random_word(size_range, window = 4)
10
+ f = File.open(Wallzilla::Runner.dict_file, 'r')
11
+ fsize = f.size
12
+ loop do
13
+ f.seek(rand(fsize))
14
+ next if f.eof?
15
+ f.readline
16
+ window.times do
17
+ break if f.eof
18
+ w = f.readline.strip
19
+ if size_range.cover? w.size
20
+ f.close
21
+ return w
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "wallzilla/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wallzilla"
8
+ spec.version = Wallzilla::VERSION
9
+ spec.authors = ["Yury Batenko"]
10
+ spec.email = ["jurbat@gmail.com"]
11
+
12
+ spec.summary = %q{Flickr best images wall generator based on provided tags}
13
+ spec.description = %q{Flickr best images wall generator based on provided tags}
14
+ spec.homepage = "https://github.com/svenyurgensson/wallzilla"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.15"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wallzilla
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yury Batenko
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-06-20 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.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
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
+ description: Flickr best images wall generator based on provided tags
42
+ email:
43
+ - jurbat@gmail.com
44
+ executables:
45
+ - wz
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - ".gitignore"
50
+ - ".rspec"
51
+ - ".travis.yml"
52
+ - Gemfile
53
+ - LICENSE.txt
54
+ - README.md
55
+ - Rakefile
56
+ - bin/console
57
+ - bin/setup
58
+ - exe/wz
59
+ - images/output.jpg
60
+ - lib/wallzilla.rb
61
+ - lib/wallzilla/fetcher.rb
62
+ - lib/wallzilla/montage.rb
63
+ - lib/wallzilla/progressbar.rb
64
+ - lib/wallzilla/runner.rb
65
+ - lib/wallzilla/version.rb
66
+ - lib/wallzilla/words.rb
67
+ - wallzilla.gemspec
68
+ homepage: https://github.com/svenyurgensson/wallzilla
69
+ licenses:
70
+ - MIT
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.6.12
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Flickr best images wall generator based on provided tags
92
+ test_files: []