wallzilla 0.1.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.
@@ -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: []