flico 0.0.2

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: d21b66c84738f5f1ef760829af88cf4f40d7c8fb
4
+ data.tar.gz: b27c22ad9028030c2be42e66b9d00a7f42534811
5
+ SHA512:
6
+ metadata.gz: affd36e436da1a851f4e3d43382b8530d17c8db550d220bf89063567076cbb61d87c69e4068ce5bd4dc4b0492abd29fe0a570c50a85c8935844d911d66ce7a3c
7
+ data.tar.gz: 9186a05a4a81b5f15eea86c955eb8e92b1e6061bf7ae84fa401393e07c12a26b30df7c8a2133cdbab9264d8ff22b3375c3987f41109025f7ddb8c72565a7f928
@@ -0,0 +1,4 @@
1
+ /.bundle/
2
+ /pkg/
3
+ /tmp/
4
+ .tags*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1 @@
1
+ 2.3.0
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
@@ -0,0 +1,39 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ flico (0.0.1)
5
+ flickraw
6
+ mini_magick
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ diff-lcs (1.3)
12
+ flickraw (0.9.9)
13
+ mini_magick (4.7.1)
14
+ rake (12.0.0)
15
+ rspec (3.6.0)
16
+ rspec-core (~> 3.6.0)
17
+ rspec-expectations (~> 3.6.0)
18
+ rspec-mocks (~> 3.6.0)
19
+ rspec-core (3.6.0)
20
+ rspec-support (~> 3.6.0)
21
+ rspec-expectations (3.6.0)
22
+ diff-lcs (>= 1.2.0, < 2.0)
23
+ rspec-support (~> 3.6.0)
24
+ rspec-mocks (3.6.0)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.6.0)
27
+ rspec-support (3.6.0)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ bundler
34
+ flico!
35
+ rake
36
+ rspec
37
+
38
+ BUNDLED WITH
39
+ 1.15.1
@@ -0,0 +1,9 @@
1
+ The MIT License
2
+
3
+ Copyright 2017 Amandeep Bhamra
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ # flico
2
+
3
+ ## Description
4
+
5
+ A command line tool to create collage using Flicr Images. It accepts 10 search keywords as arguments then, queries the Flickr API for the top-rated image for each keyword, downloads them, crops them rectangularly, assembles a collage grid from them and saves with user given file name.
6
+
7
+ If given less than ten keywords, or if any keyword fails to
8
+ result in a match, it retrieves random words from a dictionary
9
+ source such as `/usr/share/dict/words`. Repeating as necessary
10
+ until you have gathered ten images.
11
+
12
+ ## Setup
13
+
14
+ 1. [ImageMagick](http://www.imagemagick.org/). Use Homebrew for OSX `brew install imagemagick`
15
+
16
+ 2. Flickr API Key and Secret. Set them as environment variables,
17
+
18
+ `export FLICKR_KEY=**************`
19
+
20
+ `export FLICKR_SECRET=*******`
21
+
22
+ 3. Install gem using: `gem install flico`
23
+
24
+ 4. Make a collage using: `flico -f file_name keyword1 keyword2, keyword3, keyword4, keyword5...`
@@ -0,0 +1,5 @@
1
+ require "rspec/core/rake_task"
2
+ require "bundler/gem_tasks"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task :default => :spec
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "flico"
5
+ require "irb"
6
+
7
+ IRB.start
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << './lib'
3
+ require 'flico'
4
+ Flico::CommandLineInterface.start(ARGV)
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+ bundle install
@@ -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
+
5
+ Gem::Specification.new do |spec|
6
+
7
+ spec.version = '0.0.2'
8
+ spec.name = 'flico'
9
+ spec.summary = %q{CLI tool to create collage using Flickr}
10
+ spec.homepage = "https://github.com/amandeepbhamra/flico"
11
+ spec.license = 'MIT'
12
+
13
+ spec.authors = ['Amandeep Bhamra']
14
+ spec.email = ["amandeep.bhamra@gmail.com"]
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.bindir = 'bin'
18
+ spec.executables = 'flico'
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'flickraw'
22
+ spec.add_dependency 'mini_magick'
23
+ spec.add_development_dependency "bundler"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "rspec"
26
+ end
@@ -0,0 +1,79 @@
1
+ require 'flickraw'
2
+ require 'ostruct'
3
+ require 'optparse'
4
+ require 'flico/app'
5
+ require 'flico/flickr_command'
6
+ require 'flico/dictionary'
7
+ require 'flico/saver'
8
+ require 'flico/collager'
9
+
10
+ module Flico
11
+
12
+ class CommandLineInterface
13
+
14
+ def self.parse_args(args)
15
+ options = {}
16
+ OptionParser.new do |opts|
17
+ opts.banner = "Usage: flico [options] [10 keywords with space as delimiter]"
18
+ opts.on("-f", "--file_name [FileName]", "Collage FileName") do |f|
19
+ options[:file_name] = f
20
+ end
21
+ end.parse!(args)
22
+ [args, options]
23
+ end
24
+
25
+ def self.start(args)
26
+ keywords, options = parse_args(args)
27
+ puts "Given Keywords: #{keywords.join(' ')} with Options: #{options}"
28
+ resources = validate_resources(keywords, options)
29
+ App.new(resources).create_collage
30
+ end
31
+
32
+ def self.validate_resources(keywords, options={})
33
+ dictionary = validate_dictionary
34
+ dictionary.append(keywords)
35
+ col = SaveCollage.new
36
+ col.output_file_name = options[:file_name]
37
+
38
+ Resource.new(flickr_api: validate_flickr_api, dictionary: dictionary, fetch_image: FetchImage.new, collager: Collager.new, save_collage: col)
39
+ end
40
+
41
+ def self.validate_flickr_api
42
+ key, secret = ENV['FLICKR_KEY'], ENV['FLICKR_SECRET']
43
+ unless key == nil && secret == nil
44
+ FlickRaw.api_key = key
45
+ FlickRaw.shared_secret = secret
46
+ FlickrCommand.setup(FlickRaw::Flickr.new)
47
+ else
48
+ STDERR.puts "Performing AutoExit due to missing required environment variables: FLICKR_KEY and FLICKR_SECRET"
49
+ exit 1
50
+ end
51
+ end
52
+
53
+ def self.validate_dictionary
54
+ dictionary_path = '/usr/share/dict/words'
55
+ if File.exist?(dictionary_path)
56
+ dictionary = Dictionary.new(dictionary_path)
57
+ else
58
+ STDERR.puts "Performing AutoExit due to missing required dictionary at path: #{dictionary_path}"
59
+ exit 1
60
+ end
61
+ end
62
+
63
+ end
64
+
65
+ class Resource
66
+
67
+ attr_reader :flickr_api, :dictionary, :fetch_image, :collager, :save_collage
68
+
69
+ def initialize(params={})
70
+ @flickr_api = params.fetch(:flickr_api)
71
+ @dictionary = params.fetch(:dictionary)
72
+ @fetch_image = params.fetch(:fetch_image)
73
+ @collager = params.fetch(:collager)
74
+ @save_collage = params.fetch(:save_collage)
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,45 @@
1
+ module Flico
2
+
3
+ class ApplicationError < StandardError; end
4
+ class KeywordMissing < StandardError; end
5
+ class NoImage < StandardError; end
6
+ class FetchingError < StandardError; end
7
+
8
+ class App
9
+
10
+ attr_reader :resources
11
+
12
+ def initialize(resources)
13
+ @resources = resources
14
+ end
15
+
16
+ def create_collage
17
+ image_urls = []
18
+ begin
19
+ image_urls.push get_images
20
+ end while image_urls.count < 10
21
+ collage(image_urls)
22
+ end
23
+
24
+ def collage(images)
25
+ resources.save_collage.call(resources.collager.call(images))
26
+ end
27
+
28
+ def get_images
29
+ keywords_count = 10
30
+ keyword = resources.dictionary.call
31
+ image_url = resources.flickr_api.call(keyword)
32
+ downloaded_image = resources.fetch_image.call(image_url)
33
+ rescue NoImage => e
34
+ puts "Image not found for keyword '#{keyword}'. Message: #{e.message}. Retrying"
35
+ unless (tries -= 1) > 0
36
+ raise ApplicationError, "Failed getting image after retrying #{MAX_KEYWORD_RETRIES} times"
37
+ else
38
+ retry
39
+ end
40
+ rescue FetchingError => e
41
+ raise ApplicationError, e.message
42
+ end
43
+ end
44
+
45
+ end
@@ -0,0 +1,30 @@
1
+ module Flico
2
+
3
+ class Cell
4
+ attr_reader :x, :y, :width, :height
5
+
6
+ def initialize(x=0, y=0, width, height)
7
+ @x, @y = x, y
8
+ @width, @height = width, height
9
+ end
10
+
11
+ def aspect_ratio
12
+ width.to_f / height.to_f
13
+ end
14
+
15
+ def to_mm
16
+ "#{width}x#{height}+#{x}+#{y}"
17
+ end
18
+
19
+ def ==(o)
20
+ o.class == self.class && o.state == state
21
+ end
22
+
23
+ protected
24
+
25
+ def state
26
+ [@x, @y, @width, @height]
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,45 @@
1
+ require 'flico/grid'
2
+ require 'mini_magick'
3
+
4
+ module Flico
5
+
6
+ class Collager
7
+ attr_reader :grid
8
+
9
+ def initialize(grid=Grid.new)
10
+ @grid = grid
11
+ end
12
+
13
+ def call(image_urls)
14
+ images = image_urls.map { |p| MiniMagick::Image.open p.path }
15
+ temp_file = Tempfile.new ['collage_maker', '.png']
16
+ canvas = MiniMagick::Tool::Convert.new do |i|
17
+ i.size "#{grid.canv_width}x#{grid.canv_height}"
18
+ i.xc "white"
19
+ i << temp_file.path
20
+ end
21
+
22
+ resized_images = image_urls.map.with_index do |path, idx|
23
+ image = MiniMagick::Image.open path.path
24
+ image.crop(grid.crop_rectangle(idx, image.width, image.height).to_mm)
25
+ image.resize(grid.resize_rectangle(idx, image.width, image.height).to_mm)
26
+ print_to_canvas(image, grid.cell_rectangle(idx), temp_file)
27
+ end
28
+ temp_file
29
+ end
30
+
31
+ private
32
+
33
+ def print_to_canvas(image, rectangle, temp_file)
34
+ canvas = MiniMagick::Image.new temp_file.path
35
+ result = canvas.composite(image) do |c|
36
+ c.compose 'Over'
37
+ c.geometry rectangle.to_mm
38
+ end
39
+ result.write temp_file.path
40
+ temp_file.rewind
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,30 @@
1
+ module Flico
2
+
3
+ class Dictionary
4
+
5
+ def initialize(dictionary_path)
6
+ @dictionary_path = dictionary_path
7
+ @words = []
8
+ end
9
+
10
+ def call
11
+ @words.shift || dictionary_word
12
+ end
13
+
14
+ def append(keywords)
15
+ @words += keywords
16
+ end
17
+
18
+ private
19
+
20
+ def dictionary_word
21
+ selected_line = nil
22
+ File.foreach(@dictionary_path).each_with_index do |line, number|
23
+ selected_line = line if (rand < 1.0) / (number + 1)
24
+ end
25
+ selected_line.strip
26
+ end
27
+
28
+ end
29
+
30
+ end
@@ -0,0 +1,58 @@
1
+ module Flico
2
+
3
+ class FlickrCommand
4
+
5
+ def initialize(search_command:, sizes_command:)
6
+ @search_command = search_command
7
+ @sizes_command = sizes_command
8
+ end
9
+
10
+ def self.setup(flickraw)
11
+ new(search_command: SearchCommand.new(flickraw), sizes_command: SizesCommand.new(flickraw))
12
+ end
13
+
14
+ def call(keyword)
15
+ unless keyword.nil?
16
+ puts "Searching images for keyword: #{keyword}"
17
+ results = @search_command.call(keyword)
18
+ unless results.count == 0
19
+ get_image_url(results.first['id'])
20
+ else
21
+ STDERR.puts "No Image for keyword: #{keyword}"
22
+ end
23
+ else
24
+ STDERR.puts "Missing Keywords (can't be nil)"
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def get_image_url(photo_id)
31
+ sizes = @sizes_command.call(photo_id)
32
+ mid = sizes.count / 2
33
+ sizes[mid]['source']
34
+ end
35
+
36
+ end
37
+
38
+
39
+ class FlickrBase
40
+ attr_reader :api
41
+ def initialize(flickraw)
42
+ @api = flickraw
43
+ end
44
+ end
45
+
46
+ class SearchCommand < FlickrBase
47
+ def call(keyword)
48
+ api.photos.search({text: keyword, per_page: 10, sort: 'interestingness-desc'})
49
+ end
50
+ end
51
+
52
+ class SizesCommand < FlickrBase
53
+ def call(photo_id)
54
+ api.photos.getSizes(photo_id: photo_id)
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,81 @@
1
+ require 'flico/cell'
2
+
3
+ module Flico
4
+
5
+ class Grid
6
+
7
+ GRID = [[0,1,1,2], [3,4,5,6], [7,8,8,9]]
8
+ CANV_WIDTH = 1750
9
+ CANV_HEIGHT = 1250
10
+
11
+ def canv_width
12
+ CANV_WIDTH
13
+ end
14
+
15
+ def canv_height
16
+ CANV_HEIGHT
17
+ end
18
+
19
+ def columns
20
+ GRID.max_by(&:size).size
21
+ end
22
+
23
+ def column_cells
24
+ GRID.transpose
25
+ end
26
+
27
+ def rows
28
+ GRID.size
29
+ end
30
+
31
+ def row_cells
32
+ GRID
33
+ end
34
+
35
+ def cell_width(name)
36
+ cell_size(CANV_WIDTH, columns, size_multiplier(row_cells, name))
37
+ end
38
+
39
+ def cell_height(name)
40
+ cell_size(CANV_HEIGHT, rows, size_multiplier(column_cells, name))
41
+ end
42
+
43
+ def crop_rectangle(cell_name, image_width, image_height)
44
+ x, y = 0, 0
45
+ image = Cell.new(image_width, image_height)
46
+ cell = cell_rectangle(cell_name)
47
+
48
+ unless image.aspect_ratio >= cell.aspect_ratio
49
+ final_width = image.width
50
+ final_height = image.height - (image.height - (image.width / cell.aspect_ratio))
51
+ else
52
+ final_width = image_width - (image.width - (image.height * cell.aspect_ratio))
53
+ final_height = image.height
54
+ end
55
+
56
+ crop_rectangle = Cell.new(x, y, final_width, final_height)
57
+ crop_rectangle
58
+ end
59
+
60
+ def resize_rectangle(cell_name, image_width, image_height)
61
+ image = Cell.new(image_width, image_height)
62
+ cell_rectangle(cell_name)
63
+ end
64
+
65
+ def cell_rectangle(name)
66
+ row, column = row_cells.find_index {|row| row.include? name }, column_cells.find_index {|row| row.include? name }
67
+ Cell.new(column * (CANV_WIDTH / columns), row * (CANV_HEIGHT / rows), cell_width(name), cell_height(name))
68
+ end
69
+
70
+ private
71
+
72
+ def size_multiplier(table, name)
73
+ table.map {|row| row.count(name)}.max
74
+ end
75
+
76
+ def cell_size(total, divisions, multiplier)
77
+ (multiplier == 0) ? 0 : ((total / divisions) * multiplier)
78
+ end
79
+ end
80
+
81
+ end
@@ -0,0 +1,44 @@
1
+ require 'open-uri'
2
+ require 'tempfile'
3
+ require 'fileutils'
4
+ require 'date'
5
+
6
+
7
+ module Flico
8
+
9
+ class FetchingError < StandardError; end
10
+
11
+ class FetchImage
12
+
13
+ def call(url)
14
+ tempfile = Tempfile.new 'temp_image'
15
+ IO.copy_stream(open(url, read_timeout: 5), tempfile)
16
+ tempfile.rewind
17
+ tempfile
18
+ rescue OpenURI::HTTPError => e
19
+ raise FetchingError, "Couldn't download from: #{url} due to #{e.message}"
20
+ end
21
+
22
+ end
23
+
24
+ class SaveCollage
25
+
26
+ attr_accessor :output_file_name
27
+
28
+ def call(file_path)
29
+ file_name = output_file_name || validate_file_name
30
+ FileUtils.mv file_path, file_name
31
+ puts "Flicollage saved at #{file_name}"
32
+ end
33
+
34
+ private
35
+
36
+ def validate_file_name
37
+ puts "Enter file name for collage (press ENTER to use '#{default}')"
38
+ file_name = STDIN.gets.strip
39
+ file_name.empty? ? "flicollage-#{Time.now.strftime('%Y%m%d%H%M%S')}.png" : file_name
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ require 'flico/flickr_command'
3
+
4
+ describe Flico::FlickrCommand do
5
+
6
+ let(:search_results) {[{"id"=>"33472607802", "owner"=>"78759190@N05", "secret"=>"42e011bcf5", "server"=>"2805", "farm"=>3, "title"=>"Volkswagen Golf in Luxembourg", "ispublic"=>1, "isfriend"=>0, "isfamily"=>0}]}
7
+ let(:sizes_results) {
8
+ [
9
+ {"label"=>"Square", "width"=>75, "height"=>75, "source"=>"https://farm3.staticflickr.com/2805/33472607802_42e011bcf5_s.jpg", "url"=>"https://farm3.staticflickr.com/2805/33472607802_42e011bcf5/sizes/sq/", "media"=>"photo"},
10
+ {"label"=>"Large Square", "width"=>"150", "height"=>"150", "source"=>"https://farm3.staticflickr.com/2805/33472607802_42e011bcf5_q.jpg", "url"=>"https://farm3.staticflickr.com/2805/33472607802_42e011bcf5/sizes/q/", "media"=>"photo"},
11
+ {"label"=>"Thumbnail", "width"=>"100", "height"=>"66", "source"=>"https://farm3.staticflickr.com/2805/33472607802_42e011bcf5_t.jpg", "url"=>"https://farm3.staticflickr.com/2805/33472607802_42e011bcf5/sizes/t/", "media"=>"photo"}
12
+ ]
13
+ }
14
+ let(:subject) { described_class.new(search_command: search_command, sizes_command: sizes_command) }
15
+ let(:search_command) { double('search', call: search_results ) }
16
+ let(:sizes_command) { double('sizes', call: sizes_results)}
17
+
18
+ context 'search success' do
19
+ it 'should return image url for search keyword' do
20
+ expect(subject.call 'Volkswagen Golf in Luxembourg').to eq('https://farm3.staticflickr.com/2805/33472607802_42e011bcf5_q.jpg')
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,100 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
+ RSpec.configure do |config|
17
+ # rspec-expectations config goes here. You can use an alternate
18
+ # assertion/expectation library such as wrong or the stdlib/minitest
19
+ # assertions if you prefer.
20
+ config.expect_with :rspec do |expectations|
21
+ # This option will default to `true` in RSpec 4. It makes the `description`
22
+ # and `failure_message` of custom matchers include text for helper methods
23
+ # defined using `chain`, e.g.:
24
+ # be_bigger_than(2).and_smaller_than(4).description
25
+ # # => "be bigger than 2 and smaller than 4"
26
+ # ...rather than:
27
+ # # => "be bigger than 2"
28
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
29
+ end
30
+
31
+ # rspec-mocks config goes here. You can use an alternate test double
32
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
33
+ config.mock_with :rspec do |mocks|
34
+ # Prevents you from mocking or stubbing a method that does not exist on
35
+ # a real object. This is generally recommended, and will default to
36
+ # `true` in RSpec 4.
37
+ mocks.verify_partial_doubles = true
38
+ end
39
+
40
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
41
+ # have no way to turn it off -- the option exists only for backwards
42
+ # compatibility in RSpec 3). It causes shared context metadata to be
43
+ # inherited by the metadata hash of host groups and examples, rather than
44
+ # triggering implicit auto-inclusion in groups with matching metadata.
45
+ config.shared_context_metadata_behavior = :apply_to_host_groups
46
+
47
+ # The settings below are suggested to provide a good initial experience
48
+ # with RSpec, but feel free to customize to your heart's content.
49
+ =begin
50
+ # This allows you to limit a spec run to individual examples or groups
51
+ # you care about by tagging them with `:focus` metadata. When nothing
52
+ # is tagged with `:focus`, all examples get run. RSpec also provides
53
+ # aliases for `it`, `describe`, and `context` that include `:focus`
54
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
55
+ config.filter_run_when_matching :focus
56
+
57
+ # Allows RSpec to persist some state between runs in order to support
58
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
59
+ # you configure your source control system to ignore this file.
60
+ config.example_status_persistence_file_path = "spec/examples.txt"
61
+
62
+ # Limits the available syntax to the non-monkey patched syntax that is
63
+ # recommended. For more details, see:
64
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
65
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
66
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
67
+ config.disable_monkey_patching!
68
+
69
+ # This setting enables warnings. It's recommended, but in some cases may
70
+ # be too noisy due to issues in dependencies.
71
+ config.warnings = true
72
+
73
+ # Many RSpec users commonly either run the entire suite or an individual
74
+ # file, and it's useful to allow more verbose output when running an
75
+ # individual spec file.
76
+ if config.files_to_run.one?
77
+ # Use the documentation formatter for detailed output,
78
+ # unless a formatter has already been configured
79
+ # (e.g. via a command-line flag).
80
+ config.default_formatter = "doc"
81
+ end
82
+
83
+ # Print the 10 slowest examples and example groups at the
84
+ # end of the spec run, to help surface which specs are running
85
+ # particularly slow.
86
+ config.profile_examples = 10
87
+
88
+ # Run specs in random order to surface order dependencies. If you find an
89
+ # order dependency and want to debug it, you can fix the order by providing
90
+ # the seed, which is printed after each run.
91
+ # --seed 1234
92
+ config.order = :random
93
+
94
+ # Seed global randomization in this process using the `--seed` CLI option.
95
+ # Setting this allows you to use `--seed` to deterministically reproduce
96
+ # test failures related to randomization by passing the same `--seed` value
97
+ # as the one that triggered the failure.
98
+ Kernel.srand config.seed
99
+ =end
100
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: flico
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Amandeep Bhamra
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: flickraw
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mini_magick
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description:
84
+ email:
85
+ - amandeep.bhamra@gmail.com
86
+ executables:
87
+ - flico
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".ruby-version"
94
+ - Gemfile
95
+ - Gemfile.lock
96
+ - LICENSE.text
97
+ - README.md
98
+ - Rakefile
99
+ - bin/console
100
+ - bin/flico
101
+ - bin/setup
102
+ - flico.gemspec
103
+ - lib/flico.rb
104
+ - lib/flico/app.rb
105
+ - lib/flico/cell.rb
106
+ - lib/flico/collager.rb
107
+ - lib/flico/dictionary.rb
108
+ - lib/flico/flickr_command.rb
109
+ - lib/flico/grid.rb
110
+ - lib/flico/saver.rb
111
+ - spec/flickr_command_spec.rb
112
+ - spec/spec_helper.rb
113
+ homepage: https://github.com/amandeepbhamra/flico
114
+ licenses:
115
+ - MIT
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 2.5.1
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: CLI tool to create collage using Flickr
137
+ test_files: []